소스 검색

LibPDF: Use subpixel accurate text rendering

This just enables the new tricks from LibGfx with the same nice
improvements :^)
MacDue 2 년 전
부모
커밋
91db49f7b3

+ 1 - 1
Userland/Libraries/LibPDF/Fonts/PDFFont.h

@@ -41,7 +41,7 @@ public:
     virtual u32 char_code_to_code_point(u16 char_code) const = 0;
     virtual float get_char_width(u16 char_code) const = 0;
 
-    virtual void draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color) = 0;
+    virtual void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color) = 0;
 
     virtual bool is_standard_font() const { return m_is_standard_font; }
     virtual Type type() const = 0;

+ 4 - 3
Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp

@@ -94,15 +94,16 @@ PDFErrorOr<void> PS1FontProgram::create(ReadonlyBytes const& bytes, RefPtr<Encod
     return parse_encrypted_portion(decrypted);
 }
 
-RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width)
+RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset)
 {
     auto path = build_char(char_code, width);
     auto bounding_box = path.bounding_box().size();
 
-    u32 w = (u32)ceilf(bounding_box.width()) + 1;
-    u32 h = (u32)ceilf(bounding_box.height()) + 1;
+    u32 w = (u32)ceilf(bounding_box.width()) + 2;
+    u32 h = (u32)ceilf(bounding_box.height()) + 2;
 
     Gfx::PathRasterizer rasterizer(Gfx::IntSize(w, h));
+    rasterizer.translate(subpixel_offset.to_float_point());
     rasterizer.draw_path(path);
     return rasterizer.accumulate();
 }

+ 2 - 1
Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h

@@ -8,6 +8,7 @@
 
 #include <AK/Forward.h>
 #include <LibGfx/AffineTransform.h>
+#include <LibGfx/Font/Font.h>
 #include <LibGfx/Path.h>
 #include <LibPDF/Error.h>
 
@@ -20,7 +21,7 @@ class PS1FontProgram : public RefCounted<PS1FontProgram> {
 public:
     PDFErrorOr<void> create(ReadonlyBytes const&, RefPtr<Encoding>, size_t cleartext_length, size_t encrypted_length);
 
-    RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width);
+    RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset);
     Gfx::Path build_char(u32 char_code, float width);
 
     RefPtr<Encoding> encoding() const { return m_encoding; }

+ 1 - 1
Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp

@@ -68,7 +68,7 @@ float TrueTypeFont::get_char_width(u16 char_code) const
     return static_cast<float>(width) / 1000.0f;
 }
 
-void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float, u32 char_code, Color color)
+void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u32 char_code, Color color)
 {
     if (!m_data.font)
         return;

+ 1 - 1
Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h

@@ -24,7 +24,7 @@ public:
     u32 char_code_to_code_point(u16 char_code) const override;
     float get_char_width(u16 char_code) const override;
 
-    void draw_glyph(Gfx::Painter&, Gfx::IntPoint, float, u32, Color) override;
+    void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u32, Color) override;
 
     Type type() const override { return PDFFont::Type::TrueType; }
 

+ 1 - 1
Userland/Libraries/LibPDF/Fonts/Type0Font.h

@@ -27,7 +27,7 @@ public:
     u32 char_code_to_code_point(u16 char_code) const override;
     float get_char_width(u16 char_code) const override;
 
-    void draw_glyph(Gfx::Painter&, Gfx::IntPoint, float, u32, Color) override {};
+    void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u32, Color) override {};
 
     Type type() const override { return PDFFont::Type::Type0; }
 

+ 10 - 7
Userland/Libraries/LibPDF/Fonts/Type1Font.cpp

@@ -76,23 +76,26 @@ float Type1Font::get_char_width(u16 char_code) const
     return static_cast<float>(width) / 1000.0f;
 }
 
-void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color)
+void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color)
 {
     if (!m_data.font_program)
         return;
+    auto translation = m_data.font_program->glyph_translation(char_code, width);
+    point = point.translated(translation);
 
-    RefPtr<Gfx::Bitmap> bitmap;
+    auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(point);
+    Gfx::GlyphIndexWithSubpixelOffset index { char_code, glyph_position.subpixel_offset };
 
-    auto maybe_bitmap = m_glyph_cache.get(char_code);
+    RefPtr<Gfx::Bitmap> bitmap;
+    auto maybe_bitmap = m_glyph_cache.get(index);
     if (maybe_bitmap.has_value()) {
         bitmap = maybe_bitmap.value();
     } else {
-        bitmap = m_data.font_program->rasterize_glyph(char_code, width);
-        m_glyph_cache.set(char_code, bitmap);
+        bitmap = m_data.font_program->rasterize_glyph(char_code, width, glyph_position.subpixel_offset);
+        m_glyph_cache.set(index, bitmap);
     }
 
-    auto translation = m_data.font_program->glyph_translation(char_code, width);
-    painter.blit_filtered(point.translated(translation.to_rounded<int>()), *bitmap, bitmap->rect(), [color](Color pixel) -> Color {
+    painter.blit_filtered(glyph_position.blit_position, *bitmap, bitmap->rect(), [color](Color pixel) -> Color {
         return pixel.multiply(color);
     });
 }

+ 3 - 2
Userland/Libraries/LibPDF/Fonts/Type1Font.h

@@ -6,6 +6,7 @@
 
 #pragma once
 
+#include <LibGfx/Font/ScaledFont.h>
 #include <LibPDF/Fonts/PDFFont.h>
 #include <LibPDF/Fonts/PS1FontProgram.h>
 
@@ -27,13 +28,13 @@ public:
     u32 char_code_to_code_point(u16 char_code) const override;
     float get_char_width(u16 char_code) const override;
 
-    void draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color) override;
+    void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color) override;
 
     Type type() const override { return PDFFont::Type::Type1; }
 
 private:
     Data m_data;
-    HashMap<u32, RefPtr<Gfx::Bitmap>> m_glyph_cache;
+    HashMap<Gfx::GlyphIndexWithSubpixelOffset, RefPtr<Gfx::Bitmap>> m_glyph_cache;
 };
 
 }

+ 1 - 1
Userland/Libraries/LibPDF/Renderer.cpp

@@ -747,7 +747,7 @@ void Renderer::show_text(DeprecatedString const& string)
         auto glyph_width = char_width * font_size;
 
         if (code_point != 0x20)
-            text_state().font->draw_glyph(m_painter, glyph_position.to_type<int>(), glyph_width, char_code, state().paint_color);
+            text_state().font->draw_glyph(m_painter, glyph_position, glyph_width, char_code, state().paint_color);
 
         auto tx = glyph_width;
         tx += text_state().character_spacing;