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