LibGfx+LibWeb: Allow inexact size lookups when requesting scaled fonts

For bitmap fonts, we will often not have an exact match for requested
sizes. Return the closest match instead of a nullptr.

LibWeb is currently the only user of this API. If it needs to be
configurable in the future to only allow exact matches, we can add a
parameter or another method at that time.
This commit is contained in:
Timothy Flynn 2024-05-06 13:12:16 -04:00 committed by Alexander Kalenik
commit 464d7d5858
Notes: sideshowbarker 2024-07-16 22:14:49 +09:00
12 changed files with 17 additions and 18 deletions

View file

@ -410,9 +410,12 @@ String BitmapFont::variant() const
return MUST(builder.to_string());
}
RefPtr<Font> BitmapFont::with_size(float point_size) const
NonnullRefPtr<Font> BitmapFont::with_size(float point_size) const
{
return Gfx::FontDatabase::the().get(family(), point_size, weight(), width(), slope());
auto scaled_font = Gfx::FontDatabase::the().get(family(), point_size, weight(), width(), slope(), AllowInexactSizeMatch::Yes);
VERIFY(scaled_font); // The inexact lookup should, at the very least, return `this` font.
return *scaled_font;
}
Font const& Font::bold_variant() const

View file

@ -130,7 +130,7 @@ public:
virtual String qualified_name() const override;
virtual String human_readable_name() const override { return MUST(String::formatted("{} {} {}", family(), variant(), presentation_size())); }
virtual RefPtr<Font> with_size(float point_size) const override;
virtual NonnullRefPtr<Font> with_size(float point_size) const override;
private:
BitmapFont(String name, String family, Bytes rows, Span<u8> widths, bool is_fixed_width,

View file

@ -212,7 +212,7 @@ public:
virtual String qualified_name() const = 0;
virtual String human_readable_name() const = 0;
virtual RefPtr<Font> with_size(float point_size) const = 0;
virtual NonnullRefPtr<Font> with_size(float point_size) const = 0;
Font const& bold_variant() const;

View file

@ -159,7 +159,7 @@ NonnullRefPtr<ScaledFont> ScaledFont::scaled_with_size(float point_size) const
return m_font->scaled_font(point_size);
}
RefPtr<Font> ScaledFont::with_size(float point_size) const
NonnullRefPtr<Font> ScaledFont::with_size(float point_size) const
{
return scaled_with_size(point_size);
}

View file

@ -70,7 +70,7 @@ public:
virtual String human_readable_name() const override { return MUST(String::formatted("{} {} {}", family(), variant(), presentation_size())); }
virtual NonnullRefPtr<ScaledFont> scaled_with_size(float point_size) const;
virtual RefPtr<Font> with_size(float point_size) const override;
virtual NonnullRefPtr<Font> with_size(float point_size) const override;
virtual bool has_color_bitmaps() const override { return m_font->has_color_bitmaps(); }

View file

@ -2089,11 +2089,7 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::compute_font_for_style_values(
}
auto found_font = StyleProperties::font_fallback(monospace, bold);
if (auto scaled_fallback_font = found_font->with_size(font_size_in_pt)) {
font_list->add(*scaled_fallback_font);
} else {
font_list->add(*found_font);
}
font_list->add(found_font->with_size(font_size_in_pt));
return font_list;
}

View file

@ -272,7 +272,7 @@ inline Gfx::Font const& Node::scaled_font(PaintContext& context) const
inline Gfx::Font const& Node::scaled_font(float scale_factor) const
{
auto const& font = first_available_font();
return *font.with_size(font.point_size() * scale_factor);
return font.with_size(font.point_size() * scale_factor);
}
inline const CSS::ImmutableComputedValues& Node::computed_values() const

View file

@ -66,7 +66,7 @@ static Vector<Gfx::Path> compute_text_clip_paths(PaintContext& context, Paintabl
Gfx::Path glyph_run_path;
for (auto glyph : fragment.glyph_run().glyphs()) {
glyph.visit([&](auto& glyph) {
glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast<float>(context.device_pixels_per_css_pixel()));
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(context.device_pixels_per_css_pixel()));
glyph.position = glyph.position.scaled(context.device_pixels_per_css_pixel());
});

View file

@ -31,7 +31,7 @@ CommandResult CommandExecutorCPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> c
auto transformed_glyph = glyph_or_emoji;
transformed_glyph.visit([&](auto& glyph) {
glyph.position = glyph.position.scaled(scale).translated(translation);
glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
});
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
auto& glyph = transformed_glyph.get<Gfx::DrawGlyph>();

View file

@ -39,7 +39,7 @@ CommandResult CommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> c
auto transformed_glyph = glyph;
transformed_glyph.visit([&](auto& glyph) {
glyph.position = glyph.position.scaled(scale).translated(translation);
glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
});
transformed_glyph_run.append(transformed_glyph);
}

View file

@ -89,8 +89,8 @@ void CommandList::execute(CommandExecutor& executor)
for (auto const& glyph_or_emoji : command.get<DrawGlyphRun>().glyph_run->glyphs()) {
if (glyph_or_emoji.has<Gfx::DrawGlyph>()) {
auto const& glyph = glyph_or_emoji.get<Gfx::DrawGlyph>();
auto const& font = *glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
unique_glyphs.ensure(&font, [] { return HashTable<u32> {}; }).set(glyph.code_point);
auto font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(scale));
unique_glyphs.ensure(font, [] { return HashTable<u32> {}; }).set(glyph.code_point);
}
}
}

View file

@ -593,7 +593,7 @@ void paint_text_shadow(PaintContext& context, PaintableFragment const& fragment,
scaled_glyph_run.ensure_capacity(fragment.glyph_run().glyphs().size());
for (auto glyph : fragment.glyph_run().glyphs()) {
glyph.visit([&](auto& glyph) {
glyph.font = *glyph.font->with_size(glyph.font->point_size() * static_cast<float>(context.device_pixels_per_css_pixel()));
glyph.font = glyph.font->with_size(glyph.font->point_size() * static_cast<float>(context.device_pixels_per_css_pixel()));
glyph.position = glyph.position.scaled(context.device_pixels_per_css_pixel());
});
scaled_glyph_run.append(move(glyph));