Commit e17bfbc8 authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Fix GetFontWeightFromNSFont()

GetFontWeightFromNSFont() uses a table of CoreText float values to
look up corresponding Font::Weight values. The testing of the
float values was broken; fix it.

Bug: 1112998
Change-Id: Ia3346c2964e3c74cb855b701227a662aa281de8d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2337734Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795061}
parent 8c2e3651
...@@ -91,31 +91,53 @@ Font::Weight GetFontWeightFromNSFont(NSFont* font) { ...@@ -91,31 +91,53 @@ Font::Weight GetFontWeightFromNSFont(NSFont* font) {
DCHECK(font); DCHECK(font);
// Map CoreText weights in a manner similar to ct_weight_to_fontstyle() from // Map CoreText weights in a manner similar to ct_weight_to_fontstyle() from
// SkFontHost_mac.cpp, but adjust for MEDIUM so that the San Francisco's // SkFontHost_mac.cpp, but adjusted for the weights actually used by the
// custom MEDIUM weight can be picked out. San Francisco has weights: // system fonts. See PlatformFontMacTest.FontWeightAPIConsistency for details.
// [0.23, 0.23, 0.3, 0.4, 0.56, 0.62, 0.62, ...] (no thin weights). // Use ranges for paranoia.
// See PlatformFontMacTest.FontWeightAPIConsistency for details.
// Note that the table Skia uses is also determined by experiment.
constexpr struct { constexpr struct {
CGFloat ct_weight; // A range of CoreText weights.
CGFloat weight_lower;
CGFloat weight_upper;
Font::Weight gfx_weight; Font::Weight gfx_weight;
} weight_map[] = { } weight_map[] = {
// Missing: Apple "ultralight". // NSFontWeight constants introduced in 10.11:
{-0.70, Font::Weight::THIN}, // NSFontWeightUltraLight: -0.80
{-0.50, Font::Weight::EXTRA_LIGHT}, // NSFontWeightThin: -0.60
{-0.23, Font::Weight::LIGHT}, // NSFontWeightLight: -0.40
{0.00, Font::Weight::NORMAL}, // NSFontWeightRegular: 0.0
{0.23, Font::Weight::MEDIUM}, // Note: adjusted from 0.20 vs Skia. // NSFontWeightMedium: 0.23
// Missing: Apple "demibold". // NSFontWeightSemibold: 0.30
{0.30, Font::Weight::SEMIBOLD}, // NSFontWeightBold: 0.40
{0.40, Font::Weight::BOLD}, // NSFontWeightHeavy: 0.56
{0.60, Font::Weight::EXTRA_BOLD}, // NSFontWeightBlack: 0.62
// Missing: Apple "heavyface". //
// Values will be capped to BLACK (this entry is here for consistency). // Actual system font weights:
{0.80, Font::Weight::BLACK}, // 10.10:
// Missing: Apple "ultrablack". // .HelveticaNeueDeskInterface-Regular: 0.0
// Missing: Apple "extrablack". // .HelveticaNeueDeskInterface-MediumP4: 0.23
// .HelveticaNeueDeskInterface-Bold: 0.4
// .HelveticaNeueDeskInterface-Heavy: 0.62
// 10.11-:
// .AppleSystemUIFontUltraLight: -0.80 (10.12-)
// .AppleSystemUIFontLight: -0.40 (10.12-)
// .AppleSystemUIFont: 0 (10.11-)
// .AppleSystemUIFontMedium: 0.23 (10.12-)
// .AppleSystemUIFontDemi: 0.30 (10.12-)
// .AppleSystemUIFontBold: 0.40 (10.11)
// .AppleSystemUIFontEmphasized: 0.40 (10.12-)
// .AppleSystemUIFontHeavy: 0.56 (10.11-)
// .AppleSystemUIFontBlack: 0.62 (10.11-)
{-1000, -0.70, Font::Weight::THIN}, // NSFontWeightUltraLight
{-0.70, -0.45, Font::Weight::EXTRA_LIGHT}, // NSFontWeightThin
{-0.45, -0.10, Font::Weight::LIGHT}, // NSFontWeightLight
{-0.10, 0.10, Font::Weight::NORMAL}, // NSFontWeightRegular
{0.10, 0.27, Font::Weight::MEDIUM}, // NSFontWeightMedium
{0.27, 0.35, Font::Weight::SEMIBOLD}, // NSFontWeightSemibold
{0.35, 0.50, Font::Weight::BOLD}, // NSFontWeightBold
{0.50, 0.60, Font::Weight::EXTRA_BOLD}, // NSFontWeightHeavy
{0.60, 1000, Font::Weight::BLACK}, // NSFontWeightBlack
}; };
base::ScopedCFTypeRef<CFDictionaryRef> traits( base::ScopedCFTypeRef<CFDictionaryRef> traits(
CTFontCopyTraits(base::mac::NSToCFCast(font))); CTFontCopyTraits(base::mac::NSToCFCast(font)));
DCHECK(traits); DCHECK(traits);
...@@ -125,20 +147,18 @@ Font::Weight GetFontWeightFromNSFont(NSFont* font) { ...@@ -125,20 +147,18 @@ Font::Weight GetFontWeightFromNSFont(NSFont* font) {
if (!cf_weight) if (!cf_weight)
return Font::Weight::NORMAL; return Font::Weight::NORMAL;
// Documentation is vague about what sized floating point type should be used. // The value of kCTFontWeightTrait empirically is a kCFNumberFloat64Type
// However, numeric_limits::epsilon() for 64-bit types is too small to match // (double) on all tested versions of macOS. However, that doesn't really
// the above table, so use 32-bit float. Do not check for the success of // matter as only the first two decimal digits need to be tested. Do not check
// CFNumberGetValue(). CFNumberGetValue() returns false for *any* loss of // for the success of CFNumberGetValue() as it returns false for any loss of
// value, and a float is used here deliberately to coarsen the accuracy. // value and all that is needed here is two digits of accuracy.
// There's no guarantee that any particular value for the kCTFontWeightTrait CGFloat weight;
// will be able to be accurately represented with a float. CFNumberGetValue(cf_weight, kCFNumberCGFloatType, &weight);
float weight_value;
CFNumberGetValue(cf_weight, kCFNumberFloatType, &weight_value);
for (const auto& item : weight_map) { for (const auto& item : weight_map) {
if (weight_value - item.ct_weight <= std::numeric_limits<float>::epsilon()) if (item.weight_lower <= weight && weight <= item.weight_upper)
return item.gfx_weight; return item.gfx_weight;
} }
return Font::Weight::BLACK; return Font::Weight::INVALID;
} }
// Returns an autoreleased NSFont created with the passed-in specifications. // Returns an autoreleased NSFont created with the passed-in specifications.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment