1 /* 2 * Copyright (C) 2011 Brent Fulgham 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 19 */ 20 21 #include "config.h" 22 #include "platform/fonts/FontPlatformData.h" 23 24 #include "SkTypeface.h" 25 #include "platform/fonts/harfbuzz/HarfBuzzFace.h" 26 #include "wtf/HashMap.h" 27 #include "wtf/text/StringHash.h" 28 #include "wtf/text/WTFString.h" 29 30 #if OS(MACOSX) 31 #include "third_party/skia/include/ports/SkTypeface_mac.h" 32 #endif 33 34 using namespace std; 35 36 namespace blink { 37 38 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType) 39 : m_typeface(nullptr) 40 #if !OS(WIN) 41 , m_family(CString()) 42 #endif 43 , m_textSize(0) 44 , m_syntheticBold(false) 45 , m_syntheticItalic(false) 46 , m_orientation(Horizontal) 47 #if OS(MACOSX) 48 , m_isColorBitmapFont(false) 49 , m_isCompositeFontReference(false) 50 #endif 51 , m_widthVariant(RegularWidth) 52 #if OS(MACOSX) 53 , m_font(nullptr) 54 #else 55 , m_style(FontRenderStyle()) 56 #endif 57 , m_isHashTableDeletedValue(true) 58 #if OS(WIN) 59 , m_paintTextFlags(0) 60 , m_useSubpixelPositioning(false) 61 , m_minSizeForAntiAlias(0) 62 , m_minSizeForSubpixel(0) 63 #endif 64 { 65 } 66 67 FontPlatformData::FontPlatformData() 68 : m_typeface(nullptr) 69 #if !OS(WIN) 70 , m_family(CString()) 71 #endif 72 , m_textSize(0) 73 , m_syntheticBold(false) 74 , m_syntheticItalic(false) 75 , m_orientation(Horizontal) 76 #if OS(MACOSX) 77 , m_isColorBitmapFont(false) 78 , m_isCompositeFontReference(false) 79 #endif 80 , m_widthVariant(RegularWidth) 81 #if OS(MACOSX) 82 , m_font(nullptr) 83 #else 84 , m_style(FontRenderStyle()) 85 #endif 86 , m_isHashTableDeletedValue(false) 87 #if OS(WIN) 88 , m_paintTextFlags(0) 89 , m_useSubpixelPositioning(false) 90 , m_minSizeForAntiAlias(0) 91 , m_minSizeForSubpixel(0) 92 #endif 93 { 94 } 95 96 FontPlatformData::FontPlatformData(float size, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, FontWidthVariant widthVariant) 97 : m_typeface(nullptr) 98 #if !OS(WIN) 99 , m_family(CString()) 100 #endif 101 , m_textSize(size) 102 , m_syntheticBold(syntheticBold) 103 , m_syntheticItalic(syntheticItalic) 104 , m_orientation(orientation) 105 #if OS(MACOSX) 106 , m_isColorBitmapFont(false) 107 , m_isCompositeFontReference(false) 108 #endif 109 , m_widthVariant(widthVariant) 110 #if OS(MACOSX) 111 , m_font(nullptr) 112 #else 113 , m_style(FontRenderStyle()) 114 #endif 115 , m_isHashTableDeletedValue(false) 116 #if OS(WIN) 117 , m_paintTextFlags(0) 118 , m_useSubpixelPositioning(false) 119 , m_minSizeForAntiAlias(0) 120 , m_minSizeForSubpixel(0) 121 #endif 122 { 123 } 124 125 FontPlatformData::FontPlatformData(const FontPlatformData& source) 126 : m_typeface(source.m_typeface) 127 #if !OS(WIN) 128 , m_family(source.m_family) 129 #endif 130 , m_textSize(source.m_textSize) 131 , m_syntheticBold(source.m_syntheticBold) 132 , m_syntheticItalic(source.m_syntheticItalic) 133 , m_orientation(source.m_orientation) 134 #if OS(MACOSX) 135 , m_isColorBitmapFont(source.m_isColorBitmapFont) 136 , m_isCompositeFontReference(source.m_isCompositeFontReference) 137 #endif 138 , m_widthVariant(source.m_widthVariant) 139 #if !OS(MACOSX) 140 , m_style(source.m_style) 141 #endif 142 , m_harfBuzzFace(nullptr) 143 , m_isHashTableDeletedValue(false) 144 #if OS(WIN) 145 , m_paintTextFlags(source.m_paintTextFlags) 146 , m_useSubpixelPositioning(source.m_useSubpixelPositioning) 147 , m_minSizeForAntiAlias(source.m_minSizeForAntiAlias) 148 , m_minSizeForSubpixel(source.m_minSizeForSubpixel) 149 #endif 150 { 151 #if OS(MACOSX) 152 platformDataInit(source); 153 #endif 154 } 155 156 157 #if OS(MACOSX) 158 FontPlatformData::FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, FontWidthVariant widthVariant) 159 : m_typeface(nullptr) 160 , m_family(CString()) 161 , m_textSize(size) 162 , m_syntheticBold(syntheticBold) 163 , m_syntheticItalic(syntheticItalic) 164 , m_orientation(orientation) 165 , m_isColorBitmapFont(false) 166 , m_isCompositeFontReference(false) 167 , m_widthVariant(widthVariant) 168 , m_font(nullptr) 169 , m_cgFont(cgFont) 170 , m_isHashTableDeletedValue(false) 171 { 172 } 173 174 #else 175 176 FontPlatformData::FontPlatformData(PassRefPtr<SkTypeface> tf, const char* family, float textSize, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, bool subpixelTextPosition) 177 : m_typeface(tf) 178 #if !OS(WIN) 179 , m_family(family) 180 #endif 181 , m_textSize(textSize) 182 , m_syntheticBold(syntheticBold) 183 , m_syntheticItalic(syntheticItalic) 184 , m_orientation(orientation) 185 , m_widthVariant(RegularWidth) 186 , m_isHashTableDeletedValue(false) 187 #if OS(WIN) 188 , m_paintTextFlags(0) 189 , m_useSubpixelPositioning(subpixelTextPosition) 190 , m_minSizeForAntiAlias(0) 191 , m_minSizeForSubpixel(0) 192 #endif 193 { 194 querySystemForRenderStyle(subpixelTextPosition); 195 } 196 197 198 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) 199 : m_typeface(src.m_typeface) 200 #if !OS(WIN) 201 , m_family(src.m_family) 202 #endif 203 , m_textSize(textSize) 204 , m_syntheticBold(src.m_syntheticBold) 205 , m_syntheticItalic(src.m_syntheticItalic) 206 , m_orientation(src.m_orientation) 207 , m_widthVariant(RegularWidth) 208 , m_harfBuzzFace(nullptr) 209 , m_isHashTableDeletedValue(false) 210 #if OS(WIN) 211 , m_paintTextFlags(src.m_paintTextFlags) 212 , m_useSubpixelPositioning(src.m_useSubpixelPositioning) 213 , m_minSizeForAntiAlias(src.m_minSizeForAntiAlias) 214 , m_minSizeForSubpixel(src.m_minSizeForSubpixel) 215 #endif 216 { 217 querySystemForRenderStyle(FontDescription::subpixelPositioning()); 218 } 219 #endif 220 221 FontPlatformData::~FontPlatformData() 222 { 223 #if OS(MACOSX) 224 if (m_font) 225 CFRelease(m_font); 226 #endif 227 } 228 229 const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) 230 { 231 // Check for self-assignment. 232 if (this == &other) 233 return *this; 234 235 m_typeface = other.m_typeface; 236 #if !OS(WIN) 237 m_family = other.m_family; 238 #endif 239 m_textSize = other.m_textSize; 240 m_syntheticBold = other.m_syntheticBold; 241 m_syntheticItalic = other.m_syntheticItalic; 242 m_harfBuzzFace = nullptr; 243 m_orientation = other.m_orientation; 244 m_widthVariant = other.m_widthVariant; 245 #if OS(MACOSX) 246 m_isColorBitmapFont = other.m_isColorBitmapFont; 247 m_isCompositeFontReference = other.m_isCompositeFontReference; 248 #else 249 m_style = other.m_style; 250 #endif 251 m_widthVariant = other.m_widthVariant; 252 253 #if OS(WIN) 254 m_paintTextFlags = 0; 255 m_minSizeForAntiAlias = other.m_minSizeForAntiAlias; 256 m_minSizeForSubpixel = other.m_minSizeForSubpixel; 257 m_useSubpixelPositioning = other.m_useSubpixelPositioning; 258 #endif 259 260 #if OS(MACOSX) 261 return platformDataAssign(other); 262 #else 263 return *this; 264 #endif 265 } 266 267 bool FontPlatformData::operator==(const FontPlatformData& a) const 268 { 269 // If either of the typeface pointers are null then we test for pointer 270 // equality. Otherwise, we call SkTypeface::Equal on the valid pointers. 271 bool typefacesEqual = false; 272 #if !OS(MACOSX) 273 if (!m_typeface || !a.m_typeface) 274 typefacesEqual = m_typeface == a.m_typeface; 275 else 276 typefacesEqual = SkTypeface::Equal(m_typeface.get(), a.m_typeface.get()); 277 #else 278 if (m_font || a.m_font) 279 typefacesEqual = m_font == a.m_font; 280 else 281 typefacesEqual = m_cgFont == a.m_cgFont; 282 #endif 283 284 return typefacesEqual 285 && m_textSize == a.m_textSize 286 && m_isHashTableDeletedValue == a.m_isHashTableDeletedValue 287 && m_syntheticBold == a.m_syntheticBold 288 && m_syntheticItalic == a.m_syntheticItalic 289 && m_orientation == a.m_orientation 290 #if !OS(MACOSX) 291 && m_style == a.m_style 292 #else 293 && m_isColorBitmapFont == a.m_isColorBitmapFont 294 && m_isCompositeFontReference == a.m_isCompositeFontReference 295 #endif 296 && m_widthVariant == a.m_widthVariant; 297 } 298 299 SkFontID FontPlatformData::uniqueID() const 300 { 301 return typeface()->uniqueID(); 302 } 303 304 String FontPlatformData::fontFamilyName() const 305 { 306 // FIXME(crbug.com/326582): come up with a proper way of handling SVG. 307 if (!this->typeface()) 308 return ""; 309 SkTypeface::LocalizedStrings* fontFamilyIterator = this->typeface()->createFamilyNameIterator(); 310 SkTypeface::LocalizedString localizedString; 311 while (fontFamilyIterator->next(&localizedString) && !localizedString.fString.size()) { } 312 fontFamilyIterator->unref(); 313 return String(localizedString.fString.c_str()); 314 } 315 316 bool FontPlatformData::isFixedPitch() const 317 { 318 return typeface() && typeface()->isFixedPitch(); 319 } 320 321 SkTypeface* FontPlatformData::typeface() const 322 { 323 #if OS(MACOSX) 324 if (!m_typeface) 325 m_typeface = adoptRef(SkCreateTypefaceFromCTFont(ctFont())); 326 #endif 327 return m_typeface.get(); 328 } 329 330 HarfBuzzFace* FontPlatformData::harfBuzzFace() const 331 { 332 #if OS(MACOSX) 333 CTFontRef font = ctFont(); 334 // Keeping the decision not to pass AAT font to HarfBuzz for now, 335 // until we switch to HarfBuzz as a shaper for all cases. 336 if (isAATFont(font)) 337 return 0; 338 #endif 339 if (!m_harfBuzzFace) 340 m_harfBuzzFace = HarfBuzzFace::create(const_cast<FontPlatformData*>(this), uniqueID()); 341 342 return m_harfBuzzFace.get(); 343 } 344 345 } // namespace blink 346