LibGfx: Prepare the paint code for fonts whose glyphs are color bitmaps

This patch does three things:
- Font::has_color_bitmaps() (true if CBLC and CBDT are present)
- Glyph now knows when its bitmap comes from a color bitmap font
- Painter draws color bitmap glyphs with the appropriate scaling etc
This commit is contained in:
Andreas Kling 2023-03-04 20:33:02 +01:00
parent bca35bee6d
commit e8cc1a4373
Notes: sideshowbarker 2024-07-17 04:41:05 +09:00
8 changed files with 22 additions and 2 deletions

View File

@ -137,6 +137,8 @@ private:
void update_x_height() { m_x_height = m_baseline - m_mean_line; };
virtual bool has_color_bitmaps() const override { return false; }
DeprecatedString m_name;
DeprecatedString m_family;
size_t m_glyph_count { 0 };

View File

@ -64,14 +64,17 @@ public:
{
}
Glyph(RefPtr<Bitmap> bitmap, float left_bearing, float advance, float ascent)
Glyph(RefPtr<Bitmap> bitmap, float left_bearing, float advance, float ascent, bool is_color_bitmap)
: m_bitmap(bitmap)
, m_left_bearing(left_bearing)
, m_advance(advance)
, m_ascent(ascent)
, m_color_bitmap(is_color_bitmap)
{
}
bool is_color_bitmap() const { return m_color_bitmap; }
bool is_glyph_bitmap() const { return !m_bitmap; }
GlyphBitmap glyph_bitmap() const { return m_glyph_bitmap; }
RefPtr<Bitmap> bitmap() const { return m_bitmap; }
@ -85,6 +88,7 @@ private:
float m_left_bearing;
float m_advance;
float m_ascent;
bool m_color_bitmap { false };
};
struct GlyphSubpixelOffset {
@ -207,6 +211,8 @@ public:
Font const& bold_variant() const;
virtual bool has_color_bitmaps() const = 0;
private:
mutable RefPtr<Gfx::Font const> m_bold_variant;
};

View File

@ -40,6 +40,7 @@ public:
virtual u16 width() const override;
virtual u8 slope() const override;
virtual bool is_fixed_width() const override;
virtual bool has_color_bitmaps() const override;
Optional<ReadonlyBytes> font_program() const;
Optional<ReadonlyBytes> control_value_program() const;

View File

@ -88,7 +88,7 @@ Gfx::Glyph ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset
auto id = glyph_id_for_code_point(code_point);
auto bitmap = rasterize_glyph(id, subpixel_offset);
auto metrics = glyph_metrics(id);
return Gfx::Glyph(bitmap, metrics.left_side_bearing, metrics.advance_width, metrics.ascender);
return Gfx::Glyph(bitmap, metrics.left_side_bearing, metrics.advance_width, metrics.ascender, m_font->has_color_bitmaps());
}
float ScaledFont::glyph_left_bearing(u32 code_point) const

View File

@ -71,6 +71,8 @@ public:
virtual RefPtr<Font> with_size(float point_size) const override;
virtual bool has_color_bitmaps() const override { return m_font->has_color_bitmaps(); }
private:
NonnullRefPtr<VectorFont> m_font;
float m_x_scale { 0.0f };

View File

@ -47,6 +47,7 @@ public:
virtual u16 width() const = 0;
virtual u8 slope() const = 0;
virtual bool is_fixed_width() const = 0;
virtual bool has_color_bitmaps() const = 0;
};
}

View File

@ -37,6 +37,7 @@ public:
virtual u16 width() const override { return m_input_font->width(); }
virtual u8 slope() const override { return m_input_font->slope(); }
virtual bool is_fixed_width() const override { return m_input_font->is_fixed_width(); }
virtual bool has_color_bitmaps() const override { return m_input_font->has_color_bitmaps(); }
private:
Font(NonnullRefPtr<Gfx::VectorFont const> input_font, ByteBuffer input_font_buffer)

View File

@ -1369,6 +1369,13 @@ FLATTEN void Painter::draw_glyph(FloatPoint point, u32 code_point, Font const& f
if (glyph.is_glyph_bitmap()) {
draw_bitmap(top_left.to_type<int>(), glyph.glyph_bitmap(), color);
} else if (glyph.is_color_bitmap()) {
float scaled_width = glyph.advance();
float ratio = static_cast<float>(glyph.bitmap()->height()) / static_cast<float>(glyph.bitmap()->width());
float scaled_height = scaled_width * ratio;
FloatRect rect(point.x(), point.y(), scaled_width, scaled_height);
draw_scaled_bitmap(rect.to_rounded<int>(), *glyph.bitmap(), glyph.bitmap()->rect(), 1.0f, ScalingMode::BilinearBlend);
} else {
blit_filtered(glyph_position.blit_position, *glyph.bitmap(), glyph.bitmap()->rect(), [color](Color pixel) -> Color {
return pixel.multiply(color);