Home | History | Annotate | Download | only in fonts
      1 /*
      2  * Copyright 2009, The Android Open Source Project
      3  * Copyright (C) 2006 Apple Computer, Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 //This file is part of the internal font implementation.  It should not be included by anyone other than
     28 // FontMac.cpp, FontWin.cpp and Font.cpp.
     29 
     30 #include "config.h"
     31 #include "FontPlatformData.h"
     32 
     33 #ifdef SUPPORT_COMPLEX_SCRIPTS
     34 #include "HarfbuzzSkia.h"
     35 #endif
     36 #include "SkAdvancedTypefaceMetrics.h"
     37 #include "SkPaint.h"
     38 #include "SkTypeface.h"
     39 
     40 //#define TRACE_FONTPLATFORMDATA_LIFE
     41 //#define COUNT_FONTPLATFORMDATA_LIFE
     42 
     43 #ifdef COUNT_FONTPLATFORMDATA_LIFE
     44 static int gCount;
     45 static int gMaxCount;
     46 
     47 static void inc_count()
     48 {
     49     if (++gCount > gMaxCount)
     50     {
     51         gMaxCount = gCount;
     52         SkDebugf("---------- FontPlatformData %d\n", gMaxCount);
     53     }
     54 }
     55 
     56 static void dec_count() { --gCount; }
     57 #else
     58     #define inc_count()
     59     #define dec_count()
     60 #endif
     61 
     62 #ifdef TRACE_FONTPLATFORMDATA_LIFE
     63     #define trace(num)  SkDebugf("FontPlatformData%d %p %g %d %d\n", num, mTypeface, mTextSize, mFakeBold, mFakeItalic)
     64 #else
     65     #define trace(num)
     66 #endif
     67 
     68 namespace WebCore {
     69 
     70 FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace()
     71 {
     72 #ifdef SUPPORT_COMPLEX_SCRIPTS
     73     HB_FreeFace(m_harfbuzzFace);
     74 #endif
     75 }
     76 
     77 FontPlatformData::FontPlatformData()
     78     : mTypeface(NULL), mTextSize(0), mEmSizeInFontUnits(0), mFakeBold(false), mFakeItalic(false),
     79       mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight)
     80 {
     81     inc_count();
     82     trace(1);
     83 }
     84 
     85 FontPlatformData::FontPlatformData(const FontPlatformData& src)
     86 {
     87     if (hashTableDeletedFontValue() != src.mTypeface) {
     88         SkSafeRef(src.mTypeface);
     89     }
     90 
     91     mTypeface = src.mTypeface;
     92     mTextSize = src.mTextSize;
     93     mEmSizeInFontUnits = src.mEmSizeInFontUnits;
     94     mFakeBold = src.mFakeBold;
     95     mFakeItalic = src.mFakeItalic;
     96     m_harfbuzzFace = src.m_harfbuzzFace;
     97     mOrientation = src.mOrientation;
     98     mTextOrientation = src.mTextOrientation;
     99 
    100     inc_count();
    101     trace(2);
    102 }
    103 
    104 FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic,
    105     FontOrientation orientation, TextOrientation textOrientation)
    106     : mTypeface(tf), mTextSize(textSize), mEmSizeInFontUnits(0), mFakeBold(fakeBold), mFakeItalic(fakeItalic),
    107       mOrientation(orientation), mTextOrientation(textOrientation)
    108 {
    109     if (hashTableDeletedFontValue() != mTypeface) {
    110         SkSafeRef(mTypeface);
    111     }
    112 
    113     inc_count();
    114     trace(3);
    115 }
    116 
    117 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    118     : mTypeface(src.mTypeface), mTextSize(textSize), mEmSizeInFontUnits(src.mEmSizeInFontUnits), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic),
    119       mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation), m_harfbuzzFace(src.m_harfbuzzFace)
    120 {
    121     if (hashTableDeletedFontValue() != mTypeface) {
    122         SkSafeRef(mTypeface);
    123     }
    124 
    125     inc_count();
    126     trace(4);
    127 }
    128 
    129 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
    130     : mTypeface(NULL), mTextSize(size),  mEmSizeInFontUnits(0), mFakeBold(bold), mFakeItalic(oblique),
    131       mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight)
    132 {
    133     inc_count();
    134     trace(5);
    135 }
    136 
    137 FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
    138     : mTypeface(tf), mTextSize(src.mTextSize),  mEmSizeInFontUnits(0), mFakeBold(src.mFakeBold),
    139       mFakeItalic(src.mFakeItalic), mOrientation(src.mOrientation),
    140       mTextOrientation(src.mTextOrientation)
    141 {
    142     if (hashTableDeletedFontValue() != mTypeface) {
    143         SkSafeRef(mTypeface);
    144     }
    145 
    146     inc_count();
    147     trace(6);
    148 }
    149 
    150 FontPlatformData::~FontPlatformData()
    151 {
    152     dec_count();
    153 #ifdef TRACE_FONTPLATFORMDATA_LIFE
    154     SkDebugf("----------- ~FontPlatformData\n");
    155 #endif
    156 
    157     if (hashTableDeletedFontValue() != mTypeface) {
    158         SkSafeUnref(mTypeface);
    159     }
    160 }
    161 
    162 int FontPlatformData::emSizeInFontUnits() const
    163 {
    164     if (mEmSizeInFontUnits)
    165         return mEmSizeInFontUnits;
    166 
    167     SkAdvancedTypefaceMetrics* metrics = 0;
    168     if (mTypeface)
    169         metrics = mTypeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
    170     if (metrics) {
    171         mEmSizeInFontUnits = metrics->fEmSize;
    172         metrics->unref();
    173     } else
    174         mEmSizeInFontUnits = 1000;  // default value copied from Skia.
    175     return mEmSizeInFontUnits;
    176 }
    177 
    178 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
    179 {
    180     if (hashTableDeletedFontValue() != src.mTypeface) {
    181         SkSafeRef(src.mTypeface);
    182     }
    183     if (hashTableDeletedFontValue() != mTypeface) {
    184         SkSafeUnref(mTypeface);
    185     }
    186 
    187     mTypeface = src.mTypeface;
    188     mEmSizeInFontUnits = src.mEmSizeInFontUnits;
    189     mTextSize = src.mTextSize;
    190     mFakeBold = src.mFakeBold;
    191     mFakeItalic = src.mFakeItalic;
    192     m_harfbuzzFace = src.m_harfbuzzFace;
    193     mOrientation = src.mOrientation;
    194     mTextOrientation = src.mTextOrientation;
    195 
    196     return *this;
    197 }
    198 
    199 void FontPlatformData::setupPaint(SkPaint* paint) const
    200 {
    201     if (hashTableDeletedFontValue() == mTypeface)
    202         paint->setTypeface(0);
    203     else
    204         paint->setTypeface(mTypeface);
    205 
    206     paint->setAntiAlias(true);
    207     paint->setSubpixelText(true);
    208     paint->setHinting(SkPaint::kSlight_Hinting);
    209     paint->setTextSize(SkFloatToScalar(mTextSize));
    210     paint->setFakeBoldText(mFakeBold);
    211     paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0);
    212 #ifndef SUPPORT_COMPLEX_SCRIPTS
    213     paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
    214 #endif
    215 }
    216 
    217 uint32_t FontPlatformData::uniqueID() const
    218 {
    219     if (hashTableDeletedFontValue() == mTypeface)
    220         return SkTypeface::UniqueID(0);
    221     else
    222         return SkTypeface::UniqueID(mTypeface);
    223 }
    224 
    225 bool FontPlatformData::operator==(const FontPlatformData& a) const
    226 {
    227     return  mTypeface == a.mTypeface &&
    228             mTextSize == a.mTextSize &&
    229             mFakeBold == a.mFakeBold &&
    230             mFakeItalic == a.mFakeItalic &&
    231             mOrientation == a.mOrientation &&
    232             mTextOrientation == a.mTextOrientation;
    233 }
    234 
    235 unsigned FontPlatformData::hash() const
    236 {
    237     unsigned h;
    238 
    239     if (hashTableDeletedFontValue() == mTypeface) {
    240         h = reinterpret_cast<unsigned>(mTypeface);
    241     } else {
    242         h = SkTypeface::UniqueID(mTypeface);
    243     }
    244 
    245     uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize);
    246 
    247     h ^= 0x01010101 * ((static_cast<int>(mTextOrientation) << 3) | (static_cast<int>(mOrientation) << 2) |
    248          ((int)mFakeBold << 1) | (int)mFakeItalic);
    249     h ^= sizeAsInt;
    250     return h;
    251 }
    252 
    253 bool FontPlatformData::isFixedPitch() const
    254 {
    255     if (mTypeface && (mTypeface != hashTableDeletedFontValue()))
    256         return mTypeface->isFixedWidth();
    257     else
    258         return false;
    259 }
    260 
    261 HB_FaceRec_* FontPlatformData::harfbuzzFace() const
    262 {
    263 #ifdef SUPPORT_COMPLEX_SCRIPTS
    264     if (!m_harfbuzzFace)
    265         m_harfbuzzFace = RefCountedHarfbuzzFace::create(
    266             HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable));
    267 
    268     return m_harfbuzzFace->face();
    269 #else
    270     return NULL;
    271 #endif
    272 }
    273 }
    274