OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkTypes.h" // Keep this before any #ifdef ... | 8 #include "SkTypes.h" // Keep this before any #ifdef ... |
9 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 9 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
10 | 10 |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 bool fDoAA; | 363 bool fDoAA; |
364 bool fDoLCD; | 364 bool fDoLCD; |
365 | 365 |
366 static int RoundSize(int dimension) { | 366 static int RoundSize(int dimension) { |
367 return SkNextPow2(dimension); | 367 return SkNextPow2(dimension); |
368 } | 368 } |
369 }; | 369 }; |
370 | 370 |
371 /////////////////////////////////////////////////////////////////////////////// | 371 /////////////////////////////////////////////////////////////////////////////// |
372 | 372 |
373 static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value
) { | 373 static bool find_dict_CGFloat(CFDictionaryRef dict, CFStringRef name, CGFloat* v
alue) { |
374 CFNumberRef num; | 374 CFNumberRef num; |
375 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) | 375 return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num) |
376 && CFNumberIsFloatType(num) | 376 && CFNumberIsFloatType(num) |
377 && CFNumberGetValue(num, kCFNumberFloatType, value); | 377 && CFNumberGetValue(num, kCFNumberCGFloatType, value); |
378 } | 378 } |
379 | 379 |
380 static int unit_weight_to_fontstyle(float unit) { | 380 template <typename S, typename D, typename C> struct LinearInterpolater { |
381 float value; | 381 struct Mapping { |
382 if (unit < 0) { | 382 S src_val; |
383 value = 100 + (1 + unit) * 300; | 383 D dst_val; |
384 } else { | 384 }; |
385 value = 400 + unit * 500; | 385 constexpr LinearInterpolater(Mapping const mapping[], int mappingCount) |
| 386 : fMapping(mapping), fMappingCount(mappingCount) {} |
| 387 |
| 388 static D map(S value, S src_min, S src_max, D dst_min, D dst_max) { |
| 389 SkASSERT(src_min < src_max); |
| 390 SkASSERT(dst_min <= dst_max); |
| 391 return C()(dst_min + (((value - src_min) * (dst_max - dst_min)) / (src_m
ax - src_min))); |
386 } | 392 } |
387 return sk_float_round2int(value); | 393 |
| 394 int map(S val) const { |
| 395 // -Inf to [0] |
| 396 if (val < fMapping[0].src_val) { |
| 397 return fMapping[0].dst_val; |
| 398 } |
| 399 |
| 400 // Linear from [i] to [i+1] |
| 401 for (int i = 0; i < fMappingCount - 1; ++i) { |
| 402 if (val < fMapping[i+1].src_val) { |
| 403 return map(val, fMapping[i].src_val, fMapping[i+1].src_val, |
| 404 fMapping[i].dst_val, fMapping[i+1].dst_val); |
| 405 } |
| 406 } |
| 407 |
| 408 // From [n] to +Inf |
| 409 // if (fcweight < Inf) |
| 410 return fMapping[fMappingCount - 1].dst_val; |
| 411 } |
| 412 |
| 413 Mapping const * fMapping; |
| 414 int fMappingCount; |
| 415 }; |
| 416 |
| 417 struct RoundCGFloatToInt { |
| 418 int operator()(CGFloat s) { return s + 0.5; } |
| 419 }; |
| 420 |
| 421 static int ct_weight_to_fontstyle(CGFloat cgWeight) { |
| 422 using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>; |
| 423 |
| 424 // Values determined by creating font data with every weight, creating a CTF
ont, |
| 425 // and asking the CTFont for its weight. See TypefaceStyle test for basics. |
| 426 |
| 427 // Note that Mac supports the old OS2 version A so 0 through 10 are as if mu
ltiplied by 100. |
| 428 // However, on this end we can't tell. |
| 429 static constexpr Interpolator::Mapping weightMappings[] = { |
| 430 { -1.00, 0 }, |
| 431 { -0.70, 100 }, |
| 432 { -0.50, 200 }, |
| 433 { -0.23, 300 }, |
| 434 { 0.00, 400 }, |
| 435 { 0.20, 500 }, |
| 436 { 0.30, 600 }, |
| 437 { 0.40, 700 }, |
| 438 { 0.60, 800 }, |
| 439 { 0.80, 900 }, |
| 440 { 1.00, 1000 }, |
| 441 }; |
| 442 static constexpr Interpolator interpolater(weightMappings, SK_ARRAY_COUNT(we
ightMappings)); |
| 443 return interpolater.map(cgWeight); |
388 } | 444 } |
389 | 445 |
390 static int unit_width_to_fontstyle(float unit) { | 446 static int ct_width_to_fontstyle(CGFloat cgWidth) { |
391 float value; | 447 using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>; |
392 if (unit < 0) { | 448 |
393 value = 1 + (1 + unit) * 4; | 449 // Values determined by creating font data with every width, creating a CTFo
nt, |
394 } else { | 450 // and asking the CTFont for its width. See TypefaceStyle test for basics. |
395 value = 5 + unit * 4; | 451 static constexpr Interpolator::Mapping widthMappings[] = { |
396 } | 452 { -0.5, 0 }, |
397 return sk_float_round2int(value); | 453 { 0.5, 10 }, |
| 454 }; |
| 455 static constexpr Interpolator interpolater(widthMappings, SK_ARRAY_COUNT(wid
thMappings)); |
| 456 return interpolater.map(cgWidth); |
398 } | 457 } |
399 | 458 |
400 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { | 459 static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) { |
401 AutoCFRelease<CFDictionaryRef> dict( | 460 AutoCFRelease<CFDictionaryRef> dict( |
402 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); | 461 (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAt
tribute)); |
403 if (nullptr == dict.get()) { | 462 if (nullptr == dict.get()) { |
404 return SkFontStyle(); | 463 return SkFontStyle(); |
405 } | 464 } |
406 | 465 |
407 float weight, width, slant; | 466 CGFloat weight, width, slant; |
408 if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) { | 467 if (!find_dict_CGFloat(dict, kCTFontWeightTrait, &weight)) { |
409 weight = 0; | 468 weight = 0; |
410 } | 469 } |
411 if (!find_dict_float(dict, kCTFontWidthTrait, &width)) { | 470 if (!find_dict_CGFloat(dict, kCTFontWidthTrait, &width)) { |
412 width = 0; | 471 width = 0; |
413 } | 472 } |
414 if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) { | 473 if (!find_dict_CGFloat(dict, kCTFontSlantTrait, &slant)) { |
415 slant = 0; | 474 slant = 0; |
416 } | 475 } |
417 | 476 |
418 return SkFontStyle(unit_weight_to_fontstyle(weight), | 477 return SkFontStyle(ct_weight_to_fontstyle(weight), |
419 unit_width_to_fontstyle(width), | 478 ct_width_to_fontstyle(width), |
420 slant ? SkFontStyle::kItalic_Slant | 479 slant ? SkFontStyle::kItalic_Slant |
421 : SkFontStyle::kUpright_Slant); | 480 : SkFontStyle::kUpright_Slant); |
422 } | 481 } |
423 | 482 |
424 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) | 483 #define WEIGHT_THRESHOLD ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_W
eight)/2) |
425 | 484 |
426 // kCTFontColorGlyphsTrait was added in the Mac 10.7 and iPhone 4.3 SDKs. | 485 // kCTFontColorGlyphsTrait was added in the Mac 10.7 and iPhone 4.3 SDKs. |
427 // Being an enum value it is not guarded by version macros, but old SDKs must st
ill be supported. | 486 // Being an enum value it is not guarded by version macros, but old SDKs must st
ill be supported. |
428 #if defined(__MAC_10_7) || defined(__IPHONE_4_3) | 487 #if defined(__MAC_10_7) || defined(__IPHONE_4_3) |
429 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait; | 488 static const uint32_t SkCTFontColorGlyphsTrait = kCTFontColorGlyphsTrait; |
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 | 2628 |
2570 return SkSafeRef(GetDefaultFace()); | 2629 return SkSafeRef(GetDefaultFace()); |
2571 } | 2630 } |
2572 }; | 2631 }; |
2573 | 2632 |
2574 /////////////////////////////////////////////////////////////////////////////// | 2633 /////////////////////////////////////////////////////////////////////////////// |
2575 | 2634 |
2576 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2635 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
2577 | 2636 |
2578 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 2637 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
OLD | NEW |