Apply std::unique_ptr to FooFont classes
[WebKit-https.git] / Source / WebCore / platform / graphics / SimpleFontData.h
1 /*
2  * This file is part of the internal font implementation.
3  *
4  * Copyright (C) 2006, 2008, 2010 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 SimpleFontData_h
25 #define SimpleFontData_h
26
27 #include "FontBaseline.h"
28 #include "FontData.h"
29 #include "FontMetrics.h"
30 #include "FontPlatformData.h"
31 #include "FloatRect.h"
32 #include "GlyphBuffer.h"
33 #include "GlyphMetricsMap.h"
34 #include "GlyphPageTreeNode.h"
35 #include "OpenTypeMathData.h"
36 #if ENABLE(OPENTYPE_VERTICAL)
37 #include "OpenTypeVerticalData.h"
38 #endif
39 #include "TypesettingFeatures.h"
40 #include <wtf/OwnPtr.h>
41 #include <wtf/TypeCasts.h>
42 #include <wtf/text/StringHash.h>
43
44 #if PLATFORM(COCOA)
45 #include "WebCoreSystemInterface.h"
46 #include <wtf/RetainPtr.h>
47 #endif
48
49 #if PLATFORM(WIN)
50 #include <usp10.h>
51 #endif
52
53 #if USE(CAIRO)
54 #include <cairo.h>
55 #endif
56
57 #if USE(CG)
58 #if defined(__has_include) && __has_include(<CoreGraphics/CGFontRendering.h>)
59 #include <CoreGraphics/CGFontRendering.h>
60 #else
61 enum {
62     kCGFontRenderingStyleAntialiasing = (1 << 0),
63     kCGFontRenderingStyleSmoothing = (1 << 1),
64     kCGFontRenderingStyleSubpixelPositioning = (1 << 2),
65     kCGFontRenderingStyleSubpixelQuantization = (1 << 3),
66     kCGFontRenderingStylePlatformNative = (1 << 9),
67     kCGFontRenderingStyleMask = 0x20F
68 };
69 #endif
70 typedef uint32_t CGFontRenderingStyle;
71 #endif
72
73 namespace WebCore {
74
75 class FontDescription;
76 class SharedBuffer;
77 struct WidthIterator;
78
79 enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant };
80 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
81
82 class SimpleFontData final : public FontData {
83 public:
84     class AdditionalFontData {
85         WTF_MAKE_FAST_ALLOCATED;
86     public:
87         virtual ~AdditionalFontData() { }
88
89         virtual void initializeFontData(SimpleFontData*, float fontSize) = 0;
90         virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0;
91         virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const = 0;
92         virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength, String& normalizedSpacesStringCache) const = 0;
93     };
94
95     // Used to create platform fonts.
96     static PassRefPtr<SimpleFontData> create(const FontPlatformData& platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false)
97     {
98         return adoptRef(new SimpleFontData(platformData, isCustomFont, isLoading, isTextOrientationFallback));
99     }
100
101     // Used to create SVG Fonts.
102     static PassRefPtr<SimpleFontData> create(std::unique_ptr<AdditionalFontData> fontData, float fontSize, bool syntheticBold, bool syntheticItalic)
103     {
104         return adoptRef(new SimpleFontData(WTF::move(fontData), fontSize, syntheticBold, syntheticItalic));
105     }
106
107     virtual ~SimpleFontData();
108
109     static const SimpleFontData* systemFallback() { return reinterpret_cast<const SimpleFontData*>(-1); }
110
111     const FontPlatformData& platformData() const { return m_platformData; }
112     const OpenTypeMathData* mathData() const;
113 #if ENABLE(OPENTYPE_VERTICAL)
114     const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); }
115 #endif
116
117     PassRefPtr<SimpleFontData> smallCapsFontData(const FontDescription&) const;
118     PassRefPtr<SimpleFontData> emphasisMarkFontData(const FontDescription&) const;
119     PassRefPtr<SimpleFontData> brokenIdeographFontData() const;
120     PassRefPtr<SimpleFontData> nonSyntheticItalicFontData() const;
121
122     PassRefPtr<SimpleFontData> variantFontData(const FontDescription& description, FontDataVariant variant) const
123     {
124         switch (variant) {
125         case SmallCapsVariant:
126             return smallCapsFontData(description);
127         case EmphasisMarkVariant:
128             return emphasisMarkFontData(description);
129         case BrokenIdeographVariant:
130             return brokenIdeographFontData();
131         case AutoVariant:
132         case NormalVariant:
133             break;
134         }
135         ASSERT_NOT_REACHED();
136         return const_cast<SimpleFontData*>(this);
137     }
138
139     PassRefPtr<SimpleFontData> verticalRightOrientationFontData() const;
140     PassRefPtr<SimpleFontData> uprightOrientationFontData() const;
141
142     bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
143     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
144
145     FontMetrics& fontMetrics() { return m_fontMetrics; }
146     const FontMetrics& fontMetrics() const { return m_fontMetrics; }
147     float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
148
149     float maxCharWidth() const { return m_maxCharWidth; }
150     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
151
152     float avgCharWidth() const { return m_avgCharWidth; }
153     void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
154
155     FloatRect boundsForGlyph(Glyph) const;
156     float widthForGlyph(Glyph glyph) const;
157     FloatRect platformBoundsForGlyph(Glyph) const;
158     float platformWidthForGlyph(Glyph) const;
159
160     float spaceWidth() const { return m_spaceWidth; }
161     float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
162     void setSpaceWidths(float spaceWidth)
163     {
164         m_spaceWidth = spaceWidth;
165         m_adjustedSpaceWidth = spaceWidth;
166     }
167
168 #if USE(CG) || USE(CAIRO)
169     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
170 #endif
171
172     Glyph spaceGlyph() const { return m_spaceGlyph; }
173     void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
174     Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; }
175     void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
176     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
177     Glyph zeroGlyph() const { return m_zeroGlyph; }
178     void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
179
180     virtual const SimpleFontData* fontDataForCharacter(UChar32) const override;
181     virtual bool containsCharacters(const UChar*, int length) const override;
182
183     Glyph glyphForCharacter(UChar32) const;
184
185     void determinePitch();
186     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
187
188     AdditionalFontData* fontData() const { return m_fontData.get(); }
189     bool isSVGFont() const { return m_fontData != nullptr; }
190
191     virtual bool isCustomFont() const override { return m_isCustomFont; }
192     virtual bool isLoading() const override { return m_isLoading; }
193     virtual bool isSegmented() const override;
194
195     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
196     void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
197
198 #ifndef NDEBUG
199     virtual String description() const override;
200 #endif
201
202 #if USE(APPKIT)
203     const SimpleFontData* getCompositeFontReferenceFontData(NSFont *key) const;
204     NSFont* getNSFont() const { return m_platformData.font(); }
205 #endif
206
207 #if PLATFORM(IOS)
208     CTFontRef getCTFont() const { return m_platformData.font(); }
209     bool shouldNotBeUsedForArabic() const { return m_shouldNotBeUsedForArabic; };
210 #endif
211 #if PLATFORM(COCOA)
212     CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
213 #endif
214
215 #if PLATFORM(COCOA) || USE(HARFBUZZ)
216     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
217 #endif
218
219     bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const
220     {
221         // We need to handle transforms on SVG fonts internally, since they are rendered internally.
222         ASSERT(!isSVGFont());
223 #if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080)
224         wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0);
225         return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options);
226 #else
227         UNUSED_PARAM(glyphs);
228         UNUSED_PARAM(advances);
229         UNUSED_PARAM(glyphCount);
230         UNUSED_PARAM(typesettingFeatures);
231         return false;
232 #endif
233     }
234
235 #if PLATFORM(WIN)
236     bool isSystemFont() const { return m_isSystemFont; }
237     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
238     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
239     static void setShouldApplyMacAscentHack(bool);
240     static bool shouldApplyMacAscentHack();
241     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
242 #endif
243
244 private:
245     SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
246
247     SimpleFontData(std::unique_ptr<AdditionalFontData>, float fontSize, bool syntheticBold, bool syntheticItalic);
248
249     void platformInit();
250     void platformGlyphInit();
251     void platformCharWidthInit();
252     void platformDestroy();
253
254     void initCharWidths();
255
256     PassRefPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const;
257     PassRefPtr<SimpleFontData> platformCreateScaledFontData(const FontDescription&, float scaleFactor) const;
258
259 #if PLATFORM(WIN)
260     void initGDIFont();
261     void platformCommonDestroy();
262     FloatRect boundsForGDIGlyph(Glyph glyph) const;
263     float widthForGDIGlyph(Glyph glyph) const;
264 #endif
265
266 #if USE(CG)
267     bool canUseFastGlyphAdvanceGetter(Glyph glyph, CGSize& advance, bool& populatedAdvance) const;
268     CGFontRenderingStyle renderingStyle() const;
269     bool advanceForColorBitmapFont(Glyph, CGSize& result) const; // Returns true if the font is a color bitmap font
270 #endif
271
272     FontMetrics m_fontMetrics;
273     float m_maxCharWidth;
274     float m_avgCharWidth;
275
276     FontPlatformData m_platformData;
277     std::unique_ptr<AdditionalFontData> m_fontData;
278
279     mutable OwnPtr<GlyphMetricsMap<FloatRect>> m_glyphToBoundsMap;
280     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
281
282     bool m_treatAsFixedPitch;
283     bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
284     bool m_isLoading; // Whether or not this custom font is still in the act of loading.
285
286     bool m_isTextOrientationFallback;
287     bool m_isBrokenIdeographFallback;
288     mutable RefPtr<OpenTypeMathData> m_mathData;
289 #if ENABLE(OPENTYPE_VERTICAL)
290     RefPtr<OpenTypeVerticalData> m_verticalData;
291 #endif
292     bool m_hasVerticalGlyphs;
293
294     Glyph m_spaceGlyph;
295     float m_spaceWidth;
296     Glyph m_zeroGlyph;
297     float m_adjustedSpaceWidth;
298
299     Glyph m_zeroWidthSpaceGlyph;
300
301     GlyphData m_missingGlyphData;
302
303     struct DerivedFontData {
304         explicit DerivedFontData(bool custom)
305             : forCustomFont(custom)
306         {
307         }
308         ~DerivedFontData();
309
310         bool forCustomFont;
311         RefPtr<SimpleFontData> smallCaps;
312         RefPtr<SimpleFontData> emphasisMark;
313         RefPtr<SimpleFontData> brokenIdeograph;
314         RefPtr<SimpleFontData> verticalRightOrientation;
315         RefPtr<SimpleFontData> uprightOrientation;
316         RefPtr<SimpleFontData> nonSyntheticItalic;
317 #if PLATFORM(COCOA)
318         mutable RetainPtr<CFMutableDictionaryRef> compositeFontReferences;
319 #endif
320     };
321
322     mutable std::unique_ptr<DerivedFontData> m_derivedFontData;
323
324 #if USE(CG) || USE(CAIRO)
325     float m_syntheticBoldOffset;
326 #endif
327
328 #if PLATFORM(COCOA)
329     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef>> m_CFStringAttributes;
330 #endif
331
332 #if PLATFORM(COCOA) || USE(HARFBUZZ)
333     mutable OwnPtr<HashMap<String, bool>> m_combiningCharacterSequenceSupport;
334 #endif
335
336 #if PLATFORM(WIN)
337     bool m_isSystemFont;
338     mutable SCRIPT_CACHE m_scriptCache;
339     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
340 #endif
341 #if PLATFORM(IOS)
342     bool m_shouldNotBeUsedForArabic;
343 #endif
344 };
345
346 ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
347 {
348     if (isZeroWidthSpaceGlyph(glyph))
349         return FloatRect();
350
351     FloatRect bounds;
352     if (m_glyphToBoundsMap) {
353         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
354         if (bounds.width() != cGlyphSizeUnknown)
355             return bounds;
356     }
357
358     bounds = platformBoundsForGlyph(glyph);
359     if (!m_glyphToBoundsMap)
360         m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>);
361     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
362     return bounds;
363 }
364
365 ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
366 {
367     if (isZeroWidthSpaceGlyph(glyph))
368         return 0;
369
370     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
371     if (width != cGlyphSizeUnknown)
372         return width;
373
374     if (m_fontData)
375         width = m_fontData->widthForSVGGlyph(glyph, m_platformData.size());
376 #if ENABLE(OPENTYPE_VERTICAL)
377     else if (m_verticalData)
378 #if USE(CG) || USE(CAIRO)
379         width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
380 #else
381         width = m_verticalData->advanceHeight(this, glyph);
382 #endif
383 #endif
384     else
385         width = platformWidthForGlyph(glyph);
386
387     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
388     return width;
389 }
390
391 } // namespace WebCore
392
393 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SimpleFontData)
394     static bool isType(const WebCore::FontData& fontData) { return !fontData.isSegmented(); }
395 SPECIALIZE_TYPE_TRAITS_END()
396
397 #endif // SimpleFontData_h