mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Android: Use AFontMatcher to locate generic system fonts on supported platforms
This commit is contained in:
parent
f9fc03eb2b
commit
1c9947b80e
1 changed files with 59 additions and 42 deletions
|
|
@ -35,23 +35,6 @@
|
||||||
namespace juce
|
namespace juce
|
||||||
{
|
{
|
||||||
|
|
||||||
Typeface::Ptr Font::Native::getDefaultPlatformTypefaceForFont (const Font& font)
|
|
||||||
{
|
|
||||||
Font f (font);
|
|
||||||
f.setTypefaceName ([&]() -> String
|
|
||||||
{
|
|
||||||
const auto faceName = font.getTypefaceName();
|
|
||||||
|
|
||||||
if (faceName == Font::getDefaultSansSerifFontName()) return "Roboto";
|
|
||||||
if (faceName == Font::getDefaultSerifFontName()) return "Roboto";
|
|
||||||
if (faceName == Font::getDefaultMonospacedFontName()) return "Roboto";
|
|
||||||
|
|
||||||
return faceName;
|
|
||||||
}());
|
|
||||||
|
|
||||||
return Typeface::createSystemTypefaceFor (f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
|
||||||
STATICMETHOD (create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \
|
STATICMETHOD (create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \
|
||||||
|
|
@ -100,6 +83,11 @@ DECLARE_JNI_CLASS (JavaMessageDigest, "java/security/MessageDigest")
|
||||||
DECLARE_JNI_CLASS (AndroidAssetManager, "android/content/res/AssetManager")
|
DECLARE_JNI_CLASS (AndroidAssetManager, "android/content/res/AssetManager")
|
||||||
#undef JNI_CLASS_MEMBERS
|
#undef JNI_CLASS_MEMBERS
|
||||||
|
|
||||||
|
#define JUCE_INTRODUCED_IN_29 \
|
||||||
|
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE("-Wgnu-zero-variadic-macro-arguments") \
|
||||||
|
__INTRODUCED_IN (29) \
|
||||||
|
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||||
|
|
||||||
// Defined in juce_core
|
// Defined in juce_core
|
||||||
std::unique_ptr<InputStream> makeAndroidInputStreamWrapper (LocalRef<jobject> stream);
|
std::unique_ptr<InputStream> makeAndroidInputStreamWrapper (LocalRef<jobject> stream);
|
||||||
|
|
||||||
|
|
@ -313,6 +301,23 @@ public:
|
||||||
return from (FontOptions{}.withName ("Roboto"));
|
return from (FontOptions{}.withName ("Roboto"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JUCE_INTRODUCED_IN_29 Typeface::Ptr findGenericTypefaceWithMatcher (const char* name)
|
||||||
|
{
|
||||||
|
using AFontMatcherPtr = std::unique_ptr<AFontMatcher, FunctionPointerDestructor<AFontMatcher_destroy>>;
|
||||||
|
using AFontPtr = std::unique_ptr<AFont, FunctionPointerDestructor<AFont_close>>;
|
||||||
|
|
||||||
|
constexpr uint16_t testString[] { 't', 'e', 's', 't' };
|
||||||
|
|
||||||
|
const AFontMatcherPtr matcher { AFontMatcher_create() };
|
||||||
|
const AFontPtr matched { AFontMatcher_match (matcher.get(),
|
||||||
|
name,
|
||||||
|
testString,
|
||||||
|
std::size (testString),
|
||||||
|
nullptr) };
|
||||||
|
|
||||||
|
return fromMatchedFont (matched.get());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class DoCache
|
enum class DoCache
|
||||||
{
|
{
|
||||||
|
|
@ -320,14 +325,7 @@ private:
|
||||||
yes
|
yes
|
||||||
};
|
};
|
||||||
|
|
||||||
// The definition of __BIONIC_AVAILABILITY was changed in NDK 28.1 and it now has variadic
|
static JUCE_INTRODUCED_IN_29 Typeface::Ptr fromMatchedFont (AFont* matched)
|
||||||
// parameters.
|
|
||||||
//
|
|
||||||
// But __INTRODUCED_IN only has one parameter so there isn't even a way to pass on anything to
|
|
||||||
// to __BIONIC_AVAILABILITY.
|
|
||||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments")
|
|
||||||
|
|
||||||
static __INTRODUCED_IN (29) Typeface::Ptr fromMatchedFont (AFont* matched)
|
|
||||||
{
|
{
|
||||||
if (matched == nullptr)
|
if (matched == nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -348,24 +346,12 @@ private:
|
||||||
return cache->get ({ matchedFile, (int) matchedIndex }, &loadCompatibleFont);
|
return cache->get ({ matchedFile, (int) matchedIndex }, &loadCompatibleFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __INTRODUCED_IN (29) Typeface::Ptr findSystemTypefaceWithMatcher()
|
static JUCE_INTRODUCED_IN_29 Typeface::Ptr findSystemTypefaceWithMatcher()
|
||||||
{
|
{
|
||||||
using AFontMatcherPtr = std::unique_ptr<AFontMatcher, FunctionPointerDestructor<AFontMatcher_destroy>>;
|
return findGenericTypefaceWithMatcher ("system-ui");
|
||||||
using AFontPtr = std::unique_ptr<AFont, FunctionPointerDestructor<AFont_close>>;
|
|
||||||
|
|
||||||
constexpr uint16_t testString[] { 't', 'e', 's', 't' };
|
|
||||||
|
|
||||||
const AFontMatcherPtr matcher { AFontMatcher_create() };
|
|
||||||
const AFontPtr matched { AFontMatcher_match (matcher.get(),
|
|
||||||
"system-ui",
|
|
||||||
testString,
|
|
||||||
std::size (testString),
|
|
||||||
nullptr) };
|
|
||||||
|
|
||||||
return fromMatchedFont (matched.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__INTRODUCED_IN (29) Typeface::Ptr matchWithAFontMatcher (const String& text, const String& language) const
|
JUCE_INTRODUCED_IN_29 Typeface::Ptr matchWithAFontMatcher (const String& text, const String& language) const
|
||||||
{
|
{
|
||||||
using AFontMatcherPtr = std::unique_ptr<AFontMatcher, FunctionPointerDestructor<AFontMatcher_destroy>>;
|
using AFontMatcherPtr = std::unique_ptr<AFontMatcher, FunctionPointerDestructor<AFontMatcher_destroy>>;
|
||||||
using AFontPtr = std::unique_ptr<AFont, FunctionPointerDestructor<AFont_close>>;
|
using AFontPtr = std::unique_ptr<AFont, FunctionPointerDestructor<AFont_close>>;
|
||||||
|
|
@ -391,8 +377,6 @@ private:
|
||||||
return fromMatchedFont (matched.get());
|
return fromMatchedFont (matched.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
|
||||||
|
|
||||||
static bool shouldStoreAndroidFont (hb_face_t* face)
|
static bool shouldStoreAndroidFont (hb_face_t* face)
|
||||||
{
|
{
|
||||||
return (hb_ot_color_has_svg (face) || hb_ot_color_has_paint (face))
|
return (hb_ot_color_has_svg (face) || hb_ot_color_has_paint (face))
|
||||||
|
|
@ -803,4 +787,37 @@ void Typeface::scanFolderForFonts (const File&)
|
||||||
jassertfalse; // not currently available
|
jassertfalse; // not currently available
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
Typeface::Ptr Font::Native::getDefaultPlatformTypefaceForFont (const Font& font)
|
||||||
|
{
|
||||||
|
const auto faceName = font.getTypefaceName();
|
||||||
|
|
||||||
|
const auto idealFace = std::invoke ([&]() -> Typeface::Ptr
|
||||||
|
{
|
||||||
|
if (__builtin_available (android 29, *))
|
||||||
|
{
|
||||||
|
if (faceName == Font::getDefaultSansSerifFontName()) return AndroidTypeface::findGenericTypefaceWithMatcher ("sans-serif");
|
||||||
|
if (faceName == Font::getDefaultSerifFontName()) return AndroidTypeface::findGenericTypefaceWithMatcher ("serif");
|
||||||
|
if (faceName == Font::getDefaultMonospacedFontName()) return AndroidTypeface::findGenericTypefaceWithMatcher ("monospace");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (idealFace != nullptr)
|
||||||
|
return idealFace;
|
||||||
|
|
||||||
|
Font f (font);
|
||||||
|
f.setTypefaceName (std::invoke ([&]() -> String
|
||||||
|
{
|
||||||
|
if (faceName == Font::getDefaultSansSerifFontName()) return "Roboto";
|
||||||
|
if (faceName == Font::getDefaultSerifFontName()) return "Roboto";
|
||||||
|
if (faceName == Font::getDefaultMonospacedFontName()) return "Roboto";
|
||||||
|
|
||||||
|
return faceName;
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Typeface::createSystemTypefaceFor (f);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace juce
|
} // namespace juce
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue