static void _pdf_doc_extract_text( struct _pdf_doc *self, int pageno, char *tbuf, mume_rect_t *rbuf) { fz_display_list *list; fz_text_span *text, *span; fz_device *tdev; int i; list = _pdf_doc_get_list(self, pageno); text = fz_new_text_span(); tdev = fz_new_text_device(text); fz_execute_display_list( list, tdev, fz_identity, fz_infinite_bbox); for (span = text; span; span = span->next) { for (i = 0; i < span->len; i++) { *tbuf = span->text[i].c; if (*tbuf < 32) *tbuf = '?'; tbuf++; *rbuf++ = _fz_bbox_to_mume_rect(span->text[i].bbox); } if (!span->eol && span->next) continue; *tbuf++ = '\n'; *rbuf++ = mume_rect_empty; } fz_free_device(tdev); fz_free_text_span(text); }
static int _pdf_doc_text_length(struct _pdf_doc *self, int pageno) { fz_display_list *list; fz_text_span *text, *span; fz_device *tdev; int length = 0; list = _pdf_doc_get_list(self, pageno); text = fz_new_text_span(); tdev = fz_new_text_device(text); fz_execute_display_list( list, tdev, fz_identity, fz_infinite_bbox); for (span = text; span; span = span->next) { length += span->len; if (!span->eol && span->next) continue; /* End of line ? */ length += 1; } fz_free_device(tdev); fz_free_text_span(text); return length; }
static void _pdf_doc_render_page( struct _pdf_doc *self, cairo_t *cr, int x, int y, int pageno, mume_matrix_t ctm, mume_rect_t rect) { /* TODO: implement a fz_device to rendering directly to cairo. */ fz_colorspace *colorspace; fz_bbox bbox; fz_device *idev; fz_pixmap *pixmap; fz_display_list *list; cairo_format_t format; cairo_surface_t *surface; int stride; #ifdef _WIN32 colorspace = fz_device_bgr; #else colorspace = fz_device_rgb; #endif list = _pdf_doc_get_list(self, pageno); bbox = _mume_rect_to_fz_bbox(rect); pixmap = fz_new_pixmap_with_rect(colorspace, bbox); if (NULL == pixmap) { mume_error(("fz_new_pixmap_with_rect(%d, %d, %d, %d)\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1)); return; } fz_clear_pixmap_with_color(pixmap, 255); idev = fz_new_draw_device(self->glyph_cache, pixmap); fz_execute_display_list( list, idev, _mume_matrix_to_fz_matrix(ctm), bbox); fz_free_device(idev); /* Create cairo surface. */ format = CAIRO_FORMAT_ARGB32; stride = cairo_format_stride_for_width(format, pixmap->w); surface = cairo_image_surface_create_for_data( pixmap->samples, format, pixmap->w, pixmap->h, stride); if (surface) { cairo_set_source_surface(cr, surface, x, y); cairo_rectangle(cr, x, y, rect.width, rect.height); cairo_fill(cr); cairo_surface_destroy(surface); } fz_drop_pixmap(pixmap); }
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint) { char buf[256]; fz_device *idev; fz_device *tdev; fz_colorspace *colorspace; fz_matrix ctm; fz_bbox bbox; wincursor(app, WAIT); if (loadpage) { if (app->page_list) fz_free_display_list(app->page_list); if (app->page_text) fz_free_text_span(app->page_text); if (app->page_links) pdf_free_link(app->page_links); if (app->xref) pdfapp_loadpage_pdf(app); if (app->xps) pdfapp_loadpage_xps(app); /* Zero search hit position */ app->hit = -1; app->hitlen = 0; /* Extract text */ app->page_text = fz_new_text_span(); tdev = fz_new_text_device(app->page_text); fz_execute_display_list(app->page_list, tdev, fz_identity, fz_infinite_bbox); fz_free_device(tdev); } if (drawpage) { sprintf(buf, "%s - %d/%d (%d dpi)", app->doctitle, app->pageno, app->pagecount, app->resolution); wintitle(app, buf); ctm = pdfapp_viewctm(app); bbox = fz_round_rect(fz_transform_rect(ctm, app->page_bbox)); /* Draw */ if (app->image) fz_drop_pixmap(app->image); if (app->grayscale) colorspace = fz_device_gray; else #ifdef _WIN32 colorspace = fz_device_bgr; #else colorspace = fz_device_rgb; #endif app->image = fz_new_pixmap_with_rect(colorspace, bbox); fz_clear_pixmap_with_color(app->image, 255); idev = fz_new_draw_device(app->cache, app->image); fz_execute_display_list(app->page_list, idev, ctm, bbox); fz_free_device(idev); } if (repaint) { pdfapp_panview(app, app->panx, app->pany); if (app->shrinkwrap) { int w = app->image->w; int h = app->image->h; if (app->winw == w) app->panx = 0; if (app->winh == h) app->pany = 0; if (w > app->scrw * 90 / 100) w = app->scrw * 90 / 100; if (h > app->scrh * 90 / 100) h = app->scrh * 90 / 100; if (w != app->winw || h != app->winh) winresize(app, w, h); } winrepaint(app); wincursor(app, ARROW); } fz_flush_warnings(); }
static void drawpage(xps_context *ctx, int pagenum) { xps_page *page; fz_display_list *list; fz_device *dev; int start; int code; if (showtime) { start = gettime(); } code = xps_load_page(&page, ctx, pagenum - 1); if (code) die(fz_rethrow(code, "cannot load page %d in file '%s'", pagenum, filename)); list = NULL; if (uselist) { list = fz_new_display_list(); dev = fz_new_list_device(list); xps_run_page(ctx, page, dev, fz_identity); fz_free_device(dev); } if (showxml) { dev = fz_new_trace_device(); printf("<page number=\"%d\">\n", pagenum); if (list) fz_execute_display_list(list, dev, fz_identity, fz_infinite_bbox); else xps_run_page(ctx, page, dev, fz_identity); printf("</page>\n"); fz_free_device(dev); } if (showtext) { fz_text_span *text = fz_new_text_span(); dev = fz_new_text_device(text); if (list) fz_execute_display_list(list, dev, fz_identity, fz_infinite_bbox); else xps_run_page(ctx, page, dev, fz_identity); fz_free_device(dev); printf("[Page %d]\n", pagenum); if (showtext > 1) fz_debug_text_span_xml(text); else fz_debug_text_span(text); printf("\n"); fz_free_text_span(text); } if (showmd5 || showtime) printf("page %s %d", filename, pagenum); if (output || showmd5 || showtime) { float zoom; fz_matrix ctm; fz_rect rect; fz_bbox bbox; fz_pixmap *pix; rect.x0 = rect.y0 = 0; rect.x1 = page->width; rect.y1 = page->height; zoom = resolution / 96; ctm = fz_translate(0, -page->height); ctm = fz_concat(ctm, fz_scale(zoom, zoom)); bbox = fz_round_rect(fz_transform_rect(ctm, rect)); /* TODO: banded rendering and multi-page ppm */ pix = fz_new_pixmap_with_rect(colorspace, bbox); if (savealpha) fz_clear_pixmap(pix); else fz_clear_pixmap_with_color(pix, 255); dev = fz_new_draw_device(glyphcache, pix); if (list) fz_execute_display_list(list, dev, ctm, bbox); else xps_run_page(ctx, page, dev, ctm); fz_free_device(dev); if (output) { char buf[512]; sprintf(buf, output, pagenum); if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm")) fz_write_pnm(pix, buf); else if (strstr(output, ".pam")) fz_write_pam(pix, buf, savealpha); else if (strstr(output, ".png")) fz_write_png(pix, buf, savealpha); } if (showmd5) { fz_md5 md5; unsigned char digest[16]; int i; fz_md5_init(&md5); fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n); fz_md5_final(&md5, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); } fz_drop_pixmap(pix); } if (list) fz_free_display_list(list); if (showtime) { int end = gettime(); int diff = end - start; if (diff < timing.min) { timing.min = diff; timing.minpage = pagenum; } if (diff > timing.max) { timing.max = diff; timing.maxpage = pagenum; } timing.total += diff; timing.count ++; printf(" %dms", diff); } if (showmd5 || showtime) printf("\n"); }