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