Home | History | Annotate | Download | only in fonts
      1 /*
      2  * Copyright (C) 2011 Brent Fulgham
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 #include "config.h"
     22 #include "platform/fonts/FontPlatformData.h"
     23 
     24 #include "SkTypeface.h"
     25 #include "platform/fonts/harfbuzz/HarfBuzzFace.h"
     26 #include "wtf/HashMap.h"
     27 #include "wtf/text/StringHash.h"
     28 #include "wtf/text/WTFString.h"
     29 
     30 #if OS(MACOSX)
     31 #include "third_party/skia/include/ports/SkTypeface_mac.h"
     32 #endif
     33 
     34 using namespace std;
     35 
     36 namespace blink {
     37 
     38 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
     39     : m_typeface(nullptr)
     40 #if !OS(WIN)
     41     , m_family(CString())
     42 #endif
     43     , m_textSize(0)
     44     , m_syntheticBold(false)
     45     , m_syntheticItalic(false)
     46     , m_orientation(Horizontal)
     47 #if OS(MACOSX)
     48     , m_isColorBitmapFont(false)
     49     , m_isCompositeFontReference(false)
     50 #endif
     51     , m_widthVariant(RegularWidth)
     52 #if OS(MACOSX)
     53     , m_font(nullptr)
     54 #else
     55     , m_style(FontRenderStyle())
     56 #endif
     57     , m_isHashTableDeletedValue(true)
     58 #if OS(WIN)
     59     , m_paintTextFlags(0)
     60     , m_useSubpixelPositioning(false)
     61     , m_minSizeForAntiAlias(0)
     62     , m_minSizeForSubpixel(0)
     63 #endif
     64 {
     65 }
     66 
     67 FontPlatformData::FontPlatformData()
     68     : m_typeface(nullptr)
     69 #if !OS(WIN)
     70     , m_family(CString())
     71 #endif
     72     , m_textSize(0)
     73     , m_syntheticBold(false)
     74     , m_syntheticItalic(false)
     75     , m_orientation(Horizontal)
     76 #if OS(MACOSX)
     77     , m_isColorBitmapFont(false)
     78     , m_isCompositeFontReference(false)
     79 #endif
     80     , m_widthVariant(RegularWidth)
     81 #if OS(MACOSX)
     82     , m_font(nullptr)
     83 #else
     84     , m_style(FontRenderStyle())
     85 #endif
     86     , m_isHashTableDeletedValue(false)
     87 #if OS(WIN)
     88     , m_paintTextFlags(0)
     89     , m_useSubpixelPositioning(false)
     90     , m_minSizeForAntiAlias(0)
     91     , m_minSizeForSubpixel(0)
     92 #endif
     93 {
     94 }
     95 
     96 FontPlatformData::FontPlatformData(float size, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, FontWidthVariant widthVariant)
     97     : m_typeface(nullptr)
     98 #if !OS(WIN)
     99     , m_family(CString())
    100 #endif
    101     , m_textSize(size)
    102     , m_syntheticBold(syntheticBold)
    103     , m_syntheticItalic(syntheticItalic)
    104     , m_orientation(orientation)
    105 #if OS(MACOSX)
    106     , m_isColorBitmapFont(false)
    107     , m_isCompositeFontReference(false)
    108 #endif
    109     , m_widthVariant(widthVariant)
    110 #if OS(MACOSX)
    111     , m_font(nullptr)
    112 #else
    113     , m_style(FontRenderStyle())
    114 #endif
    115     , m_isHashTableDeletedValue(false)
    116 #if OS(WIN)
    117     , m_paintTextFlags(0)
    118     , m_useSubpixelPositioning(false)
    119     , m_minSizeForAntiAlias(0)
    120     , m_minSizeForSubpixel(0)
    121 #endif
    122 {
    123 }
    124 
    125 FontPlatformData::FontPlatformData(const FontPlatformData& source)
    126     : m_typeface(source.m_typeface)
    127 #if !OS(WIN)
    128     , m_family(source.m_family)
    129 #endif
    130     , m_textSize(source.m_textSize)
    131     , m_syntheticBold(source.m_syntheticBold)
    132     , m_syntheticItalic(source.m_syntheticItalic)
    133     , m_orientation(source.m_orientation)
    134 #if OS(MACOSX)
    135     , m_isColorBitmapFont(source.m_isColorBitmapFont)
    136     , m_isCompositeFontReference(source.m_isCompositeFontReference)
    137 #endif
    138     , m_widthVariant(source.m_widthVariant)
    139 #if !OS(MACOSX)
    140     , m_style(source.m_style)
    141 #endif
    142     , m_harfBuzzFace(nullptr)
    143     , m_isHashTableDeletedValue(false)
    144 #if OS(WIN)
    145     , m_paintTextFlags(source.m_paintTextFlags)
    146     , m_useSubpixelPositioning(source.m_useSubpixelPositioning)
    147     , m_minSizeForAntiAlias(source.m_minSizeForAntiAlias)
    148     , m_minSizeForSubpixel(source.m_minSizeForSubpixel)
    149 #endif
    150 {
    151 #if OS(MACOSX)
    152     platformDataInit(source);
    153 #endif
    154 }
    155 
    156 
    157 #if OS(MACOSX)
    158 FontPlatformData::FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, FontWidthVariant widthVariant)
    159     : m_typeface(nullptr)
    160     , m_family(CString())
    161     , m_textSize(size)
    162     , m_syntheticBold(syntheticBold)
    163     , m_syntheticItalic(syntheticItalic)
    164     , m_orientation(orientation)
    165     , m_isColorBitmapFont(false)
    166     , m_isCompositeFontReference(false)
    167     , m_widthVariant(widthVariant)
    168     , m_font(nullptr)
    169     , m_cgFont(cgFont)
    170     , m_isHashTableDeletedValue(false)
    171 {
    172 }
    173 
    174 #else
    175 
    176 FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family, float textSize, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, bool subpixelTextPosition)
    177     : m_typeface(tf)
    178 #if !OS(WIN)
    179     , m_family(family)
    180 #endif
    181     , m_textSize(textSize)
    182     , m_syntheticBold(syntheticBold)
    183     , m_syntheticItalic(syntheticItalic)
    184     , m_orientation(orientation)
    185     , m_widthVariant(RegularWidth)
    186     , m_isHashTableDeletedValue(false)
    187 #if OS(WIN)
    188     , m_paintTextFlags(0)
    189     , m_useSubpixelPositioning(subpixelTextPosition)
    190     , m_minSizeForAntiAlias(0)
    191     , m_minSizeForSubpixel(0)
    192 #endif
    193 {
    194     querySystemForRenderStyle(subpixelTextPosition);
    195 }
    196 
    197 
    198 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    199     : m_typeface(src.m_typeface)
    200 #if !OS(WIN)
    201     , m_family(src.m_family)
    202 #endif
    203     , m_textSize(textSize)
    204     , m_syntheticBold(src.m_syntheticBold)
    205     , m_syntheticItalic(src.m_syntheticItalic)
    206     , m_orientation(src.m_orientation)
    207     , m_widthVariant(RegularWidth)
    208     , m_harfBuzzFace(nullptr)
    209     , m_isHashTableDeletedValue(false)
    210 #if OS(WIN)
    211     , m_paintTextFlags(src.m_paintTextFlags)
    212     , m_useSubpixelPositioning(src.m_useSubpixelPositioning)
    213     , m_minSizeForAntiAlias(src.m_minSizeForAntiAlias)
    214     , m_minSizeForSubpixel(src.m_minSizeForSubpixel)
    215 #endif
    216 {
    217     querySystemForRenderStyle(FontDescription::subpixelPositioning());
    218 }
    219 #endif
    220 
    221 FontPlatformData::~FontPlatformData()
    222 {
    223 #if OS(MACOSX)
    224     if (m_font)
    225         CFRelease(m_font);
    226 #endif
    227 }
    228 
    229 const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
    230 {
    231     // Check for self-assignment.
    232     if (this == &other)
    233         return *this;
    234 
    235     m_typeface = other.m_typeface;
    236 #if !OS(WIN)
    237     m_family = other.m_family;
    238 #endif
    239     m_textSize = other.m_textSize;
    240     m_syntheticBold = other.m_syntheticBold;
    241     m_syntheticItalic = other.m_syntheticItalic;
    242     m_harfBuzzFace = nullptr;
    243     m_orientation = other.m_orientation;
    244     m_widthVariant = other.m_widthVariant;
    245 #if OS(MACOSX)
    246     m_isColorBitmapFont = other.m_isColorBitmapFont;
    247     m_isCompositeFontReference = other.m_isCompositeFontReference;
    248 #else
    249     m_style = other.m_style;
    250 #endif
    251     m_widthVariant = other.m_widthVariant;
    252 
    253 #if OS(WIN)
    254     m_paintTextFlags = 0;
    255     m_minSizeForAntiAlias = other.m_minSizeForAntiAlias;
    256     m_minSizeForSubpixel = other.m_minSizeForSubpixel;
    257     m_useSubpixelPositioning = other.m_useSubpixelPositioning;
    258 #endif
    259 
    260 #if OS(MACOSX)
    261     return platformDataAssign(other);
    262 #else
    263     return *this;
    264 #endif
    265 }
    266 
    267 bool FontPlatformData::operator==(const FontPlatformData& a) const
    268 {
    269     // If either of the typeface pointers are null then we test for pointer
    270     // equality. Otherwise, we call SkTypeface::Equal on the valid pointers.
    271     bool typefacesEqual = false;
    272 #if !OS(MACOSX)
    273     if (!m_typeface || !a.m_typeface)
    274         typefacesEqual = m_typeface == a.m_typeface;
    275     else
    276         typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get());
    277 #else
    278     if (m_font || a.m_font)
    279         typefacesEqual = m_font == a.m_font;
    280     else
    281         typefacesEqual = m_cgFont == a.m_cgFont;
    282 #endif
    283 
    284     return typefacesEqual
    285         && m_textSize == a.m_textSize
    286         && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue
    287         && m_syntheticBold == a.m_syntheticBold
    288         && m_syntheticItalic == a.m_syntheticItalic
    289         && m_orientation == a.m_orientation
    290 #if !OS(MACOSX)
    291         && m_style == a.m_style
    292 #else
    293         && m_isColorBitmapFont == a.m_isColorBitmapFont
    294         && m_isCompositeFontReference == a.m_isCompositeFontReference
    295 #endif
    296         && m_widthVariant == a.m_widthVariant;
    297 }
    298 
    299 SkFontID FontPlatformData::uniqueID() const
    300 {
    301     return typeface()->uniqueID();
    302 }
    303 
    304 String FontPlatformData::fontFamilyName() const
    305 {
    306     // FIXME(crbug.com/326582): come up with a proper way of handling SVG.
    307     if (!this->typeface())
    308         return "";
    309     SkTypeface::LocalizedStrings* fontFamilyIterator = this->typeface()->createFamilyNameIterator();
    310     SkTypeface::LocalizedString localizedString;
    311     while (fontFamilyIterator->next(&localizedString) && !localizedString.fString.size()) { }
    312     fontFamilyIterator->unref();
    313     return String(localizedString.fString.c_str());
    314 }
    315 
    316 bool FontPlatformData::isFixedPitch() const
    317 {
    318     return typeface() && typeface()->isFixedPitch();
    319 }
    320 
    321 SkTypeface* FontPlatformData::typeface() const
    322 {
    323 #if OS(MACOSX)
    324     if (!m_typeface)
    325         m_typeface = adoptRef(SkCreateTypefaceFromCTFont(ctFont()));
    326 #endif
    327     return m_typeface.get();
    328 }
    329 
    330 HarfBuzzFace* FontPlatformData::harfBuzzFace() const
    331 {
    332 #if OS(MACOSX)
    333     CTFontRef font = ctFont();
    334     // Keeping the decision not to pass AAT font to HarfBuzz for now,
    335     // until we switch to HarfBuzz as a shaper for all cases.
    336     if (isAATFont(font))
    337         return 0;
    338 #endif
    339     if (!m_harfBuzzFace)
    340         m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID());
    341 
    342     return m_harfBuzzFace.get();
    343 }
    344 
    345 } // namespace blink
    346