diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-11-14 13:03:07 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-11-14 13:23:57 +0100 |
commit | 2216f9402a9ddf232e15fdd508b9123011af8bd3 (patch) | |
tree | 3b4e44be0e332bb9d957864fcde41057ed0fcb79 /source/pdf/pdf-annot.c | |
parent | 018253cfc8a34805c4fc1e0f955e3696db60886a (diff) | |
download | mupdf-2216f9402a9ddf232e15fdd508b9123011af8bd3.tar.xz |
Add/fix page coordinates to link targets.
Correctly transformed target coordinates for PDF.
Target coordinates for EPUB and HTML.
Diffstat (limited to 'source/pdf/pdf-annot.c')
-rw-r--r-- | source/pdf/pdf-annot.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c index 44c30fe9..ec19f27a 100644 --- a/source/pdf/pdf-annot.c +++ b/source/pdf/pdf-annot.c @@ -40,8 +40,10 @@ char * pdf_parse_link_dest(fz_context *ctx, pdf_document *doc, pdf_obj *dest) { pdf_obj *obj; - char buf[40]; + char buf[256]; char *ld; + int page; + int x, y; dest = resolve_dest(ctx, doc, dest); if (dest == NULL) @@ -63,18 +65,34 @@ pdf_parse_link_dest(fz_context *ctx, pdf_document *doc, pdf_obj *dest) obj = pdf_array_get(ctx, dest, 0); if (pdf_is_int(ctx, obj)) + page = pdf_to_int(ctx, obj); + else + page = pdf_lookup_page_number(ctx, doc, obj); + + x = y = 0; + obj = pdf_array_get(ctx, dest, 1); + if (pdf_name_eq(ctx, obj, PDF_NAME_XYZ)) { - sprintf(buf, "#%d", pdf_to_int(ctx, obj) + 1); - return fz_strdup(ctx, buf); + x = pdf_to_int(ctx, pdf_array_get(ctx, dest, 2)); + y = pdf_to_int(ctx, pdf_array_get(ctx, dest, 3)); } - else + else if (pdf_name_eq(ctx, obj, PDF_NAME_FitR)) { - int page = pdf_lookup_page_number(ctx, doc, obj); - if (page >= 0) - { - sprintf(buf, "#%d", page + 1); - return fz_strdup(ctx, buf); - } + x = pdf_to_int(ctx, pdf_array_get(ctx, dest, 2)); + y = pdf_to_int(ctx, pdf_array_get(ctx, dest, 5)); + } + else if (pdf_name_eq(ctx, obj, PDF_NAME_FitH) || pdf_name_eq(ctx, obj, PDF_NAME_FitBH)) + y = pdf_to_int(ctx, pdf_array_get(ctx, dest, 2)); + else if (pdf_name_eq(ctx, obj, PDF_NAME_FitV) || pdf_name_eq(ctx, obj, PDF_NAME_FitBV)) + x = pdf_to_int(ctx, pdf_array_get(ctx, dest, 2)); + + if (page >= 0) + { + if (x != 0 || y != 0) + fz_snprintf(buf, sizeof buf, "#%d,%d,%d", page + 1, x, y); + else + fz_snprintf(buf, sizeof buf, "#%d", page + 1); + return fz_strdup(ctx, buf); } return NULL; @@ -255,10 +273,33 @@ pdf_load_link_annots(fz_context *ctx, pdf_document *doc, pdf_obj *annots, const } int -pdf_resolve_link(fz_context *ctx, pdf_document *doc, const char *uri) +pdf_resolve_link(fz_context *ctx, pdf_document *doc, const char *uri, float *xp, float *yp) { if (uri && uri[0] == '#') - return fz_atoi(uri + 1) - 1; + { + int page = fz_atoi(uri + 1) - 1; + if (xp || yp) + { + const char *x = strchr(uri, ','); + const char *y = strrchr(uri, ','); + if (x && y) + { + pdf_obj *obj; + fz_matrix ctm; + fz_point p; + + p.x = x ? fz_atoi(x + 1) : 0; + p.y = y ? fz_atoi(y + 1) : 0; + obj = pdf_lookup_page_obj(ctx, doc, page); + pdf_page_obj_transform(ctx, obj, NULL, &ctm); + fz_transform_point(&p, &ctm); + + if (xp) *xp = p.x; + if (yp) *yp = p.y; + } + } + return page; + } fz_warn(ctx, "unknown link uri '%s'", uri); return -1; } |