1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 13:47:16 +00:00

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.
This commit is contained in:
Rodrigo Tobar 2023-02-05 14:18:38 +08:00 committed by Andreas Kling
parent c084943457
commit 11a9bfd4b6
3 changed files with 27 additions and 18 deletions

View File

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

View File

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

View File

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