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" |
Robert Sesek
2015/03/19 21:53:45
Only #import things that are Objective-C. C++ head
Dominik Röttsches
2015/03/20 11:01:06
Changed to #include
| |
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); | |
Robert Sesek
2015/03/19 21:53:45
Copy methods return a strong reference.
https://d
Dominik Röttsches
2015/03/20 11:01:06
Wrapped in RetainPtr.
| |
42 // Toll-free bridged types CFStringRef and NSString*. | |
43 NSString* fontName = const_cast<NSString*>(reinterpret_cast<const NSString*> (CGFontCopyPostScriptName(cgFont))); | |
Robert Sesek
2015/03/19 21:53:45
Similarly, Copy returns a strong reference.
Robert Sesek
2015/03/19 21:53:45
Drop the const. No ObjC objects use const.
Dominik Röttsches
2015/03/20 11:01:06
Suggestions welcome, but I do not know any better
| |
44 return ![fontName isEqualToString:@"LastResort"]; | |
45 } | |
46 | |
47 static CTFontDescriptorRef cascadeToLastResortFontDescriptor() | |
48 { | |
49 static CTFontDescriptorRef descriptor; | |
50 if (descriptor) | |
51 return descriptor; | |
52 | |
53 const void* keys[] = { kCTFontCascadeListAttribute }; | |
Robert Sesek
2015/03/19 21:53:45
Move this down to above where you declare |values|
Dominik Röttsches
2015/03/20 11:01:06
Moved.
| |
54 RetainPtr<CTFontDescriptorRef> descriptorRef(AdoptCF, CTFontDescriptorCreate WithNameAndSize(CFSTR("LastResort"), 0) ); | |
Robert Sesek
2015/03/19 21:53:45
naming: lastResort ?
Dominik Röttsches
2015/03/20 11:01:07
Renamed to lastResort.
| |
55 const void* descriptors[] = { descriptorRef.get() }; | |
56 RetainPtr<CFArrayRef> valuesArray(AdoptCF, CFArrayCreate(kCFAllocatorDefault , descriptors, WTF_ARRAY_LENGTH(descriptors), &kCFTypeArrayCallBacks)); | |
57 const void* values[] = { valuesArray.get() }; | |
58 RetainPtr<CFDictionaryRef> attributes(AdoptCF, CFDictionaryCreate(kCFAllocat orDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); | |
Robert Sesek
2015/03/19 21:53:45
nit: Can you wrap this line?
Dominik Röttsches
2015/03/20 11:01:07
Wrapped this one and similar lines above.
| |
59 | |
60 descriptor = CTFontDescriptorCreateWithAttributes(attributes.get()); | |
61 | |
62 return descriptor; | |
63 } | |
64 | |
65 static PassRefPtr<SkTypeface> loadFromBrowserProcess(NSFont* nsFont, float textS ize) | |
66 { | |
67 CGFontRef cgFont; | |
68 uint32_t fontID; | |
69 // Send cross-process request to load font. | |
70 WebSandboxSupport* sandboxSupport = Platform::current()->sandboxSupport(); | |
71 if (!sandboxSupport) { | |
72 // This function should only be called in response to an error loading a | |
73 // font due to being blocked by the sandbox. | |
74 // This by definition shouldn't happen if there is no sandbox support. | |
75 ASSERT_NOT_REACHED(); | |
76 return nullptr; | |
77 } | |
78 if (!sandboxSupport->loadFont(nsFont, &cgFont, &fontID)) { | |
Robert Sesek
2015/03/19 21:53:45
According to the documentation of loadFont(), the
Dominik Röttsches
2015/03/20 11:01:07
Changed this to pass &loadedCGFont as argument, th
| |
79 // TODO crbug.com/461279: Make this appear in the inspector console? | |
80 WTF_LOG_ERROR("Loading user font \"%s\" from non system location failed. Corrupt or missing font file?", [[nsFont familyName] UTF8String]); | |
81 return nullptr; | |
82 } | |
83 | |
84 RetainPtr<CTFontRef> ctFont(AdoptCF, CTFontCreateWithGraphicsFont(cgFont, te xtSize, 0, cascadeToLastResortFontDescriptor())); | |
85 PassRefPtr<SkTypeface> returnFont = adoptRef(SkCreateTypefaceFromCTFont(ctFo nt.get())); | |
86 | |
87 if (!returnFont.get()) | |
88 // TODO crbug.com/461279: Make this appear in the inspector console? | |
89 WTF_LOG_ERROR("Instantiating SkTypeface from user font failed for font f amily \"%s\".", [[nsFont familyName] UTF8String]); | |
90 return returnFont; | |
91 } | |
92 | |
40 void FontPlatformData::setupPaint(SkPaint* paint, float, const Font* font) const | 93 void FontPlatformData::setupPaint(SkPaint* paint, float, const Font* font) const |
41 { | 94 { |
42 bool shouldSmoothFonts = true; | 95 bool shouldSmoothFonts = true; |
43 bool shouldAntialias = true; | 96 bool shouldAntialias = true; |
44 | 97 |
45 if (font) { | 98 if (font) { |
46 switch (font->fontDescription().fontSmoothing()) { | 99 switch (font->fontDescription().fontSmoothing()) { |
47 case Antialiased: | 100 case Antialiased: |
48 shouldSmoothFonts = false; | 101 shouldSmoothFonts = false; |
49 break; | 102 break; |
(...skipping 29 matching lines...) Expand all Loading... | |
79 // See crbug.com/152304 | 132 // See crbug.com/152304 |
80 if (font && (font->fontDescription().fontSmoothing() == Antialiased || font- >fontDescription().textRendering() == GeometricPrecision)) | 133 if (font && (font->fontDescription().fontSmoothing() == Antialiased || font- >fontDescription().textRendering() == GeometricPrecision)) |
81 paint->setHinting(SkPaint::kNo_Hinting); | 134 paint->setHinting(SkPaint::kNo_Hinting); |
82 } | 135 } |
83 | 136 |
84 FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol d, bool syntheticItalic, FontOrientation orientation) | 137 FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol d, bool syntheticItalic, FontOrientation orientation) |
85 : m_textSize(size) | 138 : m_textSize(size) |
86 , m_syntheticBold(syntheticBold) | 139 , m_syntheticBold(syntheticBold) |
87 , m_syntheticItalic(syntheticItalic) | 140 , m_syntheticItalic(syntheticItalic) |
88 , m_orientation(orientation) | 141 , m_orientation(orientation) |
89 , m_isColorBitmapFont(false) | |
90 , m_isCompositeFontReference(false) | |
91 , m_font(nsFont) | |
92 , m_isHashTableDeletedValue(false) | 142 , m_isHashTableDeletedValue(false) |
93 { | 143 { |
94 ASSERT_ARG(nsFont, nsFont); | 144 ASSERT_ARG(nsFont, nsFont); |
95 | 145 if (canLoadInProcess(nsFont)) { |
96 CGFontRef cgFont = 0; | 146 m_typeface = adoptRef(SkCreateTypefaceFromCTFont(toCTFontRef(nsFont))); |
97 loadFont(nsFont, size, m_font, cgFont); | 147 } else { |
98 | 148 // In process loading fails for cases where third party font manager sof tware |
99 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 | 149 // 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 | 150 // 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(). | 151 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 } | 152 } |
109 #endif | |
110 | |
111 if (m_font) | |
112 CFRetain(m_font); | |
113 | |
114 m_cgFont.adoptCF(cgFont); | |
115 } | 153 } |
116 | 154 |
117 void FontPlatformData::platformDataInit(const FontPlatformData& f) | 155 bool FontPlatformData::defaultUseSubpixelPositioning() |
118 { | 156 { |
119 m_font = f.m_font ? [f.m_font retain] : f.m_font; | 157 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 } | 158 } |
147 | 159 |
148 | 160 |
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 | 161 } // namespace blink |
OLD | NEW |