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 "SkPaint.h" 37#include "SkTypeface.h" 38 39//#define TRACE_FONTPLATFORMDATA_LIFE 40//#define COUNT_FONTPLATFORMDATA_LIFE 41 42#ifdef COUNT_FONTPLATFORMDATA_LIFE 43static int gCount; 44static int gMaxCount; 45 46static void inc_count() 47{ 48 if (++gCount > gMaxCount) 49 { 50 gMaxCount = gCount; 51 SkDebugf("---------- FontPlatformData %d\n", gMaxCount); 52 } 53} 54 55static void dec_count() { --gCount; } 56#else 57 #define inc_count() 58 #define dec_count() 59#endif 60 61#ifdef TRACE_FONTPLATFORMDATA_LIFE 62 #define trace(num) SkDebugf("FontPlatformData%d %p %g %d %d\n", num, mTypeface, mTextSize, mFakeBold, mFakeItalic) 63#else 64 #define trace(num) 65#endif 66 67namespace WebCore { 68 69FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() 70{ 71#ifdef SUPPORT_COMPLEX_SCRIPTS 72 HB_FreeFace(m_harfbuzzFace); 73#endif 74} 75 76FontPlatformData::FontPlatformData() 77 : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false), 78 mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight) 79{ 80 inc_count(); 81 trace(1); 82} 83 84FontPlatformData::FontPlatformData(const FontPlatformData& src) 85{ 86 if (hashTableDeletedFontValue() != src.mTypeface) { 87 SkSafeRef(src.mTypeface); 88 } 89 90 mTypeface = src.mTypeface; 91 92 mTextSize = src.mTextSize; 93 mFakeBold = src.mFakeBold; 94 mFakeItalic = src.mFakeItalic; 95 m_harfbuzzFace = src.m_harfbuzzFace; 96 mOrientation = src.mOrientation; 97 mTextOrientation = src.mTextOrientation; 98 99 inc_count(); 100 trace(2); 101} 102 103FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic, 104 FontOrientation orientation, TextOrientation textOrientation) 105 : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic), 106 mOrientation(orientation), mTextOrientation(textOrientation) 107{ 108 if (hashTableDeletedFontValue() != mTypeface) { 109 SkSafeRef(mTypeface); 110 } 111 112 inc_count(); 113 trace(3); 114} 115 116FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) 117 : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic), 118 m_harfbuzzFace(src.m_harfbuzzFace), mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation) 119{ 120 if (hashTableDeletedFontValue() != mTypeface) { 121 SkSafeRef(mTypeface); 122 } 123 124 inc_count(); 125 trace(4); 126} 127 128FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) 129 : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique), 130 mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight) 131{ 132 inc_count(); 133 trace(5); 134} 135 136FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf) 137 : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold), 138 mFakeItalic(src.mFakeItalic), mOrientation(src.mOrientation), 139 mTextOrientation(src.mTextOrientation) 140{ 141 if (hashTableDeletedFontValue() != mTypeface) { 142 SkSafeRef(mTypeface); 143 } 144 145 inc_count(); 146 trace(6); 147} 148 149FontPlatformData::~FontPlatformData() 150{ 151 dec_count(); 152#ifdef TRACE_FONTPLATFORMDATA_LIFE 153 SkDebugf("----------- ~FontPlatformData\n"); 154#endif 155 156 if (hashTableDeletedFontValue() != mTypeface) { 157 SkSafeUnref(mTypeface); 158 } 159} 160 161FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) 162{ 163 if (hashTableDeletedFontValue() != src.mTypeface) { 164 SkSafeRef(src.mTypeface); 165 } 166 if (hashTableDeletedFontValue() != mTypeface) { 167 SkSafeUnref(mTypeface); 168 } 169 170 mTypeface = src.mTypeface; 171 mTextSize = src.mTextSize; 172 mFakeBold = src.mFakeBold; 173 mFakeItalic = src.mFakeItalic; 174 m_harfbuzzFace = src.m_harfbuzzFace; 175 mOrientation = src.mOrientation; 176 mTextOrientation = src.mTextOrientation; 177 178 return *this; 179} 180 181void FontPlatformData::setupPaint(SkPaint* paint) const 182{ 183 float ts = mTextSize; 184 if (!(ts > 0)) 185 ts = 12; 186 187 if (hashTableDeletedFontValue() == mTypeface) 188 paint->setTypeface(0); 189 else 190 paint->setTypeface(mTypeface); 191 192 paint->setAntiAlias(true); 193 paint->setSubpixelText(true); 194 paint->setHinting(SkPaint::kSlight_Hinting); 195 paint->setTextSize(SkFloatToScalar(ts)); 196 paint->setFakeBoldText(mFakeBold); 197 paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0); 198#ifndef SUPPORT_COMPLEX_SCRIPTS 199 paint->setTextEncoding(SkPaint::kUTF16_TextEncoding); 200#endif 201} 202 203uint32_t FontPlatformData::uniqueID() const 204{ 205 if (hashTableDeletedFontValue() == mTypeface) 206 return SkTypeface::UniqueID(0); 207 else 208 return SkTypeface::UniqueID(mTypeface); 209} 210 211bool FontPlatformData::operator==(const FontPlatformData& a) const 212{ 213 return mTypeface == a.mTypeface && 214 mTextSize == a.mTextSize && 215 mFakeBold == a.mFakeBold && 216 mFakeItalic == a.mFakeItalic && 217 mOrientation == a.mOrientation && 218 mTextOrientation == a.mTextOrientation; 219} 220 221unsigned FontPlatformData::hash() const 222{ 223 unsigned h; 224 225 if (hashTableDeletedFontValue() == mTypeface) { 226 h = reinterpret_cast<unsigned>(mTypeface); 227 } else { 228 h = SkTypeface::UniqueID(mTypeface); 229 } 230 231 uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize); 232 233 h ^= 0x01010101 * ((static_cast<int>(mTextOrientation) << 3) | (static_cast<int>(mOrientation) << 2) | 234 ((int)mFakeBold << 1) | (int)mFakeItalic); 235 h ^= sizeAsInt; 236 return h; 237} 238 239bool FontPlatformData::isFixedPitch() const 240{ 241 if (mTypeface && (mTypeface != hashTableDeletedFontValue())) 242 return mTypeface->isFixedWidth(); 243 else 244 return false; 245} 246 247HB_FaceRec_* FontPlatformData::harfbuzzFace() const 248{ 249#ifdef SUPPORT_COMPLEX_SCRIPTS 250 if (!m_harfbuzzFace) 251 m_harfbuzzFace = RefCountedHarfbuzzFace::create( 252 HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable)); 253 254 return m_harfbuzzFace->face(); 255#else 256 return NULL; 257#endif 258} 259} 260