From f646e47d4624260d8583ddd5c349d58250399d98 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 16 Oct 2023 21:18:01 -0400 Subject: [PATCH] LibPDF: Extract a create_destination_from_object() function No big behavior change. The new function now produces an error if a destination isn't in one of the supported formats. --- Userland/Libraries/LibPDF/Document.cpp | 56 +++++++++++++++----------- Userland/Libraries/LibPDF/Document.h | 1 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Userland/Libraries/LibPDF/Document.cpp b/Userland/Libraries/LibPDF/Document.cpp index d5b3c671df..1c2402780a 100644 --- a/Userland/Libraries/LibPDF/Document.cpp +++ b/Userland/Libraries/LibPDF/Document.cpp @@ -487,6 +487,37 @@ PDFErrorOr Document::create_destination_from_dictionary_entry(Nonnu return create_destination_from_parameters(d_array, page_number_by_index_ref); } +PDFErrorOr Document::create_destination_from_object(NonnullRefPtr const& dest_obj, HashMap const& page_number_by_index_ref) +{ + // PDF 1.7 spec, "8.2.1 Destinations" + if (dest_obj->is()) { + auto dest_arr = dest_obj->cast(); + return TRY(create_destination_from_parameters(dest_arr, page_number_by_index_ref)); + } + + if (dest_obj->is() || dest_obj->is()) { + DeprecatedFlyString dest_name; + if (dest_obj->is()) + dest_name = dest_obj->cast()->name(); + else + dest_name = dest_obj->cast()->string(); + if (auto dests_value = m_catalog->get(CommonNames::Dests); dests_value.has_value()) { + auto dests = dests_value.value().get>()->cast(); + auto entry = MUST(dests->get_object(this, dest_name)); + return TRY(create_destination_from_dictionary_entry(entry, page_number_by_index_ref)); + } + if (auto names_value = m_catalog->get(CommonNames::Names); names_value.has_value()) { + auto names = TRY(resolve(names_value.release_value())).get>()->cast(); + if (!names->contains(CommonNames::Dests)) + return Error { Error::Type::MalformedPDF, "Missing Dests key in document catalogue's Names dictionary" }; + auto dest_obj = TRY(find_in_name_tree(TRY(names->get_dict(this, CommonNames::Dests)), dest_name)); + return TRY(create_destination_from_dictionary_entry(dest_obj, page_number_by_index_ref)); + } + } + + return Error { Error::Type::MalformedPDF, "Malformed outline destination" }; +} + PDFErrorOr> Document::build_outline_item(NonnullRefPtr const& outline_item_dict, HashMap const& page_number_by_index_ref) { auto outline_item = adopt_ref(*new OutlineItem {}); @@ -508,30 +539,7 @@ PDFErrorOr> Document::build_outline_item(NonnullRefPt if (outline_item_dict->contains(CommonNames::Dest)) { auto dest_obj = TRY(outline_item_dict->get_object(this, CommonNames::Dest)); - - if (dest_obj->is()) { - auto dest_arr = dest_obj->cast(); - outline_item->dest = TRY(create_destination_from_parameters(dest_arr, page_number_by_index_ref)); - } else if (dest_obj->is() || dest_obj->is()) { - DeprecatedFlyString dest_name; - if (dest_obj->is()) - dest_name = dest_obj->cast()->name(); - else - dest_name = dest_obj->cast()->string(); - if (auto dests_value = m_catalog->get(CommonNames::Dests); dests_value.has_value()) { - auto dests = dests_value.value().get>()->cast(); - auto entry = MUST(dests->get_object(this, dest_name)); - outline_item->dest = TRY(create_destination_from_dictionary_entry(entry, page_number_by_index_ref)); - } else if (auto names_value = m_catalog->get(CommonNames::Names); names_value.has_value()) { - auto names = TRY(resolve(names_value.release_value())).get>()->cast(); - if (!names->contains(CommonNames::Dests)) - return Error { Error::Type::MalformedPDF, "Missing Dests key in document catalogue's Names dictionary" }; - auto dest_obj = TRY(find_in_name_tree(TRY(names->get_dict(this, CommonNames::Dests)), dest_name)); - outline_item->dest = TRY(create_destination_from_dictionary_entry(dest_obj, page_number_by_index_ref)); - } else { - return Error { Error::Type::MalformedPDF, "Malformed outline destination" }; - } - } + outline_item->dest = TRY(create_destination_from_object(dest_obj, page_number_by_index_ref)); } if (outline_item_dict->contains(CommonNames::C)) { diff --git a/Userland/Libraries/LibPDF/Document.h b/Userland/Libraries/LibPDF/Document.h index 0c6c7298b4..3328e40f49 100644 --- a/Userland/Libraries/LibPDF/Document.h +++ b/Userland/Libraries/LibPDF/Document.h @@ -166,6 +166,7 @@ private: PDFErrorOr create_destination_from_parameters(NonnullRefPtr, HashMap const&); PDFErrorOr create_destination_from_dictionary_entry(NonnullRefPtr const& entry, HashMap const& page_number_by_index_ref); + PDFErrorOr create_destination_from_object(NonnullRefPtr const& dest_obj, HashMap const& page_number_by_index_ref); PDFErrorOr>> get_inheritable_object(DeprecatedFlyString const& name, NonnullRefPtr); PDFErrorOr> get_inheritable_value(DeprecatedFlyString const& name, NonnullRefPtr);