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:
parent
c084943457
commit
11a9bfd4b6
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue
Block a user