Update ANGLE
[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-2016 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 "FontMetrics.h"
29 #include "FontPlatformData.h"
30 #include "GlyphBuffer.h"
31 #include "GlyphMetricsMap.h"
32 #include "GlyphPage.h"
33 #include "OpenTypeMathData.h"
34 #if ENABLE(OPENTYPE_VERTICAL)
35 #include "OpenTypeVerticalData.h"
36 #endif
37 #include <wtf/BitVector.h>
38 #include <wtf/Optional.h>
39 #include <wtf/text/StringHash.h>
40
41 #if PLATFORM(COCOA)
42 #include <wtf/RetainPtr.h>
43 #endif
44
45 #if PLATFORM(WIN)
46 #include <usp10.h>
47 #endif
48
49 #if USE(CG)
50 #include <pal/spi/cg/CoreGraphicsSPI.h>
51 #endif
52
53 #if USE(DIRECT2D)
54 interface IDWriteFactory5;
55 interface IDWriteGdiInterop;
56 #endif
57
58 namespace WebCore {
59
60 class GlyphPage;
61 class FontDescription;
62 class SharedBuffer;
63 struct GlyphData;
64 struct WidthIterator;
65
66 enum FontVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant };
67 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
68 enum class IsForPlatformFont : uint8_t { No, Yes };
69
70 class Font : public RefCounted<Font> {
71 public:
72     // Used to create platform fonts.
73     enum class Origin : uint8_t {
74         Remote,
75         Local
76     };
77     enum class Interstitial : uint8_t {
78         Yes,
79         No
80     };
81     enum class Visibility : uint8_t {
82         Visible,
83         Invisible
84     };
85     enum class OrientationFallback : uint8_t {
86         Yes,
87         No
88     };
89     static Ref<Font> create(const FontPlatformData& platformData, Origin origin = Origin::Local, Interstitial interstitial = Interstitial::No, Visibility visibility = Visibility::Visible, OrientationFallback orientationFallback = OrientationFallback::No)
90     {
91         return adoptRef(*new Font(platformData, origin, interstitial, visibility, orientationFallback));
92     }
93
94     WEBCORE_EXPORT ~Font();
95
96     static const Font* systemFallback() { return reinterpret_cast<const Font*>(-1); }
97
98     const FontPlatformData& platformData() const { return m_platformData; }
99     const OpenTypeMathData* mathData() const;
100 #if ENABLE(OPENTYPE_VERTICAL)
101     const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); }
102 #endif
103
104     const Font* smallCapsFont(const FontDescription&) const;
105     const Font& noSynthesizableFeaturesFont() const;
106     const Font* emphasisMarkFont(const FontDescription&) const;
107     const Font& brokenIdeographFont() const;
108
109     const Font* variantFont(const FontDescription& description, FontVariant variant) const
110     {
111 #if PLATFORM(COCOA)
112         ASSERT(variant != SmallCapsVariant);
113 #endif
114         switch (variant) {
115         case SmallCapsVariant:
116             return smallCapsFont(description);
117         case EmphasisMarkVariant:
118             return emphasisMarkFont(description);
119         case BrokenIdeographVariant:
120             return &brokenIdeographFont();
121         case AutoVariant:
122         case NormalVariant:
123             break;
124         }
125         ASSERT_NOT_REACHED();
126         return const_cast<Font*>(this);
127     }
128
129     bool variantCapsSupportsCharacterForSynthesis(FontVariantCaps, UChar32) const;
130
131     const Font& verticalRightOrientationFont() const;
132     const Font& uprightOrientationFont() const;
133     const Font& invisibleFont() const;
134
135     bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
136     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
137
138     FontMetrics& fontMetrics() { return m_fontMetrics; }
139     const FontMetrics& fontMetrics() const { return m_fontMetrics; }
140     float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
141
142     float maxCharWidth() const { return m_maxCharWidth; }
143     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
144
145     float avgCharWidth() const { return m_avgCharWidth; }
146     void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
147
148     FloatRect boundsForGlyph(Glyph) const;
149     float widthForGlyph(Glyph) const;
150     const Path& pathForGlyph(Glyph) const; // Don't store the result of this! The hash map is free to rehash at any point, leaving this reference dangling.
151     FloatRect platformBoundsForGlyph(Glyph) const;
152     float platformWidthForGlyph(Glyph) const;
153     Path platformPathForGlyph(Glyph) const;
154
155     float spaceWidth() const { return m_spaceWidth; }
156     float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
157     void setSpaceWidths(float spaceWidth)
158     {
159         m_spaceWidth = spaceWidth;
160         m_adjustedSpaceWidth = spaceWidth;
161     }
162
163 #if USE(CG) || USE(DIRECT2D) || USE(CAIRO)
164     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
165 #endif
166
167     Glyph spaceGlyph() const { return m_spaceGlyph; }
168     void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
169     Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; }
170     void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
171     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
172     Glyph zeroGlyph() const { return m_zeroGlyph; }
173     void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
174
175     GlyphData glyphDataForCharacter(UChar32) const;
176     Glyph glyphForCharacter(UChar32) const;
177     bool supportsCodePoint(UChar32) const;
178     bool platformSupportsCodePoint(UChar32, Optional<UChar32> variation = WTF::nullopt) const;
179
180     RefPtr<Font> systemFallbackFontForCharacter(UChar32, const FontDescription&, IsForPlatformFont) const;
181
182     const GlyphPage* glyphPage(unsigned pageNumber) const;
183
184     void determinePitch();
185     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
186
187     Origin origin() const { return m_origin; }
188     bool isInterstitial() const { return m_isInterstitial; }
189     Visibility visibility() const { return m_visibility; }
190
191 #if !LOG_DISABLED
192     String description() const;
193 #endif
194
195 #if PLATFORM(IOS_FAMILY)
196     bool shouldNotBeUsedForArabic() const { return m_shouldNotBeUsedForArabic; };
197 #endif
198 #if PLATFORM(COCOA)
199     CTFontRef getCTFont() const { return m_platformData.font(); }
200     CFDictionaryRef getCFStringAttributes(bool enableKerning, FontOrientation) const;
201     const BitVector& glyphsSupportedBySmallCaps() const;
202     const BitVector& glyphsSupportedByAllSmallCaps() const;
203     const BitVector& glyphsSupportedByPetiteCaps() const;
204     const BitVector& glyphsSupportedByAllPetiteCaps() const;
205 #endif
206
207 #if HAVE(DISALLOWABLE_USER_INSTALLED_FONTS)
208     bool isUserInstalledFont() const;
209 #endif
210
211     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
212     bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t glyphCount, bool enableKerning, bool requiresShaping) const;
213
214 #if PLATFORM(WIN)
215     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
216     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
217     static void setShouldApplyMacAscentHack(bool);
218     static bool shouldApplyMacAscentHack();
219     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
220 #endif
221
222 private:
223     Font(const FontPlatformData&, Origin, Interstitial, Visibility, OrientationFallback);
224
225     void platformInit();
226     void platformGlyphInit();
227     void platformCharWidthInit();
228     void platformDestroy();
229
230     void initCharWidths();
231
232     RefPtr<Font> createFontWithoutSynthesizableFeatures() const;
233     RefPtr<Font> createScaledFont(const FontDescription&, float scaleFactor) const;
234     RefPtr<Font> platformCreateScaledFont(const FontDescription&, float scaleFactor) const;
235
236     void removeFromSystemFallbackCache();
237     
238     struct DerivedFonts;
239     DerivedFonts& ensureDerivedFontData() const;
240
241 #if PLATFORM(WIN)
242     void initGDIFont();
243     void platformCommonDestroy();
244     FloatRect boundsForGDIGlyph(Glyph) const;
245     float widthForGDIGlyph(Glyph) const;
246 #endif
247
248     FontMetrics m_fontMetrics;
249     float m_maxCharWidth { -1 };
250     float m_avgCharWidth { -1 };
251
252     const FontPlatformData m_platformData;
253
254     mutable RefPtr<GlyphPage> m_glyphPageZero;
255     mutable HashMap<unsigned, RefPtr<GlyphPage>> m_glyphPages;
256     mutable std::unique_ptr<GlyphMetricsMap<FloatRect>> m_glyphToBoundsMap;
257     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
258     mutable GlyphMetricsMap<Optional<Path>> m_glyphPathMap;
259     mutable BitVector m_codePointSupport;
260
261     mutable RefPtr<OpenTypeMathData> m_mathData;
262 #if ENABLE(OPENTYPE_VERTICAL)
263     RefPtr<OpenTypeVerticalData> m_verticalData;
264 #endif
265
266     struct DerivedFonts {
267         WTF_MAKE_STRUCT_FAST_ALLOCATED;
268     public:
269
270         RefPtr<Font> smallCapsFont;
271         RefPtr<Font> noSynthesizableFeaturesFont;
272         RefPtr<Font> emphasisMarkFont;
273         RefPtr<Font> brokenIdeographFont;
274         RefPtr<Font> verticalRightOrientationFont;
275         RefPtr<Font> uprightOrientationFont;
276         RefPtr<Font> invisibleFont;
277     };
278
279     mutable std::unique_ptr<DerivedFonts> m_derivedFontData;
280
281 #if PLATFORM(COCOA)
282     mutable RetainPtr<CFMutableDictionaryRef> m_nonKernedCFStringAttributes;
283     mutable RetainPtr<CFMutableDictionaryRef> m_kernedCFStringAttributes;
284     mutable Optional<BitVector> m_glyphsSupportedBySmallCaps;
285     mutable Optional<BitVector> m_glyphsSupportedByAllSmallCaps;
286     mutable Optional<BitVector> m_glyphsSupportedByPetiteCaps;
287     mutable Optional<BitVector> m_glyphsSupportedByAllPetiteCaps;
288 #endif
289
290 #if PLATFORM(WIN)
291     mutable SCRIPT_CACHE m_scriptCache;
292     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
293 #endif
294
295     Glyph m_spaceGlyph { 0 };
296     Glyph m_zeroGlyph { 0 };
297     Glyph m_zeroWidthSpaceGlyph { 0 };
298
299     Origin m_origin; // Whether or not we are custom font loaded via @font-face
300     Visibility m_visibility; // @font-face's internal timer can cause us to show fonts even when a font is being downloaded.
301
302     float m_spaceWidth { 0 };
303     float m_adjustedSpaceWidth { 0 };
304
305 #if USE(CG) || USE(DIRECT2D) || USE(CAIRO)
306     float m_syntheticBoldOffset { 0 };
307 #endif
308
309     unsigned m_treatAsFixedPitch : 1;
310     unsigned m_isInterstitial : 1; // Whether or not this custom font is the last resort placeholder for a loading font
311
312     unsigned m_isTextOrientationFallback : 1;
313     unsigned m_isBrokenIdeographFallback : 1;
314     unsigned m_hasVerticalGlyphs : 1;
315
316     unsigned m_isUsedInSystemFallbackCache : 1;
317
318 #if PLATFORM(IOS_FAMILY)
319     unsigned m_shouldNotBeUsedForArabic : 1;
320 #endif
321 };
322
323 #if PLATFORM(IOS_FAMILY)
324 bool fontFamilyShouldNotBeUsedForArabic(CFStringRef);
325 #endif
326
327 ALWAYS_INLINE FloatRect Font::boundsForGlyph(Glyph glyph) const
328 {
329     if (isZeroWidthSpaceGlyph(glyph))
330         return FloatRect();
331
332     FloatRect bounds;
333     if (m_glyphToBoundsMap) {
334         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
335         if (bounds.width() != cGlyphSizeUnknown)
336             return bounds;
337     }
338
339     bounds = platformBoundsForGlyph(glyph);
340     if (!m_glyphToBoundsMap)
341         m_glyphToBoundsMap = makeUnique<GlyphMetricsMap<FloatRect>>();
342     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
343     return bounds;
344 }
345
346 ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const
347 {
348     // The optimization of returning 0 for the zero-width-space glyph is incorrect for the LastResort font,
349     // used in place of the actual font when isLoading() is true on both macOS and iOS.
350     // The zero-width-space glyph in that font does not have a width of zero and, further, that glyph is used
351     // for many other characters and must not be zero width when used for them.
352     if (isZeroWidthSpaceGlyph(glyph) && !isInterstitial())
353         return 0;
354
355     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
356     if (width != cGlyphSizeUnknown)
357         return width;
358
359 #if ENABLE(OPENTYPE_VERTICAL)
360     if (m_verticalData) {
361 #if USE(CG) || USE(DIRECT2D) || USE(CAIRO)
362         width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
363 #else
364         width = m_verticalData->advanceHeight(this, glyph);
365 #endif
366     } else
367 #endif
368         width = platformWidthForGlyph(glyph);
369
370     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
371     return width;
372 }
373
374 } // namespace WebCore
375
376 #endif // Font_h