mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:47:35 +00:00
LibPDF: Implement GoTo action for outline
Outline items can contain either a /Dest key or an /A key. The /Dest key points to a "Destination" (various ways to reference a page in the same document). The /A key points to an "Action" which can have several types. One type, the /GoTo type, just also points to a Destination. Implement GoTo actions. This makes clicking "Contents" in the outline of https://developer.apple.com/library/archive/documentation/mac/pdf/Text.pdf work. (Almost all other items in this file's outline use /Dest. "Contents" could too, but it uses /A /GoTo for some reason.) (Other action types are things like opening a hyperlink, opening a different file, playing a sound, submitting a form, etc. Actions are also used for in-page links, not just in outlines. Many of these action types we'll likely never want to implement.)
This commit is contained in:
parent
d9c9510d3c
commit
182639217f
2 changed files with 18 additions and 0 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/DeprecatedFlyString.h>
|
#include <AK/DeprecatedFlyString.h>
|
||||||
|
|
||||||
#define ENUMERATE_COMMON_NAMES(X) \
|
#define ENUMERATE_COMMON_NAMES(X) \
|
||||||
|
X(A) \
|
||||||
X(AIS) \
|
X(AIS) \
|
||||||
X(Alternate) \
|
X(Alternate) \
|
||||||
X(ASCII85Decode) \
|
X(ASCII85Decode) \
|
||||||
|
@ -134,6 +135,7 @@
|
||||||
X(Root) \
|
X(Root) \
|
||||||
X(Rotate) \
|
X(Rotate) \
|
||||||
X(RunLengthDecode) \
|
X(RunLengthDecode) \
|
||||||
|
X(S) \
|
||||||
X(SA) \
|
X(SA) \
|
||||||
X(SM) \
|
X(SM) \
|
||||||
X(SMask) \
|
X(SMask) \
|
||||||
|
|
|
@ -540,6 +540,22 @@ PDFErrorOr<NonnullRefPtr<OutlineItem>> Document::build_outline_item(NonnullRefPt
|
||||||
if (outline_item_dict->contains(CommonNames::Dest)) {
|
if (outline_item_dict->contains(CommonNames::Dest)) {
|
||||||
auto dest_obj = TRY(outline_item_dict->get_object(this, CommonNames::Dest));
|
auto dest_obj = TRY(outline_item_dict->get_object(this, CommonNames::Dest));
|
||||||
outline_item->dest = TRY(create_destination_from_object(dest_obj, page_number_by_index_ref));
|
outline_item->dest = TRY(create_destination_from_object(dest_obj, page_number_by_index_ref));
|
||||||
|
} else if (outline_item_dict->contains(CommonNames::A)) {
|
||||||
|
// PDF 1.7 spec, "8.5 Actions"
|
||||||
|
auto action_dict = TRY(outline_item_dict->get_dict(this, CommonNames::A));
|
||||||
|
if (action_dict->contains(CommonNames::S)) {
|
||||||
|
// PDF 1.7 spec, "TABLE 8.48 Action types"
|
||||||
|
auto action_type = TRY(action_dict->get_name(this, CommonNames::S))->name();
|
||||||
|
if (action_type == "GoTo") {
|
||||||
|
// PDF 1.7 spec, "Go-To Actions"
|
||||||
|
if (action_dict->contains(CommonNames::D)) {
|
||||||
|
auto dest_obj = TRY(action_dict->get_object(this, CommonNames::D));
|
||||||
|
outline_item->dest = TRY(create_destination_from_object(dest_obj, page_number_by_index_ref));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dbgln("Unhandled action type {}", action_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outline_item_dict->contains(CommonNames::C)) {
|
if (outline_item_dict->contains(CommonNames::C)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue