LibPDF: Implement Type1Font::append_glyph_path()

With this, we can draw rotated type1 text.

The `glyph_width` multiplication in SimpleFont::append_text_path
corresponds to the same in SimpleFont::draw_axis_aligned_glyphs.

Type1FontProgram::append_glyph_to() uses AppendRelativeToLastPoint::Yes
like ScaledFont::append_glyph_path_to().

Type1FontProgram::append_glyph_to() is like build_char() in the same
class, except it does no subpixel translation, and it doesn't move
the origin to the top left corner.
This commit is contained in:
Nico Weber committed 2026-08-19 18:59:30 -04:00
1 parent 8dd45d8e09
commit 0ac7f5228f
4 files changed
+20 -2

No files matched your search

@@ -95,6 +95,7 @@ PDFErrorOr<Gfx::FloatPoint> SimpleFont::append_text_path(Gfx::Path& path, Gfx::F
auto const& text_rendering_matrix = renderer.calculate_text_rendering_matrix();
return for_each_glyph_position(position, string, renderer, [&](Gfx::FloatPoint glyph_position, float glyph_width, u8 char_code) {
// The glyph position is in terms of the `renderer.text_state().font_size`, so we need to scale it to the requested font size.
glyph_width *= text_rendering_matrix.x_scale() / horizontal_scaling;
return append_glyph_path(path, glyph_position.scaled(text_rendering_matrix.x_scale() / horizontal_scaling, 1), glyph_width, char_code, renderer);
});
}
@@ -149,11 +149,15 @@ PDFErrorOr<void> Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint po
return {};
}
PDFErrorOr<void> Type1Font::append_glyph_path(Gfx::Path& path, Gfx::FloatPoint point, float, u8 char_code, Renderer const& renderer)
PDFErrorOr<void> Type1Font::append_glyph_path(Gfx::Path& path, Gfx::FloatPoint point, float width, u8 char_code, Renderer const& renderer)
{
if (!m_font_program)
return m_fallback_font_painter->append_glyph_path(path, point, char_code, renderer);
return Error { Error::Type::RenderingUnsupported, "append_glyph_path not implemented for font" };
auto char_name = char_name_for_char_code(char_code);
path.move_to(point);
m_font_program->append_glyph_path_to(path, char_name, width);
return {};
}
}
@@ -71,6 +71,18 @@ RefPtr<Gfx::Bitmap> Type1FontProgram::rasterize_glyph(DeprecatedFlyString const&
return bitmap;
}
bool Type1FontProgram::append_glyph_path_to(Gfx::Path& path, DeprecatedFlyString const& char_name, float width)
{
auto maybe_glyph = m_glyph_map.get(char_name);
if (!maybe_glyph.has_value())
return false;
auto const& glyph = maybe_glyph.value();
auto transform = glyph_transform_to_device_space(glyph, width);
path.append_path(glyph.path().copy_transformed(transform), Gfx::Path::AppendRelativeToLastPoint::Yes);
return true;
}
Gfx::Path Type1FontProgram::build_char(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset)
{
auto maybe_glyph = m_glyph_map.get(char_name);
@@ -25,6 +25,7 @@ public:
};
RefPtr<Gfx::Bitmap> rasterize_glyph(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset);
bool append_glyph_path_to(Gfx::Path&, DeprecatedFlyString const& char_name, float width);
Gfx::FloatPoint glyph_translation(DeprecatedFlyString const& char_name, float width) const;
RefPtr<Encoding> encoding() const { return m_encoding; }