mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:47:45 +00:00
LibPDF: Make PDF version accessible on Document
This commit is contained in:
parent
9174ffd7e6
commit
ea89053c12
4 changed files with 26 additions and 15 deletions
|
@ -79,8 +79,7 @@ PDFErrorOr<NonnullRefPtr<Document>> Document::create(ReadonlyBytes bytes)
|
||||||
auto parser = adopt_ref(*new DocumentParser({}, bytes));
|
auto parser = adopt_ref(*new DocumentParser({}, bytes));
|
||||||
auto document = adopt_ref(*new Document(parser));
|
auto document = adopt_ref(*new Document(parser));
|
||||||
|
|
||||||
TRY(parser->initialize());
|
document->m_version = TRY(parser->initialize());
|
||||||
|
|
||||||
document->m_trailer = parser->trailer();
|
document->m_trailer = parser->trailer();
|
||||||
document->m_catalog = TRY(parser->trailer()->get_dict(document, CommonNames::Root));
|
document->m_catalog = TRY(parser->trailer()->get_dict(document, CommonNames::Root));
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ public:
|
||||||
// need to handle the case where the user password is the empty string.
|
// need to handle the case where the user password is the empty string.
|
||||||
PDFErrorOr<void> initialize();
|
PDFErrorOr<void> initialize();
|
||||||
|
|
||||||
|
Version version() const { return m_version; }
|
||||||
|
|
||||||
ALWAYS_INLINE RefPtr<SecurityHandler> const& security_handler() const { return m_security_handler; }
|
ALWAYS_INLINE RefPtr<SecurityHandler> const& security_handler() const { return m_security_handler; }
|
||||||
|
|
||||||
ALWAYS_INLINE RefPtr<OutlineDict> const& outline() const { return m_outline; }
|
ALWAYS_INLINE RefPtr<OutlineDict> const& outline() const { return m_outline; }
|
||||||
|
@ -188,6 +190,7 @@ private:
|
||||||
PDFErrorOr<NonnullRefPtr<Object>> find_in_key_value_array(NonnullRefPtr<ArrayObject> key_value_array, DeprecatedFlyString name);
|
PDFErrorOr<NonnullRefPtr<Object>> find_in_key_value_array(NonnullRefPtr<ArrayObject> key_value_array, DeprecatedFlyString name);
|
||||||
|
|
||||||
NonnullRefPtr<DocumentParser> m_parser;
|
NonnullRefPtr<DocumentParser> m_parser;
|
||||||
|
Version m_version;
|
||||||
RefPtr<DictObject> m_catalog;
|
RefPtr<DictObject> m_catalog;
|
||||||
RefPtr<DictObject> m_trailer;
|
RefPtr<DictObject> m_trailer;
|
||||||
Vector<u32> m_page_object_indices;
|
Vector<u32> m_page_object_indices;
|
||||||
|
|
|
@ -21,22 +21,25 @@ DocumentParser::DocumentParser(Document* document, ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<void> DocumentParser::initialize()
|
PDFErrorOr<Version> DocumentParser::initialize()
|
||||||
{
|
{
|
||||||
m_reader.set_reading_forwards();
|
m_reader.set_reading_forwards();
|
||||||
if (m_reader.remaining() == 0)
|
if (m_reader.remaining() == 0)
|
||||||
return error("Empty PDF document");
|
return error("Empty PDF document");
|
||||||
|
|
||||||
auto maybe_error = parse_header();
|
auto maybe_version = parse_header();
|
||||||
if (maybe_error.is_error()) {
|
if (maybe_version.is_error()) {
|
||||||
warnln("{}", maybe_error.error().message());
|
warnln("{}", maybe_version.error().message());
|
||||||
warnln("No valid PDF header detected, continuing anyway.");
|
warnln("No valid PDF header detected, continuing anyway.");
|
||||||
|
maybe_version = Version { 1, 6 }; // ¯\_(ツ)_/¯
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const linearization_result = TRY(initialize_linearization_dict());
|
auto const linearization_result = TRY(initialize_linearization_dict());
|
||||||
|
|
||||||
if (linearization_result == LinearizationResult::NotLinearized)
|
if (linearization_result == LinearizationResult::NotLinearized) {
|
||||||
return initialize_non_linearized_xref_table();
|
TRY(initialize_non_linearized_xref_table());
|
||||||
|
return maybe_version.value();
|
||||||
|
}
|
||||||
|
|
||||||
bool is_linearized = m_linearization_dictionary.has_value();
|
bool is_linearized = m_linearization_dictionary.has_value();
|
||||||
if (is_linearized) {
|
if (is_linearized) {
|
||||||
|
@ -53,9 +56,11 @@ PDFErrorOr<void> DocumentParser::initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_linearized)
|
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<Value> DocumentParser::parse_object_with_index(u32 index)
|
PDFErrorOr<Value> DocumentParser::parse_object_with_index(u32 index)
|
||||||
|
@ -73,9 +78,8 @@ PDFErrorOr<Value> DocumentParser::parse_object_with_index(u32 index)
|
||||||
return indirect_value->value();
|
return indirect_value->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<void> DocumentParser::parse_header()
|
PDFErrorOr<Version> DocumentParser::parse_header()
|
||||||
{
|
{
|
||||||
// FIXME: Do something with the version?
|
|
||||||
m_reader.move_to(0);
|
m_reader.move_to(0);
|
||||||
if (m_reader.remaining() < 8 || !m_reader.matches("%PDF-"))
|
if (m_reader.remaining() < 8 || !m_reader.matches("%PDF-"))
|
||||||
return error("Not a PDF document");
|
return error("Not a PDF document");
|
||||||
|
@ -106,7 +110,7 @@ PDFErrorOr<void> DocumentParser::parse_header()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return Version { major_ver - '0', minor_ver - '0' };
|
||||||
}
|
}
|
||||||
|
|
||||||
PDFErrorOr<DocumentParser::LinearizationResult> DocumentParser::initialize_linearization_dict()
|
PDFErrorOr<DocumentParser::LinearizationResult> DocumentParser::initialize_linearization_dict()
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
|
|
||||||
namespace PDF {
|
namespace PDF {
|
||||||
|
|
||||||
|
struct Version {
|
||||||
|
int major { 0 };
|
||||||
|
int minor { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
class DocumentParser final : public RefCounted<DocumentParser>
|
class DocumentParser final : public RefCounted<DocumentParser>
|
||||||
, public Parser {
|
, public Parser {
|
||||||
public:
|
public:
|
||||||
|
@ -23,7 +28,7 @@ public:
|
||||||
[[nodiscard]] ALWAYS_INLINE RefPtr<DictObject> const& trailer() const { return m_xref_table->trailer(); }
|
[[nodiscard]] ALWAYS_INLINE RefPtr<DictObject> const& trailer() const { return m_xref_table->trailer(); }
|
||||||
|
|
||||||
// Parses the header and initializes the xref table and trailer
|
// Parses the header and initializes the xref table and trailer
|
||||||
PDFErrorOr<void> initialize();
|
PDFErrorOr<Version> initialize();
|
||||||
|
|
||||||
bool can_resolve_references() { return m_xref_table; }
|
bool can_resolve_references() { return m_xref_table; }
|
||||||
|
|
||||||
|
@ -77,7 +82,7 @@ private:
|
||||||
friend struct AK::Formatter<PageOffsetHintTable>;
|
friend struct AK::Formatter<PageOffsetHintTable>;
|
||||||
friend struct AK::Formatter<PageOffsetHintTableEntry>;
|
friend struct AK::Formatter<PageOffsetHintTableEntry>;
|
||||||
|
|
||||||
PDFErrorOr<void> parse_header();
|
PDFErrorOr<Version> parse_header();
|
||||||
PDFErrorOr<LinearizationResult> initialize_linearization_dict();
|
PDFErrorOr<LinearizationResult> initialize_linearization_dict();
|
||||||
PDFErrorOr<void> initialize_linearized_xref_table();
|
PDFErrorOr<void> initialize_linearized_xref_table();
|
||||||
PDFErrorOr<void> initialize_non_linearized_xref_table();
|
PDFErrorOr<void> initialize_non_linearized_xref_table();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue