1 /* 2 * Copyright (C) 2000 Lars Knoll (knoll (at) kde.org) 3 * (C) 2000 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2000 Dirk Mueller (mueller (at) 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/text/TextDirection.h" 33 #include "platform/text/TextPath.h" 34 #include "wtf/HashMap.h" 35 #include "wtf/HashSet.h" 36 #include "wtf/MathExtras.h" 37 #include "wtf/unicode/CharacterNames.h" 38 39 // "X11/X.h" defines Complex to 0 and conflicts 40 // with Complex value in CodePath enum. 41 #ifdef Complex 42 #undef Complex 43 #endif 44 45 namespace WebCore { 46 47 class FloatPoint; 48 class FloatRect; 49 class FontData; 50 class FontMetrics; 51 class FontPlatformData; 52 class FontSelector; 53 class GlyphBuffer; 54 class GraphicsContext; 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 PLATFORM_EXPORT Font { 79 public: 80 Font(); 81 Font(const FontDescription&); 82 ~Font(); 83 84 Font(const Font&); 85 Font& operator=(const Font&); 86 87 bool operator==(const Font& other) const; 88 bool operator!=(const Font& other) const { return !(*this == other); } 89 90 const FontDescription& fontDescription() const { return m_fontDescription; } 91 92 void update(PassRefPtrWillBeRawPtr<FontSelector>) const; 93 94 enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady }; 95 void drawText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const; 96 void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const; 97 98 float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; 99 float width(const TextRun&, int& charsConsumed, Glyph& glyphId) const; 100 101 int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const; 102 FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1, bool accountForGlyphBounds = false) const; 103 104 bool isFixedPitch() const; 105 106 // Metrics that we query the FontFallbackList for. 107 const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); } 108 float spaceWidth() const { return primaryFont()->spaceWidth() + fontDescription().letterSpacing(); } 109 float tabWidth(const SimpleFontData&, unsigned tabSize, float position) const; 110 float tabWidth(unsigned tabSize, float position) const { return tabWidth(*primaryFont(), tabSize, position); } 111 112 int emphasisMarkAscent(const AtomicString&) const; 113 int emphasisMarkDescent(const AtomicString&) const; 114 int emphasisMarkHeight(const AtomicString&) const; 115 116 const SimpleFontData* primaryFont() const; 117 const FontData* fontDataAt(unsigned) const; 118 inline GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant = AutoVariant) const 119 { 120 return glyphDataAndPageForCharacter(c, mirror, variant).first; 121 } 122 #if OS(MACOSX) 123 const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const; 124 #endif 125 std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const; 126 bool primaryFontHasGlyphForCharacter(UChar32) const; 127 128 CodePath codePath(const TextRun&) const; 129 130 private: 131 enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis }; 132 133 // Returns the initial in-stream advance. 134 float getGlyphsAndAdvancesForSimpleText(const TextRunPaintInfo&, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const; 135 void drawSimpleText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const; 136 void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const; 137 void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&, const FloatRect& textRect) const; 138 void drawGlyphBuffer(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const FloatPoint&) const; 139 void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const; 140 float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, IntRectExtent* glyphBounds = 0) const; 141 int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const; 142 FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to, bool accountForGlyphBounds) const; 143 144 bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const; 145 146 // Returns the initial in-stream advance. 147 float getGlyphsAndAdvancesForComplexText(const TextRunPaintInfo&, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const; 148 void drawComplexText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const; 149 void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const; 150 float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts, IntRectExtent* glyphBounds) const; 151 int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const; 152 FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const; 153 154 friend struct WidthIterator; 155 friend class SVGTextRunRenderingContext; 156 157 public: 158 // Useful for debugging the different font rendering code paths. 159 static void setCodePath(CodePath); 160 static CodePath codePath(); 161 static CodePath s_codePath; 162 163 FontSelector* fontSelector() const; 164 165 FontFallbackList* fontList() const { return m_fontFallbackList.get(); } 166 167 void willUseFontData(UChar32) const; 168 169 static FloatRect pixelSnappedSelectionRect(float fromX, float toX, float y, float height); 170 private: 171 bool loadingCustomFonts() const 172 { 173 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); 174 } 175 176 bool shouldSkipDrawing() const 177 { 178 return m_fontFallbackList && m_fontFallbackList->shouldSkipDrawing(); 179 } 180 181 FontDescription m_fontDescription; 182 mutable RefPtr<FontFallbackList> m_fontFallbackList; 183 }; 184 185 inline Font::~Font() 186 { 187 } 188 189 inline const SimpleFontData* Font::primaryFont() const 190 { 191 ASSERT(m_fontFallbackList); 192 return m_fontFallbackList->primarySimpleFontData(m_fontDescription); 193 } 194 195 inline const FontData* Font::fontDataAt(unsigned index) const 196 { 197 ASSERT(m_fontFallbackList); 198 return m_fontFallbackList->fontDataAt(m_fontDescription, index); 199 } 200 201 inline bool Font::isFixedPitch() const 202 { 203 ASSERT(m_fontFallbackList); 204 return m_fontFallbackList->isFixedPitch(m_fontDescription); 205 } 206 207 inline FontSelector* Font::fontSelector() const 208 { 209 return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0; 210 } 211 212 inline float Font::tabWidth(const SimpleFontData& fontData, unsigned tabSize, float position) const 213 { 214 if (!tabSize) 215 return fontDescription().letterSpacing(); 216 float tabWidth = tabSize * fontData.spaceWidth() + fontDescription().letterSpacing(); 217 return tabWidth - fmodf(position, tabWidth); 218 } 219 220 } 221 222 #endif 223