summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/pdf/annot.h4
-rw-r--r--resources/pdf/names.txt4
-rw-r--r--source/pdf/pdf-annot.c33
-rw-r--r--source/pdf/pdf-outline.c2
-rw-r--r--source/pdf/pdf-page.c2
5 files changed, 36 insertions, 9 deletions
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h
index f8806728..866e5ba5 100644
--- a/include/mupdf/pdf/annot.h
+++ b/include/mupdf/pdf/annot.h
@@ -104,13 +104,13 @@ struct pdf_annot_s
char *pdf_parse_file_spec(fz_context *ctx, pdf_document *doc, pdf_obj *file_spec, pdf_obj *dest);
char *pdf_parse_link_dest(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
-char *pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
+char *pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *obj, int pagenum);
pdf_obj *pdf_lookup_dest(fz_context *ctx, pdf_document *doc, pdf_obj *needle);
pdf_obj *pdf_lookup_name(fz_context *ctx, pdf_document *doc, pdf_obj *which, pdf_obj *needle);
pdf_obj *pdf_load_name_tree(fz_context *ctx, pdf_document *doc, pdf_obj *which);
int pdf_resolve_link(fz_context *ctx, pdf_document *doc, const char *uri, float *xp, float *yp);
-fz_link *pdf_load_link_annots(fz_context *ctx, pdf_document *, pdf_obj *annots, const fz_matrix *page_ctm);
+fz_link *pdf_load_link_annots(fz_context *ctx, pdf_document *, pdf_obj *annots, int pagenum, const fz_matrix *page_ctm);
void pdf_annot_transform(fz_context *ctx, pdf_annot *annot, fz_matrix *annot_ctm);
void pdf_load_annots(fz_context *ctx, pdf_page *page, pdf_obj *annots);
diff --git a/resources/pdf/names.txt b/resources/pdf/names.txt
index 071e7f2e..cfe83ed2 100644
--- a/resources/pdf/names.txt
+++ b/resources/pdf/names.txt
@@ -144,6 +144,7 @@ Filespec
Filter
First
FirstChar
+FirstPage
Fit
FitB
FitBH
@@ -214,6 +215,7 @@ LZWDecode
Lab
Last
LastChar
+LastPage
Launch
Length
Length1
@@ -244,6 +246,7 @@ Named
Names
NewWindow
Next
+NextPage
None
Normal
O
@@ -279,6 +282,7 @@ Polygon
Popup
Predictor
Prev
+PrevPage
Print
PrinterMark
ProcSet
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 539c4882..b90b5e86 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -169,7 +169,7 @@ pdf_parse_file_spec(fz_context *ctx, pdf_document *doc, pdf_obj *file_spec, pdf_
}
char *
-pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *action)
+pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *action, int pagenum)
{
pdf_obj *obj, *dest, *file_spec;
@@ -208,12 +208,35 @@ pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *action)
file_spec = pdf_dict_get(ctx, action, PDF_NAME_F);
return pdf_parse_file_spec(ctx, doc, file_spec, dest);
}
+ else if (pdf_name_eq(ctx, PDF_NAME_Named, obj))
+ {
+ dest = pdf_dict_get(ctx, action, PDF_NAME_N);
+
+ if (pdf_name_eq(ctx, PDF_NAME_FirstPage, dest))
+ pagenum = 0;
+ else if (pdf_name_eq(ctx, PDF_NAME_LastPage, dest))
+ pagenum = pdf_count_pages(ctx, doc) - 1;
+ else if (pdf_name_eq(ctx, PDF_NAME_PrevPage, dest) && pagenum >= 0)
+ {
+ if (pagenum > 0)
+ pagenum--;
+ }
+ else if (pdf_name_eq(ctx, PDF_NAME_NextPage, dest) && pagenum >= 0)
+ {
+ if (pagenum < pdf_count_pages(ctx, doc) - 1)
+ pagenum++;
+ }
+ else
+ return NULL;
+
+ return fz_asprintf(ctx, "#%d", pagenum + 1);
+ }
return NULL;
}
static fz_link *
-pdf_load_link(fz_context *ctx, pdf_document *doc, pdf_obj *dict, const fz_matrix *page_ctm)
+pdf_load_link(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int pagenum, const fz_matrix *page_ctm)
{
pdf_obj *action;
pdf_obj *obj;
@@ -241,7 +264,7 @@ pdf_load_link(fz_context *ctx, pdf_document *doc, pdf_obj *dict, const fz_matrix
/* fall back to additional action button's down/up action */
if (!action)
action = pdf_dict_geta(ctx, pdf_dict_get(ctx, dict, PDF_NAME_AA), PDF_NAME_U, PDF_NAME_D);
- uri = pdf_parse_link_action(ctx, doc, action);
+ uri = pdf_parse_link_action(ctx, doc, action, pagenum);
}
if (!uri)
@@ -253,7 +276,7 @@ pdf_load_link(fz_context *ctx, pdf_document *doc, pdf_obj *dict, const fz_matrix
}
fz_link *
-pdf_load_link_annots(fz_context *ctx, pdf_document *doc, pdf_obj *annots, const fz_matrix *page_ctm)
+pdf_load_link_annots(fz_context *ctx, pdf_document *doc, pdf_obj *annots, int pagenum, const fz_matrix *page_ctm)
{
fz_link *link, *head, *tail;
pdf_obj *obj;
@@ -269,7 +292,7 @@ pdf_load_link_annots(fz_context *ctx, pdf_document *doc, pdf_obj *annots, const
fz_try(ctx)
{
obj = pdf_array_get(ctx, annots, i);
- link = pdf_load_link(ctx, doc, obj, page_ctm);
+ link = pdf_load_link(ctx, doc, obj, pagenum, page_ctm);
}
fz_catch(ctx)
{
diff --git a/source/pdf/pdf-outline.c b/source/pdf/pdf-outline.c
index 7c8cfdaa..708f7087 100644
--- a/source/pdf/pdf-outline.c
+++ b/source/pdf/pdf-outline.c
@@ -29,7 +29,7 @@ pdf_load_outline_imp(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
if ((obj = pdf_dict_get(ctx, dict, PDF_NAME_Dest)) != NULL)
node->uri = pdf_parse_link_dest(ctx, doc, obj);
else if ((obj = pdf_dict_get(ctx, dict, PDF_NAME_A)) != NULL)
- node->uri = pdf_parse_link_action(ctx, doc, obj);
+ node->uri = pdf_parse_link_action(ctx, doc, obj, -1);
else
node->uri = NULL;
diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c
index dc907798..f3860e52 100644
--- a/source/pdf/pdf-page.c
+++ b/source/pdf/pdf-page.c
@@ -699,7 +699,7 @@ pdf_load_page(fz_context *ctx, pdf_document *doc, int number)
fz_rect page_mediabox;
fz_matrix page_ctm;
pdf_page_transform(ctx, page, &page_mediabox, &page_ctm);
- page->links = pdf_load_link_annots(ctx, doc, obj, &page_ctm);
+ page->links = pdf_load_link_annots(ctx, doc, obj, number, &page_ctm);
pdf_load_annots(ctx, page, obj);
}
}