summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF
diff options
context:
space:
mode:
authorRodrigo Tobar <rtobar@icrar.org>2022-11-21 13:32:09 +0800
committerAndreas Kling <kling@serenityos.org>2022-11-30 14:51:14 +0100
commitcb3e05f47638a4432f13cfe3103952c0afba3910 (patch)
tree34a0a1fb68700b23174aec71d21c458d0c1fb674 /Userland/Libraries/LibPDF
parentb3007c17bd28c47c4564d8a6e3a2110b1ab945f9 (diff)
downloadserenity-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.cpp33
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)
{