void render_page(void) { fz_annot *annot; fz_pixmap *pix; fz_scale(&page_ctm, currentzoom / 72, currentzoom / 72); fz_pre_rotate(&page_ctm, -currentrotate); fz_invert_matrix(&page_inv_ctm, &page_ctm); fz_drop_page(ctx, page); page = fz_load_page(ctx, doc, currentpage); fz_drop_link(ctx, links); links = NULL; links = fz_load_links(ctx, page); pix = fz_new_pixmap_from_page_contents(ctx, page, &page_ctm, fz_device_rgb(ctx), 0); texture_from_pixmap(&page_tex, pix); fz_drop_pixmap(ctx, pix); annot_count = 0; for (annot = fz_first_annot(ctx, page); annot; annot = fz_next_annot(ctx, annot)) { pix = fz_new_pixmap_from_annot(ctx, annot, &page_ctm, fz_device_rgb(ctx), 1); texture_from_pixmap(&annot_tex[annot_count++], pix); fz_drop_pixmap(ctx, pix); if (annot_count >= nelem(annot_tex)) { fz_warn(ctx, "too many annotations to display!"); break; } } }
JNIEXPORT jobjectArray JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageLinksInternal(JNIEnv * env, jobject thiz, int pageNumber) { jclass linkInfoClass; jmethodID ctor; jobjectArray arr; jobject linkInfo; fz_matrix ctm; float zoom; fz_link *list; fz_link *link; int count; page_cache *pc; linkInfoClass = (*env)->FindClass(env, "com/artifex/mupdf/LinkInfo"); if (linkInfoClass == NULL) return NULL; ctor = (*env)->GetMethodID(env, linkInfoClass, "<init>", "(FFFFI)V"); if (ctor == NULL) return NULL; Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(env, thiz, pageNumber); pc = &pages[current]; if (pc->page == NULL || pc->number != pageNumber) return NULL; zoom = resolution / 72; ctm = fz_scale(zoom, zoom); list = fz_load_links(doc, pc->page); count = 0; for (link = list; link; link = link->next) { if (link->dest.kind == FZ_LINK_GOTO) count++ ; } arr = (*env)->NewObjectArray(env, count, linkInfoClass, NULL); if (arr == NULL) return NULL; count = 0; for (link = list; link; link = link->next) { if (link->dest.kind == FZ_LINK_GOTO) { fz_rect rect = fz_transform_rect(ctm, link->rect); linkInfo = (*env)->NewObject(env, linkInfoClass, ctor, (float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1, link->dest.ld.gotor.page); if (linkInfo == NULL) return NULL; (*env)->SetObjectArrayElement(env, arr, count, linkInfo); (*env)->DeleteLocalRef(env, linkInfo); count ++; } } return arr; }
JNIEXPORT int JNICALL Java_com_artifex_mupdf_MuPDFCore_getPageLink(JNIEnv * env, jobject thiz, int pageNumber, float x, float y) { fz_matrix ctm; float zoom; fz_link *link; fz_point p; page_cache *pc; Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(env, thiz, pageNumber); pc = &pages[current]; if (pc->number != pageNumber || pc->page == NULL) return -1; p.x = x; p.y = y; /* Ultimately we should probably return a pointer to a java structure * with the link details in, but for now, page number will suffice. */ zoom = resolution / 72; ctm = fz_scale(zoom, zoom); ctm = fz_invert_matrix(ctm); p = fz_transform_point(ctm, p); for (link = fz_load_links(doc, pc->page); link; link = link->next) { if (p.x >= link->rect.x0 && p.x <= link->rect.x1) if (p.y >= link->rect.y0 && p.y <= link->rect.y1) break; } if (link == NULL) return -1; if (link->dest.kind == FZ_LINK_URI) { //gotouri(link->dest.ld.uri.uri); return -1; } else if (link->dest.kind == FZ_LINK_GOTO) return link->dest.ld.gotor.page; return -1; }
std::shared_ptr<std::vector<std::shared_ptr<MuPDFDocLink>>> MuPDFDoc::GetLinks() { PageCache *pageCache = &m_pages[m_currentPage]; std::shared_ptr<std::vector<std::shared_ptr<MuPDFDocLink>>> links(new std::vector<std::shared_ptr<MuPDFDocLink>>()); fz_matrix ctm = CalcConvertMatrix(); fz_link* list = fz_load_links(m_document, pageCache->page); for(fz_link* link = list; link; link = link->next) { fz_rect rect = fz_transform_rect(ctm, link->rect); std::shared_ptr<MuPDFDocLink> docLink; switch (link->dest.kind) { case FZ_LINK_GOTO: { docLink = CreateInternalLink(link, rect); break; } case FZ_LINK_GOTOR: { docLink = CreateRemoteLink(link, rect); break; } case FZ_LINK_URI: { docLink = CreateURILink(link, rect); break; } default: continue; } links->push_back(docLink); } fz_drop_link(m_context, list); return links; }
static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) { fz_page *page; fz_link *links; fz_display_list *list = NULL; fz_device *dev = NULL; int start; fz_var(list); fz_var(dev); if (showtime) { start = gettime(); } fz_try(ctx) { page = fz_load_page(doc, pagenum - 1); } fz_catch(ctx) { fz_throw(ctx, "cannot load page %d in file '%s'", pagenum, filename); } fz_try(ctx) { links = fz_load_links(doc, page); } fz_catch(ctx) { fz_throw(ctx, "cannot load links for page %d in file '%s'", pagenum, filename); } if (uselist) { fz_try(ctx) { list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, list); fz_run_page(doc, page, dev, fz_identity, NULL); } fz_catch(ctx) { fz_free_device(dev); fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_throw(ctx, "cannot draw page %d in file '%s'", pagenum, filename); } fz_free_device(dev); dev = NULL; } if (showjson) { fz_text_page *text = NULL; fz_var(text); fz_try(ctx) { text = fz_new_text_page(ctx, fz_bound_page(doc, page)); dev = fz_new_text_device(ctx, sheet, text); if (list) fz_run_display_list(list, dev, fz_identity, fz_infinite_bbox, NULL); else fz_run_page(doc, page, dev, fz_identity, NULL); fz_free_device(dev); dev = NULL; fz_print_text_page_json(ctx, stdout, text, links); printf("\f\n"); } fz_catch(ctx) { fz_free_device(dev); fz_free_text_page(ctx, text); fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_rethrow(ctx); } fz_free_text_page(ctx, text); } if (showmd5 || showtime) printf("page %s %d", filename, pagenum); if (output || showmd5 || showtime) { float zoom; fz_matrix ctm; fz_rect bounds, bounds2; fz_bbox bbox; fz_pixmap *pix = NULL; int w, h; fz_var(pix); bounds = fz_bound_page(doc, page); zoom = resolution / 72; ctm = fz_scale(zoom, zoom); ctm = fz_concat(ctm, fz_rotate(rotation)); bounds2 = fz_transform_rect(ctm, bounds); bbox = fz_round_rect(bounds2); /* Make local copies of our width/height */ w = width; h = height; /* If a resolution is specified, check to see whether w/h are * exceeded; if not, unset them. */ if (res_specified) { int t; t = bbox.x1 - bbox.x0; if (w && t <= w) w = 0; t = bbox.y1 - bbox.y0; if (h && t <= h) h = 0; } /* Now w or h will be 0 unless then need to be enforced. */ if (w || h) { float scalex = w/(bounds2.x1-bounds2.x0); float scaley = h/(bounds2.y1-bounds2.y0); if (fit) { if (w == 0) scalex = 1.0f; if (h == 0) scaley = 1.0f; } else { if (w == 0) scalex = scaley; if (h == 0) scaley = scalex; } if (!fit) { if (scalex > scaley) scalex = scaley; else scaley = scalex; } ctm = fz_concat(ctm, fz_scale(scalex, scaley)); bounds2 = fz_transform_rect(ctm, bounds); } bbox = fz_round_rect(bounds2); /* TODO: banded rendering and multi-page ppm */ fz_try(ctx) { pix = fz_new_pixmap_with_bbox(ctx, colorspace, bbox); if (savealpha) fz_clear_pixmap(ctx, pix); else fz_clear_pixmap_with_value(ctx, pix, 255); dev = fz_new_draw_device(ctx, pix); if (list) fz_run_display_list(list, dev, ctm, bbox, NULL); else fz_run_page(doc, page, dev, ctm, NULL); fz_free_device(dev); dev = NULL; if (invert) fz_invert_pixmap(ctx, pix); if (gamma_value != 1) fz_gamma_pixmap(ctx, pix, gamma_value); if (savealpha) fz_unmultiply_pixmap(ctx, pix); if (output) { char buf[512]; sprintf(buf, output, pagenum); if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm")) fz_write_pnm(ctx, pix, buf); else if (strstr(output, ".pam")) fz_write_pam(ctx, pix, buf, savealpha); else if (strstr(output, ".png")) fz_write_png(ctx, pix, buf, savealpha); else if (strstr(output, ".pbm")) { fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); fz_write_pbm(ctx, bit, buf); fz_drop_bitmap(ctx, bit); } } if (showmd5) { unsigned char digest[16]; int i; fz_md5_pixmap(pix, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); } fz_drop_pixmap(ctx, pix); } fz_catch(ctx) { fz_free_device(dev); fz_drop_pixmap(ctx, pix); fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_rethrow(ctx); } }