82353c9446dc924eb1a90e093691e6162444d48f
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / fonts / Font.h
1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2006, 2007, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) 2008 Holger Hans Peter Freyther
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #ifndef Font_h
26 #define Font_h
27
28 #include "platform/PlatformExport.h"
29 #include "platform/fonts/FontDescription.h"
30 #include "platform/fonts/FontFallbackList.h"
31 #include "platform/fonts/SimpleFontData.h"
32 #include "platform/fonts/TypesettingFeatures.h"
33 #include "platform/text/TextDirection.h"
34 #include "platform/text/TextPath.h"
35 #include "wtf/HashMap.h"
36 #include "wtf/HashSet.h"
37 #include "wtf/MathExtras.h"
38 #include "wtf/unicode/CharacterNames.h"
39
40 // "X11/X.h" defines Complex to 0 and conflicts
41 // with Complex value in CodePath enum.
42 #ifdef Complex
43 #undef Complex
44 #endif
45
46 namespace WebCore {
47
48 class FloatPoint;
49 class FloatRect;
50 class FontData;
51 class FontMetrics;
52 class FontPlatformData;
53 class FontSelector;
54 class GlyphBuffer;
55 class GraphicsContext;
56 class TextRun;
57 struct TextRunPaintInfo;
58
59 struct GlyphData;
60
61 struct GlyphOverflow {
62     GlyphOverflow()
63         : left(0)
64         , right(0)
65         , top(0)
66         , bottom(0)
67         , computeBounds(false)
68     {
69     }
70
71     int left;
72     int right;
73     int top;
74     int bottom;
75     bool computeBounds;
76 };
77
78
79 class PLATFORM_EXPORT Font {
80 public:
81     Font();
82     Font(const FontDescription&, float letterSpacing, float wordSpacing);
83     ~Font();
84
85     Font(const Font&);
86     Font& operator=(const Font&);
87
88     bool operator==(const Font& other) const;
89     bool operator!=(const Font& other) const { return !(*this == other); }
90
91     const FontDescription& fontDescription() const { return m_fontDescription; }
92
93     int pixelSize() const { return fontDescription().computedPixelSize(); }
94     float size() const { return fontDescription().computedSize(); }
95
96     void update(PassRefPtr<FontSelector>) const;
97
98     enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
99     void drawText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
100     void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
101
102     float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
103     float width(const TextRun&, int& charsConsumed, String& glyphName) const;
104
105     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
106     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
107
108     bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
109
110     float wordSpacing() const { return m_wordSpacing; }
111     float letterSpacing() const { return m_letterSpacing; }
112     void setWordSpacing(float s) { m_wordSpacing = s; }
113     void setLetterSpacing(float s) { m_letterSpacing = s; }
114     bool isFixedPitch() const;
115     bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); }
116
117     TypesettingFeatures typesettingFeatures() const { return static_cast<TypesettingFeatures>(m_typesettingFeatures); }
118
119     FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
120     const FontFamily& family() const { return m_fontDescription.family(); }
121
122     FontItalic italic() const { return m_fontDescription.italic(); }
123     FontWeight weight() const { return m_fontDescription.weight(); }
124     FontWidthVariant widthVariant() const { return m_fontDescription.widthVariant(); }
125
126     // Metrics that we query the FontFallbackList for.
127     const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); }
128     float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; }
129     float tabWidth(const SimpleFontData&, unsigned tabSize, float position) const;
130     float tabWidth(unsigned tabSize, float position) const { return tabWidth(*primaryFont(), tabSize, position); }
131
132     int emphasisMarkAscent(const AtomicString&) const;
133     int emphasisMarkDescent(const AtomicString&) const;
134     int emphasisMarkHeight(const AtomicString&) const;
135
136     const SimpleFontData* primaryFont() const;
137     const FontData* fontDataAt(unsigned) const;
138     inline GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant = AutoVariant) const
139     {
140         return glyphDataAndPageForCharacter(c, mirror, variant).first;
141     }
142 #if OS(MACOSX)
143     const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const;
144 #endif
145     std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
146     bool primaryFontHasGlyphForCharacter(UChar32) const;
147
148     static bool isCJKIdeograph(UChar32);
149     static bool isCJKIdeographOrSymbol(UChar32);
150
151     static unsigned expansionOpportunityCount(const LChar*, size_t length, TextDirection, bool& isAfterExpansion);
152     static unsigned expansionOpportunityCount(const UChar*, size_t length, TextDirection, bool& isAfterExpansion);
153
154     static void setShouldUseSmoothing(bool);
155     static bool shouldUseSmoothing();
156
157     CodePath codePath(const TextRun&) const;
158     static CodePath characterRangeCodePath(const LChar*, unsigned) { return SimplePath; }
159     static CodePath characterRangeCodePath(const UChar*, unsigned len);
160
161 private:
162     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
163
164     // Returns the initial in-stream advance.
165     float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
166     void drawSimpleText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const;
167     void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
168     void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&, const FloatRect& textRect) const;
169     void drawGlyphBuffer(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const FloatPoint&) const;
170     void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
171     float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
172     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
173     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
174
175     bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
176
177     static bool canReturnFallbackFontsForComplexText();
178     static bool canExpandAroundIdeographsInComplexText();
179
180     // Returns the initial in-stream advance.
181     float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
182     void drawComplexText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const;
183     void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
184     float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
185     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
186     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
187
188     friend struct WidthIterator;
189     friend class SVGTextRunRenderingContext;
190
191 public:
192     // Useful for debugging the different font rendering code paths.
193     static void setCodePath(CodePath);
194     static CodePath codePath();
195     static CodePath s_codePath;
196
197     static void setDefaultTypesettingFeatures(TypesettingFeatures);
198     static TypesettingFeatures defaultTypesettingFeatures();
199
200     static const uint8_t s_roundingHackCharacterTable[256];
201     static bool isRoundingHackCharacter(UChar32 c)
202     {
203         return !(c & ~0xFF) && s_roundingHackCharacterTable[c];
204     }
205
206     FontSelector* fontSelector() const;
207     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
208     static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInComplexScript(c) || c == 0x200c || c == 0x200d; }
209     static bool treatAsZeroWidthSpaceInComplexScript(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || c == zeroWidthSpace || (c >= 0x200e && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == zeroWidthNoBreakSpace || c == objectReplacementCharacter; }
210     static bool canReceiveTextEmphasis(UChar32 c);
211
212     static inline UChar normalizeSpaces(UChar character)
213     {
214         if (treatAsSpace(character))
215             return space;
216
217         if (treatAsZeroWidthSpace(character))
218             return zeroWidthSpace;
219
220         return character;
221     }
222
223     static String normalizeSpaces(const LChar*, unsigned length);
224     static String normalizeSpaces(const UChar*, unsigned length);
225
226     FontFallbackList* fontList() const { return m_fontFallbackList.get(); }
227
228     void willUseFontData() const;
229
230 private:
231     bool loadingCustomFonts() const
232     {
233         return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
234     }
235
236     TypesettingFeatures computeTypesettingFeatures() const
237     {
238         TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
239         TypesettingFeatures features = s_defaultTypesettingFeatures;
240
241         switch (textRenderingMode) {
242         case AutoTextRendering:
243             break;
244         case OptimizeSpeed:
245             features &= ~(Kerning | Ligatures);
246             break;
247         case GeometricPrecision:
248         case OptimizeLegibility:
249             features |= Kerning | Ligatures;
250             break;
251         }
252
253         switch (m_fontDescription.kerning()) {
254         case FontDescription::NoneKerning:
255             features &= ~Kerning;
256             break;
257         case FontDescription::NormalKerning:
258             features |= Kerning;
259             break;
260         case FontDescription::AutoKerning:
261             break;
262         }
263
264         switch (m_fontDescription.commonLigaturesState()) {
265         case FontDescription::DisabledLigaturesState:
266             features &= ~Ligatures;
267             break;
268         case FontDescription::EnabledLigaturesState:
269             features |= Ligatures;
270             break;
271         case FontDescription::NormalLigaturesState:
272             break;
273         }
274
275         return features;
276     }
277
278     static TypesettingFeatures s_defaultTypesettingFeatures;
279
280     FontDescription m_fontDescription;
281     mutable RefPtr<FontFallbackList> m_fontFallbackList;
282     float m_letterSpacing;
283     float m_wordSpacing;
284     mutable unsigned m_typesettingFeatures : 2; // (TypesettingFeatures) Caches values computed from m_fontDescription.
285 };
286
287 inline Font::~Font()
288 {
289 }
290
291 inline const SimpleFontData* Font::primaryFont() const
292 {
293     ASSERT(m_fontFallbackList);
294     return m_fontFallbackList->primarySimpleFontData(m_fontDescription);
295 }
296
297 inline const FontData* Font::fontDataAt(unsigned index) const
298 {
299     ASSERT(m_fontFallbackList);
300     return m_fontFallbackList->fontDataAt(m_fontDescription, index);
301 }
302
303 inline bool Font::isFixedPitch() const
304 {
305     ASSERT(m_fontFallbackList);
306     return m_fontFallbackList->isFixedPitch(m_fontDescription);
307 }
308
309 inline FontSelector* Font::fontSelector() const
310 {
311     return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
312 }
313
314 inline float Font::tabWidth(const SimpleFontData& fontData, unsigned tabSize, float position) const
315 {
316     if (!tabSize)
317         return letterSpacing();
318     float tabWidth = tabSize * fontData.spaceWidth() + letterSpacing();
319     return tabWidth - fmodf(position, tabWidth);
320 }
321
322 }
323
324 #endif