OLD | NEW |
| (Empty) |
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 "core/platform/graphics/FontFallbackList.h" | |
29 #include "core/platform/graphics/SimpleFontData.h" | |
30 #include "platform/fonts/FontDescription.h" | |
31 #include "platform/fonts/TypesettingFeatures.h" | |
32 #include "platform/text/TextDirection.h" | |
33 #include "wtf/HashMap.h" | |
34 #include "wtf/HashSet.h" | |
35 #include "wtf/MathExtras.h" | |
36 #include "wtf/unicode/CharacterNames.h" | |
37 | |
38 // "X11/X.h" defines Complex to 0 and conflicts | |
39 // with Complex value in CodePath enum. | |
40 #ifdef Complex | |
41 #undef Complex | |
42 #endif | |
43 | |
44 namespace WebCore { | |
45 | |
46 class FloatPoint; | |
47 class FloatRect; | |
48 class FontData; | |
49 class FontMetrics; | |
50 class FontPlatformData; | |
51 class FontSelector; | |
52 class GlyphBuffer; | |
53 class GraphicsContext; | |
54 class TextLayout; | |
55 class TextRun; | |
56 struct TextRunPaintInfo; | |
57 | |
58 struct GlyphData; | |
59 | |
60 struct GlyphOverflow { | |
61 GlyphOverflow() | |
62 : left(0) | |
63 , right(0) | |
64 , top(0) | |
65 , bottom(0) | |
66 , computeBounds(false) | |
67 { | |
68 } | |
69 | |
70 int left; | |
71 int right; | |
72 int top; | |
73 int bottom; | |
74 bool computeBounds; | |
75 }; | |
76 | |
77 | |
78 class Font { | |
79 public: | |
80 Font(); | |
81 Font(const FontDescription&, float letterSpacing, float wordSpacing); | |
82 // This constructor is only used if the platform wants to start with a nativ
e font. | |
83 Font(const FontPlatformData&, bool isPrinting, FontSmoothingMode = AutoSmoot
hing); | |
84 ~Font(); | |
85 | |
86 Font(const Font&); | |
87 Font& operator=(const Font&); | |
88 | |
89 bool operator==(const Font& other) const; | |
90 bool operator!=(const Font& other) const { return !(*this == other); } | |
91 | |
92 const FontDescription& fontDescription() const { return m_fontDescription; } | |
93 | |
94 int pixelSize() const { return fontDescription().computedPixelSize(); } | |
95 float size() const { return fontDescription().computedSize(); } | |
96 | |
97 void update(PassRefPtr<FontSelector>) const; | |
98 | |
99 enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontN
otReady }; | |
100 void drawText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&,
CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const; | |
101 void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const Atom
icString& mark, const FloatPoint&) const; | |
102 | |
103 float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts =
0, GlyphOverflow* = 0) const; | |
104 float width(const TextRun&, int& charsConsumed, String& glyphName) const; | |
105 | |
106 PassOwnPtr<TextLayout> createLayoutForMacComplexText(const TextRun&, unsigne
d textLength, float xPos, bool collapseWhiteSpace) const; | |
107 static void deleteLayout(TextLayout*); | |
108 static float width(TextLayout&, unsigned from, unsigned len, HashSet<const S
impleFontData*>* fallbackFonts = 0); | |
109 | |
110 int offsetForPosition(const TextRun&, float position, bool includePartialGly
phs) const; | |
111 FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int
from = 0, int to = -1) const; | |
112 | |
113 bool isSmallCaps() const { return m_fontDescription.smallCaps(); } | |
114 | |
115 float wordSpacing() const { return m_wordSpacing; } | |
116 float letterSpacing() const { return m_letterSpacing; } | |
117 void setWordSpacing(float s) { m_wordSpacing = s; } | |
118 void setLetterSpacing(float s) { m_letterSpacing = s; } | |
119 bool isFixedPitch() const; | |
120 bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); } | |
121 | |
122 TypesettingFeatures typesettingFeatures() const { return static_cast<Typeset
tingFeatures>(m_typesettingFeatures); } | |
123 | |
124 FontFamily& firstFamily() { return m_fontDescription.firstFamily(); } | |
125 const FontFamily& family() const { return m_fontDescription.family(); } | |
126 | |
127 FontItalic italic() const { return m_fontDescription.italic(); } | |
128 FontWeight weight() const { return m_fontDescription.weight(); } | |
129 FontWidthVariant widthVariant() const { return m_fontDescription.widthVarian
t(); } | |
130 | |
131 bool isPlatformFont() const { return m_isPlatformFont; } | |
132 | |
133 // Metrics that we query the FontFallbackList for. | |
134 const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics()
; } | |
135 float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpac
ing; } | |
136 float tabWidth(const SimpleFontData&, unsigned tabSize, float position) cons
t; | |
137 float tabWidth(unsigned tabSize, float position) const { return tabWidth(*pr
imaryFont(), tabSize, position); } | |
138 | |
139 int emphasisMarkAscent(const AtomicString&) const; | |
140 int emphasisMarkDescent(const AtomicString&) const; | |
141 int emphasisMarkHeight(const AtomicString&) const; | |
142 | |
143 const SimpleFontData* primaryFont() const; | |
144 const FontData* fontDataAt(unsigned) const; | |
145 inline GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVaria
nt variant = AutoVariant) const | |
146 { | |
147 return glyphDataAndPageForCharacter(c, mirror, variant).first; | |
148 } | |
149 #if OS(MACOSX) | |
150 const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, si
ze_t length, FontDataVariant) const; | |
151 #endif | |
152 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32, bool
mirror, FontDataVariant = AutoVariant) const; | |
153 bool primaryFontHasGlyphForCharacter(UChar32) const; | |
154 | |
155 static bool isCJKIdeograph(UChar32); | |
156 static bool isCJKIdeographOrSymbol(UChar32); | |
157 | |
158 static unsigned expansionOpportunityCount(const LChar*, size_t length, TextD
irection, bool& isAfterExpansion); | |
159 static unsigned expansionOpportunityCount(const UChar*, size_t length, TextD
irection, bool& isAfterExpansion); | |
160 | |
161 static void setShouldUseSmoothing(bool); | |
162 static bool shouldUseSmoothing(); | |
163 | |
164 enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow }; | |
165 CodePath codePath(const TextRun&) const; | |
166 static CodePath characterRangeCodePath(const LChar*, unsigned) { return Simp
le; } | |
167 static CodePath characterRangeCodePath(const UChar*, unsigned len); | |
168 | |
169 private: | |
170 enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis }; | |
171 | |
172 // Returns the initial in-stream advance. | |
173 float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, Gl
yphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const; | |
174 void drawSimpleText(GraphicsContext*, const TextRunPaintInfo&, const FloatPo
int&) const; | |
175 void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRunPaintInfo
&, const AtomicString& mark, const FloatPoint&) const; | |
176 void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&,
unsigned from, unsigned numGlyphs, const FloatPoint&, const FloatRect& textRect
) const; | |
177 void drawGlyphBuffer(GraphicsContext*, const TextRunPaintInfo&, const GlyphB
uffer&, const FloatPoint&) const; | |
178 void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const Glyp
hBuffer&, const AtomicString&, const FloatPoint&) const; | |
179 float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>
* fallbackFonts = 0, GlyphOverflow* = 0) const; | |
180 int offsetForPositionForSimpleText(const TextRun&, float position, bool incl
udePartialGlyphs) const; | |
181 FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int
h, int from, int to) const; | |
182 | |
183 bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const; | |
184 | |
185 static bool canReturnFallbackFontsForComplexText(); | |
186 static bool canExpandAroundIdeographsInComplexText(); | |
187 | |
188 // Returns the initial in-stream advance. | |
189 float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, G
lyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const; | |
190 void drawComplexText(GraphicsContext*, const TextRunPaintInfo&, const FloatP
oint&) const; | |
191 void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRunPaintInf
o&, const AtomicString& mark, const FloatPoint&) const; | |
192 float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*
>* fallbackFonts = 0, GlyphOverflow* = 0) const; | |
193 int offsetForPositionForComplexText(const TextRun&, float position, bool inc
ludePartialGlyphs) const; | |
194 FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int
h, int from, int to) const; | |
195 | |
196 friend struct WidthIterator; | |
197 friend class SVGTextRunRenderingContext; | |
198 | |
199 public: | |
200 // Useful for debugging the different font rendering code paths. | |
201 static void setCodePath(CodePath); | |
202 static CodePath codePath(); | |
203 static CodePath s_codePath; | |
204 | |
205 static void setDefaultTypesettingFeatures(TypesettingFeatures); | |
206 static TypesettingFeatures defaultTypesettingFeatures(); | |
207 | |
208 static const uint8_t s_roundingHackCharacterTable[256]; | |
209 static bool isRoundingHackCharacter(UChar32 c) | |
210 { | |
211 return !(c & ~0xFF) && s_roundingHackCharacterTable[c]; | |
212 } | |
213 | |
214 FontSelector* fontSelector() const; | |
215 static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n
' || c == noBreakSpace; } | |
216 static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInC
omplexScript(c) || c == 0x200c || c == 0x200d; } | |
217 static bool treatAsZeroWidthSpaceInComplexScript(UChar c) { return c < 0x20
|| (c >= 0x7F && c < 0xA0) || c == softHyphen || c == zeroWidthSpace || (c >= 0x
200e && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == zeroWidthNoBreakSpa
ce || c == objectReplacementCharacter; } | |
218 static bool canReceiveTextEmphasis(UChar32 c); | |
219 | |
220 static inline UChar normalizeSpaces(UChar character) | |
221 { | |
222 if (treatAsSpace(character)) | |
223 return space; | |
224 | |
225 if (treatAsZeroWidthSpace(character)) | |
226 return zeroWidthSpace; | |
227 | |
228 return character; | |
229 } | |
230 | |
231 static String normalizeSpaces(const LChar*, unsigned length); | |
232 static String normalizeSpaces(const UChar*, unsigned length); | |
233 | |
234 FontFallbackList* fontList() const { return m_fontFallbackList.get(); } | |
235 | |
236 void willUseFontData() const; | |
237 | |
238 private: | |
239 bool loadingCustomFonts() const | |
240 { | |
241 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | |
242 } | |
243 | |
244 TypesettingFeatures computeTypesettingFeatures() const | |
245 { | |
246 TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMod
e(); | |
247 TypesettingFeatures features = s_defaultTypesettingFeatures; | |
248 | |
249 switch (textRenderingMode) { | |
250 case AutoTextRendering: | |
251 break; | |
252 case OptimizeSpeed: | |
253 features &= ~(Kerning | Ligatures); | |
254 break; | |
255 case GeometricPrecision: | |
256 case OptimizeLegibility: | |
257 features |= Kerning | Ligatures; | |
258 break; | |
259 } | |
260 | |
261 switch (m_fontDescription.kerning()) { | |
262 case FontDescription::NoneKerning: | |
263 features &= ~Kerning; | |
264 break; | |
265 case FontDescription::NormalKerning: | |
266 features |= Kerning; | |
267 break; | |
268 case FontDescription::AutoKerning: | |
269 break; | |
270 } | |
271 | |
272 switch (m_fontDescription.commonLigaturesState()) { | |
273 case FontDescription::DisabledLigaturesState: | |
274 features &= ~Ligatures; | |
275 break; | |
276 case FontDescription::EnabledLigaturesState: | |
277 features |= Ligatures; | |
278 break; | |
279 case FontDescription::NormalLigaturesState: | |
280 break; | |
281 } | |
282 | |
283 return features; | |
284 } | |
285 | |
286 static TypesettingFeatures s_defaultTypesettingFeatures; | |
287 | |
288 FontDescription m_fontDescription; | |
289 mutable RefPtr<FontFallbackList> m_fontFallbackList; | |
290 float m_letterSpacing; | |
291 float m_wordSpacing; | |
292 bool m_isPlatformFont; | |
293 mutable unsigned m_typesettingFeatures : 2; // (TypesettingFeatures) Caches
values computed from m_fontDescription. | |
294 }; | |
295 | |
296 inline Font::~Font() | |
297 { | |
298 } | |
299 | |
300 inline const SimpleFontData* Font::primaryFont() const | |
301 { | |
302 ASSERT(m_fontFallbackList); | |
303 return m_fontFallbackList->primarySimpleFontData(m_fontDescription); | |
304 } | |
305 | |
306 inline const FontData* Font::fontDataAt(unsigned index) const | |
307 { | |
308 ASSERT(m_fontFallbackList); | |
309 return m_fontFallbackList->fontDataAt(m_fontDescription, index); | |
310 } | |
311 | |
312 inline bool Font::isFixedPitch() const | |
313 { | |
314 ASSERT(m_fontFallbackList); | |
315 return m_fontFallbackList->isFixedPitch(m_fontDescription); | |
316 } | |
317 | |
318 inline FontSelector* Font::fontSelector() const | |
319 { | |
320 return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0; | |
321 } | |
322 | |
323 inline float Font::tabWidth(const SimpleFontData& fontData, unsigned tabSize, fl
oat position) const | |
324 { | |
325 if (!tabSize) | |
326 return letterSpacing(); | |
327 float tabWidth = tabSize * fontData.spaceWidth() + letterSpacing(); | |
328 return tabWidth - fmodf(position, tabWidth); | |
329 } | |
330 | |
331 } | |
332 | |
333 namespace WTF { | |
334 | |
335 template <> struct OwnedPtrDeleter<WebCore::TextLayout> { | |
336 static void deletePtr(WebCore::TextLayout*); | |
337 }; | |
338 | |
339 } | |
340 | |
341 #endif | |
OLD | NEW |