Block popups from content extensions.
[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 "TypesettingFeatures.h"
39 #include <wtf/TypeCasts.h>
40 #include <wtf/text/StringHash.h>
41
42 #if PLATFORM(COCOA)
43 #include "WebCoreSystemInterface.h"
44 #include <wtf/RetainPtr.h>
45 #endif
46
47 #if PLATFORM(WIN)
48 #include <usp10.h>
49 #endif
50
51 #if USE(CAIRO)
52 #include <cairo.h>
53 #endif
54
55 #if USE(CG)
56 #include <WebCore/CoreGraphicsSPI.h>
57 #endif
58
59 namespace WebCore {
60
61 class GlyphPage;
62 class FontDescription;
63 class SharedBuffer;
64 struct GlyphData;
65 struct WidthIterator;
66
67 enum FontVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant };
68 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
69
70 class Font : public RefCounted<Font> {
71 public:
72     class SVGData {
73         WTF_MAKE_FAST_ALLOCATED;
74     public:
75         virtual ~SVGData() { }
76
77         virtual void initializeFont(Font*, float fontSize) = 0;
78         virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0;
79         virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const Font*) const = 0;
80     };
81
82     // Used to create platform fonts.
83     static Ref<Font> create(const FontPlatformData& platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false)
84     {
85         return adoptRef(*new Font(platformData, isCustomFont, isLoading, isTextOrientationFallback));
86     }
87
88     // Used to create SVG Fonts.
89     static Ref<Font> create(std::unique_ptr<SVGData> svgData, float fontSize, bool syntheticBold, bool syntheticItalic)
90     {
91         return adoptRef(*new Font(WTF::move(svgData), fontSize, syntheticBold, syntheticItalic));
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     PassRefPtr<Font> smallCapsFont(const FontDescription&) const;
105     PassRefPtr<Font> emphasisMarkFont(const FontDescription&) const;
106     PassRefPtr<Font> brokenIdeographFont() const;
107     PassRefPtr<Font> nonSyntheticItalicFont() const;
108
109     PassRefPtr<Font> variantFont(const FontDescription& description, FontVariant variant) const
110     {
111         switch (variant) {
112         case SmallCapsVariant:
113             return smallCapsFont(description);
114         case EmphasisMarkVariant:
115             return emphasisMarkFont(description);
116         case BrokenIdeographVariant:
117             return brokenIdeographFont();
118         case AutoVariant:
119         case NormalVariant:
120             break;
121         }
122         ASSERT_NOT_REACHED();
123         return const_cast<Font*>(this);
124     }
125
126     PassRefPtr<Font> verticalRightOrientationFont() const;
127     PassRefPtr<Font> uprightOrientationFont() const;
128
129     bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
130     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
131
132     FontMetrics& fontMetrics() { return m_fontMetrics; }
133     const FontMetrics& fontMetrics() const { return m_fontMetrics; }
134     float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
135
136     float maxCharWidth() const { return m_maxCharWidth; }
137     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
138
139     float avgCharWidth() const { return m_avgCharWidth; }
140     void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
141
142     FloatRect boundsForGlyph(Glyph) const;
143     float widthForGlyph(Glyph) const;
144     FloatRect platformBoundsForGlyph(Glyph) const;
145     float platformWidthForGlyph(Glyph) const;
146
147     float spaceWidth() const { return m_spaceWidth; }
148     float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
149     void setSpaceWidths(float spaceWidth)
150     {
151         m_spaceWidth = spaceWidth;
152         m_adjustedSpaceWidth = spaceWidth;
153     }
154
155 #if USE(CG) || USE(CAIRO)
156     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
157 #endif
158
159     Glyph spaceGlyph() const { return m_spaceGlyph; }
160     void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
161     Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; }
162     void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
163     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
164     Glyph zeroGlyph() const { return m_zeroGlyph; }
165     void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
166
167     GlyphData glyphDataForCharacter(UChar32) const;
168     Glyph glyphForCharacter(UChar32) const;
169
170     RefPtr<Font> systemFallbackFontForCharacter(UChar32, const FontDescription&, bool isForPlatformFont) const;
171
172     const GlyphPage* glyphPage(unsigned pageNumber) const;
173
174     void determinePitch();
175     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
176
177     const SVGData* svgData() const { return m_svgData.get(); }
178     bool isSVGFont() const { return !!m_svgData; }
179
180     bool isCustomFont() const { return m_isCustomFont; }
181     bool isLoading() const { return m_isLoading; }
182
183 #ifndef NDEBUG
184     String description() const;
185 #endif
186
187 #if USE(APPKIT)
188     const Font* compositeFontReferenceFont(NSFont *key) const;
189     NSFont* getNSFont() const { return m_platformData.nsFont(); }
190 #endif
191
192 #if PLATFORM(IOS)
193     CTFontRef getCTFont() const { return m_platformData.font(); }
194     bool shouldNotBeUsedForArabic() const { return m_shouldNotBeUsedForArabic; };
195 #endif
196 #if PLATFORM(COCOA)
197     CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
198 #endif
199
200 #if PLATFORM(COCOA) || USE(HARFBUZZ)
201     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
202 #endif
203
204     bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t glyphCount, TypesettingFeatures) const;
205
206 #if PLATFORM(WIN)
207     bool isSystemFont() const { return m_isSystemFont; }
208     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
209     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
210     static void setShouldApplyMacAscentHack(bool);
211     static bool shouldApplyMacAscentHack();
212     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
213 #endif
214
215 private:
216     Font(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
217
218     Font(std::unique_ptr<SVGData>, float fontSize, bool syntheticBold, bool syntheticItalic);
219
220     void platformInit();
221     void platformGlyphInit();
222     void platformCharWidthInit();
223     void platformDestroy();
224
225     void initCharWidths();
226
227     PassRefPtr<Font> createScaledFont(const FontDescription&, float scaleFactor) const;
228     PassRefPtr<Font> platformCreateScaledFont(const FontDescription&, float scaleFactor) const;
229
230     void removeFromSystemFallbackCache();
231
232 #if PLATFORM(WIN)
233     void initGDIFont();
234     void platformCommonDestroy();
235     FloatRect boundsForGDIGlyph(Glyph) const;
236     float widthForGDIGlyph(Glyph) const;
237 #endif
238
239     FontMetrics m_fontMetrics;
240     float m_maxCharWidth;
241     float m_avgCharWidth;
242
243     FontPlatformData m_platformData;
244     std::unique_ptr<SVGData> m_svgData;
245
246     mutable RefPtr<GlyphPage> m_glyphPageZero;
247     mutable HashMap<unsigned, RefPtr<GlyphPage>> m_glyphPages;
248     mutable std::unique_ptr<GlyphMetricsMap<FloatRect>> m_glyphToBoundsMap;
249     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
250
251     bool m_treatAsFixedPitch;
252     bool m_isCustomFont; // Whether or not we are custom font loaded via @font-face
253     bool m_isLoading; // Whether or not this custom font is still in the act of loading.
254
255     bool m_isTextOrientationFallback;
256     bool m_isBrokenIdeographFallback;
257
258     bool m_isUsedInSystemFallbackCache { false };
259
260     mutable RefPtr<OpenTypeMathData> m_mathData;
261 #if ENABLE(OPENTYPE_VERTICAL)
262     RefPtr<OpenTypeVerticalData> m_verticalData;
263 #endif
264     bool m_hasVerticalGlyphs;
265
266     Glyph m_spaceGlyph;
267     float m_spaceWidth;
268     Glyph m_zeroGlyph;
269     float m_adjustedSpaceWidth;
270
271     Glyph m_zeroWidthSpaceGlyph;
272
273     struct DerivedFontData {
274         explicit DerivedFontData(bool custom)
275             : forCustomFont(custom)
276         {
277         }
278         ~DerivedFontData();
279
280         bool forCustomFont;
281         RefPtr<Font> smallCaps;
282         RefPtr<Font> emphasisMark;
283         RefPtr<Font> brokenIdeograph;
284         RefPtr<Font> verticalRightOrientation;
285         RefPtr<Font> uprightOrientation;
286         RefPtr<Font> nonSyntheticItalic;
287 #if USE(APPKIT)
288         HashMap<NSFont*, RefPtr<Font>> compositeFontReferences;
289 #endif
290     };
291
292     mutable std::unique_ptr<DerivedFontData> m_derivedFontData;
293
294 #if USE(CG) || USE(CAIRO)
295     float m_syntheticBoldOffset;
296 #endif
297
298 #if PLATFORM(COCOA)
299     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef>> m_CFStringAttributes;
300 #endif
301
302 #if PLATFORM(COCOA) || USE(HARFBUZZ)
303     mutable std::unique_ptr<HashMap<String, bool>> m_combiningCharacterSequenceSupport;
304 #endif
305
306 #if PLATFORM(WIN)
307     bool m_isSystemFont;
308     mutable SCRIPT_CACHE m_scriptCache;
309     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
310 #endif
311 #if PLATFORM(IOS)
312     bool m_shouldNotBeUsedForArabic;
313 #endif
314 };
315
316 ALWAYS_INLINE FloatRect Font::boundsForGlyph(Glyph glyph) const
317 {
318     if (isZeroWidthSpaceGlyph(glyph))
319         return FloatRect();
320
321     FloatRect bounds;
322     if (m_glyphToBoundsMap) {
323         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
324         if (bounds.width() != cGlyphSizeUnknown)
325             return bounds;
326     }
327
328     bounds = platformBoundsForGlyph(glyph);
329     if (!m_glyphToBoundsMap)
330         m_glyphToBoundsMap = std::make_unique<GlyphMetricsMap<FloatRect>>();
331     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
332     return bounds;
333 }
334
335 ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const
336 {
337     if (isZeroWidthSpaceGlyph(glyph))
338         return 0;
339
340     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
341     if (width != cGlyphSizeUnknown)
342         return width;
343
344     if (isSVGFont())
345         width = m_svgData->widthForSVGGlyph(glyph, m_platformData.size());
346 #if ENABLE(OPENTYPE_VERTICAL)
347     else if (m_verticalData)
348 #if USE(CG) || USE(CAIRO)
349         width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
350 #else
351         width = m_verticalData->advanceHeight(this, glyph);
352 #endif
353 #endif
354     else
355         width = platformWidthForGlyph(glyph);
356
357     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
358     return width;
359 }
360
361 } // namespace WebCore
362
363 #endif // Font_h