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 g_count;
     45 static int g_maxCount;
     46 
     47 static void inc_count()
     48 {
     49     if (++g_count > g_maxCount)
     50     {
     51         g_maxCount = g_count;
     52         SkDebugf("---------- FontPlatformData %d\n", g_maxCount);
     53     }
     54 }
     55 
     56 static void dec_count() { --g_count; }
     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, m_typeface, m_textSize, m_fakeBold, m_fakeItalic)
     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     : m_typeface(NULL), m_textSize(0), m_emSizeInFontUnits(0), m_fakeBold(false), m_fakeItalic(false),
     79       m_orientation(Horizontal), m_textOrientation(TextOrientationVerticalRight)
     80 {
     81     inc_count();
     82     trace(1);
     83 }
     84 
     85 FontPlatformData::FontPlatformData(const FontPlatformData& src)
     86 {
     87     if (hashTableDeletedFontValue() != src.m_typeface) {
     88         SkSafeRef(src.m_typeface);
     89     }
     90 
     91     m_typeface = src.m_typeface;
     92     m_textSize = src.m_textSize;
     93     m_emSizeInFontUnits = src.m_emSizeInFontUnits;
     94     m_fakeBold = src.m_fakeBold;
     95     m_fakeItalic = src.m_fakeItalic;
     96     m_harfbuzzFace = src.m_harfbuzzFace;
     97     m_orientation = src.m_orientation;
     98     m_textOrientation = src.m_textOrientation;
     99     inc_count();
    100     trace(2);
    101 }
    102 
    103 FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic,
    104     FontOrientation orientation, TextOrientation textOrientation)
    105     : m_typeface(tf), m_textSize(textSize), m_emSizeInFontUnits(0), m_fakeBold(fakeBold), m_fakeItalic(fakeItalic),
    106       m_orientation(orientation), m_textOrientation(textOrientation)
    107 {
    108     if (hashTableDeletedFontValue() != m_typeface) {
    109         SkSafeRef(m_typeface);
    110     }
    111 
    112     inc_count();
    113     trace(3);
    114 }
    115 
    116 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
    117     : m_typeface(src.m_typeface), m_textSize(textSize), m_emSizeInFontUnits(src.m_emSizeInFontUnits), m_fakeBold(src.m_fakeBold), m_fakeItalic(src.m_fakeItalic),
    118       m_orientation(src.m_orientation), m_textOrientation(src.m_textOrientation), m_harfbuzzFace(src.m_harfbuzzFace)
    119 {
    120     if (hashTableDeletedFontValue() != m_typeface) {
    121         SkSafeRef(m_typeface);
    122     }
    123 
    124     inc_count();
    125     trace(4);
    126 }
    127 
    128 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
    129     : m_typeface(NULL), m_textSize(size),  m_emSizeInFontUnits(0), m_fakeBold(bold), m_fakeItalic(oblique),
    130       m_orientation(Horizontal), m_textOrientation(TextOrientationVerticalRight)
    131 {
    132     inc_count();
    133     trace(5);
    134 }
    135 
    136 FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
    137     : m_typeface(tf), m_textSize(src.m_textSize),  m_emSizeInFontUnits(0), m_fakeBold(src.m_fakeBold),
    138       m_fakeItalic(src.m_fakeItalic), m_orientation(src.m_orientation),
    139       m_textOrientation(src.m_textOrientation)
    140 {
    141     if (hashTableDeletedFontValue() != m_typeface) {
    142         SkSafeRef(m_typeface);
    143     }
    144 
    145     inc_count();
    146     trace(6);
    147 }
    148 
    149 FontPlatformData::~FontPlatformData()
    150 {
    151     dec_count();
    152 #ifdef TRACE_FONTPLATFORMDATA_LIFE
    153     SkDebugf("----------- ~FontPlatformData\n");
    154 #endif
    155 
    156     if (hashTableDeletedFontValue() != m_typeface) {
    157         SkSafeUnref(m_typeface);
    158     }
    159 }
    160 
    161 int FontPlatformData::emSizeInFontUnits() const
    162 {
    163     if (m_emSizeInFontUnits)
    164         return m_emSizeInFontUnits;
    165 
    166     SkAdvancedTypefaceMetrics* metrics = 0;
    167     if (m_typeface)
    168         metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
    169     if (metrics) {
    170         m_emSizeInFontUnits = metrics->fEmSize;
    171         metrics->unref();
    172     } else
    173         m_emSizeInFontUnits = 1000;  // default value copied from Skia.
    174     return m_emSizeInFontUnits;
    175 }
    176 
    177 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
    178 {
    179     if (hashTableDeletedFontValue() != src.m_typeface) {
    180         SkSafeRef(src.m_typeface);
    181     }
    182     if (hashTableDeletedFontValue() != m_typeface) {
    183         SkSafeUnref(m_typeface);
    184     }
    185 
    186     m_typeface = src.m_typeface;
    187     m_emSizeInFontUnits = src.m_emSizeInFontUnits;
    188     m_textSize = src.m_textSize;
    189     m_fakeBold = src.m_fakeBold;
    190     m_fakeItalic = src.m_fakeItalic;
    191     m_harfbuzzFace = src.m_harfbuzzFace;
    192     m_orientation = src.m_orientation;
    193     m_textOrientation = src.m_textOrientation;
    194 
    195     return *this;
    196 }
    197 
    198 SkLanguage FontPlatformData::s_defaultLanguage;
    199 void FontPlatformData::setDefaultLanguage(const char* language) {
    200     s_defaultLanguage = SkLanguage(language);
    201 }
    202 
    203 void FontPlatformData::setupPaint(SkPaint* paint) const
    204 {
    205     if (hashTableDeletedFontValue() == m_typeface)
    206         paint->setTypeface(0);
    207     else
    208         paint->setTypeface(m_typeface);
    209 
    210     paint->setAntiAlias(true);
    211     paint->setSubpixelText(true);
    212     paint->setHinting(SkPaint::kSlight_Hinting);
    213     paint->setTextSize(SkFloatToScalar(m_textSize));
    214     paint->setFakeBoldText(m_fakeBold);
    215     paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1/4 : 0);
    216     paint->setLanguage(s_defaultLanguage);
    217 #ifndef SUPPORT_COMPLEX_SCRIPTS
    218     paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
    219 #endif
    220 }
    221 
    222 uint32_t FontPlatformData::uniqueID() const
    223 {
    224     if (hashTableDeletedFontValue() == m_typeface)
    225         return SkTypeface::UniqueID(0);
    226     else
    227         return SkTypeface::UniqueID(m_typeface);
    228 }
    229 
    230 bool FontPlatformData::operator==(const FontPlatformData& a) const
    231 {
    232     return  m_typeface == a.m_typeface &&
    233             m_textSize == a.m_textSize &&
    234             m_fakeBold == a.m_fakeBold &&
    235             m_fakeItalic == a.m_fakeItalic &&
    236             m_orientation == a.m_orientation &&
    237             m_textOrientation == a.m_textOrientation;
    238 }
    239 
    240 unsigned FontPlatformData::hash() const
    241 {
    242     unsigned h;
    243 
    244     if (hashTableDeletedFontValue() == m_typeface) {
    245         h = reinterpret_cast<unsigned>(m_typeface);
    246     } else {
    247         h = SkTypeface::UniqueID(m_typeface);
    248     }
    249 
    250     uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&m_textSize);
    251 
    252     h ^= 0x01010101 * ((static_cast<int>(m_textOrientation) << 3) | (static_cast<int>(m_orientation) << 2) |
    253          ((int)m_fakeBold << 1) | (int)m_fakeItalic);
    254     h ^= sizeAsInt;
    255     return h;
    256 }
    257 
    258 bool FontPlatformData::isFixedPitch() const
    259 {
    260     if (m_typeface && (m_typeface != hashTableDeletedFontValue()))
    261         return m_typeface->isFixedWidth();
    262     else
    263         return false;
    264 }
    265 
    266 HB_FaceRec_* FontPlatformData::harfbuzzFace() const
    267 {
    268 #ifdef SUPPORT_COMPLEX_SCRIPTS
    269     if (!m_harfbuzzFace)
    270         m_harfbuzzFace = RefCountedHarfbuzzFace::create(
    271             HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable));
    272 
    273     return m_harfbuzzFace->face();
    274 #else
    275     return NULL;
    276 #endif
    277 }
    278 }
    279