| 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 |