1/* 2 * This file is part of the internal font implementation. 3 * 4 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 5 * Copyright (c) 2010 Google Inc. All rights reserved. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 * 22 */ 23 24#import "config.h" 25#import "FontPlatformData.h" 26 27#import "PlatformString.h" 28#import "WebCoreSystemInterface.h" 29#import <AppKit/NSFont.h> 30 31namespace WebCore { 32 33// These CoreText Text Spacing feature selectors are not defined in CoreText. 34enum TextSpacingCTFeatureSelector { TextSpacingProportional, TextSpacingFullWidth, TextSpacingHalfWidth, TextSpacingThirdWidth, TextSpacingQuarterWidth }; 35 36#if PLATFORM(MAC) 37void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFontRef& cgFont) 38{ 39 outNSFont = nsFont; 40#ifndef BUILDING_ON_TIGER 41 cgFont = CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0); 42#else 43 cgFont = wkGetCGFontFromNSFont(nsFont); 44#endif 45} 46#endif // PLATFORM(MAC) 47 48FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, 49 TextOrientation textOrientation, FontWidthVariant widthVariant) 50 : m_syntheticBold(syntheticBold) 51 , m_syntheticOblique(syntheticOblique) 52 , m_orientation(orientation) 53 , m_textOrientation(textOrientation) 54 , m_size(size) 55 , m_widthVariant(widthVariant) 56 , m_font(nsFont) 57#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 58 // FIXME: Chromium: The following code isn't correct for the Chromium port since the sandbox might 59 // have blocked font loading, in which case we'll only have the real loaded font file after the call to loadFont(). 60 , m_isColorBitmapFont(CTFontGetSymbolicTraits(toCTFontRef(nsFont)) & kCTFontColorGlyphsTrait) 61#else 62 , m_isColorBitmapFont(false) 63#endif 64{ 65 ASSERT_ARG(nsFont, nsFont); 66 67 CGFontRef cgFont = 0; 68 loadFont(nsFont, size, m_font, cgFont); 69 70 if (m_font) 71 CFRetain(m_font); 72 73#ifndef BUILDING_ON_TIGER 74 m_cgFont.adoptCF(cgFont); 75#else 76 m_cgFont = cgFont; 77#endif 78} 79 80FontPlatformData:: ~FontPlatformData() 81{ 82 if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) 83 CFRelease(m_font); 84} 85 86void FontPlatformData::platformDataInit(const FontPlatformData& f) 87{ 88 m_font = f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1) ? const_cast<NSFont *>(static_cast<const NSFont *>(CFRetain(f.m_font))) : f.m_font; 89 90 m_cgFont = f.m_cgFont; 91 m_CTFont = f.m_CTFont; 92 93#if PLATFORM(CHROMIUM) && OS(DARWIN) 94 m_inMemoryFont = f.m_inMemoryFont; 95#endif 96} 97 98const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& f) 99{ 100 m_cgFont = f.m_cgFont; 101 if (m_font == f.m_font) 102 return *this; 103 if (f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1)) 104 CFRetain(f.m_font); 105 if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) 106 CFRelease(m_font); 107 m_font = f.m_font; 108 m_CTFont = f.m_CTFont; 109#if PLATFORM(CHROMIUM) && OS(DARWIN) 110 m_inMemoryFont = f.m_inMemoryFont; 111#endif 112 return *this; 113} 114 115bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const 116{ 117 return m_font == other.m_font 118 && m_cgFont == other.m_cgFont; 119} 120 121void FontPlatformData::setFont(NSFont *font) 122{ 123 ASSERT_ARG(font, font); 124 ASSERT(m_font != reinterpret_cast<NSFont *>(-1)); 125 126 if (m_font == font) 127 return; 128 129 CFRetain(font); 130 if (m_font) 131 CFRelease(m_font); 132 m_font = font; 133 m_size = [font pointSize]; 134 135 CGFontRef cgFont = 0; 136 NSFont* loadedFont = 0; 137 loadFont(m_font, m_size, loadedFont, cgFont); 138 139#if PLATFORM(CHROMIUM) && OS(DARWIN) 140 // If loadFont replaced m_font with a fallback font, then release the 141 // previous font to counter the retain above. Then retain the new font. 142 if (loadedFont != m_font) { 143 CFRelease(m_font); 144 CFRetain(loadedFont); 145 m_font = loadedFont; 146 } 147#endif 148 149#ifndef BUILDING_ON_TIGER 150 m_cgFont.adoptCF(cgFont); 151#else 152 m_cgFont = cgFont; 153#endif 154#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 155 m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(m_font)) & kCTFontColorGlyphsTrait; 156#endif 157 m_CTFont = 0; 158} 159 160bool FontPlatformData::roundsGlyphAdvances() const 161{ 162 return [m_font renderingMode] == NSFontAntialiasedIntegerAdvancementsRenderingMode; 163} 164 165bool FontPlatformData::allowsLigatures() const 166{ 167 return ![[m_font coveredCharacterSet] characterIsMember:'a']; 168} 169 170inline int mapFontWidthVariantToCTFeatureSelector(FontWidthVariant variant) 171{ 172 switch(variant) { 173 case RegularWidth: 174 return TextSpacingProportional; 175 176 case HalfWidth: 177 return TextSpacingHalfWidth; 178 179 case ThirdWidth: 180 return TextSpacingThirdWidth; 181 182 case QuarterWidth: 183 return TextSpacingQuarterWidth; 184 } 185 186 ASSERT_NOT_REACHED(); 187 return TextSpacingProportional; 188} 189 190CTFontRef FontPlatformData::ctFont() const 191{ 192 if (m_widthVariant == RegularWidth) { 193 if (m_font) 194 return toCTFontRef(m_font); 195 if (!m_CTFont) 196 m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0)); 197 return m_CTFont.get(); 198 } 199 200 if (!m_CTFont) { 201 int featureTypeValue = kTextSpacingType; 202 int featureSelectorValue = mapFontWidthVariantToCTFeatureSelector(m_widthVariant); 203 RetainPtr<CTFontRef> sourceFont(AdoptCF, CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0)); 204 RetainPtr<CTFontDescriptorRef> sourceDescriptor(AdoptCF, CTFontCopyFontDescriptor(sourceFont.get())); 205 RetainPtr<CFNumberRef> featureType(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureTypeValue)); 206 RetainPtr<CFNumberRef> featureSelector(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureSelectorValue)); 207 RetainPtr<CTFontDescriptorRef> newDescriptor(AdoptCF, CTFontDescriptorCreateCopyWithFeature(sourceDescriptor.get(), featureType.get(), featureSelector.get())); 208 RetainPtr<CTFontRef> newFont(AdoptCF, CTFontCreateWithFontDescriptor(newDescriptor.get(), m_size, 0)); 209 210 m_CTFont = newFont.get() ? newFont : sourceFont; 211 } 212 return m_CTFont.get(); 213} 214 215#ifndef NDEBUG 216String FontPlatformData::description() const 217{ 218 RetainPtr<CFStringRef> cgFontDescription(AdoptCF, CFCopyDescription(cgFont())); 219 return String(cgFontDescription.get()) + " " + String::number(m_size) 220 + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : "") + (m_orientation ? " vertical orientation" : ""); 221} 222#endif 223 224} // namespace WebCore 225