Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / platform / graphics / Font.h
1 /*
2  * This file is part of the internal font implementation.
3  *
4  * Copyright (C) 2006, 2008, 2010, 2015 Apple Inc. All rights reserved.
5  * Copyright (C) 2007-2008 Torch Mobile, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #ifndef Font_h
25 #define Font_h
26
27 #include "FloatRect.h"
28 #include "FontBaseline.h"
29 #include "FontMetrics.h"
30 #include "FontPlatformData.h"
31 #include "GlyphBuffer.h"
32 #include "GlyphMetricsMap.h"
33 #include "GlyphPage.h"
34 #include "OpenTypeMathData.h"
35 #if ENABLE(OPENTYPE_VERTICAL)
36 #include "OpenTypeVerticalData.h"
37 #endif
38 #include <wtf/BitVector.h>
39 #include <wtf/Optional.h>
40 #include <wtf/TypeCasts.h>
41 #include <wtf/text/StringHash.h>
42
43 #if PLATFORM(COCOA)
44 #include "WebCoreSystemInterface.h"
45 #include <wtf/RetainPtr.h>
46 #endif
47
48 #if PLATFORM(WIN)
49 #include <usp10.h>
50 #endif
51
52 #if USE(CAIRO)
53 #include <cairo.h>
54 #endif
55
56 #if USE(CG)
57 #include <WebCore/CoreGraphicsSPI.h>
58 #endif
59
60 namespace WebCore {
61
62 class GlyphPage;
63 class FontDescription;
64 class SharedBuffer;
65 struct GlyphData;
66 struct WidthIterator;
67
68 enum FontVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant };
69 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
70
71 class Font : public RefCounted<Font> {
72 public:
73     class SVGData {
74         WTF_MAKE_FAST_ALLOCATED;
75     public:
76         virtual ~SVGData() { }
77
78         virtual void initializeFont(Font*, float fontSize) = 0;
79         virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0;
80         virtual bool fillSVGGlyphPage(GlyphPage*, UChar* buffer, unsigned bufferLength) const = 0;
81     };
82
83     // Used to create platform fonts.
84     static Ref<Font> create(const FontPlatformData& platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false)
85     {
86         return adoptRef(*new Font(platformData, isCustomFont, isLoading, isTextOrientationFallback));
87     }
88
89     // Used to create SVG Fonts.
90     static Ref<Font> create(std::unique_ptr<SVGData> svgData, float fontSize, bool syntheticBold, bool syntheticItalic)
91     {
92         return adoptRef(*new Font(WTFMove(svgData), fontSize, syntheticBold, syntheticItalic));
93     }
94
95     WEBCORE_EXPORT ~Font();
96
97     static const Font* systemFallback() { return reinterpret_cast<const Font*>(-1); }
98
99     const FontPlatformData& platformData() const { return m_platformData; }
100     const OpenTypeMathData* mathData() const;
101 #if ENABLE(OPENTYPE_VERTICAL)
102     const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); }
103 #endif
104
105     const Font* smallCapsFont(const FontDescription&) const;
106     const Font& noSynthesizableFeaturesFont() const;
107     const Font* emphasisMarkFont(const FontDescription&) const;
108     const Font& brokenIdeographFont() const;
109     const Font& nonSyntheticItalicFont() const;
110
111     const Font* variantFont(const FontDescription& description, FontVariant variant) const
112     {
113 #if PLATFORM(COCOA)
114         ASSERT(variant != SmallCapsVariant);
115 #endif
116         switch (variant) {
117         case SmallCapsVariant:
118             return smallCapsFont(description);
119         case EmphasisMarkVariant:
120             return emphasisMarkFont(description);
121         case BrokenIdeographVariant:
122             return &brokenIdeographFont();
123         case AutoVariant:
124         case NormalVariant:
125             break;
126         }
127         ASSERT_NOT_REACHED();
128         return const_cast<Font*>(this);
129     }
130
131     bool variantCapsSupportsCharacterForSynthesis(FontVariantCaps, UChar32) const;
132
133     const Font& verticalRightOrientationFont() const;
134     const Font& uprightOrientationFont() const;
135
136     bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
137     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
138
139     FontMetrics& fontMetrics() { return m_fontMetrics; }
140     const FontMetrics& fontMetrics() const { return m_fontMetrics; }
141     float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
142
143     float maxCharWidth() const { return m_maxCharWidth; }
144     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
145
146     float avgCharWidth() const { return m_avgCharWidth; }
147     void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
148
149     FloatRect boundsForGlyph(Glyph) const;
150     float widthForGlyph(Glyph) const;
151     FloatRect platformBoundsForGlyph(Glyph) const;
152     float platformWidthForGlyph(Glyph) const;
153
154     float spaceWidth() const { return m_spaceWidth; }
155     float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
156     void setSpaceWidths(float spaceWidth)
157     {
158         m_spaceWidth = spaceWidth;
159         m_adjustedSpaceWidth = spaceWidth;
160     }
161
162 #if USE(CG) || USE(CAIRO)
163     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
164 #endif
165
166     Glyph spaceGlyph() const { return m_spaceGlyph; }
167     void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
168     Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; }
169     void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
170     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
171     Glyph zeroGlyph() const { return m_zeroGlyph; }
172     void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
173
174     GlyphData glyphDataForCharacter(UChar32) const;
175     Glyph glyphForCharacter(UChar32) const;
176
177     RefPtr<Font> systemFallbackFontForCharacter(UChar32, const FontDescription&, bool isForPlatformFont) const;
178
179     const GlyphPage* glyphPage(unsigned pageNumber) const;
180
181     void determinePitch();
182     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
183
184     const SVGData* svgData() const { return m_svgData.get(); }
185     bool isSVGFont() const { return !!m_svgData; }
186
187     bool isCustomFont() const { return m_isCustomFont; }
188     bool isLoading() const { return m_isLoading; }
189
190 #ifndef NDEBUG
191     String description() const;
192 #endif
193
194 #if USE(APPKIT)
195     NSFont* getNSFont() const { return m_platformData.nsFont(); }
196 #endif
197
198 #if PLATFORM(IOS)
199     CTFontRef getCTFont() const { return m_platformData.font(); }
200     bool shouldNotBeUsedForArabic() const { return m_shouldNotBeUsedForArabic; };
201 #endif
202 #if PLATFORM(COCOA)
203     CFDictionaryRef getCFStringAttributes(bool enableKerning, FontOrientation) const;
204     const BitVector& glyphsSupportedBySmallCaps() const;
205     const BitVector& glyphsSupportedByAllSmallCaps() const;
206     const BitVector& glyphsSupportedByPetiteCaps() const;
207     const BitVector& glyphsSupportedByAllPetiteCaps() const;
208 #endif
209
210 #if PLATFORM(COCOA) || USE(HARFBUZZ)
211     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
212 #endif
213
214     bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t glyphCount, bool enableKerning, bool requiresShaping) const;
215
216 #if PLATFORM(COCOA) || PLATFORM(WIN)
217 #endif
218
219 #if PLATFORM(WIN)
220     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
221     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
222     static void setShouldApplyMacAscentHack(bool);
223     static bool shouldApplyMacAscentHack();
224     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
225 #endif
226
227 private:
228     Font(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
229
230     Font(std::unique_ptr<SVGData>, float fontSize, bool syntheticBold, bool syntheticItalic);
231
232     Font(const FontPlatformData&, std::unique_ptr<SVGData>&&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
233
234     void platformInit();
235     void platformGlyphInit();
236     void platformCharWidthInit();
237     void platformDestroy();
238
239     void initCharWidths();
240
241     RefPtr<Font> createFontWithoutSynthesizableFeatures() const;
242     RefPtr<Font> createScaledFont(const FontDescription&, float scaleFactor) const;
243     RefPtr<Font> platformCreateScaledFont(const FontDescription&, float scaleFactor) const;
244
245     void removeFromSystemFallbackCache();
246
247 #if PLATFORM(WIN)
248     void initGDIFont();
249     void platformCommonDestroy();
250     FloatRect boundsForGDIGlyph(Glyph) const;
251     float widthForGDIGlyph(Glyph) const;
252 #endif
253
254     FontMetrics m_fontMetrics;
255     float m_maxCharWidth;
256     float m_avgCharWidth;
257
258     FontPlatformData m_platformData;
259     std::unique_ptr<SVGData> m_svgData;
260
261     mutable RefPtr<GlyphPage> m_glyphPageZero;
262     mutable HashMap<unsigned, RefPtr<GlyphPage>> m_glyphPages;
263     mutable std::unique_ptr<GlyphMetricsMap<FloatRect>> m_glyphToBoundsMap;
264     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
265
266     mutable RefPtr<OpenTypeMathData> m_mathData;
267 #if ENABLE(OPENTYPE_VERTICAL)
268     RefPtr<OpenTypeVerticalData> m_verticalData;
269 #endif
270
271     Glyph m_spaceGlyph { 0 };
272     float m_spaceWidth { 0 };
273     Glyph m_zeroGlyph { 0 };
274     float m_adjustedSpaceWidth { 0 };
275
276     Glyph m_zeroWidthSpaceGlyph { 0 };
277
278     struct DerivedFontData {
279 #if !COMPILER(MSVC)
280         WTF_MAKE_FAST_ALLOCATED;
281 #endif
282     public:
283         explicit DerivedFontData(bool custom)
284             : forCustomFont(custom)
285         {
286         }
287         ~DerivedFontData();
288
289         bool forCustomFont;
290         RefPtr<Font> smallCaps;
291         RefPtr<Font> noSynthesizableFeatures;
292         RefPtr<Font> emphasisMark;
293         RefPtr<Font> brokenIdeograph;
294         RefPtr<Font> verticalRightOrientation;
295         RefPtr<Font> uprightOrientation;
296         RefPtr<Font> nonSyntheticItalic;
297     };
298
299     mutable std::unique_ptr<DerivedFontData> m_derivedFontData;
300
301 #if USE(CG) || USE(CAIRO)
302     float m_syntheticBoldOffset;
303 #endif
304
305 #if PLATFORM(COCOA)
306     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef>> m_CFStringAttributes;
307     mutable Optional<BitVector> m_glyphsSupportedBySmallCaps;
308     mutable Optional<BitVector> m_glyphsSupportedByAllSmallCaps;
309     mutable Optional<BitVector> m_glyphsSupportedByPetiteCaps;
310     mutable Optional<BitVector> m_glyphsSupportedByAllPetiteCaps;
311 #endif
312
313 #if PLATFORM(COCOA) || USE(HARFBUZZ)
314     mutable std::unique_ptr<HashMap<String, bool>> m_combiningCharacterSequenceSupport;
315 #endif
316
317 #if PLATFORM(WIN)
318     mutable SCRIPT_CACHE m_scriptCache;
319     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
320 #endif
321
322     unsigned m_treatAsFixedPitch : 1;
323     unsigned m_isCustomFont : 1; // Whether or not we are custom font loaded via @font-face
324     unsigned m_isLoading : 1; // Whether or not this custom font is still in the act of loading.
325
326     unsigned m_isTextOrientationFallback : 1;
327     unsigned m_isBrokenIdeographFallback : 1;
328     unsigned m_hasVerticalGlyphs : 1;
329
330     unsigned m_isUsedInSystemFallbackCache : 1;
331
332 #if PLATFORM(IOS)
333     unsigned m_shouldNotBeUsedForArabic : 1;
334 #endif
335 };
336
337 #if PLATFORM(IOS)
338 bool fontFamilyShouldNotBeUsedForArabic(CFStringRef);
339 #endif
340
341 ALWAYS_INLINE FloatRect Font::boundsForGlyph(Glyph glyph) const
342 {
343     if (isZeroWidthSpaceGlyph(glyph))
344         return FloatRect();
345
346     FloatRect bounds;
347     if (m_glyphToBoundsMap) {
348         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
349         if (bounds.width() != cGlyphSizeUnknown)
350             return bounds;
351     }
352
353     bounds = platformBoundsForGlyph(glyph);
354     if (!m_glyphToBoundsMap)
355         m_glyphToBoundsMap = std::make_unique<GlyphMetricsMap<FloatRect>>();
356     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
357     return bounds;
358 }
359
360 ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const
361 {
362     if (isZeroWidthSpaceGlyph(glyph))
363         return 0;
364
365     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
366     if (width != cGlyphSizeUnknown)
367         return width;
368
369     if (isSVGFont())
370         width = m_svgData->widthForSVGGlyph(glyph, m_platformData.size());
371 #if ENABLE(OPENTYPE_VERTICAL)
372     else if (m_verticalData)
373 #if USE(CG) || USE(CAIRO)
374         width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
375 #else
376         width = m_verticalData->advanceHeight(this, glyph);
377 #endif
378 #endif
379     else
380         width = platformWidthForGlyph(glyph);
381
382     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
383     return width;
384 }
385
386 } // namespace WebCore
387
388 #endif // Font_h