summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2013-08-24 23:07:06 +0200
committerSebastian Rasmussen <sebras@gmail.com>2013-08-24 23:38:02 +0200
commit0bfe9501ebc2e2a2329a5435100ef189b6166219 (patch)
treebd9ea782ecf2722ce9c51979810778bf48d7107e
parent8ac325e2550a509995bbad5a28c09c4a3ded0dc1 (diff)
downloadmupdf-0bfe9501ebc2e2a2329a5435100ef189b6166219.tar.xz
Support named destinations in remote link annotations.
Previously there was a bug when parsing GoToR link annotations that had a named destination. mupdf incorrectly attempted to resolve the destination in the current document. Now the destination name is present in the link objects returned to the application so it can resolve any names for GoToR links in the remote document instead.
-rw-r--r--include/mupdf/fitz/link.h10
-rw-r--r--include/mupdf/pdf/annot.h2
-rw-r--r--source/pdf/pdf-annot.c42
-rw-r--r--source/pdf/pdf-outline.c2
4 files changed, 38 insertions, 18 deletions
diff --git a/include/mupdf/fitz/link.h b/include/mupdf/fitz/link.h
index 65a77fd2..7a400851 100644
--- a/include/mupdf/fitz/link.h
+++ b/include/mupdf/fitz/link.h
@@ -47,7 +47,14 @@ enum {
For FZ_LINK_GOTO or FZ_LINK_GOTOR:
gotor.page: The target page number to move to (0 being the
- first page in the document).
+ first page in the document). In the FZ_LINK_GOTOR case, the
+ page number either refers to to the file specified by
+ gotor.file_spec, or the page number is -1 suggesting that
+ the destination is given by gotor.dest.
+
+ gotor.dest: If set, the target destination name to be
+ resolved in the file specified by gotor.file_spec. Always
+ NULL in the FZ_LINK_GOTO case.
gotor.flags: A bitfield consisting of fz_link_flag_*
describing the validity and meaning of the different parts
@@ -97,6 +104,7 @@ struct fz_link_dest_s
struct
{
int page;
+ char *dest;
int flags;
fz_point lt;
fz_point rb;
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h
index d6950970..bf912ef9 100644
--- a/include/mupdf/pdf/annot.h
+++ b/include/mupdf/pdf/annot.h
@@ -56,7 +56,7 @@ struct pdf_annot_s
int widget_type;
};
-fz_link_dest pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest);
+fz_link_dest pdf_parse_link_dest(pdf_document *doc, fz_link_kind kind, pdf_obj *dest);
fz_link_dest pdf_parse_action(pdf_document *doc, pdf_obj *action);
pdf_obj *pdf_lookup_dest(pdf_document *doc, pdf_obj *needle);
pdf_obj *pdf_lookup_name(pdf_document *doc, char *which, pdf_obj *needle);
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 335f6512..eb999581 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -1,15 +1,20 @@
#include "mupdf/pdf.h"
static pdf_obj *
-resolve_dest_rec(pdf_document *doc, pdf_obj *dest, int depth)
+resolve_dest_rec(pdf_document *doc, pdf_obj *dest, fz_link_kind kind, int depth)
{
if (depth > 10) /* Arbitrary to avoid infinite recursion */
return NULL;
if (pdf_is_name(dest) || pdf_is_string(dest))
{
- dest = pdf_lookup_dest(doc, dest);
- return resolve_dest_rec(doc, dest, depth+1);
+ if (kind == FZ_LINK_GOTO)
+ {
+ dest = pdf_lookup_dest(doc, dest);
+ dest = resolve_dest_rec(doc, dest, kind, depth+1);
+ }
+
+ return dest;
}
else if (pdf_is_array(dest))
@@ -20,7 +25,7 @@ resolve_dest_rec(pdf_document *doc, pdf_obj *dest, int depth)
else if (pdf_is_dict(dest))
{
dest = pdf_dict_gets(dest, "D");
- return resolve_dest_rec(doc, dest, depth+1);
+ return resolve_dest_rec(doc, dest, kind, depth+1);
}
else if (pdf_is_indirect(dest))
@@ -30,13 +35,13 @@ resolve_dest_rec(pdf_document *doc, pdf_obj *dest, int depth)
}
static pdf_obj *
-resolve_dest(pdf_document *doc, pdf_obj *dest)
+resolve_dest(pdf_document *doc, pdf_obj *dest, fz_link_kind kind)
{
- return resolve_dest_rec(doc, dest, 0);
+ return resolve_dest_rec(doc, dest, kind, 0);
}
fz_link_dest
-pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest)
+pdf_parse_link_dest(pdf_document *doc, fz_link_kind kind, pdf_obj *dest)
{
fz_link_dest ld;
pdf_obj *obj;
@@ -49,17 +54,25 @@ pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest)
int t_from_2 = 0;
int z_from_4 = 0;
- ld.kind = FZ_LINK_GOTO;
+ ld.kind = kind;
ld.ld.gotor.flags = 0;
ld.ld.gotor.lt.x = 0;
ld.ld.gotor.lt.y = 0;
ld.ld.gotor.rb.x = 0;
ld.ld.gotor.rb.y = 0;
+ ld.ld.gotor.page = -1;
+ ld.ld.gotor.dest = NULL;
- dest = resolve_dest(doc, dest);
- if (dest == NULL || !pdf_is_array(dest))
+ dest = resolve_dest(doc, dest, kind);
+
+ if (pdf_is_name(dest))
+ {
+ ld.ld.gotor.dest = pdf_to_name(dest);
+ return ld;
+ }
+ else if (pdf_is_string(dest))
{
- ld.kind = FZ_LINK_NONE;
+ ld.ld.gotor.dest = pdf_to_str_buf(dest);
return ld;
}
@@ -244,7 +257,7 @@ pdf_parse_action(pdf_document *doc, pdf_obj *action)
if (!strcmp(pdf_to_name(obj), "GoTo"))
{
dest = pdf_dict_gets(action, "D");
- ld = pdf_parse_link_dest(doc, dest);
+ ld = pdf_parse_link_dest(doc, FZ_LINK_GOTO, dest);
}
else if (!strcmp(pdf_to_name(obj), "URI"))
{
@@ -269,9 +282,8 @@ pdf_parse_action(pdf_document *doc, pdf_obj *action)
else if (!strcmp(pdf_to_name(obj), "GoToR"))
{
dest = pdf_dict_gets(action, "D");
- ld = pdf_parse_link_dest(doc, dest);
- ld.kind = FZ_LINK_GOTOR;
file_spec = pdf_dict_gets(action, "F");
+ ld = pdf_parse_link_dest(doc, FZ_LINK_GOTOR, dest);
ld.ld.gotor.file_spec = pdf_parse_file_spec(doc, file_spec);
ld.ld.gotor.new_window = pdf_to_int(pdf_dict_gets(action, "NewWindow"));
}
@@ -298,7 +310,7 @@ pdf_load_link(pdf_document *doc, pdf_obj *dict, const fz_matrix *page_ctm)
obj = pdf_dict_gets(dict, "Dest");
if (obj)
- ld = pdf_parse_link_dest(doc, obj);
+ ld = pdf_parse_link_dest(doc, FZ_LINK_GOTO, obj);
else
{
action = pdf_dict_gets(dict, "A");
diff --git a/source/pdf/pdf-outline.c b/source/pdf/pdf-outline.c
index 2d545b63..1e01b692 100644
--- a/source/pdf/pdf-outline.c
+++ b/source/pdf/pdf-outline.c
@@ -32,7 +32,7 @@ pdf_load_outline_imp(pdf_document *doc, pdf_obj *dict)
node->title = pdf_to_utf8(doc, obj);
if ((obj = pdf_dict_gets(dict, "Dest")))
- node->dest = pdf_parse_link_dest(doc, obj);
+ node->dest = pdf_parse_link_dest(doc, FZ_LINK_GOTO, obj);
else if ((obj = pdf_dict_gets(dict, "A")))
node->dest = pdf_parse_action(doc, obj);