diff --git a/Userland/Libraries/LibPDF/Document.cpp b/Userland/Libraries/LibPDF/Document.cpp index acc43ef192..6097122ffc 100644 --- a/Userland/Libraries/LibPDF/Document.cpp +++ b/Userland/Libraries/LibPDF/Document.cpp @@ -315,6 +315,17 @@ PDFErrorOr> Document::get_inheritable_object(FlyString con return object->get_object(this, name); } +PDFErrorOr Document::create_destination_from_dictionary_entry(NonnullRefPtr const& entry, HashMap const& page_number_by_index_ref) +{ + if (entry->is()) { + auto entry_array = entry->cast(); + return create_destination_from_parameters(entry_array, page_number_by_index_ref); + } + auto entry_dictionary = entry->cast(); + auto d_array = MUST(entry_dictionary->get_array(this, CommonNames::D)); + return create_destination_from_parameters(d_array, page_number_by_index_ref); +} + PDFErrorOr> Document::build_outline_item(NonnullRefPtr const& outline_item_dict, HashMap const& page_number_by_index_ref) { auto outline_item = adopt_ref(*new OutlineItem {}); @@ -340,19 +351,22 @@ PDFErrorOr> Document::build_outline_item(NonnullRefPt 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()) { - auto dest_name = dest_obj->cast()->name(); + } else if (dest_obj->is() || dest_obj->is()) { + FlyString 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)); - if (entry->is()) { - auto entry_array = entry->cast(); - outline_item->dest = TRY(create_destination_from_parameters(entry_array, page_number_by_index_ref)); - } else { - auto entry_dictionary = entry->cast(); - auto d_array = MUST(entry_dictionary->get_array(this, CommonNames::D)); - outline_item->dest = TRY(create_destination_from_parameters(d_array, page_number_by_index_ref)); - } + 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" }; } diff --git a/Userland/Libraries/LibPDF/Document.h b/Userland/Libraries/LibPDF/Document.h index 3b183ceab9..2074af9455 100644 --- a/Userland/Libraries/LibPDF/Document.h +++ b/Userland/Libraries/LibPDF/Document.h @@ -136,6 +136,7 @@ private: PDFErrorOr> build_outline_item_chain(Value const& first_ref, HashMap const&); 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> get_inheritable_object(FlyString const& name, NonnullRefPtr);