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 #if PLATFORM(ANDROID)
    175 public:
    176 #endif
    177     void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
    178 #if PLATFORM(ANDROID)
    179 private:
    180 #endif
    181     void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const FloatPoint&) const;
    182     void drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
    183     float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    184     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
    185     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    186 
    187     bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
    188 
    189     static bool canReturnFallbackFontsForComplexText();
    190     static bool canExpandAroundIdeographsInComplexText();
    191 
    192     CodePath codePath(const TextRun&) const;
    193 
    194     // Returns the initial in-stream advance.
    195     float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    196     void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
    197     void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
    198     float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    199     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
    200     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    201 
    202     friend struct WidthIterator;
    203 
    204 public:
    205     // Useful for debugging the different font rendering code paths.
    206     static void setCodePath(CodePath);
    207     static CodePath codePath();
    208     static CodePath s_codePath;
    209 
    210     FontSelector* fontSelector() const;
    211     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
    212     static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInComplexScript(c) || c == 0x200c || c == 0x200d; }
    213     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; }
    214     static bool canReceiveTextEmphasis(UChar32 c);
    215 
    216     static inline UChar normalizeSpaces(UChar character)
    217     {
    218         if (treatAsSpace(character))
    219             return space;
    220 
    221         if (treatAsZeroWidthSpace(character))
    222             return zeroWidthSpace;
    223 
    224         return character;
    225     }
    226 
    227     static String normalizeSpaces(const UChar*, unsigned length);
    228 
    229 #if ENABLE(SVG_FONTS)
    230     bool isSVGFont() const;
    231     SVGFontElement* svgFont() const;
    232 #endif
    233 
    234     bool needsTranscoding() const { return m_needsTranscoding; }
    235 
    236 private:
    237     bool loadingCustomFonts() const
    238     {
    239         return m_fontList && m_fontList->loadingCustomFonts();
    240     }
    241 
    242     FontDescription m_fontDescription;
    243     mutable RefPtr<FontFallbackList> m_fontList;
    244     short m_letterSpacing;
    245     short m_wordSpacing;
    246     bool m_isPlatformFont;
    247     bool m_needsTranscoding;
    248 };
    249 
    250 inline Font::~Font()
    251 {
    252 }
    253 
    254 inline const SimpleFontData* Font::primaryFont() const
    255 {
    256     ASSERT(m_fontList);
    257     return m_fontList->primarySimpleFontData(this);
    258 }
    259 
    260 inline const FontData* Font::fontDataAt(unsigned index) const
    261 {
    262     ASSERT(m_fontList);
    263     return m_fontList->fontDataAt(this, index);
    264 }
    265 
    266 inline bool Font::isFixedPitch() const
    267 {
    268     ASSERT(m_fontList);
    269     return m_fontList->isFixedPitch(this);
    270 }
    271 
    272 inline FontSelector* Font::fontSelector() const
    273 {
    274     return m_fontList ? m_fontList->fontSelector() : 0;
    275 }
    276 
    277 }
    278 
    279 #endif
    280