diff options
-rw-r--r-- | include/mupdf/fitz/document.h | 6 | ||||
-rw-r--r-- | include/mupdf/pdf/annot.h | 2 | ||||
-rw-r--r-- | include/mupdf/pdf/page.h | 1 | ||||
-rw-r--r-- | platform/android/viewer/jni/mupdf.c | 2 | ||||
-rw-r--r-- | platform/gl/gl-main.c | 2 | ||||
-rw-r--r-- | platform/java/mupdf_native.c | 4 | ||||
-rw-r--r-- | platform/x11/pdfapp.c | 2 | ||||
-rw-r--r-- | source/fitz/document.c | 6 | ||||
-rw-r--r-- | source/html/epub-doc.c | 10 | ||||
-rw-r--r-- | source/html/html-doc.c | 9 | ||||
-rw-r--r-- | source/pdf/pdf-annot.c | 65 | ||||
-rw-r--r-- | source/pdf/pdf-outline.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-page.c | 11 | ||||
-rw-r--r-- | source/xps/xps-doc.c | 2 | ||||
-rw-r--r-- | source/xps/xps-imp.h | 2 | ||||
-rw-r--r-- | source/xps/xps-outline.c | 2 |
16 files changed, 93 insertions, 35 deletions
diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h index d8123a00..105692e6 100644 --- a/include/mupdf/fitz/document.h +++ b/include/mupdf/fitz/document.h @@ -32,7 +32,7 @@ typedef int (fz_document_authenticate_password_fn)(fz_context *ctx, fz_document typedef int (fz_document_has_permission_fn)(fz_context *ctx, fz_document *doc, fz_permission permission); typedef fz_outline *(fz_document_load_outline_fn)(fz_context *ctx, fz_document *doc); typedef void (fz_document_layout_fn)(fz_context *ctx, fz_document *doc, float w, float h, float em); -typedef int (fz_document_resolve_link_fn)(fz_context *ctx, fz_document *doc, const char *uri); +typedef int (fz_document_resolve_link_fn)(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp); typedef int (fz_document_count_pages_fn)(fz_context *ctx, fz_document *doc); typedef fz_page *(fz_document_load_page_fn)(fz_context *ctx, fz_document *doc, int number); typedef int (fz_document_lookup_metadata_fn)(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size); @@ -214,9 +214,11 @@ int fz_count_pages(fz_context *ctx, fz_document *doc); /* fz_resolve_link: Resolve an internal link to a page number. + xp, yp: Pointer to store coordinate of destination on the page. + Returns -1 if the URI cannot be resolved. */ -int fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri); +int fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp); /* fz_load_page: Load a page. diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h index caaa9047..49ae9246 100644 --- a/include/mupdf/pdf/annot.h +++ b/include/mupdf/pdf/annot.h @@ -108,7 +108,7 @@ 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); +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); void pdf_annot_transform(fz_context *ctx, pdf_annot *annot, fz_matrix *annot_ctm); diff --git a/include/mupdf/pdf/page.h b/include/mupdf/pdf/page.h index 407fcc09..bae9193f 100644 --- a/include/mupdf/pdf/page.h +++ b/include/mupdf/pdf/page.h @@ -34,6 +34,7 @@ void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_obj *page); pdf_page *pdf_load_page(fz_context *ctx, pdf_document *doc, int number); void pdf_drop_page(fz_context *ctx, pdf_page *page); +void pdf_page_obj_transform(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm); void pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm); pdf_obj *pdf_page_resources(fz_context *ctx, pdf_page *page); pdf_obj *pdf_page_contents(fz_context *ctx, pdf_page *page); diff --git a/platform/android/viewer/jni/mupdf.c b/platform/android/viewer/jni/mupdf.c index 895f6912..236efbf2 100644 --- a/platform/android/viewer/jni/mupdf.c +++ b/platform/android/viewer/jni/mupdf.c @@ -1903,7 +1903,7 @@ JNI_FN(MuPDFCore_getPageLinksInternal)(JNIEnv * env, jobject thiz, int pageNumbe { linkInfo = (*env)->NewObject(env, linkInfoInternalClass, ctorInternal, (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1, - fz_resolve_link(glo->ctx, link->doc, link->uri)); + fz_resolve_link(glo->ctx, link->doc, link->uri, NULL, NULL)); } else { diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c index 2a46e1b1..557d616a 100644 --- a/platform/gl/gl-main.c +++ b/platform/gl/gl-main.c @@ -589,7 +589,7 @@ static void do_links(fz_link *link, int xofs, int yofs) if (fz_is_external_link(ctx, link->uri)) open_browser(link->uri); else - jump_to_page(fz_resolve_link(ctx, doc, link->uri)); + jump_to_page(fz_resolve_link(ctx, doc, link->uri, NULL, NULL)); } ui_needs_update = 1; } diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c index 537646a6..843a79dc 100644 --- a/platform/java/mupdf_native.c +++ b/platform/java/mupdf_native.c @@ -1031,7 +1031,7 @@ static inline jobject to_Outline_safe(fz_context *ctx, JNIEnv *env, fz_document if (!juri) return NULL; } else - jpage = fz_resolve_link(ctx, doc, outline->uri); + jpage = fz_resolve_link(ctx, doc, outline->uri, NULL, NULL); if (outline->down) { @@ -4564,7 +4564,7 @@ FUN(Page_getLinks)(JNIEnv *env, jobject self) if (!juri) return NULL; } else - page = fz_resolve_link(ctx, link->doc, link->uri); + page = fz_resolve_link(ctx, link->doc, link->uri, NULL, NULL); jlink = (*env)->NewObject(env, cls_Link, mid_Link_init, jbounds, page, juri); (*env)->DeleteLocalRef(env, jbounds); diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 19983ee9..58a50db5 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -1740,7 +1740,7 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta if (fz_is_external_link(ctx, link->uri)) pdfapp_gotouri(app, link->uri); else - pdfapp_gotopage(app, fz_resolve_link(ctx, app->doc, link->uri) + 1); + pdfapp_gotopage(app, fz_resolve_link(ctx, app->doc, link->uri, NULL, NULL) + 1); return; } } diff --git a/source/fitz/document.c b/source/fitz/document.c index 87ad3884..684c8523 100644 --- a/source/fitz/document.c +++ b/source/fitz/document.c @@ -216,11 +216,13 @@ fz_load_outline(fz_context *ctx, fz_document *doc) } int -fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri) +fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp) { fz_ensure_layout(ctx, doc); + if (xp) *xp = 0; + if (yp) *yp = 0; if (doc && doc->resolve_link) - return doc->resolve_link(ctx, doc, uri); + return doc->resolve_link(ctx, doc, uri, xp, yp); return -1; } diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c index a30fbcd3..f5f3ca67 100644 --- a/source/html/epub-doc.c +++ b/source/html/epub-doc.c @@ -35,7 +35,7 @@ struct epub_page_s }; static int -epub_resolve_link(fz_context *ctx, fz_document *doc_, const char *dest) +epub_resolve_link(fz_context *ctx, fz_document *doc_, const char *dest, float *xp, float *yp) { epub_document *doc = (epub_document*)doc_; epub_chapter *ch; @@ -54,7 +54,11 @@ epub_resolve_link(fz_context *ctx, fz_document *doc_, const char *dest) /* Search for a matching fragment */ float y = fz_find_html_target(ctx, ch->html, s+1); if (y >= 0) - return ch->start + y / ch->page_h; + { + int page = y / ch->page_h; + if (yp) *yp = y - page * ch->page_h; + return ch->start + page; + } } return ch->start; } @@ -68,7 +72,7 @@ epub_update_outline(fz_context *ctx, fz_document *doc, fz_outline *node) { while (node) { - node->page = epub_resolve_link(ctx, doc, node->uri); + node->page = epub_resolve_link(ctx, doc, node->uri, NULL, NULL); epub_update_outline(ctx, doc, node->down); node = node->next; } diff --git a/source/html/html-doc.c b/source/html/html-doc.c index 810b92c1..8d602030 100644 --- a/source/html/html-doc.c +++ b/source/html/html-doc.c @@ -32,16 +32,19 @@ htdoc_drop_document(fz_context *ctx, fz_document *doc_) } static int -htdoc_resolve_link(fz_context *ctx, fz_document *doc_, const char *dest) +htdoc_resolve_link(fz_context *ctx, fz_document *doc_, const char *dest, float *xp, float *yp) { html_document *doc = (html_document*)doc_; - const char *s = strchr(dest, '#'); if (s && s[1] != 0) { float y = fz_find_html_target(ctx, doc->html, s+1); if (y >= 0) - return y / doc->page_h; + { + int page = y / doc->page_h; + if (yp) *yp = y - page * doc->page_h; + return page; + } } return -1; 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; } diff --git a/source/pdf/pdf-outline.c b/source/pdf/pdf-outline.c index d82db02c..7db65153 100644 --- a/source/pdf/pdf-outline.c +++ b/source/pdf/pdf-outline.c @@ -33,7 +33,7 @@ pdf_load_outline_imp(fz_context *ctx, pdf_document *doc, pdf_obj *dict) else node->uri = NULL; - node->page = pdf_resolve_link(ctx, doc, node->uri); + node->page = pdf_resolve_link(ctx, doc, node->uri, NULL, NULL); obj = pdf_dict_get(ctx, dict, PDF_NAME_First); if (obj) diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c index e3c78877..89b62005 100644 --- a/source/pdf/pdf-page.c +++ b/source/pdf/pdf-page.c @@ -215,7 +215,7 @@ pdf_lookup_anchor(fz_context *ctx, pdf_document *doc, const char *name) fz_rethrow(ctx); uri = pdf_parse_link_dest(ctx, doc, dest); - return pdf_resolve_link(ctx, doc, uri); + return pdf_resolve_link(ctx, doc, uri, NULL, NULL); } static pdf_obj * @@ -443,9 +443,8 @@ pdf_page_contents(fz_context *ctx, pdf_page *page) } void -pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *page_mediabox, fz_matrix *page_ctm) +pdf_page_obj_transform(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm) { - pdf_obj *pageobj = page->obj; pdf_obj *obj; fz_rect mediabox, cropbox, realbox, pagebox; fz_matrix tmp; @@ -507,6 +506,12 @@ pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *page_mediabox, fz_m fz_concat(page_ctm, page_ctm, &tmp); } +void +pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *page_mediabox, fz_matrix *page_ctm) +{ + return pdf_page_obj_transform(ctx, page->obj, page_mediabox, page_ctm); +} + static void pdf_drop_page_imp(fz_context *ctx, pdf_page *page) { diff --git a/source/xps/xps-doc.c b/source/xps/xps-doc.c index d530bdbd..8197f505 100644 --- a/source/xps/xps-doc.c +++ b/source/xps/xps-doc.c @@ -124,7 +124,7 @@ xps_add_link_target(fz_context *ctx, xps_document *doc, char *name) } int -xps_lookup_link_target(fz_context *ctx, xps_document *doc, char *target_uri) +xps_lookup_link_target(fz_context *ctx, xps_document *doc, char *target_uri, float *xp, float *yp) { xps_target *target; char *needle = strrchr(target_uri, '#'); diff --git a/source/xps/xps-imp.h b/source/xps/xps-imp.h index 4f21fb95..2ba78a50 100644 --- a/source/xps/xps-imp.h +++ b/source/xps/xps-imp.h @@ -105,7 +105,7 @@ void xps_read_page_list(fz_context *ctx, xps_document *doc); void xps_print_page_list(fz_context *ctx, xps_document *doc); void xps_drop_page_list(fz_context *ctx, xps_document *doc); -int xps_lookup_link_target(fz_context *ctx, xps_document *doc, char *target_uri); +int xps_lookup_link_target(fz_context *ctx, xps_document *doc, char *target_uri, float *xp, float *yp); /* * Images, fonts, and colorspaces. diff --git a/source/xps/xps-outline.c b/source/xps/xps-outline.c index 1fe294fb..bcb16509 100644 --- a/source/xps/xps-outline.c +++ b/source/xps/xps-outline.c @@ -34,7 +34,7 @@ xps_parse_document_outline(fz_context *ctx, xps_document *doc, fz_xml *root) entry = fz_new_outline(ctx); entry->title = fz_strdup(ctx, description); entry->uri = fz_strdup(ctx, target); - entry->page = xps_lookup_link_target(ctx, doc, target); + entry->page = xps_lookup_link_target(ctx, doc, target, NULL, NULL); entry->down = NULL; entry->next = NULL; |