Fix font creation lost style on Mac
On Mac 10.11, when creating a font from its name and style by using a font descriptor, sometimes the created font lost the style. To work around this problem, we check the font style after the creation, if it is not correct, we will resort to font creation with symbolic traits which creates the correct font. BUG=skia:8447 BUG=874103 Change-Id: I8b57e5a81d0d19d9fb0a7bd2951de75f2c41e236 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/172200 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
fc894d4c0e
commit
40d9c5162f
@ -853,13 +853,43 @@ static SkUniqueCFRef<CTFontDescriptorRef> create_descriptor(const char familyNam
|
||||
CTFontDescriptorCreateWithAttributes(cfAttributes.get()));
|
||||
}
|
||||
|
||||
// Same as the above function except style is included so we can
|
||||
// compare whether the created font conforms to the style. If not, we need
|
||||
// to recreate the font with symbolic traits. This is needed due to MacOS 10.11
|
||||
// font creation problem https://bugs.chromium.org/p/skia/issues/detail?id=8447.
|
||||
static sk_sp<SkTypeface> create_from_desc_and_style(CTFontDescriptorRef desc,
|
||||
const SkFontStyle& style) {
|
||||
SkUniqueCFRef<CTFontRef> ctFont(CTFontCreateWithFontDescriptor(desc, 0, nullptr));
|
||||
if (!ctFont) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctFont.get());
|
||||
CTFontSymbolicTraits expected_traits = traits;
|
||||
if (style.slant() != SkFontStyle::kUpright_Slant) {
|
||||
expected_traits |= kCTFontItalicTrait;
|
||||
}
|
||||
if (style.weight() >= SkFontStyle::kBold_Weight) {
|
||||
expected_traits |= kCTFontBoldTrait;
|
||||
}
|
||||
|
||||
if (expected_traits != traits) {
|
||||
SkUniqueCFRef<CTFontRef> ctNewFont(CTFontCreateCopyWithSymbolicTraits(ctFont.get(), 0, nullptr, expected_traits, expected_traits));
|
||||
if (ctNewFont) {
|
||||
ctFont = std::move(ctNewFont);
|
||||
}
|
||||
}
|
||||
|
||||
return create_from_CTFontRef(std::move(ctFont), nullptr, nullptr);
|
||||
}
|
||||
|
||||
/** Creates a typeface from a name, searching the cache. */
|
||||
static sk_sp<SkTypeface> create_from_name(const char familyName[], const SkFontStyle& style) {
|
||||
SkUniqueCFRef<CTFontDescriptorRef> desc = create_descriptor(familyName, style);
|
||||
if (!desc) {
|
||||
return nullptr;
|
||||
}
|
||||
return create_from_desc(desc.get());
|
||||
return create_from_desc_and_style(desc.get(), style);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -363,3 +363,20 @@ DEF_TEST(Typeface_glyph_to_char, reporter) {
|
||||
originalCodepoints[i], newCodepoints[i], glyphs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// This test makes sure the legacy typeface creation does not lose its specified
|
||||
// style. See https://bugs.chromium.org/p/skia/issues/detail?id=8447 for more
|
||||
// context.
|
||||
DEF_TEST(LegacyMakeTypeface, reporter) {
|
||||
sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
|
||||
sk_sp<SkTypeface> typeface1 = fm->legacyMakeTypeface(nullptr, SkFontStyle::Italic());
|
||||
sk_sp<SkTypeface> typeface2 = fm->legacyMakeTypeface(nullptr, SkFontStyle::Bold());
|
||||
sk_sp<SkTypeface> typeface3 = fm->legacyMakeTypeface(nullptr, SkFontStyle::BoldItalic());
|
||||
|
||||
REPORTER_ASSERT(reporter, typeface1->isItalic());
|
||||
REPORTER_ASSERT(reporter, !typeface1->isBold());
|
||||
REPORTER_ASSERT(reporter, !typeface2->isItalic());
|
||||
REPORTER_ASSERT(reporter, typeface2->isBold());
|
||||
REPORTER_ASSERT(reporter, typeface3->isItalic());
|
||||
REPORTER_ASSERT(reporter, typeface3->isBold());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user