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

Side by Side Diff: Source/platform/fonts/mac/FontFamilyMatcherMac.mm

Issue 1292593003: Revert "Revert "Reland 2: mac: Use a placeholder string for the family name of the system font." Br… (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 4 months 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> 3 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 18 matching lines...) Expand all
29 29
30 #import "config.h" 30 #import "config.h"
31 #import "platform/fonts/mac/FontFamilyMatcherMac.h" 31 #import "platform/fonts/mac/FontFamilyMatcherMac.h"
32 32
33 #import <AppKit/AppKit.h> 33 #import <AppKit/AppKit.h>
34 #import <Foundation/Foundation.h> 34 #import <Foundation/Foundation.h>
35 #import <math.h> 35 #import <math.h>
36 #import <wtf/HashSet.h> 36 #import <wtf/HashSet.h>
37 #import <wtf/text/AtomicStringHash.h> 37 #import <wtf/text/AtomicStringHash.h>
38 38
39 #include "platform/fonts/FontTraits.h"
40 #include "platform/LayoutTestSupport.h"
41 #include "platform/mac/VersionUtilMac.h"
42
43 @interface NSFont (YosemiteAdditions)
44 + (NSFont*)systemFontOfSize:(CGFloat)size weight:(CGFloat)weight;
45 @end
46
47 namespace {
48
49 static CGFloat toYosemiteFontWeight(blink::FontWeight fontWeight)
50 {
51 static uint64_t nsFontWeights[] = {
52 0xbfe99999a0000000, // NSFontWeightUltraLight
53 0xbfe3333340000000, // NSFontWeightThin
54 0xbfd99999a0000000, // NSFontWeightLight
55 0x0000000000000000, // NSFontWeightRegular
56 0x3fcd70a3e0000000, // NSFontWeightMedium
57 0x3fd3333340000000, // NSFontWeightSemibold
58 0x3fd99999a0000000, // NSFontWeightBold
59 0x3fe1eb8520000000, // NSFontWeightHeavy
60 0x3fe3d70a40000000, // NSFontWeightBlack
61 };
62 ASSERT(fontWeight >= 0 && fontWeight <= 8);
63 CGFloat* weight = reinterpret_cast<CGFloat*>(&nsFontWeights[fontWeight]);
64 return *weight;
65 }
66 }
67
39 namespace blink { 68 namespace blink {
40 69
41 const NSFontTraitMask SYNTHESIZED_FONT_TRAITS = (NSBoldFontMask | NSItalicFontMa sk); 70 const NSFontTraitMask SYNTHESIZED_FONT_TRAITS = (NSBoldFontMask | NSItalicFontMa sk);
42 71
43 const NSFontTraitMask IMPORTANT_FONT_TRAITS = (NSCompressedFontMask 72 const NSFontTraitMask IMPORTANT_FONT_TRAITS = (NSCompressedFontMask
44 | NSCondensedFontMask 73 | NSCondensedFontMask
45 | NSExpandedFontMask 74 | NSExpandedFontMask
46 | NSItalicFontMask 75 | NSItalicFontMask
47 | NSNarrowFontMask 76 | NSNarrowFontMask
48 | NSPosterFontMask 77 | NSPosterFontMask
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude) 123 if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude)
95 return abs(candidateWeight - 6) > abs(chosenWeight - 6); 124 return abs(candidateWeight - 6) > abs(chosenWeight - 6);
96 125
97 // Otherwise, prefer the one closer to the desired weight. 126 // Otherwise, prefer the one closer to the desired weight.
98 return candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude; 127 return candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude;
99 } 128 }
100 129
101 // Family name is somewhat of a misnomer here. We first attempt to find an exac t match 130 // Family name is somewhat of a misnomer here. We first attempt to find an exac t match
102 // comparing the desiredFamily to the PostScript name of the installed fonts. I f that fails 131 // comparing the desiredFamily to the PostScript name of the installed fonts. I f that fails
103 // we then do a search based on the family names of the installed fonts. 132 // we then do a search based on the family names of the installed fonts.
104 NSFont* MatchNSFontFamily(NSString* desiredFamily, NSFontTraitMask desiredTraits , int desiredWeight, float size) 133 NSFont* MatchNSFontFamily(NSString* desiredFamily, NSFontTraitMask desiredTraits , FontWeight desiredWeight, float size)
105 { 134 {
135 if ([desiredFamily isEqualToString:@"BlinkMacSystemFont"]) {
136 // On OSX 10.9, the default system font depends on the SDK version. When
137 // compiled against the OSX 10.10 SDK, the font is .LucidaGrandeUI. When
138 // compiled against the OSX 10.6 SDK, the font is Lucida Grande. Layout
139 // tests don't support different expectations based on the SDK version,
140 // so force layout tests to use "Lucida Grande". Once the 10.10 SDK
141 // switch is made, this should be changed to return .LucidaGrandeUI and
142 // the Layout Expectations should be updated. http://crbug.com/515836.
143 if (LayoutTestSupport::isRunningLayoutTest() && IsOSMavericks()) {
144 if (desiredWeight >= blink::FontWeightBold)
145 return [NSFont fontWithName:@"Lucida Grande Bold" size:size];
146 else
147 return [NSFont fontWithName:@"Lucida Grande" size:size];
148 }
149
150 NSFont* font = nil;
151 if (IsOSMavericksOrEarlier()) {
152 // On older OSX versions, only bold and regular are available.
153 if (desiredWeight >= blink::FontWeightBold)
154 font = [NSFont boldSystemFontOfSize:size];
155 else
156 font = [NSFont systemFontOfSize:size];
157 }
158 else {
159 // On OSX 10.10+, the default system font has more weights.
160 font = [NSFont systemFontOfSize:size weight:toYosemiteFontWeight(des iredWeight)];
161 }
162
163 if (desiredTraits & IMPORTANT_FONT_TRAITS)
164 font = [[NSFontManager sharedFontManager] convertFont:font toHaveTra it:desiredTraits];
165 return font;
166 }
167
106 NSFontManager *fontManager = [NSFontManager sharedFontManager]; 168 NSFontManager *fontManager = [NSFontManager sharedFontManager];
107 169
108 // Do a simple case insensitive search for a matching font family. 170 // Do a simple case insensitive search for a matching font family.
109 // NSFontManager requires exact name matches. 171 // NSFontManager requires exact name matches.
110 // This addresses the problem of matching arial to Arial, etc., but perhaps not all the issues. 172 // This addresses the problem of matching arial to Arial, etc., but perhaps not all the issues.
111 NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator]; 173 NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator];
112 NSString *availableFamily; 174 NSString *availableFamily;
113 while ((availableFamily = [e nextObject])) { 175 while ((availableFamily = [e nextObject])) {
114 if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedS ame) 176 if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedS ame)
115 break; 177 break;
116 } 178 }
117 179
180 int appKitFontWeight = toAppKitFontWeight(desiredWeight);
118 if (!availableFamily) { 181 if (!availableFamily) {
119 // Match by PostScript name. 182 // Match by PostScript name.
120 NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnume rator]; 183 NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnume rator];
121 NSString *availableFont; 184 NSString *availableFont;
122 NSFont *nameMatchedFont = nil; 185 NSFont *nameMatchedFont = nil;
123 NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (desiredWeig ht >= 7 ? NSBoldFontMask : 0); 186 NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (appKitFontW eight >= 7 ? NSBoldFontMask : 0);
124 while ((availableFont = [availableFonts nextObject])) { 187 while ((availableFont = [availableFonts nextObject])) {
125 if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrdere dSame) { 188 if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrdere dSame) {
126 nameMatchedFont = [NSFont fontWithName:availableFont size:size]; 189 nameMatchedFont = [NSFont fontWithName:availableFont size:size];
127 190
128 // Special case Osaka-Mono. According to <rdar://problem/399946 7>, we need to 191 // Special case Osaka-Mono. According to <rdar://problem/399946 7>, we need to
129 // treat Osaka-Mono as fixed pitch. 192 // treat Osaka-Mono as fixed pitch.
130 if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOr deredSame && desiredTraitsForNameMatch == 0) 193 if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOr deredSame && desiredTraitsForNameMatch == 0)
131 return nameMatchedFont; 194 return nameMatchedFont;
132 195
133 NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFo nt]; 196 NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFo nt];
(...skipping 21 matching lines...) Expand all
155 // Array indices must be hard coded because of lame AppKit API. 218 // Array indices must be hard coded because of lame AppKit API.
156 NSString *fontFullName = [fontInfo objectAtIndex:0]; 219 NSString *fontFullName = [fontInfo objectAtIndex:0];
157 NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue]; 220 NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue];
158 221
159 NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValu e]; 222 NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValu e];
160 223
161 BOOL newWinner; 224 BOOL newWinner;
162 if (!choseFont) 225 if (!choseFont)
163 newWinner = acceptableChoice(desiredTraits, fontTraits); 226 newWinner = acceptableChoice(desiredTraits, fontTraits);
164 else 227 else
165 newWinner = betterChoice(desiredTraits, desiredWeight, chosenTraits, chosenWeight, fontTraits, fontWeight); 228 newWinner = betterChoice(desiredTraits, appKitFontWeight, chosenTrai ts, chosenWeight, fontTraits, fontWeight);
166 229
167 if (newWinner) { 230 if (newWinner) {
168 choseFont = YES; 231 choseFont = YES;
169 chosenWeight = fontWeight; 232 chosenWeight = fontWeight;
170 chosenTraits = fontTraits; 233 chosenTraits = fontTraits;
171 chosenFullName = fontFullName; 234 chosenFullName = fontFullName;
172 235
173 if (chosenWeight == desiredWeight && (chosenTraits & IMPORTANT_FONT_ TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS)) 236 if (chosenWeight == appKitFontWeight && (chosenTraits & IMPORTANT_FO NT_TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS))
174 break; 237 break;
175 } 238 }
176 } 239 }
177 240
178 if (!choseFont) 241 if (!choseFont)
179 return nil; 242 return nil;
180 243
181 NSFont *font = [NSFont fontWithName:chosenFullName size:size]; 244 NSFont *font = [NSFont fontWithName:chosenFullName size:size];
182 245
183 if (!font) 246 if (!font)
184 return nil; 247 return nil;
185 248
186 NSFontTraitMask actualTraits = 0; 249 NSFontTraitMask actualTraits = 0;
187 if (desiredTraits & NSFontItalicTrait) 250 if (desiredTraits & NSFontItalicTrait)
188 actualTraits = [fontManager traitsOfFont:font]; 251 actualTraits = [fontManager traitsOfFont:font];
189 int actualWeight = [fontManager weightOfFont:font]; 252 int actualWeight = [fontManager weightOfFont:font];
190 253
191 bool syntheticBold = desiredWeight >= 7 && actualWeight < 7; 254 bool syntheticBold = appKitFontWeight >= 7 && actualWeight < 7;
192 bool syntheticItalic = (desiredTraits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait); 255 bool syntheticItalic = (desiredTraits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
193 256
194 // There are some malformed fonts that will be correctly returned by -fontWi thFamily:traits:weight:size: as a match for a particular trait, 257 // There are some malformed fonts that will be correctly returned by -fontWi thFamily:traits:weight:size: as a match for a particular trait,
195 // though -[NSFontManager traitsOfFont:] incorrectly claims the font does no t have the specified trait. This could result in applying 258 // though -[NSFontManager traitsOfFont:] incorrectly claims the font does no t have the specified trait. This could result in applying
196 // 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 259 // 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
197 // 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 260 // 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
198 // the same family without those traits (to apply the synthetic traits to la ter). 261 // the same family without those traits (to apply the synthetic traits to la ter).
199 NSFontTraitMask nonSyntheticTraits = desiredTraits; 262 NSFontTraitMask nonSyntheticTraits = desiredTraits;
200 263
201 if (syntheticBold) 264 if (syntheticBold)
202 nonSyntheticTraits &= ~NSBoldFontMask; 265 nonSyntheticTraits &= ~NSBoldFontMask;
203 266
204 if (syntheticItalic) 267 if (syntheticItalic)
205 nonSyntheticTraits &= ~NSItalicFontMask; 268 nonSyntheticTraits &= ~NSItalicFontMask;
206 269
207 if (nonSyntheticTraits != desiredTraits) { 270 if (nonSyntheticTraits != desiredTraits) {
208 NSFont *fontWithoutSyntheticTraits = [fontManager fontWithFamily:availab leFamily traits:nonSyntheticTraits weight:chosenWeight size:size]; 271 NSFont *fontWithoutSyntheticTraits = [fontManager fontWithFamily:availab leFamily traits:nonSyntheticTraits weight:chosenWeight size:size];
209 if (fontWithoutSyntheticTraits) 272 if (fontWithoutSyntheticTraits)
210 font = fontWithoutSyntheticTraits; 273 font = fontWithoutSyntheticTraits;
211 } 274 }
212 275
213 return font; 276 return font;
214 } 277 }
215 278
279 int toAppKitFontWeight(FontWeight fontWeight)
280 {
281 static int appKitFontWeights[] = {
282 2, // FontWeight100
283 3, // FontWeight200
284 4, // FontWeight300
285 5, // FontWeight400
286 6, // FontWeight500
287 8, // FontWeight600
288 9, // FontWeight700
289 10, // FontWeight800
290 12, // FontWeight900
291 };
292 return appKitFontWeights[fontWeight];
293 }
294
216 } // namespace blink 295 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/fonts/mac/FontFamilyMatcherMac.h ('k') | Source/platform/fonts/mac/FontFamilyMatcherMacTest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698