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