OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFontDescriptor.h" | 8 #include "SkFontDescriptor.h" |
9 #include "SkFontMgr.h" | 9 #include "SkFontMgr.h" |
10 #include "SkOncePtr.h" | 10 #include "SkOncePtr.h" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 */ | 204 */ |
205 SkTypeface* SkFontStyleSet::matchStyleCSS3(const SkFontStyle& pattern) { | 205 SkTypeface* SkFontStyleSet::matchStyleCSS3(const SkFontStyle& pattern) { |
206 int count = this->count(); | 206 int count = this->count(); |
207 if (0 == count) { | 207 if (0 == count) { |
208 return nullptr; | 208 return nullptr; |
209 } | 209 } |
210 | 210 |
211 struct Score { | 211 struct Score { |
212 int score; | 212 int score; |
213 int index; | 213 int index; |
214 Score& operator +=(int rhs) { this->score += rhs; return *this; } | |
215 Score& operator <<=(int rhs) { this->score <<= rhs; return *this; } | |
216 bool operator <(const Score& that) { return this->score < that.score; } | |
214 }; | 217 }; |
215 | 218 |
216 Score maxScore = { 0, 0 }; | 219 Score maxScore = { 0, 0 }; |
217 for (int i = 0; i < count; ++i) { | 220 for (int i = 0; i < count; ++i) { |
218 SkFontStyle current; | 221 SkFontStyle current; |
219 this->getStyle(i, ¤t, nullptr); | 222 this->getStyle(i, ¤t, nullptr); |
220 Score currentScore = { 0, i }; | 223 Score currentScore = { 0, i }; |
221 | 224 |
222 // CSS stretch. (This is the width.) | 225 // CSS stretch. (This is the width.) |
223 // This has the highest priority. | 226 // This has the highest priority. |
224 if (pattern.width() <= SkFontStyle::kNormal_Width) { | 227 if (pattern.width() <= SkFontStyle::kNormal_Width) { |
225 if (current.width() <= pattern.width()) { | 228 if (current.width() <= pattern.width()) { |
226 currentScore.score += 10 - pattern.width() + current.width(); | 229 currentScore += 10 - pattern.width() + current.width(); |
227 } else { | 230 } else { |
228 currentScore.score += 10 - current.width(); | 231 currentScore += 10 - current.width(); |
229 } | 232 } |
230 } else { | 233 } else { |
231 if (current.width() > pattern.width()) { | 234 if (current.width() > pattern.width()) { |
232 currentScore.score += 10 + pattern.width() - current.width(); | 235 currentScore += 10 + pattern.width() - current.width(); |
233 } else { | 236 } else { |
234 currentScore.score += current.width(); | 237 currentScore += current.width(); |
235 } | 238 } |
236 } | 239 } |
237 currentScore.score *= 1002; | 240 currentScore <<= 8; |
238 | 241 |
239 // CSS style (italic/oblique) | 242 // CSS style (normal/italic/oblique) |
240 // Being italic trumps all valid weights which are not italic. | 243 // Style takes priority over all valid weights. |
reed1
2016/04/26 20:36:09
s/Style/Slant ?
bungeman-skia
2016/04/27 15:37:20
Eck, yeah. So CSS uses the terms stretch, style, w
| |
241 // Note that newer specs differentiate between italic and oblique. | 244 switch (pattern.slant()) { |
242 if (pattern.isItalic() == current.isItalic()) { | 245 case SkFontStyle::kUpright_Slant: { |
reed1
2016/04/26 20:36:09
Sure seems like a table or other calc might be cle
bungeman-skia
2016/04/27 15:37:20
I originally wrote this as a small 3x3 score table
| |
243 currentScore.score += 1001; | 246 switch (current.slant()) { |
247 case SkFontStyle::kUpright_Slant: currentScore += 3; break; | |
248 case SkFontStyle::kItalic_Slant : currentScore += 1; break; | |
249 case SkFontStyle::kOblique_Slant: currentScore += 2; break; | |
250 default: SkASSERT(false); break; | |
251 }; | |
252 } break; | |
253 case SkFontStyle::kItalic_Slant: { | |
254 switch (current.slant()) { | |
255 case SkFontStyle::kUpright_Slant: currentScore += 1; break; | |
256 case SkFontStyle::kItalic_Slant : currentScore += 3; break; | |
257 case SkFontStyle::kOblique_Slant: currentScore += 2; break; | |
258 default: SkASSERT(false); break; | |
259 }; | |
260 } break; | |
261 case SkFontStyle::kOblique_Slant: { | |
262 switch (current.slant()) { | |
263 case SkFontStyle::kUpright_Slant: currentScore += 1; break; | |
264 case SkFontStyle::kItalic_Slant : currentScore += 2; break; | |
265 case SkFontStyle::kOblique_Slant: currentScore += 3; break; | |
266 default: SkASSERT(false); break; | |
267 }; | |
268 } break; | |
269 default: SkASSERT(false); break; | |
244 } | 270 } |
271 currentScore <<= 8; | |
245 | 272 |
246 // Synthetics (weight/style) [no stretch synthetic?] | 273 // Synthetics (weight/style) [no stretch synthetic?] |
247 | 274 |
248 // The 'closer' to the target weight, the higher the score. | 275 // The 'closer' to the target weight, the higher the score. |
249 // 1000 is the 'heaviest' recognized weight | 276 // 1000 is the 'heaviest' recognized weight |
250 if (pattern.weight() == current.weight()) { | 277 if (pattern.weight() == current.weight()) { |
251 currentScore.score += 1000; | 278 currentScore += 1000; |
252 } else if (pattern.weight() <= 500) { | 279 } else if (pattern.weight() <= 500) { |
253 if (400 <= pattern.weight() && pattern.weight() < 450) { | 280 if (400 <= pattern.weight() && pattern.weight() < 450) { |
254 if (450 <= current.weight() && current.weight() <= 500) { | 281 if (450 <= current.weight() && current.weight() <= 500) { |
255 // Artificially boost the 500 weight. | 282 // Artificially boost the 500 weight. |
256 // TODO: determine correct number to use. | 283 // TODO: determine correct number to use. |
257 currentScore.score += 500; | 284 currentScore += 500; |
258 } | 285 } |
259 } | 286 } |
260 if (current.weight() <= pattern.weight()) { | 287 if (current.weight() <= pattern.weight()) { |
261 currentScore.score += 1000 - pattern.weight() + current.weight() ; | 288 currentScore += 1000 - pattern.weight() + current.weight(); |
262 } else { | 289 } else { |
263 currentScore.score += 1000 - current.weight(); | 290 currentScore += 1000 - current.weight(); |
264 } | 291 } |
265 } else if (pattern.weight() > 500) { | 292 } else if (pattern.weight() > 500) { |
266 if (current.weight() > pattern.weight()) { | 293 if (current.weight() > pattern.weight()) { |
267 currentScore.score += 1000 + pattern.weight() - current.weight() ; | 294 currentScore += 1000 + pattern.weight() - current.weight(); |
268 } else { | 295 } else { |
269 currentScore.score += current.weight(); | 296 currentScore += current.weight(); |
270 } | 297 } |
271 } | 298 } |
272 | 299 |
273 if (currentScore.score > maxScore.score) { | 300 if (maxScore < currentScore) { |
274 maxScore = currentScore; | 301 maxScore = currentScore; |
275 } | 302 } |
276 } | 303 } |
277 | 304 |
278 return this->createTypeface(maxScore.index); | 305 return this->createTypeface(maxScore.index); |
279 } | 306 } |
OLD | NEW |