瀏覽代碼

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
Andreas Kling 2 年之前
父節點
當前提交
e8cc1a4373

+ 2 - 0
Userland/Libraries/LibGfx/Font/BitmapFont.h

@@ -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 };

+ 7 - 1
Userland/Libraries/LibGfx/Font/Font.h

@@ -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;
 };

+ 1 - 0
Userland/Libraries/LibGfx/Font/OpenType/Font.h

@@ -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;

+ 1 - 1
Userland/Libraries/LibGfx/Font/ScaledFont.cpp

@@ -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

+ 2 - 0
Userland/Libraries/LibGfx/Font/ScaledFont.h

@@ -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 };

+ 1 - 0
Userland/Libraries/LibGfx/Font/VectorFont.h

@@ -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;
 };
 
 }

+ 1 - 0
Userland/Libraries/LibGfx/Font/WOFF/Font.h

@@ -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)

+ 7 - 0
Userland/Libraries/LibGfx/Painter.cpp

@@ -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);