00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef Font_h
00027 #define Font_h
00028
00029 #include "FontDescription.h"
00030 #include <wtf/HashMap.h>
00031
00032 #if PLATFORM(QT)
00033 #include <QtGui/qfont.h>
00034 #include <QtGui/qfontmetrics.h>
00035 #endif
00036
00037 namespace WebCore {
00038
00039 class FloatPoint;
00040 class FloatRect;
00041 class FontData;
00042 class FontFallbackList;
00043 class FontPlatformData;
00044 class FontSelector;
00045 class GlyphBuffer;
00046 class GlyphPageTreeNode;
00047 class GraphicsContext;
00048 class IntPoint;
00049 class RenderObject;
00050 class SimpleFontData;
00051 class SVGFontElement;
00052 class SVGPaintServer;
00053
00054 struct GlyphData;
00055
00056 class TextRun {
00057 public:
00058 TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
00059 bool applyRunRounding = true, bool applyWordRounding = true)
00060 : m_characters(c)
00061 , m_len(len)
00062 , m_allowTabs(allowTabs)
00063 , m_xpos(xpos)
00064 , m_padding(padding)
00065 , m_rtl(rtl)
00066 , m_directionalOverride(directionalOverride)
00067 , m_applyRunRounding(applyRunRounding)
00068 , m_applyWordRounding(applyWordRounding)
00069 , m_disableSpacing(false)
00070 #if ENABLE(SVG_FONTS)
00071 , m_referencingRenderObject(0)
00072 , m_activePaintServer(0)
00073 #endif
00074 {
00075 }
00076
00077 TextRun(const String& s, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
00078 bool applyRunRounding = true, bool applyWordRounding = true)
00079 : m_characters(s.characters())
00080 , m_len(s.length())
00081 , m_allowTabs(allowTabs)
00082 , m_xpos(xpos)
00083 , m_padding(padding)
00084 , m_rtl(rtl)
00085 , m_directionalOverride(directionalOverride)
00086 , m_applyRunRounding(applyRunRounding)
00087 , m_applyWordRounding(applyWordRounding)
00088 , m_disableSpacing(false)
00089 #if ENABLE(SVG_FONTS)
00090 , m_referencingRenderObject(0)
00091 , m_activePaintServer(0)
00092 #endif
00093 {
00094 }
00095
00096 UChar operator[](int i) const { return m_characters[i]; }
00097 const UChar* data(int i) const { return &m_characters[i]; }
00098
00099 const UChar* characters() const { return m_characters; }
00100 int length() const { return m_len; }
00101
00102 void setText(const UChar* c, int len) { m_characters = c; m_len = len; }
00103
00104 bool allowTabs() const { return m_allowTabs; }
00105 int xPos() const { return m_xpos; }
00106 int padding() const { return m_padding; }
00107 bool rtl() const { return m_rtl; }
00108 bool ltr() const { return !m_rtl; }
00109 bool directionalOverride() const { return m_directionalOverride; }
00110 bool applyRunRounding() const { return m_applyRunRounding; }
00111 bool applyWordRounding() const { return m_applyWordRounding; }
00112 bool spacingDisabled() const { return m_disableSpacing; }
00113
00114 void disableSpacing() { m_disableSpacing = true; }
00115 void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; }
00116 void setRTL(bool b) { m_rtl = b; }
00117 void setDirectionalOverride(bool override) { m_directionalOverride = override; }
00118
00119 #if ENABLE(SVG_FONTS)
00120 RenderObject* referencingRenderObject() const { return m_referencingRenderObject; }
00121 void setReferencingRenderObject(RenderObject* object) { m_referencingRenderObject = object; }
00122
00123 SVGPaintServer* activePaintServer() const { return m_activePaintServer; }
00124 void setActivePaintServer(SVGPaintServer* object) { m_activePaintServer = object; }
00125 #endif
00126
00127 private:
00128 const UChar* m_characters;
00129 int m_len;
00130
00131 bool m_allowTabs;
00132 int m_xpos;
00133 int m_padding;
00134 bool m_rtl;
00135 bool m_directionalOverride;
00136 bool m_applyRunRounding;
00137 bool m_applyWordRounding;
00138 bool m_disableSpacing;
00139
00140 #if ENABLE(SVG_FONTS)
00141 RenderObject* m_referencingRenderObject;
00142 SVGPaintServer* m_activePaintServer;
00143 #endif
00144 };
00145
00146 class Font {
00147 public:
00148 Font();
00149 Font(const FontDescription&, short letterSpacing, short wordSpacing);
00150 #if !PLATFORM(QT)
00151 Font(const FontPlatformData&, bool isPrinting);
00152 #endif
00153 ~Font();
00154
00155 Font(const Font&);
00156 Font& operator=(const Font&);
00157
00158 bool operator==(const Font& other) const;
00159 bool operator!=(const Font& other) const {
00160 return !(*this == other);
00161 }
00162
00163 const FontDescription& fontDescription() const { return m_fontDescription; }
00164
00165 int pixelSize() const { return fontDescription().computedPixelSize(); }
00166 float size() const { return fontDescription().computedSize(); }
00167
00168 void update(PassRefPtr<FontSelector>) const;
00169
00170 void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
00171
00172 int width(const TextRun&) const;
00173 float floatWidth(const TextRun&) const;
00174 float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
00175
00176 int offsetForPosition(const TextRun&, int position, bool includePartialGlyphs) const;
00177 FloatRect selectionRectForText(const TextRun&, const IntPoint&, int h, int from = 0, int to = -1) const;
00178
00179 bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
00180
00181 short wordSpacing() const { return m_wordSpacing; }
00182 short letterSpacing() const { return m_letterSpacing; }
00183 #if !PLATFORM(QT)
00184 void setWordSpacing(short s) { m_wordSpacing = s; }
00185 void setLetterSpacing(short s) { m_letterSpacing = s; }
00186 #else
00187 void setWordSpacing(short s);
00188 void setLetterSpacing(short s);
00189 #endif
00190 bool isFixedPitch() const;
00191 bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); }
00192
00193 FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
00194
00195 FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
00196 const FontFamily& family() const { return m_fontDescription.family(); }
00197
00198 bool italic() const { return m_fontDescription.italic(); }
00199 FontWeight weight() const { return m_fontDescription.weight(); }
00200
00201 #if !PLATFORM(QT)
00202 bool isPlatformFont() const { return m_isPlatformFont; }
00203 #endif
00204
00205 #if PLATFORM(QT)
00206 inline const QFont &font() const { return m_font; }
00207 inline const QFont &scFont() const { return m_scFont; }
00208 #endif
00209
00210
00211 int ascent() const;
00212 int descent() const;
00213 int height() const { return ascent() + descent(); }
00214 int lineSpacing() const;
00215 float xHeight() const;
00216 unsigned unitsPerEm() const;
00217 int spaceWidth() const;
00218 int tabWidth() const { return 8 * spaceWidth(); }
00219
00220 #if !PLATFORM(QT)
00221 const SimpleFontData* primaryFont() const {
00222 if (!m_cachedPrimaryFont)
00223 cachePrimaryFont();
00224 return m_cachedPrimaryFont;
00225 }
00226
00227 const FontData* fontDataAt(unsigned) const;
00228 const GlyphData& glyphDataForCharacter(UChar32, bool mirror, bool forceSmallCaps = false) const;
00229
00230 const FontData* fontDataForCharacters(const UChar*, int length) const;
00231
00232 private:
00233 bool canUseGlyphCache(const TextRun&) const;
00234 void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
00235 #if ENABLE(SVG_FONTS)
00236 void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
00237 float floatWidthUsingSVGFont(const TextRun&) const;
00238 float floatWidthUsingSVGFont(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
00239 FloatRect selectionRectForTextUsingSVGFont(const TextRun&, const IntPoint&, int h, int from, int to) const;
00240 int offsetForPositionForTextUsingSVGFont(const TextRun&, int position, bool includePartialGlyphs) const;
00241 #endif
00242 void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
00243 void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const TextRun&, const FloatPoint&) const;
00244 void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
00245 float floatWidthForSimpleText(const TextRun&, GlyphBuffer*) const;
00246 float floatWidthForComplexText(const TextRun&) const;
00247 int offsetForPositionForSimpleText(const TextRun&, int position, bool includePartialGlyphs) const;
00248 int offsetForPositionForComplexText(const TextRun&, int position, bool includePartialGlyphs) const;
00249 FloatRect selectionRectForSimpleText(const TextRun&, const IntPoint&, int h, int from, int to) const;
00250 FloatRect selectionRectForComplexText(const TextRun&, const IntPoint&, int h, int from, int to) const;
00251 void cachePrimaryFont() const;
00252 #endif
00253 friend struct WidthIterator;
00254
00255
00256 public:
00257 #if !PLATFORM(QT)
00258 enum CodePath { Auto, Simple, Complex };
00259 static void setCodePath(CodePath);
00260 static CodePath codePath;
00261
00262 static const uint8_t gRoundingHackCharacterTable[256];
00263 static bool isRoundingHackCharacter(UChar32 c)
00264 {
00265 return (((c & ~0xFF) == 0 && gRoundingHackCharacterTable[c]));
00266 }
00267
00268 FontSelector* fontSelector() const;
00269 #endif
00270 static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == 0x00A0; }
00271 static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == 0x200e || c == 0x200f || c >= 0x202a && c <= 0x202e; }
00272
00273 #if ENABLE(SVG_FONTS)
00274 bool isSVGFont() const;
00275 SVGFontElement* svgFont() const;
00276 #endif
00277
00278 private:
00279 FontDescription m_fontDescription;
00280 #if !PLATFORM(QT)
00281 mutable RefPtr<FontFallbackList> m_fontList;
00282 mutable HashMap<int, GlyphPageTreeNode*> m_pages;
00283 mutable GlyphPageTreeNode* m_pageZero;
00284 mutable const SimpleFontData* m_cachedPrimaryFont;
00285 #endif
00286 short m_letterSpacing;
00287 short m_wordSpacing;
00288 #if !PLATFORM(QT)
00289 bool m_isPlatformFont;
00290 #else
00291 QFont m_font;
00292 QFont m_scFont;
00293 int m_spaceWidth;
00294 #endif
00295 };
00296
00297 }
00298
00299 #endif