Kaynağa Gözat

LibPDF: Turn Glyph into a class

Glyph was a simple structure, but even now it's become more complex that
it was initially. Turning it into a class hides some of that complexity,
and make sit easier to understand to external eyes.

While doing this I also decided to remove the float + bool combo for
keeping track of the glyph's width, and replaced it with an Optional
instead.
Rodrigo Tobar 2 yıl önce
ebeveyn
işleme
11a9bfd4b6

+ 3 - 3
Userland/Libraries/LibPDF/Fonts/CFF.cpp

@@ -102,10 +102,10 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
 
     // Adjust glyphs' widths as they are deltas from nominalWidthX
     for (auto& glyph : glyphs) {
-        if (!glyph.width_specified)
-            glyph.width = float(defaultWidthX);
+        if (!glyph.has_width())
+            glyph.set_width(float(defaultWidthX));
         else
-            glyph.width += float(nominalWidthX);
+            glyph.set_width(glyph.width() + float(nominalWidthX));
     }
 
     for (size_t i = 0; i < glyphs.size(); i++) {

+ 8 - 11
Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp

@@ -71,17 +71,16 @@ Gfx::Path Type1FontProgram::build_char(DeprecatedFlyString const& char_name, flo
     if (!maybe_glyph.has_value())
         return {};
 
-    auto& glyph = maybe_glyph.value();
+    auto const& glyph = maybe_glyph.value();
     auto transform = Gfx::AffineTransform()
                          .translate(subpixel_offset.to_float_point())
                          .multiply(glyph_transform_to_device_space(glyph, width));
 
     // Translate such that the top-left point is at [0, 0].
-    auto bounding_box = glyph.path.bounding_box();
+    auto bounding_box = glyph.path().bounding_box();
     Gfx::FloatPoint translation(-bounding_box.x(), -(bounding_box.y() + bounding_box.height()));
     transform.translate(translation);
-
-    return glyph.path.copy_transformed(transform);
+    return glyph.path().copy_transformed(transform);
 }
 
 Gfx::FloatPoint Type1FontProgram::glyph_translation(DeprecatedFlyString const& char_name, float width) const
@@ -94,7 +93,7 @@ Gfx::FloatPoint Type1FontProgram::glyph_translation(DeprecatedFlyString const& c
     auto transform = glyph_transform_to_device_space(glyph, width);
 
     // Undo the translation we applied earlier.
-    auto bounding_box = glyph.path.bounding_box();
+    auto bounding_box = glyph.path().bounding_box();
     Gfx::FloatPoint translation(bounding_box.x(), bounding_box.y() + bounding_box.height());
 
     return transform.map(translation);
@@ -102,7 +101,7 @@ Gfx::FloatPoint Type1FontProgram::glyph_translation(DeprecatedFlyString const& c
 
 Gfx::AffineTransform Type1FontProgram::glyph_transform_to_device_space(Glyph const& glyph, float width) const
 {
-    auto scale = width / (m_font_matrix.a() * glyph.width + m_font_matrix.e());
+    auto scale = width / (m_font_matrix.a() * glyph.width() + m_font_matrix.e());
     auto transform = m_font_matrix;
 
     // Convert character space to device space.
@@ -132,7 +131,7 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
         return value;
     };
 
-    auto& path = state.glyph.path;
+    auto& path = state.glyph.path();
     auto& point = state.point;
 
     // Core operations: move to, line to, curve to
@@ -214,8 +213,7 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
     auto maybe_read_width = [&](EvenOrOdd required_argument_count) {
         if (!is_type2 || !is_first_command || state.sp % 2 != required_argument_count)
             return;
-        state.glyph.width = pop_front();
-        state.glyph.width_specified = true;
+        state.glyph.set_width(pop_front());
     };
 
     // Parse the stream of parameters and commands that make up a glyph outline.
@@ -434,8 +432,7 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
                 auto wx = pop();
                 auto sbx = pop();
 
-                state.glyph.width = wx;
-                state.glyph.width_specified = true;
+                state.glyph.set_width(wx);
                 state.point = { sbx, 0.0f };
                 state.sp = 0;
                 break;

+ 16 - 4
Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h

@@ -25,10 +25,22 @@ public:
     RefPtr<Encoding> encoding() const { return m_encoding; }
 
 protected:
-    struct Glyph {
-        Gfx::Path path;
-        float width { 0 };
-        bool width_specified { false };
+    class Glyph {
+
+    public:
+        bool has_width() const { return m_width.has_value(); }
+        float width() const { return m_width.value(); }
+        void set_width(float width)
+        {
+            m_width = width;
+        }
+
+        Gfx::Path& path() { return m_path; }
+        Gfx::Path const& path() const { return m_path; }
+
+    private:
+        Gfx::Path m_path;
+        Optional<float> m_width;
     };
 
     struct GlyphParserState {