mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:27:35 +00:00
LibPDF: Add an initial implementation of type 3 glyph rendering
This is a very inefficient implementation: Every time a type 3 font glyph is drawn, we parse its operator stream and execute all the operators therein. We'll want to instead cache the glyphs in bitmaps (at least in most cases), like we do for other fonts. But it's a good first step, and all the coordinate math seems to work in the files I've tested. Good test files from pdfa dataset 0000.zip: - 0000559.pdf page 1 (and 2): Has a non-default font matrix; text appears mirrored if the font matrix isn't handled correctly - 0000425.pdf, page 1: Draws several glyphs in a single run; glyphs overlap if Renderer::render_type3_glyph() ignores the passed-in point - 0000211.pdf, any page: Uses type 3 glyphs for all text. Good perf test (already "reasonably fast") - 0000521.pdf, page 5 (or 7 or or 16): The little red flag in the purple box is a type 3 font glyph, and it's colored (which in part means the first operator is `d0`, while all the other documents above use `d1`)
This commit is contained in:
parent
14ddab5519
commit
29396415d5
3 changed files with 26 additions and 4 deletions
|
@ -1008,4 +1008,21 @@ Gfx::AffineTransform const& Renderer::calculate_text_rendering_matrix() const
|
|||
return m_text_rendering_matrix;
|
||||
}
|
||||
|
||||
PDFErrorOr<void> Renderer::render_type3_glyph(Gfx::FloatPoint point, StreamObject const& glyph_data, Gfx::AffineTransform const& font_matrix, Optional<NonnullRefPtr<DictObject>> resources)
|
||||
{
|
||||
ScopedState scoped_state { *this };
|
||||
|
||||
auto text_rendering_matrix = calculate_text_rendering_matrix();
|
||||
text_rendering_matrix.set_translation(point);
|
||||
state().ctm = text_rendering_matrix;
|
||||
state().ctm.scale(text_state().font_size, text_state().font_size);
|
||||
state().ctm.multiply(font_matrix);
|
||||
m_text_rendering_matrix_is_dirty = true;
|
||||
|
||||
auto operators = TRY(Parser::parse_operators(m_document, glyph_data.bytes()));
|
||||
for (auto& op : operators)
|
||||
TRY(handle_operator(op, resources));
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue