Support the ch unit from css3-values
[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     Glyph zeroGlyph() const { return m_zeroGlyph; }
164     void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
165
166     virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
167     virtual bool containsCharacters(const UChar*, int length) const;
168
169     Glyph glyphForCharacter(UChar32) const;
170
171     void determinePitch();
172     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
173
174     AdditionalFontData* fontData() const { return m_fontData.get(); }
175     bool isSVGFont() const { return m_fontData; }
176
177     virtual bool isCustomFont() const { return m_isCustomFont; }
178     virtual bool isLoading() const { return m_isLoading; }
179     virtual bool isSegmented() const;
180
181     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
182     void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
183
184 #ifndef NDEBUG
185     virtual String description() const;
186 #endif
187
188 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
189     const SimpleFontData* getCompositeFontReferenceFontData(NSFont *key) const;
190     NSFont* getNSFont() const { return m_platformData.font(); }
191 #elif (PLATFORM(WX) && OS(DARWIN)) 
192     const SimpleFontData* getCompositeFontReferenceFontData(NSFont *key) const;
193     NSFont* getNSFont() const { return m_platformData.nsFont(); }
194 #endif
195
196 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
197     CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
198 #endif
199
200 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) || USE(HARFBUZZ)
201     bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
202 #endif
203
204     bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const
205     {
206 #if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
207         UNUSED_PARAM(glyphs);
208         UNUSED_PARAM(advances);
209         UNUSED_PARAM(glyphCount);
210         UNUSED_PARAM(typesettingFeatures);
211         ASSERT_NOT_REACHED();
212         return false;
213 #else
214     wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0);
215     return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options);
216 #endif
217     }
218
219 #if PLATFORM(QT)
220     QRawFont getQtRawFont() const { return m_platformData.rawFont(); }
221 #endif
222
223 #if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
224     bool isSystemFont() const { return m_isSystemFont; }
225 #if !OS(WINCE) // disable unused members to save space
226     SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
227     SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
228 #endif
229     static void setShouldApplyMacAscentHack(bool);
230     static bool shouldApplyMacAscentHack();
231     static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
232 #endif
233
234 #if PLATFORM(WX)
235     wxFont* getWxFont() const { return m_platformData.font(); }
236 #endif
237
238 private:
239     SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
240
241     SimpleFontData(PassOwnPtr<AdditionalFontData> , float fontSize, bool syntheticBold, bool syntheticItalic);
242
243     void platformInit();
244     void platformGlyphInit();
245     void platformCharWidthInit();
246     void platformDestroy();
247     
248     void initCharWidths();
249
250     void commonInit();
251
252     PassRefPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const;
253
254 #if (PLATFORM(WIN) && !OS(WINCE)) \
255     || (OS(WINDOWS) && PLATFORM(WX))
256     void initGDIFont();
257     void platformCommonDestroy();
258     FloatRect boundsForGDIGlyph(Glyph glyph) const;
259     float widthForGDIGlyph(Glyph glyph) const;
260 #endif
261
262     FontMetrics m_fontMetrics;
263     float m_maxCharWidth;
264     float m_avgCharWidth;
265     
266     FontPlatformData m_platformData;
267     OwnPtr<AdditionalFontData> m_fontData;
268
269     mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
270     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
271
272     bool m_treatAsFixedPitch;
273     bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
274     bool m_isLoading; // Whether or not this custom font is still in the act of loading.
275     
276     bool m_isTextOrientationFallback;
277     bool m_isBrokenIdeographFallback;
278 #if ENABLE(OPENTYPE_VERTICAL)
279     RefPtr<OpenTypeVerticalData> m_verticalData;
280 #endif
281     bool m_hasVerticalGlyphs;
282     
283     Glyph m_spaceGlyph;
284     float m_spaceWidth;
285     Glyph m_zeroGlyph;
286     float m_adjustedSpaceWidth;
287
288     Glyph m_zeroWidthSpaceGlyph;
289
290     GlyphData m_missingGlyphData;
291
292     struct DerivedFontData {
293         static PassOwnPtr<DerivedFontData> create(bool forCustomFont);
294         ~DerivedFontData();
295
296         bool forCustomFont;
297         RefPtr<SimpleFontData> smallCaps;
298         RefPtr<SimpleFontData> emphasisMark;
299         RefPtr<SimpleFontData> brokenIdeograph;
300         RefPtr<SimpleFontData> verticalRightOrientation;
301         RefPtr<SimpleFontData> uprightOrientation;
302 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
303         mutable RetainPtr<CFMutableDictionaryRef> compositeFontReferences;
304 #endif
305         
306     private:
307         DerivedFontData(bool custom)
308             : forCustomFont(custom)
309         {
310         }
311     };
312
313     mutable OwnPtr<DerivedFontData> m_derivedFontData;
314
315 #if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROMIUM)
316     float m_syntheticBoldOffset;
317 #endif
318
319 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
320     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes;
321 #endif
322
323 #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) || USE(HARFBUZZ)
324     mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport;
325 #endif
326
327 #if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
328     bool m_isSystemFont;
329 #if !OS(WINCE) // disable unused members to save space
330     mutable SCRIPT_CACHE m_scriptCache;
331     mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
332 #endif
333 #endif
334 };
335
336 ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
337 {
338     if (isZeroWidthSpaceGlyph(glyph))
339         return FloatRect();
340
341     FloatRect bounds;
342     if (m_glyphToBoundsMap) {
343         bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
344         if (bounds.width() != cGlyphSizeUnknown)
345             return bounds;
346     }
347
348     bounds = platformBoundsForGlyph(glyph);
349     if (!m_glyphToBoundsMap)
350         m_glyphToBoundsMap = adoptPtr(new GlyphMetricsMap<FloatRect>);
351     m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
352     return bounds;
353 }
354
355 ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
356 {
357     if (isZeroWidthSpaceGlyph(glyph))
358         return 0;
359
360     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
361     if (width != cGlyphSizeUnknown)
362         return width;
363
364     if (m_fontData)
365         width = m_fontData->widthForSVGGlyph(glyph, m_platformData.size());
366 #if ENABLE(OPENTYPE_VERTICAL)
367     else if (m_verticalData)
368 #if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROMIUM)
369         width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
370 #else
371         width = m_verticalData->advanceHeight(this, glyph);
372 #endif
373 #endif
374     else
375         width = platformWidthForGlyph(glyph);
376
377     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
378     return width;
379 }
380
381 } // namespace WebCore
382 #endif // SimpleFontData_h