diff --git a/Userland/Libraries/LibPDF/CMakeLists.txt b/Userland/Libraries/LibPDF/CMakeLists.txt index 2862b23cf8..0f58e65b8e 100644 --- a/Userland/Libraries/LibPDF/CMakeLists.txt +++ b/Userland/Libraries/LibPDF/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES Fonts/Type1FontProgram.cpp Interpolation.cpp ObjectDerivatives.cpp + Page.cpp Parser.cpp Reader.cpp Renderer.cpp diff --git a/Userland/Libraries/LibPDF/Page.cpp b/Userland/Libraries/LibPDF/Page.cpp new file mode 100644 index 0000000000..d77b743bfe --- /dev/null +++ b/Userland/Libraries/LibPDF/Page.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-2022, Matthew Olsson + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace PDF { + +PDFErrorOr Page::page_contents(Document& document) const +{ + if (contents.is_null()) + return ByteBuffer {}; + + // Use our own vector, as the /Content can be an array with multiple + // streams which gets concatenated. + // FIXME: Text operators are supposed to only have effects on the current + // stream object. Do the text operators treat this concatenated stream + // as one stream or multiple? + ByteBuffer byte_buffer; + if (contents->is()) { + auto array = contents->cast(); + for (auto& ref : *array) { + auto bytes = TRY(document.resolve_to(ref))->bytes(); + byte_buffer.append(bytes.data(), bytes.size()); + } + } else { + auto bytes = contents->cast()->bytes(); + byte_buffer.append(bytes.data(), bytes.size()); + } + return byte_buffer; +} + +} diff --git a/Userland/Libraries/LibPDF/Page.h b/Userland/Libraries/LibPDF/Page.h index ba77f31c87..eb8d59a5cd 100644 --- a/Userland/Libraries/LibPDF/Page.h +++ b/Userland/Libraries/LibPDF/Page.h @@ -28,6 +28,8 @@ struct Page { Rectangle crop_box; float user_unit; int rotate; + + PDFErrorOr page_contents(Document&) const; }; } diff --git a/Userland/Libraries/LibPDF/Renderer.cpp b/Userland/Libraries/LibPDF/Renderer.cpp index 7d59aa61b7..26c24837ca 100644 --- a/Userland/Libraries/LibPDF/Renderer.cpp +++ b/Userland/Libraries/LibPDF/Renderer.cpp @@ -85,28 +85,7 @@ Renderer::Renderer(RefPtr document, Page const& page, RefPtr Renderer::render() { - if (m_page.contents.is_null()) - return {}; - - // Use our own vector, as the /Content can be an array with multiple - // streams which gets concatenated - // FIXME: Text operators are supposed to only have effects on the current - // stream object. Do the text operators treat this concatenated stream - // as one stream or multiple? - ByteBuffer byte_buffer; - - if (m_page.contents->is()) { - auto contents = m_page.contents->cast(); - for (auto& ref : *contents) { - auto bytes = TRY(m_document->resolve_to(ref))->bytes(); - byte_buffer.append(bytes.data(), bytes.size()); - } - } else { - auto bytes = m_page.contents->cast()->bytes(); - byte_buffer.append(bytes.data(), bytes.size()); - } - - auto operators = TRY(Parser::parse_operators(m_document, byte_buffer)); + auto operators = TRY(Parser::parse_operators(m_document, TRY(m_page.page_contents(*m_document)))); Errors errors; for (auto& op : operators) {