Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: Source/core/platform/mac/WebFontCache.mm

Issue 67433002: Move Mac related files to Source/platform (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Also export BlockExceptions Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/platform/mac/WebFontCache.h ('k') | Source/platform/blink_platform.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
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 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #import "config.h"
31 #import "core/platform/mac/WebFontCache.h"
32
33 #import <AppKit/AppKit.h>
34 #import <Foundation/Foundation.h>
35 #import <math.h>
36 #import "platform/fonts/FontTraitsMask.h"
37 #import <wtf/UnusedParam.h>
38
39 using namespace WebCore;
40
41
42 #define SYNTHESIZED_FONT_TRAITS (NSBoldFontMask | NSItalicFontMask)
43
44 #define IMPORTANT_FONT_TRAITS (0 \
45 | NSCompressedFontMask \
46 | NSCondensedFontMask \
47 | NSExpandedFontMask \
48 | NSItalicFontMask \
49 | NSNarrowFontMask \
50 | NSPosterFontMask \
51 | NSSmallCapsFontMask \
52 )
53
54 static BOOL acceptableChoice(NSFontTraitMask desiredTraits, NSFontTraitMask cand idateTraits)
55 {
56 desiredTraits &= ~SYNTHESIZED_FONT_TRAITS;
57 return (candidateTraits & desiredTraits) == desiredTraits;
58 }
59
60 static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight,
61 NSFontTraitMask chosenTraits, int chosenWeight,
62 NSFontTraitMask candidateTraits, int candidateWeight)
63 {
64 if (!acceptableChoice(desiredTraits, candidateTraits))
65 return NO;
66
67 // A list of the traits we care about.
68 // The top item in the list is the worst trait to mismatch; if a font has th is
69 // and we didn't ask for it, we'd prefer any other font in the family.
70 const NSFontTraitMask masks[] = {
71 NSPosterFontMask,
72 NSSmallCapsFontMask,
73 NSItalicFontMask,
74 NSCompressedFontMask,
75 NSCondensedFontMask,
76 NSExpandedFontMask,
77 NSNarrowFontMask,
78 0
79 };
80
81 int i = 0;
82 NSFontTraitMask mask;
83 while ((mask = masks[i++])) {
84 BOOL desired = (desiredTraits & mask) != 0;
85 BOOL chosenHasUnwantedTrait = desired != ((chosenTraits & mask) != 0);
86 BOOL candidateHasUnwantedTrait = desired != ((candidateTraits & mask) != 0);
87 if (!candidateHasUnwantedTrait && chosenHasUnwantedTrait)
88 return YES;
89 if (!chosenHasUnwantedTrait && candidateHasUnwantedTrait)
90 return NO;
91 }
92
93 int chosenWeightDeltaMagnitude = abs(chosenWeight - desiredWeight);
94 int candidateWeightDeltaMagnitude = abs(candidateWeight - desiredWeight);
95
96 // If both are the same distance from the desired weight, prefer the candida te if it is further from medium.
97 if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude)
98 return abs(candidateWeight - 6) > abs(chosenWeight - 6);
99
100 // Otherwise, prefer the one closer to the desired weight.
101 return candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude;
102 }
103
104 static inline FontTraitsMask toTraitsMask(NSFontTraitMask appKitTraits, NSIntege r appKitWeight)
105 {
106 return static_cast<FontTraitsMask>(((appKitTraits & NSFontItalicTrait) ? Fon tStyleItalicMask : FontStyleNormalMask)
107 | FontVariantNormalMask
108 | (appKitWeight == 1 ? FontWeight100Mask :
109 appKitWeight == 2 ? FontWeight200Mask :
110 appKitWeight <= 4 ? FontWeight300Mask :
111 appKitWeight == 5 ? FontWeight400Mask :
112 appKitWeight == 6 ? FontWeight500Mask :
113 appKitWeight <= 8 ? FontWeight600Mask :
114 appKitWeight == 9 ? FontWeight700Mask :
115 appKitWeight <= 11 ? FontWeight800Mask :
116 FontWeight900Mask));
117 }
118
119 @implementation WebFontCache
120
121 + (void)getTraits:(Vector<unsigned>&)traitsMasks inFamily:(NSString *)desiredFam ily
122 {
123 NSFontManager *fontManager = [NSFontManager sharedFontManager];
124
125 NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator];
126 NSString *availableFamily;
127 while ((availableFamily = [e nextObject])) {
128 if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedS ame)
129 break;
130 }
131
132 if (!availableFamily) {
133 // Match by PostScript name.
134 NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnume rator];
135 NSString *availableFont;
136 while ((availableFont = [availableFonts nextObject])) {
137 if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrdere dSame) {
138 NSFont *font = [NSFont fontWithName:availableFont size:10];
139 NSInteger weight = [fontManager weightOfFont:font];
140 traitsMasks.append(toTraitsMask([fontManager traitsOfFont:font], weight));
141 break;
142 }
143 }
144 return;
145 }
146
147 NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily];
148 unsigned n = [fonts count];
149 unsigned i;
150 for (i = 0; i < n; i++) {
151 NSArray *fontInfo = [fonts objectAtIndex:i];
152 // Array indices must be hard coded because of lame AppKit API.
153 NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue];
154
155 NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValu e];
156 traitsMasks.append(toTraitsMask(fontTraits, fontWeight));
157 }
158 }
159
160 // Family name is somewhat of a misnomer here. We first attempt to find an exac t match
161 // comparing the desiredFamily to the PostScript name of the installed fonts. I f that fails
162 // we then do a search based on the family names of the installed fonts.
163 + (NSFont *)internalFontWithFamily:(NSString *)desiredFamily traits:(NSFontTrait Mask)desiredTraits weight:(int)desiredWeight size:(float)size
164 {
165 NSFontManager *fontManager = [NSFontManager sharedFontManager];
166
167 // Do a simple case insensitive search for a matching font family.
168 // NSFontManager requires exact name matches.
169 // This addresses the problem of matching arial to Arial, etc., but perhaps not all the issues.
170 NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator];
171 NSString *availableFamily;
172 while ((availableFamily = [e nextObject])) {
173 if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedS ame)
174 break;
175 }
176
177 if (!availableFamily) {
178 // Match by PostScript name.
179 NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnume rator];
180 NSString *availableFont;
181 NSFont *nameMatchedFont = nil;
182 NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (desiredWeig ht >= 7 ? NSBoldFontMask : 0);
183 while ((availableFont = [availableFonts nextObject])) {
184 if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrdere dSame) {
185 nameMatchedFont = [NSFont fontWithName:availableFont size:size];
186
187 // Special case Osaka-Mono. According to <rdar://problem/399946 7>, we need to
188 // treat Osaka-Mono as fixed pitch.
189 if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOr deredSame && desiredTraitsForNameMatch == 0)
190 return nameMatchedFont;
191
192 NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFo nt];
193 if ((traits & desiredTraitsForNameMatch) == desiredTraitsForName Match)
194 return [fontManager convertFont:nameMatchedFont toHaveTrait: desiredTraitsForNameMatch];
195
196 availableFamily = [nameMatchedFont familyName];
197 break;
198 }
199 }
200 }
201
202 // Found a family, now figure out what weight and traits to use.
203 BOOL choseFont = false;
204 int chosenWeight = 0;
205 NSFontTraitMask chosenTraits = 0;
206 NSString *chosenFullName = 0;
207
208 NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily];
209 unsigned n = [fonts count];
210 unsigned i;
211 for (i = 0; i < n; i++) {
212 NSArray *fontInfo = [fonts objectAtIndex:i];
213
214 // Array indices must be hard coded because of lame AppKit API.
215 NSString *fontFullName = [fontInfo objectAtIndex:0];
216 NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue];
217
218 NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValu e];
219
220 BOOL newWinner;
221 if (!choseFont)
222 newWinner = acceptableChoice(desiredTraits, fontTraits);
223 else
224 newWinner = betterChoice(desiredTraits, desiredWeight, chosenTraits, chosenWeight, fontTraits, fontWeight);
225
226 if (newWinner) {
227 choseFont = YES;
228 chosenWeight = fontWeight;
229 chosenTraits = fontTraits;
230 chosenFullName = fontFullName;
231
232 if (chosenWeight == desiredWeight && (chosenTraits & IMPORTANT_FONT_ TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS))
233 break;
234 }
235 }
236
237 if (!choseFont)
238 return nil;
239
240 NSFont *font = [NSFont fontWithName:chosenFullName size:size];
241
242 if (!font)
243 return nil;
244
245 NSFontTraitMask actualTraits = 0;
246 if (desiredTraits & NSFontItalicTrait)
247 actualTraits = [fontManager traitsOfFont:font];
248 int actualWeight = [fontManager weightOfFont:font];
249
250 bool syntheticBold = desiredWeight >= 7 && actualWeight < 7;
251 bool syntheticOblique = (desiredTraits & NSFontItalicTrait) && !(actualTrait s & NSFontItalicTrait);
252
253 // There are some malformed fonts that will be correctly returned by -fontWi thFamily:traits:weight:size: as a match for a particular trait,
254 // though -[NSFontManager traitsOfFont:] incorrectly claims the font does no t have the specified trait. This could result in applying
255 // synthetic bold on top of an already-bold font, as reported in <http://bug s.webkit.org/show_bug.cgi?id=6146>. To work around this
256 // problem, if we got an apparent exact match, but the requested traits aren 't present in the matched font, we'll try to get a font from
257 // the same family without those traits (to apply the synthetic traits to la ter).
258 NSFontTraitMask nonSyntheticTraits = desiredTraits;
259
260 if (syntheticBold)
261 nonSyntheticTraits &= ~NSBoldFontMask;
262
263 if (syntheticOblique)
264 nonSyntheticTraits &= ~NSItalicFontMask;
265
266 if (nonSyntheticTraits != desiredTraits) {
267 NSFont *fontWithoutSyntheticTraits = [fontManager fontWithFamily:availab leFamily traits:nonSyntheticTraits weight:chosenWeight size:size];
268 if (fontWithoutSyntheticTraits)
269 font = fontWithoutSyntheticTraits;
270 }
271
272 return font;
273 }
274
275 + (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)des iredTraits weight:(int)desiredWeight size:(float)size
276 {
277 NSFont *font = [self internalFontWithFamily:desiredFamily traits:desiredTrai ts weight:desiredWeight size:size];
278 if (font)
279 return font;
280
281 // Auto activate the font before looking for it a second time.
282 // Ignore the result because we want to use our own algorithm to actually fi nd the font.
283 [NSFont fontWithName:desiredFamily size:size];
284
285 return [self internalFontWithFamily:desiredFamily traits:desiredTraits weigh t:desiredWeight size:size];
286 }
287
288 + (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)des iredTraits size:(float)size
289 {
290 int desiredWeight = (desiredTraits & NSBoldFontMask) ? 9 : 5;
291 return [self fontWithFamily:desiredFamily traits:desiredTraits weight:desire dWeight size:size];
292 }
293
294 @end
OLDNEW
« no previous file with comments | « Source/core/platform/mac/WebFontCache.h ('k') | Source/platform/blink_platform.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698