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