diff options
author | Rodrigo Tobar <rtobar@icrar.org> | 2022-11-21 13:32:09 +0800 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-11-30 14:51:14 +0100 |
commit | cb3e05f47638a4432f13cfe3103952c0afba3910 (patch) | |
tree | 34a0a1fb68700b23174aec71d21c458d0c1fb674 /Userland/Libraries/LibPDF | |
parent | b3007c17bd28c47c4564d8a6e3a2110b1ab945f9 (diff) | |
download | serenity-cb3e05f47638a4432f13cfe3103952c0afba3910.zip |
LibPDF: Add initial implementation of XObject rendering
This implementation currently handles Form XObjects only, skipping
image XObjects. When rendering an XObject, its resources are passed to
the underlying operations so they use those instead of the Page's.
Diffstat (limited to 'Userland/Libraries/LibPDF')
-rw-r--r-- | Userland/Libraries/LibPDF/Renderer.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index 4a1e9412ed..8eb8edab1f 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -620,7 +620,38 @@ RENDERER_TODO(shade) RENDERER_TODO(inline_image_begin) RENDERER_TODO(inline_image_begin_data) RENDERER_TODO(inline_image_end) -RENDERER_TODO(paint_xobject) +RENDERER_HANDLER(paint_xobject) +{ + VERIFY(args.size() > 0); + auto resources = extra_resources.value_or(m_page.resources); + auto xobject_name = args[0].get<NonnullRefPtr<Object>>()->cast<NameObject>()->name(); + auto xobjects_dict = MUST(resources->get_dict(m_document, CommonNames::XObject)); + auto xobject = MUST(xobjects_dict->get_stream(m_document, xobject_name)); + + auto subtype = MUST(xobject->dict()->get_name(m_document, CommonNames::Subtype))->name(); + if (subtype == CommonNames::Image) { + dbgln("Skipping image"); + return {}; + } + + MUST(handle_save_state({})); + Vector<Value> matrix; + if (xobject->dict()->contains(CommonNames::Matrix)) { + matrix = xobject->dict()->get_array(m_document, CommonNames::Matrix).value()->elements(); + } else { + matrix = Vector { Value { 1 }, Value { 0 }, Value { 0 }, Value { 1 }, Value { 0 }, Value { 0 } }; + } + MUST(handle_concatenate_matrix(matrix)); + Optional<NonnullRefPtr<DictObject>> xobject_resources {}; + if (xobject->dict()->contains(CommonNames::Resources)) { + xobject_resources = xobject->dict()->get_dict(m_document, CommonNames::Resources).value(); + } + auto operators = TRY(Parser::parse_operators(m_document, xobject->bytes())); + for (auto& op : operators) + TRY(handle_operator(op, xobject_resources)); + MUST(handle_restore_state({})); + return {}; +} RENDERER_HANDLER(marked_content_point) { |