dd86f004e4c8396363c951234dafaf5240798b31
[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     
122     float maxCharWidth() const { return m_maxCharWidth; }
123     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
124
125     float avgCharWidth() const { return m_avgCharWidth; }
126     void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
127
128     FloatRect boundsForGlyph(Glyph) const;
129     float widthForGlyph(Glyph glyph) const;
130     FloatRect platformBoundsForGlyph(Glyph) const;
131     float platformWidthForGlyph(Glyph) const;
132
133     float spaceWidth() const { return m_spaceWidth; }
134     float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
135     void setSpaceWidth(float spaceWidth) { m_spaceWidth = spaceWidth; }
136
137 #if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROMIUM)
138     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
139 #endif
140
141     Glyph spaceGlyph() const { return m_spaceGlyph; }
142     void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
143     void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
144     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
145
146     virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
147     virtual bool containsCharacters(const UChar*, int length) const;
148
149     void determinePitch();
150     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
151
152     AdditionalFontData* fontData() const { return m_fontData.get(); }
153     bool isSVGFont() const { return m_fontData; }
154
155     virtual bool isCustomFont() const { return m_isCustomFont; }
156     virtual bool isLoading() const { return m_isLoading; }
157     virtual bool isSegmented() const;
158
159     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
160     void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
161
162 #ifndef NDEBUG
163     virtual String description() const;
164 #endif
165
166 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
167     NSFont* getNSFont() const { return m_platformData.font(); }
168 #elif (PLATFORM(WX) && OS(DARWIN)) 
169     NSFont* getNSFont() const { return m_platformData.nsFont(); }
170 #endif
171
172 #if PLATFORM(MAC) || USE(CORE_TEXT)
173     CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
174 #endif
175
176 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
177     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
178 #endif
179
180 #if USE(ATSUI)
181     void checkShapesArabic() const;
182     bool shapesArabic() const
183     {
184         if (!m_checkedShapesArabic)
185             checkShapesArabic();
186         return m_shapesArabic;
187     }
188 #endif
189
190 #if PLATFORM(QT)
191     QFont getQtFont() const { return m_platformData.font(); }
192 #endif
193
194 #if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
195     bool isSystemFont() const { return m_isSystemFont; }
196 #if !OS(WINCE) // disable unused members to save space
197     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
198     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
199 #endif
200     static void setShouldApplyMacAscentHack(bool);
201     static bool shouldApplyMacAscentHack();
202     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
203 #endif
204
205 #if PLATFORM(WX)
206     wxFont* getWxFont() const { return m_platformData.font(); }
207 #endif
208
209 private:
210     void platformInit();
211     void platformGlyphInit();
212     void platformCharWidthInit();
213     void platformDestroy();
214     
215     void initCharWidths();
216
217     void commonInit();
218
219     PassOwnPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const;
220
221 #if (PLATFORM(WIN) && !OS(WINCE)) \
222     || (OS(WINDOWS) && PLATFORM(WX))
223     void initGDIFont();
224     void platformCommonDestroy();
225     FloatRect boundsForGDIGlyph(Glyph glyph) const;
226     float widthForGDIGlyph(Glyph glyph) const;
227 #endif
228
229     FontMetrics m_fontMetrics;
230     float m_maxCharWidth;
231     float m_avgCharWidth;
232     
233     FontPlatformData m_platformData;
234     OwnPtr<AdditionalFontData> m_fontData;
235
236     mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
237     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
238
239     bool m_treatAsFixedPitch;
240     bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
241     bool m_isLoading; // Whether or not this custom font is still in the act of loading.
242     
243     bool m_isTextOrientationFallback;
244     bool m_isBrokenIdeographFallback;
245     bool m_hasVerticalGlyphs;
246     
247     Glyph m_spaceGlyph;
248     float m_spaceWidth;
249     float m_adjustedSpaceWidth;
250
251     Glyph m_zeroWidthSpaceGlyph;
252
253     GlyphData m_missingGlyphData;
254
255     struct DerivedFontData {
256         static PassOwnPtr<DerivedFontData> create(bool forCustomFont);
257         ~DerivedFontData();
258
259         bool forCustomFont;
260         OwnPtr<SimpleFontData> smallCaps;
261         OwnPtr<SimpleFontData> emphasisMark;
262         OwnPtr<SimpleFontData> brokenIdeograph;
263         OwnPtr<SimpleFontData> verticalRightOrientation;
264         OwnPtr<SimpleFontData> uprightOrientation;
265
266     private:
267         DerivedFontData(bool custom)
268             : forCustomFont(custom)
269         {
270         }
271     };
272
273     mutable OwnPtr<DerivedFontData> m_derivedFontData;
274
275 #if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROMIUM)
276     float m_syntheticBoldOffset;
277 #endif
278
279
280 #if USE(ATSUI)
281 public:
282     mutable HashMap<unsigned, ATSUStyle> m_ATSUStyleMap;
283     mutable bool m_ATSUMirrors;
284     mutable bool m_checkedShapesArabic;
285     mutable bool m_shapesArabic;
286
287 private:
288 #endif
289
290 #if PLATFORM(MAC) || USE(CORE_TEXT)
291     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes;
292 #endif
293
294 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
295     mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport;
296 #endif
297
298 #if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
299     bool m_isSystemFont;
300 #if !OS(WINCE) // disable unused members to save space
301     mutable SCRIPT_CACHE m_scriptCache;
302     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
303 #endif
304 #endif
305 };
306
307 #if !(PLATFORM(QT) && !HAVE(QRAWFONT))
308 ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
309 {
310     if (isZeroWidthSpaceGlyph(glyph))
311         return FloatRect();
312
313     FloatRect bounds;
314     if (m_glyphToBoundsMap) {
315         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
316         if (bounds.width() != cGlyphSizeUnknown)
317             return bounds;
318     }
319
320     bounds = platformBoundsForGlyph(glyph);
321     if (!m_glyphToBoundsMap)
322         m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>);
323     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
324     return bounds;
325 }
326
327 ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
328 {
329     if (isZeroWidthSpaceGlyph(glyph))
330         return 0;
331
332     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
333     if (width != cGlyphSizeUnknown)
334         return width;
335
336     if (m_fontData)
337         width = m_fontData->widthForSVGGlyph(glyph, m_platformData.size());
338     else
339         width = platformWidthForGlyph(glyph);
340
341     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
342     return width;
343 }
344 #endif
345
346 } // namespace WebCore
347
348 #endif // SimpleFontData_h