Home | History | Annotate | Download | only in graphics
      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 "FontDescription.h"
     29 #include "FontFallbackList.h"
     30 #include "SimpleFontData.h"
     31 #include "TextDirection.h"
     32 #include "TypesettingFeatures.h"
     33 #include <wtf/HashMap.h>
     34 #include <wtf/HashSet.h>
     35 #include <wtf/MathExtras.h>
     36 #include <wtf/unicode/CharacterNames.h>
     37 
     38 #if PLATFORM(QT)
     39 #include <QFont>
     40 #endif
     41 
     42 namespace WebCore {
     43 
     44 class FloatPoint;
     45 class FloatRect;
     46 class FontData;
     47 class FontMetrics;
     48 class FontPlatformData;
     49 class FontSelector;
     50 class GlyphBuffer;
     51 class GlyphPageTreeNode;
     52 class GraphicsContext;
     53 class SVGFontElement;
     54 class TextRun;
     55 
     56 struct GlyphData;
     57 
     58 struct GlyphOverflow {
     59     GlyphOverflow()
     60         : left(0)
     61         , right(0)
     62         , top(0)
     63         , bottom(0)
     64         , computeBounds(false)
     65     {
     66     }
     67 
     68     int left;
     69     int right;
     70     int top;
     71     int bottom;
     72     bool computeBounds;
     73 };
     74 
     75 
     76 class Font {
     77 public:
     78     Font();
     79     Font(const FontDescription&, short letterSpacing, short wordSpacing);
     80     // This constructor is only used if the platform wants to start with a native font.
     81     Font(const FontPlatformData&, bool isPrinting, FontSmoothingMode = AutoSmoothing);
     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     int pixelSize() const { return fontDescription().computedPixelSize(); }
     93     float size() const { return fontDescription().computedSize(); }
     94 
     95     void update(PassRefPtr<FontSelector>) const;
     96 
     97     void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
     98     void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
     99 
    100     float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    101     float width(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
    102 
    103     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
    104     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
    105 
    106     bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
    107 
    108     short wordSpacing() const { return m_wordSpacing; }
    109     short letterSpacing() const { return m_letterSpacing; }
    110     void setWordSpacing(short s) { m_wordSpacing = s; }
    111     void setLetterSpacing(short s) { m_letterSpacing = s; }
    112     bool isFixedPitch() const;
    113     bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); }
    114 
    115     FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
    116 
    117     TypesettingFeatures typesettingFeatures() const
    118     {
    119         TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
    120         return textRenderingMode == OptimizeLegibility || textRenderingMode == GeometricPrecision ? Kerning | Ligatures : 0;
    121     }
    122 
    123     FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
    124     const FontFamily& family() const { return m_fontDescription.family(); }
    125 
    126     bool italic() const { return m_fontDescription.italic(); }
    127     FontWeight weight() const { return m_fontDescription.weight(); }
    128     FontWidthVariant widthVariant() const { return m_fontDescription.widthVariant(); }
    129 
    130     bool isPlatformFont() const { return m_isPlatformFont; }
    131 
    132     // Metrics that we query the FontFallbackList for.
    133     const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); }
    134     float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; }
    135     float tabWidth(const SimpleFontData& fontData) const { return 8 * fontData.spaceWidth() + letterSpacing(); }
    136     int emphasisMarkAscent(const AtomicString&) const;
    137     int emphasisMarkDescent(const AtomicString&) const;
    138     int emphasisMarkHeight(const AtomicString&) const;
    139 
    140     const SimpleFontData* primaryFont() const;
    141     const FontData* fontDataAt(unsigned) const;
    142     GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
    143     bool primaryFontHasGlyphForCharacter(UChar32) const;
    144 
    145     static bool isCJKIdeograph(UChar32);
    146     static bool isCJKIdeographOrSymbol(UChar32);
    147 
    148     static unsigned expansionOpportunityCount(const UChar*, size_t length, TextDirection, bool& isAfterExpansion);
    149 
    150 #if PLATFORM(QT)
    151     QFont font() const;
    152 #endif
    153 
    154     static void setShouldUseSmoothing(bool);
    155     static bool shouldUseSmoothing();
    156 
    157     enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow };
    158 
    159 private:
    160 #if ENABLE(SVG_FONTS)
    161     void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
    162     float floatWidthUsingSVGFont(const TextRun&) const;
    163     float floatWidthUsingSVGFont(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
    164     FloatRect selectionRectForTextUsingSVGFont(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    165     int offsetForPositionForTextUsingSVGFont(const TextRun&, float position, bool includePartialGlyphs) const;
    166 #endif
    167 
    168     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
    169 
    170     // Returns the initial in-stream advance.
    171     float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    172     void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
    173     void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
    174     void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
    175     void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const FloatPoint&) const;
    176     void drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
    177     float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    178     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
    179     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    180 
    181     bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
    182 
    183     static bool canReturnFallbackFontsForComplexText();
    184     static bool canExpandAroundIdeographsInComplexText();
    185 
    186     CodePath codePath(const TextRun&) const;
    187 
    188     // Returns the initial in-stream advance.
    189     float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    190     void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
    191     void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
    192     float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    193     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
    194     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    195 
    196     friend struct WidthIterator;
    197 
    198 public:
    199     // Useful for debugging the different font rendering code paths.
    200     static void setCodePath(CodePath);
    201     static CodePath codePath();
    202     static CodePath s_codePath;
    203 
    204     FontSelector* fontSelector() const;
    205     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
    206     static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInComplexScript(c) || c == 0x200c || c == 0x200d; }
    207     static bool treatAsZeroWidthSpaceInComplexScript(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200e && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == zeroWidthNoBreakSpace || c == objectReplacementCharacter; }
    208     static bool canReceiveTextEmphasis(UChar32 c);
    209 
    210     static inline UChar normalizeSpaces(UChar character)
    211     {
    212         if (treatAsSpace(character))
    213             return space;
    214 
    215         if (treatAsZeroWidthSpace(character))
    216             return zeroWidthSpace;
    217 
    218         return character;
    219     }
    220 
    221     static String normalizeSpaces(const UChar*, unsigned length);
    222 
    223 #if ENABLE(SVG_FONTS)
    224     bool isSVGFont() const;
    225     SVGFontElement* svgFont() const;
    226 #endif
    227 
    228     bool needsTranscoding() const { return m_needsTranscoding; }
    229 
    230 private:
    231     bool loadingCustomFonts() const
    232     {
    233         return m_fontList && m_fontList->loadingCustomFonts();
    234     }
    235 
    236     FontDescription m_fontDescription;
    237     mutable RefPtr<FontFallbackList> m_fontList;
    238     short m_letterSpacing;
    239     short m_wordSpacing;
    240     bool m_isPlatformFont;
    241     bool m_needsTranscoding;
    242 };
    243 
    244 inline Font::~Font()
    245 {
    246 }
    247 
    248 inline const SimpleFontData* Font::primaryFont() const
    249 {
    250     ASSERT(m_fontList);
    251     return m_fontList->primarySimpleFontData(this);
    252 }
    253 
    254 inline const FontData* Font::fontDataAt(unsigned index) const
    255 {
    256     ASSERT(m_fontList);
    257     return m_fontList->fontDataAt(this, index);
    258 }
    259 
    260 inline bool Font::isFixedPitch() const
    261 {
    262     ASSERT(m_fontList);
    263     return m_fontList->isFixedPitch(this);
    264 }
    265 
    266 inline FontSelector* Font::fontSelector() const
    267 {
    268     return m_fontList ? m_fontList->fontSelector() : 0;
    269 }
    270 
    271 }
    272 
    273 #endif
    274