diff --git a/Userland/Libraries/LibPDF/Document.cpp b/Userland/Libraries/LibPDF/Document.cpp index 7a657fd885..ac5f4193b2 100644 --- a/Userland/Libraries/LibPDF/Document.cpp +++ b/Userland/Libraries/LibPDF/Document.cpp @@ -79,8 +79,7 @@ PDFErrorOr> Document::create(ReadonlyBytes bytes) auto parser = adopt_ref(*new DocumentParser({}, bytes)); auto document = adopt_ref(*new Document(parser)); - TRY(parser->initialize()); - + document->m_version = TRY(parser->initialize()); document->m_trailer = parser->trailer(); document->m_catalog = TRY(parser->trailer()->get_dict(document, CommonNames::Root)); diff --git a/Userland/Libraries/LibPDF/Document.h b/Userland/Libraries/LibPDF/Document.h index b3a6649bf4..fc56ac2999 100644 --- a/Userland/Libraries/LibPDF/Document.h +++ b/Userland/Libraries/LibPDF/Document.h @@ -122,6 +122,8 @@ public: // need to handle the case where the user password is the empty string. PDFErrorOr initialize(); + Version version() const { return m_version; } + ALWAYS_INLINE RefPtr const& security_handler() const { return m_security_handler; } ALWAYS_INLINE RefPtr const& outline() const { return m_outline; } @@ -188,6 +190,7 @@ private: PDFErrorOr> find_in_key_value_array(NonnullRefPtr key_value_array, DeprecatedFlyString name); NonnullRefPtr m_parser; + Version m_version; RefPtr m_catalog; RefPtr m_trailer; Vector m_page_object_indices; diff --git a/Userland/Libraries/LibPDF/DocumentParser.cpp b/Userland/Libraries/LibPDF/DocumentParser.cpp index 7d7f3d1f9b..47253a6b20 100644 --- a/Userland/Libraries/LibPDF/DocumentParser.cpp +++ b/Userland/Libraries/LibPDF/DocumentParser.cpp @@ -21,22 +21,25 @@ DocumentParser::DocumentParser(Document* document, ReadonlyBytes bytes) { } -PDFErrorOr DocumentParser::initialize() +PDFErrorOr DocumentParser::initialize() { m_reader.set_reading_forwards(); if (m_reader.remaining() == 0) return error("Empty PDF document"); - auto maybe_error = parse_header(); - if (maybe_error.is_error()) { - warnln("{}", maybe_error.error().message()); + auto maybe_version = parse_header(); + if (maybe_version.is_error()) { + warnln("{}", maybe_version.error().message()); warnln("No valid PDF header detected, continuing anyway."); + maybe_version = Version { 1, 6 }; // ¯\_(ツ)_/¯ } auto const linearization_result = TRY(initialize_linearization_dict()); - if (linearization_result == LinearizationResult::NotLinearized) - return initialize_non_linearized_xref_table(); + if (linearization_result == LinearizationResult::NotLinearized) { + TRY(initialize_non_linearized_xref_table()); + return maybe_version.value(); + } bool is_linearized = m_linearization_dictionary.has_value(); if (is_linearized) { @@ -53,9 +56,11 @@ PDFErrorOr DocumentParser::initialize() } if (is_linearized) - return initialize_linearized_xref_table(); + TRY(initialize_linearized_xref_table()); + else + TRY(initialize_non_linearized_xref_table()); - return initialize_non_linearized_xref_table(); + return maybe_version.value(); } PDFErrorOr DocumentParser::parse_object_with_index(u32 index) @@ -73,9 +78,8 @@ PDFErrorOr DocumentParser::parse_object_with_index(u32 index) return indirect_value->value(); } -PDFErrorOr DocumentParser::parse_header() +PDFErrorOr DocumentParser::parse_header() { - // FIXME: Do something with the version? m_reader.move_to(0); if (m_reader.remaining() < 8 || !m_reader.matches("%PDF-")) return error("Not a PDF document"); @@ -106,7 +110,7 @@ PDFErrorOr DocumentParser::parse_header() } } - return {}; + return Version { major_ver - '0', minor_ver - '0' }; } PDFErrorOr DocumentParser::initialize_linearization_dict() diff --git a/Userland/Libraries/LibPDF/DocumentParser.h b/Userland/Libraries/LibPDF/DocumentParser.h index 34839cca34..cbb127417a 100644 --- a/Userland/Libraries/LibPDF/DocumentParser.h +++ b/Userland/Libraries/LibPDF/DocumentParser.h @@ -10,6 +10,11 @@ namespace PDF { +struct Version { + int major { 0 }; + int minor { 0 }; +}; + class DocumentParser final : public RefCounted , public Parser { public: @@ -23,7 +28,7 @@ public: [[nodiscard]] ALWAYS_INLINE RefPtr const& trailer() const { return m_xref_table->trailer(); } // Parses the header and initializes the xref table and trailer - PDFErrorOr initialize(); + PDFErrorOr initialize(); bool can_resolve_references() { return m_xref_table; } @@ -77,7 +82,7 @@ private: friend struct AK::Formatter; friend struct AK::Formatter; - PDFErrorOr parse_header(); + PDFErrorOr parse_header(); PDFErrorOr initialize_linearization_dict(); PDFErrorOr initialize_linearized_xref_table(); PDFErrorOr initialize_non_linearized_xref_table();