1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Fonts: Avoid calling deprecated CTFontManagerRegisterGraphicsFont

The main reason for removing this call is that this function is
deprecated, and is no longer needed now that we keep our own cache of
CTFonts that have been loaded from memory, and now that we no longer use
CoreText text layouts.

This also appears to fix an issue with garbled text which was
occasionally seen when different versions of the same font were
available, e.g. because differing versions of the font were
simultaneously embedded as BinaryData and installed on the system.
This commit is contained in:
reuk 2024-09-10 19:21:20 +01:00
parent 44e2d0343b
commit 68d0ea9dfb
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C

View file

@ -51,21 +51,56 @@ class CoreTextTypeface final : public Typeface
void add (CTFontRef ref)
{
const std::scoped_lock lock { mutex };
CFUniquePtr<CGFontRef> cgFont { CTFontCopyGraphicsFont (ref, nullptr) };
if (CTFontManagerRegisterGraphicsFont (cgFont.get(), nullptr))
map.emplace (ref, std::move (cgFont));
set.emplace (addOwner (ref));
}
void remove (CTFontRef ref)
{
const std::scoped_lock lock { mutex };
if (const auto iter = map.find (ref); iter != map.end())
{
CTFontManagerUnregisterGraphicsFont (iter->second.get(), nullptr);
map.erase (iter);
set.erase (addOwner (ref));
}
CFUniquePtr<CTFontRef> findMatch (const String& fontName, const String& fontStyle) const
{
const std::scoped_lock lock { mutex };
for (auto& item : set)
{
const auto keyAsString = [&] (auto key)
{
return String::fromCFString (CFUniquePtr<CFStringRef> { CTFontCopyName (item.get(), key) }.get());
};
const auto family = keyAsString (kCTFontFamilyNameKey);
const auto style = keyAsString (kCTFontStyleNameKey);
if (fontName == family && (style.isEmpty() || fontStyle.equalsIgnoreCase (style)))
return addOwner (item.get());
}
return nullptr;
}
std::vector<CFUniquePtr<CTFontRef>> findAllStylesForFamily (const String& fontName) const
{
const std::scoped_lock lock { mutex };
std::vector<CFUniquePtr<CTFontRef>> result;
for (auto& item : set)
{
const auto keyAsString = [&] (auto key)
{
return String::fromCFString (CFUniquePtr<CFStringRef> { CTFontCopyName (item.get(), key) }.get());
};
const auto family = keyAsString (kCTFontFamilyNameKey);
if (fontName == family)
result.emplace_back (addOwner (item.get()));
}
return result;
}
std::set<String> getRegisteredFamilies() const
@ -73,9 +108,9 @@ class CoreTextTypeface final : public Typeface
const std::scoped_lock lock { mutex };
std::set<String> result;
for (const auto& item : map)
for (const auto& item : set)
{
const CFUniquePtr<CFStringRef> family { CTFontCopyName (item.first, kCTFontFamilyNameKey) };
const CFUniquePtr<CFStringRef> family { CTFontCopyName (item.get(), kCTFontFamilyNameKey) };
result.insert (String::fromCFString (family.get()));
}
@ -83,7 +118,13 @@ class CoreTextTypeface final : public Typeface
}
private:
std::map<CTFontRef, CFUniquePtr<CGFontRef>> map;
static CFUniquePtr<CTFontRef> addOwner (CTFontRef reference)
{
CFRetain (reference);
return CFUniquePtr<CTFontRef> { reference };
}
std::set<CFUniquePtr<CTFontRef>> set;
mutable std::mutex mutex;
};
@ -94,6 +135,11 @@ class CoreTextTypeface final : public Typeface
public:
static Typeface::Ptr from (const Font& font)
{
auto ctFont = [&]() -> CFUniquePtr<CTFontRef>
{
if (auto f = getRegistered().findMatch (font.getTypefaceName(), font.getTypefaceStyle()))
return f;
CFUniquePtr<CFStringRef> cfFontFamily (FontStyleHelpers::getConcreteFamilyName (font).toCFString());
if (cfFontFamily == nullptr)
@ -122,7 +168,8 @@ public:
if (ctFontDescRef == nullptr)
return {};
CFUniquePtr<CTFontRef> ctFont { CTFontCreateWithFontDescriptor (ctFontDescRef.get(), 1, nullptr) };
return CFUniquePtr<CTFontRef> { CTFontCreateWithFontDescriptor (ctFontDescRef.get(), 1, nullptr) };
}();
if (ctFont == nullptr)
return {};
@ -231,6 +278,11 @@ public:
return getRegistered().getRegisteredFamilies();
}
static std::vector<CFUniquePtr<CTFontRef>> findRegisteredStylesForFamily (const String& family)
{
return getRegistered().findAllStylesForFamily (family);
}
~CoreTextTypeface() override
{
getRegistered().remove (ctFont.get());
@ -330,8 +382,6 @@ StringArray Font::findAllTypefaceNames()
{
StringArray names;
// The collection returned from CTFontCollectionCreateFromAvailableFonts doesn't include fonts registered by
// CTFontManagerRegisterGraphicsFont on iOS, so we need to keep track of registered fonts ourselves.
auto nameSet = CoreTextTypeface::getRegisteredFamilies();
CFUniquePtr<CTFontCollectionRef> fontCollectionRef (CTFontCollectionCreateFromAvailableFonts (nullptr));
@ -356,7 +406,14 @@ StringArray Font::findAllTypefaceStyles (const String& family)
if (FontStyleHelpers::isPlaceholderFamilyName (family))
return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family));
StringArray results;
std::set<String> results;
for (const auto& font : CoreTextTypeface::findRegisteredStylesForFamily (family))
{
const CFUniquePtr<CTFontDescriptorRef> descriptor (CTFontCopyFontDescriptor (font.get()));
const CFUniquePtr<CFStringRef> cfsFontStyle ((CFStringRef) CTFontDescriptorCopyAttribute (descriptor.get(), kCTFontStyleNameAttribute));
results.insert (String::fromCFString (cfsFontStyle.get()));
}
CFUniquePtr<CFStringRef> cfsFontFamily (family.toCFString());
CFStringRef keys[] { kCTFontFamilyNameAttribute };
@ -376,11 +433,16 @@ StringArray Font::findAllTypefaceStyles (const String& family)
{
auto ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray.get(), i);
CFUniquePtr<CFStringRef> cfsFontStyle ((CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontStyleNameAttribute));
results.add (String::fromCFString (cfsFontStyle.get()));
results.insert (String::fromCFString (cfsFontStyle.get()));
}
}
return results;
StringArray stringArray;
for (const auto& result : results)
stringArray.add (result);
return stringArray;
}
struct DefaultFontNames