Sfoglia il codice sorgente

LibPDF: Pass Renderer to PDFFont::draw_string()

It's a bit unfortunate that fonts need to know about the renderer,
but type 3 fonts contain PDF drawing operators, so it's necessary.

On the bright side, it makes it possible to pass fewer parameters
around and compute things locally as needed.

(As we implement more fonts, we'll probably want to create some
functions to do these computations in a central place, eventually.)

No behavior change.
Nico Weber 1 anno fa
parent
commit
bcc6439b5f

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

@@ -14,6 +14,8 @@
 
 namespace PDF {
 
+class Renderer;
+
 class PDFFont : public RefCounted<PDFFont> {
 public:
     static PDFErrorOr<NonnullRefPtr<PDFFont>> create(Document*, NonnullRefPtr<DictObject> const&, float font_size);
@@ -21,7 +23,7 @@ public:
     virtual ~PDFFont() = default;
 
     virtual void set_font_size(float font_size) = 0;
-    virtual PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float font_size, float character_spacing, float word_spacing, float horizontal_scaling) = 0;
+    virtual PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Renderer const&) = 0;
 
 protected:
     virtual PDFErrorOr<void> initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size);

+ 11 - 1
Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp

@@ -11,6 +11,7 @@
 #include <LibPDF/Fonts/SimpleFont.h>
 #include <LibPDF/Fonts/TrueTypeFont.h>
 #include <LibPDF/Fonts/Type1Font.h>
+#include <LibPDF/Renderer.h>
 
 namespace PDF {
 
@@ -45,8 +46,17 @@ PDFErrorOr<void> SimpleFont::initialize(Document* document, NonnullRefPtr<DictOb
     return {};
 }
 
-PDFErrorOr<Gfx::FloatPoint> SimpleFont::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Color const& paint_color, float font_size, float character_spacing, float word_spacing, float horizontal_scaling)
+PDFErrorOr<Gfx::FloatPoint> SimpleFont::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Renderer const& renderer)
 {
+    Color const& paint_color = renderer.state().paint_color;
+
+    auto const& text_rendering_matrix = renderer.calculate_text_rendering_matrix();
+    auto font_size = text_rendering_matrix.x_scale() * renderer.text_state().font_size;
+
+    auto character_spacing = text_rendering_matrix.x_scale() * renderer.text_state().character_spacing;
+    auto word_spacing = text_rendering_matrix.x_scale() * renderer.text_state().word_spacing;
+    auto horizontal_scaling = renderer.text_state().horizontal_scaling;
+
     for (auto char_code : string.bytes()) {
         // Use the width specified in the font's dictionary if available,
         // and use the default width for the given font otherwise.

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

@@ -13,7 +13,7 @@ namespace PDF {
 
 class SimpleFont : public PDFFont {
 public:
-    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float font_size, float character_spacing, float word_spacing, float horizontal_scaling) override;
+    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Renderer const&) override;
 
 protected:
     PDFErrorOr<void> initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) override;

+ 7 - 7
Userland/Libraries/LibPDF/Fonts/Type0Font.cpp

@@ -13,15 +13,15 @@ namespace PDF {
 class CIDFontType {
 public:
     virtual ~CIDFontType() = default;
-    virtual PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) = 0;
+    virtual PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&) = 0;
 };
 
 class CIDFontType0 : public CIDFontType {
 public:
-    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) override;
+    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&) override;
 };
 
-PDFErrorOr<Gfx::FloatPoint> CIDFontType0::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float)
+PDFErrorOr<Gfx::FloatPoint> CIDFontType0::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&)
 {
     // ISO 32000 (PDF 2.0) 9.7.4.2 Glyph selection in CIDFonts
     // "When the CIDFont contains an embedded font program that is represented in the Compact Font Format (CFF),
@@ -39,7 +39,7 @@ class CIDFontType2 : public CIDFontType {
 public:
     static PDFErrorOr<NonnullOwnPtr<CIDFontType2>> create(Document*, NonnullRefPtr<DictObject> const& descendant, float font_size);
 
-    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) override;
+    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&) override;
 };
 
 PDFErrorOr<NonnullOwnPtr<CIDFontType2>> CIDFontType2::create(Document* document, NonnullRefPtr<DictObject> const& descendant, float font_size)
@@ -70,7 +70,7 @@ PDFErrorOr<NonnullOwnPtr<CIDFontType2>> CIDFontType2::create(Document* document,
     return TRY(adopt_nonnull_own_or_enomem(new (nothrow) CIDFontType2()));
 }
 
-PDFErrorOr<Gfx::FloatPoint> CIDFontType2::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float)
+PDFErrorOr<Gfx::FloatPoint> CIDFontType2::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&)
 {
     // ISO 32000 (PDF 2.0) 9.7.4.2 Glyph selection in CIDFonts
     // "For Type 2, the CIDFont program is actually a TrueType font program, which has no native notion of CIDs.
@@ -175,7 +175,7 @@ void Type0Font::set_font_size(float)
 {
 }
 
-PDFErrorOr<Gfx::FloatPoint> Type0Font::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Color const& paint_color, float font_size, float character_spacing, float word_spacing, float horizontal_scaling)
+PDFErrorOr<Gfx::FloatPoint> Type0Font::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Renderer const&)
 {
     // Type0 fonts map bytes to character IDs ("CIDs"), and then CIDs to glyphs.
 
@@ -196,7 +196,7 @@ PDFErrorOr<Gfx::FloatPoint> Type0Font::draw_string(Gfx::Painter& painter, Gfx::F
 
     // FIXME: Map string data to CIDs, then call m_cid_font_type with CIDs.
 
-    return m_cid_font_type->draw_string(painter, glyph_position, string, paint_color, font_size, character_spacing, word_spacing, horizontal_scaling);
+    return m_cid_font_type->draw_string(painter, glyph_position, string);
 }
 
 }

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

@@ -26,7 +26,7 @@ public:
     ~Type0Font();
 
     void set_font_size(float font_size) override;
-    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint pos, DeprecatedString const&, Color const&, float, float, float, float) override;
+    PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Renderer const&) override;
 
     DeprecatedFlyString base_font_name() const { return m_base_font_name; }
 

+ 3 - 5
Userland/Libraries/LibPDF/Renderer.cpp

@@ -802,12 +802,10 @@ PDFErrorOr<void> Renderer::show_text(DeprecatedString const& string)
     if (!text_state().font)
         return Error::rendering_unsupported_error("Can't draw text because an invalid font was in use");
 
-    auto& text_rendering_matrix = calculate_text_rendering_matrix();
-
-    auto font_size = text_rendering_matrix.x_scale() * text_state().font_size;
+    auto const& text_rendering_matrix = calculate_text_rendering_matrix();
 
     auto start_position = text_rendering_matrix.map(Gfx::FloatPoint { 0.0f, 0.0f });
-    auto end_position = TRY(text_state().font->draw_string(m_painter, start_position, string, state().paint_color, font_size, text_state().character_spacing * text_rendering_matrix.x_scale(), text_state().word_spacing * text_rendering_matrix.x_scale(), text_state().horizontal_scaling));
+    auto end_position = TRY(text_state().font->draw_string(m_painter, start_position, string, *this));
 
     // Update text matrix
     auto delta_x = end_position.x() - start_position.x();
@@ -983,7 +981,7 @@ PDFErrorOr<NonnullRefPtr<ColorSpace>> Renderer::get_color_space_from_document(No
     return ColorSpace::create(m_document, color_space_object);
 }
 
-Gfx::AffineTransform const& Renderer::calculate_text_rendering_matrix()
+Gfx::AffineTransform const& Renderer::calculate_text_rendering_matrix() const
 {
     if (m_text_rendering_matrix_is_dirty) {
         m_text_rendering_matrix = Gfx::AffineTransform(

+ 6 - 5
Userland/Libraries/LibPDF/Renderer.h

@@ -107,6 +107,10 @@ public:
         bool operator==(FontCacheKey const&) const = default;
     };
 
+    ALWAYS_INLINE GraphicsState const& state() const { return m_graphics_state_stack.last(); }
+    ALWAYS_INLINE TextState const& text_state() const { return state().text_state; }
+
+    Gfx::AffineTransform const& calculate_text_rendering_matrix() const;
 private:
     Renderer(RefPtr<Document>, Page const&, RefPtr<Gfx::Bitmap>, RenderingPreferences);
 
@@ -130,9 +134,7 @@ private:
     PDFErrorOr<NonnullRefPtr<ColorSpace>> get_color_space_from_resources(Value const&, NonnullRefPtr<DictObject>);
     PDFErrorOr<NonnullRefPtr<ColorSpace>> get_color_space_from_document(NonnullRefPtr<Object>);
 
-    ALWAYS_INLINE GraphicsState const& state() const { return m_graphics_state_stack.last(); }
     ALWAYS_INLINE GraphicsState& state() { return m_graphics_state_stack.last(); }
-    ALWAYS_INLINE TextState const& text_state() const { return state().text_state; }
     ALWAYS_INLINE TextState& text_state() { return state().text_state; }
 
     template<typename T>
@@ -144,7 +146,6 @@ private:
     template<typename T>
     ALWAYS_INLINE Gfx::Rect<T> map(Gfx::Rect<T>) const;
 
-    Gfx::AffineTransform const& calculate_text_rendering_matrix();
     Gfx::AffineTransform calculate_image_space_transformation(int width, int height);
 
     PDFErrorOr<NonnullRefPtr<PDFFont>> get_font(FontCacheKey const&);
@@ -161,8 +162,8 @@ private:
     Gfx::AffineTransform m_text_matrix;
     Gfx::AffineTransform m_text_line_matrix;
 
-    bool m_text_rendering_matrix_is_dirty { true };
-    Gfx::AffineTransform m_text_rendering_matrix;
+    bool mutable m_text_rendering_matrix_is_dirty { true };
+    Gfx::AffineTransform mutable m_text_rendering_matrix;
 
     HashMap<FontCacheKey, NonnullRefPtr<PDFFont>> m_font_cache;
 };