LibGfx: Add Font::AllowInexactSizeMatch parameter to font lookup

This allows bitmap font lookup to return the best matching size instead
of failing completely. The previous behavior (exact matches only)
remains the default.
This commit is contained in:
Andreas Kling 2022-02-25 13:30:08 +01:00
parent 95715f0c8f
commit 4dd9e2df78
Notes: sideshowbarker 2024-07-17 18:17:03 +09:00
5 changed files with 28 additions and 8 deletions

View file

@ -95,6 +95,11 @@ struct FontMetrics {
class Font : public RefCounted<Font> {
public:
enum class AllowInexactSizeMatch {
No,
Yes,
};
virtual NonnullRefPtr<Font> clone() const = 0;
virtual ~Font() {};

View file

@ -164,20 +164,20 @@ RefPtr<Gfx::Font> FontDatabase::get_by_name(StringView name)
return it->value;
}
RefPtr<Gfx::Font> FontDatabase::get(const String& family, unsigned size, unsigned weight, unsigned slope)
RefPtr<Gfx::Font> FontDatabase::get(String const& family, unsigned size, unsigned weight, unsigned slope, Font::AllowInexactSizeMatch allow_inexact_size_match)
{
for (auto typeface : m_private->typefaces) {
if (typeface->family() == family && typeface->weight() == weight && typeface->slope() == slope)
return typeface->get_font(size);
return typeface->get_font(size, allow_inexact_size_match);
}
return nullptr;
}
RefPtr<Gfx::Font> FontDatabase::get(const String& family, const String& variant, unsigned size)
RefPtr<Gfx::Font> FontDatabase::get(String const& family, const String& variant, unsigned size, Font::AllowInexactSizeMatch allow_inexact_size_match)
{
for (auto typeface : m_private->typefaces) {
if (typeface->family() == family && typeface->variant() == variant)
return typeface->get_font(size);
return typeface->get_font(size, allow_inexact_size_match);
}
return nullptr;
}

View file

@ -44,8 +44,8 @@ public:
static void set_fixed_width_font_query(String);
static void set_default_fonts_lookup_path(String);
RefPtr<Gfx::Font> get(const String& family, unsigned size, unsigned weight, unsigned slope);
RefPtr<Gfx::Font> get(const String& family, const String& variant, unsigned size);
RefPtr<Gfx::Font> get(const String& family, unsigned size, unsigned weight, unsigned slope, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No);
RefPtr<Gfx::Font> get(const String& family, const String& variant, unsigned size, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No);
RefPtr<Gfx::Font> get_by_name(StringView);
void for_each_font(Function<void(const Gfx::Font&)>);
void for_each_fixed_width_font(Function<void(const Gfx::Font&)>);

View file

@ -48,13 +48,28 @@ void Typeface::set_ttf_font(RefPtr<TTF::Font> font)
m_ttf_font = move(font);
}
RefPtr<Font> Typeface::get_font(unsigned size) const
RefPtr<Font> Typeface::get_font(unsigned size, Font::AllowInexactSizeMatch allow_inexact_size_match) const
{
VERIFY(size < NumericLimits<int>::max());
RefPtr<BitmapFont> best_match;
int best_delta = NumericLimits<int>::max();
for (auto font : m_bitmap_fonts) {
if (font->presentation_size() == size)
return font;
if (allow_inexact_size_match == Font::AllowInexactSizeMatch::Yes) {
int delta = static_cast<int>(font->presentation_size()) - static_cast<int>(size);
if (abs(delta) < best_delta) {
best_match = font;
best_delta = abs(delta);
}
}
}
if (allow_inexact_size_match == Font::AllowInexactSizeMatch::Yes && best_match)
return best_match;
if (m_ttf_font)
return adopt_ref(*new TTF::ScaledFont(*m_ttf_font, size, size));

View file

@ -36,7 +36,7 @@ public:
void add_bitmap_font(RefPtr<BitmapFont>);
void set_ttf_font(RefPtr<TTF::Font>);
RefPtr<Font> get_font(unsigned size) const;
RefPtr<Font> get_font(unsigned size, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No) const;
private:
String m_family;