Skip to content

Commit b5d977f

Browse files
Ben WagnerSkia Commit-Bot
authored andcommitted
Control opsz instead of CGFont in create_exact_copy.
Bug: flutter/flutter#49492 Change-Id: Ia32a158e3326c1fe65f5d6f4e497592451458684 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272116 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Herb Derby <herb@google.com>
1 parent 19304d8 commit b5d977f

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

src/ports/SkFontHost_mac.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
10501045
static 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

10831094
SkScalerContext_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

Comments
 (0)