Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * This file is part of the internal font implementation. | 2 * This file is part of the internal font implementation. |
| 3 * | 3 * |
| 4 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 4 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 5 * Copyright (c) 2010 Google Inc. All rights reserved. | 5 * Copyright (c) 2010 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 * | 21 * |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #import "config.h" | 24 #import "config.h" |
| 25 #import "platform/fonts/FontPlatformData.h" | 25 #import "platform/fonts/FontPlatformData.h" |
| 26 | 26 |
| 27 #import <AppKit/NSFont.h> | 27 #import <AppKit/NSFont.h> |
| 28 #import <AvailabilityMacros.h> | 28 #import <AvailabilityMacros.h> |
| 29 #import <wtf/text/WTFString.h> | 29 #import <wtf/text/WTFString.h> |
| 30 | 30 |
| 31 #include "platform/LayoutTestSupport.h" | 31 #import "platform/LayoutTestSupport.h" |
| 32 #include "platform/fonts/Font.h" | 32 #import "platform/fonts/Font.h" |
| 33 #import "platform/fonts/shaping/HarfBuzzFace.h" | 33 #import "platform/fonts/shaping/HarfBuzzFace.h" |
| 34 #include "third_party/skia/include/ports/SkTypeface_mac.h" | 34 #import "public/platform/Platform.h" |
| 35 | 35 #import "public/platform/mac/WebSandboxSupport.h" |
| 36 | 36 #import "third_party/skia/include/ports/SkTypeface_mac.h" |
| 37 | 37 |
| 38 namespace blink { | 38 namespace blink { |
| 39 | 39 |
| 40 static bool canLoadInProcess(NSFont* nsFont) { | |
| 41 CGFontRef cgFont = CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0); | |
| 42 NSString* fontName = (NSString*)CGFontCopyPostScriptName(cgFont); | |
|
Robert Sesek
2015/02/24 16:13:07
Use reinterpret_cast<> again like in the other CF-
Dominik Röttsches
2015/03/19 15:20:00
Done.
| |
| 43 return ![fontName isEqualToString:@"LastResort"]; | |
| 44 } | |
| 45 | |
| 46 static CTFontDescriptorRef cascadeToLastResortFontDescriptor() | |
| 47 { | |
| 48 static CTFontDescriptorRef descriptor; | |
| 49 if (descriptor) | |
| 50 return descriptor; | |
| 51 | |
| 52 const void* keys[] = { kCTFontCascadeListAttribute }; | |
| 53 const void* descriptors[] = { CTFontDescriptorCreateWithNameAndSize(CFSTR("L astResort"), 0) }; | |
|
Robert Sesek
2015/02/24 16:13:07
Functions that follow the Create naming scheme ret
Dominik Röttsches
2015/03/19 15:20:00
Tried to fixed this case by using RetainPtr wrappe
| |
| 54 const void* values[] = { CFArrayCreate(kCFAllocatorDefault, descriptors, WTF _ARRAY_LENGTH(descriptors), &kCFTypeArrayCallBacks) }; | |
| 55 RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocat orDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); | |
|
Robert Sesek
2015/02/24 16:13:07
Similarly, the array in |values| will be leaked be
Dominik Röttsches
2015/03/19 15:20:00
Hopefully fixed by using a RetainPtr here as well.
| |
| 56 | |
| 57 descriptor = CTFontDescriptorCreateWithAttributes(attributes.get()); | |
| 58 | |
| 59 return descriptor; | |
| 60 } | |
| 61 | |
| 62 static PassRefPtr<SkTypeface> loadFromBrowserProcess(NSFont* nsFont, float textS ize) | |
| 63 { | |
| 64 CGFontRef cgFont; | |
| 65 uint32_t fontID; | |
| 66 // Send cross-process request to load font. | |
| 67 WebSandboxSupport* sandboxSupport = Platform::current()->sandboxSupport(); | |
| 68 if (!sandboxSupport) { | |
| 69 // This function should only be called in response to an error loading a | |
| 70 // font due to being blocked by the sandbox. | |
| 71 // This by definition shouldn't happen if there is no sandbox support. | |
| 72 ASSERT_NOT_REACHED(); | |
| 73 return nullptr; | |
| 74 } | |
| 75 if (!sandboxSupport->loadFont(nsFont, &cgFont, &fontID)) { | |
| 76 // TODO crbug.com/461279: Make this appear in the inspector console? | |
| 77 WTF_LOG_ERROR("Loading user font \"%s\" from non system location failed. Corrupt or missing font file?", [[nsFont familyName] UTF8String]); | |
| 78 return nullptr; | |
| 79 } | |
| 80 | |
| 81 CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, textSize, 0, cascade ToLastResortFontDescriptor()); | |
|
Robert Sesek
2015/02/24 16:13:07
Create is strong ref. Unless SkCreateTypefaceFromC
Dominik Röttsches
2015/03/19 15:20:00
Yes, Skia does not adopt the reference. [1] Wrappe
| |
| 82 PassRefPtr<SkTypeface> returnFont = adoptRef(SkCreateTypefaceFromCTFont(ctFo nt)); | |
| 83 | |
| 84 if (!returnFont.get()) | |
| 85 // TODO crbug.com/461279: Make this appear in the inspector console? | |
| 86 WTF_LOG_ERROR("Instantiating SkTypeface from user font failed for font f amily \"%s\".", [[nsFont familyName] UTF8String]); | |
| 87 return returnFont; | |
| 88 } | |
| 89 | |
| 40 void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext*, const Font* font) const | 90 void FontPlatformData::setupPaint(SkPaint* paint, GraphicsContext*, const Font* font) const |
| 41 { | 91 { |
| 42 bool shouldSmoothFonts = true; | 92 bool shouldSmoothFonts = true; |
| 43 bool shouldAntialias = true; | 93 bool shouldAntialias = true; |
| 44 | 94 |
| 45 if (font) { | 95 if (font) { |
| 46 switch (font->fontDescription().fontSmoothing()) { | 96 switch (font->fontDescription().fontSmoothing()) { |
| 47 case Antialiased: | 97 case Antialiased: |
| 48 shouldSmoothFonts = false; | 98 shouldSmoothFonts = false; |
| 49 break; | 99 break; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 79 // See crbug.com/152304 | 129 // See crbug.com/152304 |
| 80 if (font && (font->fontDescription().fontSmoothing() == Antialiased || font- >fontDescription().textRendering() == GeometricPrecision)) | 130 if (font && (font->fontDescription().fontSmoothing() == Antialiased || font- >fontDescription().textRendering() == GeometricPrecision)) |
| 81 paint->setHinting(SkPaint::kNo_Hinting); | 131 paint->setHinting(SkPaint::kNo_Hinting); |
| 82 } | 132 } |
| 83 | 133 |
| 84 FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol d, bool syntheticItalic, FontOrientation orientation) | 134 FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol d, bool syntheticItalic, FontOrientation orientation) |
| 85 : m_textSize(size) | 135 : m_textSize(size) |
| 86 , m_syntheticBold(syntheticBold) | 136 , m_syntheticBold(syntheticBold) |
| 87 , m_syntheticItalic(syntheticItalic) | 137 , m_syntheticItalic(syntheticItalic) |
| 88 , m_orientation(orientation) | 138 , m_orientation(orientation) |
| 89 , m_isColorBitmapFont(false) | |
| 90 , m_isCompositeFontReference(false) | |
| 91 , m_font(nsFont) | |
| 92 , m_isHashTableDeletedValue(false) | 139 , m_isHashTableDeletedValue(false) |
| 93 { | 140 { |
| 94 ASSERT_ARG(nsFont, nsFont); | 141 ASSERT_ARG(nsFont, nsFont); |
| 95 | 142 if (canLoadInProcess(nsFont)) { |
| 96 CGFontRef cgFont = 0; | 143 m_typeface = adoptRef(SkCreateTypefaceFromCTFont(toCTFontRef(nsFont))); |
| 97 loadFont(nsFont, size, m_font, cgFont); | 144 } else { |
| 98 | 145 // In process loading fails for cases where third party font manager sof tware |
| 99 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 | 146 // registers fonts in non system locations such as /Library/Fonts |
| 100 // FIXME: Chromium: The following code isn't correct for the Chromium port s ince the sandbox might | 147 // and ~/Library Fonts, see crbug.com/72727 or crbug.com/108645. |
| 101 // have blocked font loading, in which case we'll only have the real loaded font file after the call to loadFont(). | 148 m_typeface = loadFromBrowserProcess(nsFont, size); |
| 102 { | |
| 103 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(toCTFontRef(m_font )); | |
| 104 m_isColorBitmapFont = traits & kCTFontColorGlyphsTrait; | |
| 105 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 | |
| 106 m_isCompositeFontReference = traits & kCTFontCompositeTrait; | |
| 107 #endif | |
| 108 } | 149 } |
| 109 #endif | |
| 110 | |
| 111 if (m_font) | |
| 112 CFRetain(m_font); | |
| 113 | |
| 114 m_cgFont.adoptCF(cgFont); | |
| 115 } | 150 } |
| 116 | 151 |
| 117 void FontPlatformData::platformDataInit(const FontPlatformData& f) | 152 bool FontPlatformData::defaultUseSubpixelPositioning() |
| 118 { | 153 { |
| 119 m_font = f.m_font ? [f.m_font retain] : f.m_font; | 154 return FontDescription::subpixelPositioning(); |
| 120 | |
| 121 m_cgFont = f.m_cgFont; | |
| 122 m_CTFont = f.m_CTFont; | |
| 123 | |
| 124 m_inMemoryFont = f.m_inMemoryFont; | |
| 125 m_harfBuzzFace = f.m_harfBuzzFace; | |
| 126 m_typeface = f.m_typeface; | |
| 127 } | |
| 128 | |
| 129 const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformD ata& f) | |
| 130 { | |
| 131 m_cgFont = f.m_cgFont; | |
| 132 if (m_font == f.m_font) | |
| 133 return *this; | |
| 134 if (f.m_font) | |
| 135 CFRetain(f.m_font); | |
| 136 if (m_font) | |
| 137 CFRelease(m_font); | |
| 138 m_font = f.m_font; | |
| 139 m_CTFont = f.m_CTFont; | |
| 140 | |
| 141 m_inMemoryFont = f.m_inMemoryFont; | |
| 142 m_harfBuzzFace = f.m_harfBuzzFace; | |
| 143 m_typeface = f.m_typeface; | |
| 144 | |
| 145 return *this; | |
| 146 } | 155 } |
| 147 | 156 |
| 148 | 157 |
| 149 void FontPlatformData::setFont(NSFont *font) | |
| 150 { | |
| 151 ASSERT_ARG(font, font); | |
| 152 | |
| 153 if (m_font == font) | |
| 154 return; | |
| 155 | |
| 156 CFRetain(font); | |
| 157 if (m_font) | |
| 158 CFRelease(m_font); | |
| 159 m_font = font; | |
| 160 m_textSize = [font pointSize]; | |
| 161 | |
| 162 CGFontRef cgFont = 0; | |
| 163 NSFont* loadedFont = 0; | |
| 164 loadFont(m_font, m_textSize, loadedFont, cgFont); | |
| 165 | |
| 166 // If loadFont replaced m_font with a fallback font, then release the | |
| 167 // previous font to counter the retain above. Then retain the new font. | |
| 168 if (loadedFont != m_font) { | |
| 169 CFRelease(m_font); | |
| 170 CFRetain(loadedFont); | |
| 171 m_font = loadedFont; | |
| 172 } | |
| 173 | |
| 174 m_cgFont.adoptCF(cgFont); | |
| 175 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 | |
| 176 { | |
| 177 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(toCTFontRef(m_font )); | |
| 178 m_isColorBitmapFont = traits & kCTFontColorGlyphsTrait; | |
| 179 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 | |
| 180 m_isCompositeFontReference = traits & kCTFontCompositeTrait; | |
| 181 #endif | |
| 182 } | |
| 183 #endif | |
| 184 m_CTFont = nullptr; | |
| 185 } | |
| 186 | |
| 187 bool FontPlatformData::roundsGlyphAdvances() const | |
| 188 { | |
| 189 return [m_font renderingMode] == NSFontAntialiasedIntegerAdvancementsRenderi ngMode; | |
| 190 } | |
| 191 | |
| 192 bool FontPlatformData::allowsLigatures() const | |
| 193 { | |
| 194 return ![[m_font coveredCharacterSet] characterIsMember:'a']; | |
| 195 } | |
| 196 | |
| 197 static CFDictionaryRef createFeatureSettingDictionary(int featureTypeIdentifier, int featureSelectorIdentifier) | |
| 198 { | |
| 199 RetainPtr<CFNumberRef> featureTypeIdentifierNumber(AdoptCF, CFNumberCreate(k CFAllocatorDefault, kCFNumberIntType, &featureTypeIdentifier)); | |
| 200 RetainPtr<CFNumberRef> featureSelectorIdentifierNumber(AdoptCF, CFNumberCrea te(kCFAllocatorDefault, kCFNumberIntType, &featureSelectorIdentifier)); | |
| 201 | |
| 202 const void* settingKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatur eSelectorIdentifierKey }; | |
| 203 const void* settingValues[] = { featureTypeIdentifierNumber.get(), featureSe lectorIdentifierNumber.get() }; | |
| 204 | |
| 205 return CFDictionaryCreate(kCFAllocatorDefault, settingKeys, settingValues, W TF_ARRAY_LENGTH(settingKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionary ValueCallBacks); | |
| 206 } | |
| 207 | |
| 208 static CTFontDescriptorRef cascadeToLastResortFontDescriptor() | |
| 209 { | |
| 210 static CTFontDescriptorRef descriptor; | |
| 211 if (descriptor) | |
| 212 return descriptor; | |
| 213 | |
| 214 const void* keys[] = { kCTFontCascadeListAttribute }; | |
| 215 const void* descriptors[] = { CTFontDescriptorCreateWithNameAndSize(CFSTR("L astResort"), 0) }; | |
| 216 const void* values[] = { CFArrayCreate(kCFAllocatorDefault, descriptors, WTF _ARRAY_LENGTH(descriptors), &kCFTypeArrayCallBacks) }; | |
| 217 RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocat orDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); | |
| 218 | |
| 219 descriptor = CTFontDescriptorCreateWithAttributes(attributes.get()); | |
| 220 | |
| 221 return descriptor; | |
| 222 } | |
| 223 | |
| 224 static CTFontDescriptorRef cascadeToLastResortAndDisableSwashesFontDescriptor() | |
| 225 { | |
| 226 static CTFontDescriptorRef descriptor; | |
| 227 if (descriptor) | |
| 228 return descriptor; | |
| 229 | |
| 230 RetainPtr<CFDictionaryRef> lineInitialSwashesOffSetting(AdoptCF, createFeatu reSettingDictionary(kSmartSwashType, kLineInitialSwashesOffSelector)); | |
| 231 RetainPtr<CFDictionaryRef> lineFinalSwashesOffSetting(AdoptCF, createFeature SettingDictionary(kSmartSwashType, kLineFinalSwashesOffSelector)); | |
| 232 | |
| 233 const void* settingDictionaries[] = { lineInitialSwashesOffSetting.get(), li neFinalSwashesOffSetting.get() }; | |
| 234 RetainPtr<CFArrayRef> featureSettings(AdoptCF, CFArrayCreate(kCFAllocatorDef ault, settingDictionaries, WTF_ARRAY_LENGTH(settingDictionaries), &kCFTypeArrayC allBacks)); | |
| 235 | |
| 236 const void* keys[] = { kCTFontFeatureSettingsAttribute }; | |
| 237 const void* values[] = { featureSettings.get() }; | |
| 238 RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocat orDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); | |
| 239 | |
| 240 descriptor = CTFontDescriptorCreateCopyWithAttributes(cascadeToLastResortFon tDescriptor(), attributes.get()); | |
| 241 | |
| 242 return descriptor; | |
| 243 } | |
| 244 | |
| 245 CTFontRef FontPlatformData::ctFont() const | |
| 246 { | |
| 247 if (m_CTFont) | |
| 248 return m_CTFont.get(); | |
| 249 | |
| 250 if (m_inMemoryFont) { | |
| 251 m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_inMemoryFont->cgFont(), m_textSize, 0, cascadeToLastResortFontDescriptor())); | |
| 252 return m_CTFont.get(); | |
| 253 } | |
| 254 | |
| 255 m_CTFont = toCTFontRef(m_font); | |
| 256 if (m_CTFont) { | |
| 257 CTFontDescriptorRef fontDescriptor; | |
| 258 RetainPtr<CFStringRef> postScriptName(AdoptCF, CTFontCopyPostScriptName( m_CTFont.get())); | |
| 259 // Hoefler Text Italic has line-initial and -final swashes enabled by de fault, so disable them. | |
| 260 if (CFEqual(postScriptName.get(), CFSTR("HoeflerText-Italic")) || CFEqua l(postScriptName.get(), CFSTR("HoeflerText-BlackItalic"))) | |
| 261 fontDescriptor = cascadeToLastResortAndDisableSwashesFontDescriptor( ); | |
| 262 else | |
| 263 fontDescriptor = cascadeToLastResortFontDescriptor(); | |
| 264 m_CTFont.adoptCF(CTFontCreateCopyWithAttributes(m_CTFont.get(), m_textSi ze, 0, fontDescriptor)); | |
| 265 } else | |
| 266 m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_textSize , 0, cascadeToLastResortFontDescriptor())); | |
| 267 | |
| 268 return m_CTFont.get(); | |
| 269 } | |
| 270 | |
| 271 } // namespace blink | 158 } // namespace blink |
| OLD | NEW |