@@ -1042,42 +1042,53 @@ static void add_notrak_attr(CFMutableDictionaryRef attr) {
10421042 CFDictionarySetValue (attr, SkCTFontUnscaledTrackingAttribute, unscaledTrackingNumber.get ());
10431043}
10441044
1045- // CTFontCreateCopyWithAttributes or CTFontCreateCopyWithSymbolicTraits cannot be used on 10.10
1046- // and later, as they will return different underlying fonts depending on the size requested.
1047- // It is not possible to use descriptors with CTFontCreateWithFontDescriptor, since that does not
1048- // work with non-system fonts. As a result, create the strike specific CTFonts from the underlying
1049- // CGFont.
10501045static SkUniqueCFRef<CTFontRef> ctfont_create_exact_copy (CTFontRef baseFont, CGFloat textSize,
10511046 OpszVariation opsz)
10521047{
1053- SkUniqueCFRef<CGFontRef> baseCGFont (CTFontCopyGraphicsFont (baseFont, nullptr ));
1054-
1055- // Because we cannot setup the CTFont descriptor to match, the same restriction applies here
1056- // as other uses of CTFontCreateWithGraphicsFont which is that such CTFonts should not escape
1057- // the scaler context, since they aren't 'normal'.
1058-
10591048 SkUniqueCFRef<CFMutableDictionaryRef> attr (
10601049 CFDictionaryCreateMutable (kCFAllocatorDefault , 1 ,
10611050 &kCFTypeDictionaryKeyCallBacks ,
10621051 &kCFTypeDictionaryValueCallBacks ));
10631052
10641053 if (opsz.isSet ) {
10651054 add_opsz_attr (attr.get (), opsz.value );
1055+ #if !defined(SK_IGNORE_MAC_OPSZ_FORCE)
1056+ } else {
1057+ // On (at least) 10.10 though 10.14 the default system font was SFNSText/SFNSDisplay.
1058+ // The CTFont is backed by both; optical size < 20 means SFNSText else SFNSDisplay.
1059+ // On at least 10.11 the glyph ids in these fonts became non-interchangable.
1060+ // To keep glyph ids stable over size changes, preserve the optical size.
1061+ // In 10.15 this was replaced with use of variable fonts with an opsz axis.
1062+ // A CTFont backed by multiple fonts picked by opsz where the multiple backing fonts are
1063+ // variable fonts with opsz axis and non-interchangeable glyph ids would break the
1064+ // opsz.isSet branch above, but hopefully that never happens.
1065+ // See https://crbug.com/524646 .
1066+ CFStringRef SkCTFontOpticalSizeAttribute = CFSTR (" NSCTFontOpticalSizeAttribute" );
1067+ SkUniqueCFRef<CFTypeRef> opsz (CTFontCopyAttribute (baseFont, SkCTFontOpticalSizeAttribute));
1068+ double opsz_val;
1069+ if (!opsz ||
1070+ CFGetTypeID (opsz.get ()) != CFNumberGetTypeID () ||
1071+ !CFNumberGetValue (static_cast <CFNumberRef>(opsz.get ()),kCFNumberDoubleType ,&opsz_val) ||
1072+ opsz_val <= 0 )
1073+ {
1074+ opsz_val = CTFontGetSize (baseFont);
1075+ }
1076+ add_opsz_attr (attr.get (), opsz_val);
1077+ #endif
10661078 }
10671079 add_notrak_attr (attr.get ());
10681080
10691081 SkUniqueCFRef<CTFontDescriptorRef> desc (CTFontDescriptorCreateWithAttributes (attr.get ()));
10701082
1071- // The attributes parameter to CTFontCreateWithGraphicsFont *must* not set variations.
1072- // If it sets variations then with fonts with variation axes the copy will fail in
1073- // CGFontVariationFromDictCallback when it assumes kCGFontVariationAxisName is CFNumberRef
1074- // which it quite obviously is not (in 10.11, fixed by 10.14).
1075-
1076- // However, the attributes parameter to CTFontCreateWithGraphicsFont *must* not be nullptr.
1077- // If it is then variable system fonts will only work on named instances on 10.14 and earlier.
1078-
1083+ #if !defined(SK_IGNORE_MAC_OPSZ_FORCE)
1084+ return SkUniqueCFRef<CTFontRef>(
1085+ CTFontCreateCopyWithAttributes (baseFont, textSize, nullptr , desc.get ()));
1086+ #else
1087+ SkUniqueCFRef<CGFontRef> baseCGFont (CTFontCopyGraphicsFont (baseFont, nullptr ));
10791088 return SkUniqueCFRef<CTFontRef>(
10801089 CTFontCreateWithGraphicsFont (baseCGFont.get (), textSize, nullptr , desc.get ()));
1090+
1091+ #endif
10811092}
10821093
10831094SkScalerContext_Mac::SkScalerContext_Mac (sk_sp<SkTypeface_Mac> typeface,
@@ -1108,7 +1119,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface,
11081119 }
11091120
11101121 // The transform contains everything except the requested text size.
1111- // Some properties, like 'trak', are based on the text size (before applying the matrix) .
1122+ // Some properties, like 'trak', are based on the optical text size.
11121123 CGFloat textSize = ScalarToCG (scale.y ());
11131124 fCTFont = ctfont_create_exact_copy (ctFont, textSize,
11141125 ((SkTypeface_Mac*)this ->getTypeface ())->fOpszVariation );
0 commit comments