Home | History | Annotate | Download | only in fonts
      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/fonts/TypesettingFeatures.h"
     33 #include "platform/text/TextDirection.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 TextLayout;
     56 class TextRun;
     57 struct TextRunPaintInfo;
     58 
     59 struct GlyphData;
     60 
     61 struct GlyphOverflow {
     62     GlyphOverflow()
     63         : left(0)
     64         , right(0)
     65         , top(0)
     66         , bottom(0)
     67         , computeBounds(false)
     68     {
     69     }
     70 
     71     int left;
     72     int right;
     73     int top;
     74     int bottom;
     75     bool computeBounds;
     76 };
     77 
     78 
     79 class PLATFORM_EXPORT Font {
     80 public:
     81     Font();
     82     Font(const FontDescription&, float letterSpacing, float wordSpacing);
     83     // This constructor is only used if the platform wants to start with a native font.
     84     Font(const FontPlatformData&, bool isPrinting, FontSmoothingMode = AutoSmoothing);
     85     ~Font();
     86 
     87     Font(const Font&);
     88     Font& operator=(const Font&);
     89 
     90     bool operator==(const Font& other) const;
     91     bool operator!=(const Font& other) const { return !(*this == other); }
     92 
     93     const FontDescription& fontDescription() const { return m_fontDescription; }
     94 
     95     int pixelSize() const { return fontDescription().computedPixelSize(); }
     96     float size() const { return fontDescription().computedSize(); }
     97 
     98     void update(PassRefPtr<FontSelector>) const;
     99 
    100     enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
    101     void drawText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
    102     void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
    103 
    104     float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    105     float width(const TextRun&, int& charsConsumed, String& glyphName) const;
    106 
    107     PassOwnPtr<TextLayout> createLayoutForMacComplexText(const TextRun&, unsigned textLength, float xPos, bool collapseWhiteSpace) const;
    108     static void deleteLayout(TextLayout*);
    109     static float width(TextLayout&, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts = 0);
    110 
    111     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
    112     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
    113 
    114     bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
    115 
    116     float wordSpacing() const { return m_wordSpacing; }
    117     float letterSpacing() const { return m_letterSpacing; }
    118     void setWordSpacing(float s) { m_wordSpacing = s; }
    119     void setLetterSpacing(float s) { m_letterSpacing = s; }
    120     bool isFixedPitch() const;
    121     bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); }
    122 
    123     TypesettingFeatures typesettingFeatures() const { return static_cast<TypesettingFeatures>(m_typesettingFeatures); }
    124 
    125     FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
    126     const FontFamily& family() const { return m_fontDescription.family(); }
    127 
    128     FontItalic italic() const { return m_fontDescription.italic(); }
    129     FontWeight weight() const { return m_fontDescription.weight(); }
    130     FontWidthVariant widthVariant() const { return m_fontDescription.widthVariant(); }
    131 
    132     bool isPlatformFont() const { return m_isPlatformFont; }
    133 
    134     // Metrics that we query the FontFallbackList for.
    135     const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); }
    136     float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; }
    137     float tabWidth(const SimpleFontData&, unsigned tabSize, float position) const;
    138     float tabWidth(unsigned tabSize, float position) const { return tabWidth(*primaryFont(), tabSize, position); }
    139 
    140     int emphasisMarkAscent(const AtomicString&) const;
    141     int emphasisMarkDescent(const AtomicString&) const;
    142     int emphasisMarkHeight(const AtomicString&) const;
    143 
    144     const SimpleFontData* primaryFont() const;
    145     const FontData* fontDataAt(unsigned) const;
    146     inline GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant = AutoVariant) const
    147     {
    148         return glyphDataAndPageForCharacter(c, mirror, variant).first;
    149     }
    150 #if OS(MACOSX)
    151     const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const;
    152 #endif
    153     std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
    154     bool primaryFontHasGlyphForCharacter(UChar32) const;
    155 
    156     static bool isCJKIdeograph(UChar32);
    157     static bool isCJKIdeographOrSymbol(UChar32);
    158 
    159     static unsigned expansionOpportunityCount(const LChar*, size_t length, TextDirection, bool& isAfterExpansion);
    160     static unsigned expansionOpportunityCount(const UChar*, size_t length, TextDirection, bool& isAfterExpansion);
    161 
    162     static void setShouldUseSmoothing(bool);
    163     static bool shouldUseSmoothing();
    164 
    165     enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow };
    166     CodePath codePath(const TextRun&) const;
    167     static CodePath characterRangeCodePath(const LChar*, unsigned) { return Simple; }
    168     static CodePath characterRangeCodePath(const UChar*, unsigned len);
    169 
    170 private:
    171     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
    172 
    173     // Returns the initial in-stream advance.
    174     float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    175     void drawSimpleText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const;
    176     void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
    177     void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&, const FloatRect& textRect) const;
    178     void drawGlyphBuffer(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const FloatPoint&) const;
    179     void drawEmphasisMarks(GraphicsContext*, const TextRunPaintInfo&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
    180     float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    181     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
    182     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    183 
    184     bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
    185 
    186     static bool canReturnFallbackFontsForComplexText();
    187     static bool canExpandAroundIdeographsInComplexText();
    188 
    189     // Returns the initial in-stream advance.
    190     float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    191     void drawComplexText(GraphicsContext*, const TextRunPaintInfo&, const FloatPoint&) const;
    192     void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&) const;
    193     float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    194     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
    195     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    196 
    197     friend struct WidthIterator;
    198     friend class SVGTextRunRenderingContext;
    199 
    200 public:
    201     // Useful for debugging the different font rendering code paths.
    202     static void setCodePath(CodePath);
    203     static CodePath codePath();
    204     static CodePath s_codePath;
    205 
    206     static void setDefaultTypesettingFeatures(TypesettingFeatures);
    207     static TypesettingFeatures defaultTypesettingFeatures();
    208 
    209     static const uint8_t s_roundingHackCharacterTable[256];
    210     static bool isRoundingHackCharacter(UChar32 c)
    211     {
    212         return !(c & ~0xFF) && s_roundingHackCharacterTable[c];
    213     }
    214 
    215     FontSelector* fontSelector() const;
    216     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
    217     static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInComplexScript(c) || c == 0x200c || c == 0x200d; }
    218     static bool treatAsZeroWidthSpaceInComplexScript(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || c == zeroWidthSpace || (c >= 0x200e && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == zeroWidthNoBreakSpace || c == objectReplacementCharacter; }
    219     static bool canReceiveTextEmphasis(UChar32 c);
    220 
    221     static inline UChar normalizeSpaces(UChar character)
    222     {
    223         if (treatAsSpace(character))
    224             return space;
    225 
    226         if (treatAsZeroWidthSpace(character))
    227             return zeroWidthSpace;
    228 
    229         return character;
    230     }
    231 
    232     static String normalizeSpaces(const LChar*, unsigned length);
    233     static String normalizeSpaces(const UChar*, unsigned length);
    234 
    235     FontFallbackList* fontList() const { return m_fontFallbackList.get(); }
    236 
    237     void willUseFontData() const;
    238 
    239 private:
    240     bool loadingCustomFonts() const
    241     {
    242         return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
    243     }
    244 
    245     TypesettingFeatures computeTypesettingFeatures() const
    246     {
    247         TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
    248         TypesettingFeatures features = s_defaultTypesettingFeatures;
    249 
    250         switch (textRenderingMode) {
    251         case AutoTextRendering:
    252             break;
    253         case OptimizeSpeed:
    254             features &= ~(Kerning | Ligatures);
    255             break;
    256         case GeometricPrecision:
    257         case OptimizeLegibility:
    258             features |= Kerning | Ligatures;
    259             break;
    260         }
    261 
    262         switch (m_fontDescription.kerning()) {
    263         case FontDescription::NoneKerning:
    264             features &= ~Kerning;
    265             break;
    266         case FontDescription::NormalKerning:
    267             features |= Kerning;
    268             break;
    269         case FontDescription::AutoKerning:
    270             break;
    271         }
    272 
    273         switch (m_fontDescription.commonLigaturesState()) {
    274         case FontDescription::DisabledLigaturesState:
    275             features &= ~Ligatures;
    276             break;
    277         case FontDescription::EnabledLigaturesState:
    278             features |= Ligatures;
    279             break;
    280         case FontDescription::NormalLigaturesState:
    281             break;
    282         }
    283 
    284         return features;
    285     }
    286 
    287     static TypesettingFeatures s_defaultTypesettingFeatures;
    288 
    289     FontDescription m_fontDescription;
    290     mutable RefPtr<FontFallbackList> m_fontFallbackList;
    291     float m_letterSpacing;
    292     float m_wordSpacing;
    293     bool m_isPlatformFont;
    294     mutable unsigned m_typesettingFeatures : 2; // (TypesettingFeatures) Caches values computed from m_fontDescription.
    295 };
    296 
    297 inline Font::~Font()
    298 {
    299 }
    300 
    301 inline const SimpleFontData* Font::primaryFont() const
    302 {
    303     ASSERT(m_fontFallbackList);
    304     return m_fontFallbackList->primarySimpleFontData(m_fontDescription);
    305 }
    306 
    307 inline const FontData* Font::fontDataAt(unsigned index) const
    308 {
    309     ASSERT(m_fontFallbackList);
    310     return m_fontFallbackList->fontDataAt(m_fontDescription, index);
    311 }
    312 
    313 inline bool Font::isFixedPitch() const
    314 {
    315     ASSERT(m_fontFallbackList);
    316     return m_fontFallbackList->isFixedPitch(m_fontDescription);
    317 }
    318 
    319 inline FontSelector* Font::fontSelector() const
    320 {
    321     return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
    322 }
    323 
    324 inline float Font::tabWidth(const SimpleFontData& fontData, unsigned tabSize, float position) const
    325 {
    326     if (!tabSize)
    327         return letterSpacing();
    328     float tabWidth = tabSize * fontData.spaceWidth() + letterSpacing();
    329     return tabWidth - fmodf(position, tabWidth);
    330 }
    331 
    332 }
    333 
    334 namespace WTF {
    335 
    336 template <> struct PLATFORM_EXPORT OwnedPtrDeleter<WebCore::TextLayout> {
    337     static void deletePtr(WebCore::TextLayout*);
    338 };
    339 
    340 }
    341 
    342 #endif
    343