From b66925c26188075d843f7661f8d0a21eeb37ec22 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 13 Jul 2017 15:28:09 +0200 Subject: Add 'mutool trace' command. --- source/fitz/trace-device.c | 2 +- source/tools/mutool.c | 2 + source/tools/mutrace.c | 170 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 source/tools/mutrace.c (limited to 'source') diff --git a/source/fitz/trace-device.c b/source/fitz/trace-device.c index 13ce7256..2b7b24aa 100644 --- a/source/fitz/trace-device.c +++ b/source/fitz/trace-device.c @@ -332,7 +332,7 @@ static int fz_trace_begin_tile(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id) { fz_output *out = ((fz_trace_device*)dev)->out; - fz_write_printf(ctx, out, "x0, area->y0, area->x1, area->y1); fz_write_printf(ctx, out, " view=\"%g %g %g %g\"", view->x0, view->y0, view->x1, view->y1); fz_write_printf(ctx, out, " xstep=\"%g\" ystep=\"%g\"", xstep, ystep); diff --git a/source/tools/mutool.c b/source/tools/mutool.c index 688c4fbb..3e4cbf09 100644 --- a/source/tools/mutool.c +++ b/source/tools/mutool.c @@ -13,6 +13,7 @@ int muconvert_main(int argc, char *argv[]); int mudraw_main(int argc, char *argv[]); +int mutrace_main(int argc, char *argv[]); int murun_main(int argc, char *argv[]); int pdfclean_main(int argc, char *argv[]); @@ -38,6 +39,7 @@ static struct { { pdfcreate_main, "create", "create pdf document" }, #endif { mudraw_main, "draw", "convert document" }, + { mutrace_main, "trace", "trace device calls" }, #if FZ_ENABLE_PDF { pdfextract_main, "extract", "extract font and image resources" }, #endif diff --git a/source/tools/mutrace.c b/source/tools/mutrace.c new file mode 100644 index 00000000..2baef7d1 --- /dev/null +++ b/source/tools/mutrace.c @@ -0,0 +1,170 @@ +#include "mupdf/fitz.h" + +#include +#include +#include + +static void usage(void) +{ + fprintf(stderr, + "Usage: mutool trace [options] file [pages]\n" + "\t-p -\tpassword\n" + "\n" + "\t-W -\tpage width for EPUB layout\n" + "\t-H -\tpage height for EPUB layout\n" + "\t-S -\tfont size for EPUB layout\n" + "\t-U -\tfile name of user stylesheet for EPUB layout\n" + "\t-X\tdisable document styles for EPUB layout\n" + "\n" + "\t-d\tuse display list\n" + "\n" + "\tpages\tcomma separated list of page numbers and ranges\n" + ); + exit(1); +} + +static float layout_w = 450; +static float layout_h = 600; +static float layout_em = 12; +static char *layout_css = NULL; +static int layout_use_doc_css = 1; + +static int use_display_list = 0; + +static void runpage(fz_context *ctx, fz_document *doc, int number) +{ + fz_page *page = NULL; + fz_display_list *list = NULL; + fz_device *dev = NULL; + fz_rect mediabox; + + fz_var(page); + fz_var(list); + fz_var(dev); + fz_try(ctx) + { + page = fz_load_page(ctx, doc, number - 1); + fz_bound_page(ctx, page, &mediabox); + printf("\n", + number, mediabox.x0, mediabox.y0, mediabox.x1, mediabox.y1); + dev = fz_new_trace_device(ctx, fz_stdout(ctx)); + if (use_display_list) + { + list = fz_new_display_list_from_page(ctx, page); + fz_run_display_list(ctx, list, dev, &fz_identity, NULL, NULL); + } + else + { + fz_run_page(ctx, page, dev, &fz_identity, NULL); + } + printf("\n"); + } + fz_always(ctx) + { + fz_drop_display_list(ctx, list); + fz_drop_page(ctx, page); + fz_drop_device(ctx, dev); + } + fz_catch(ctx) + fz_rethrow(ctx); +} + +static void runrange(fz_context *ctx, fz_document *doc, int count, const char *range) +{ + int start, end, i; + + while ((range = fz_parse_page_range(ctx, range, &start, &end, count))) + { + if (start < end) + for (i = start; i <= end; ++i) + runpage(ctx, doc, i); + else + for (i = start; i >= end; --i) + runpage(ctx, doc, i); + } +} + +int mutrace_main(int argc, char **argv) +{ + fz_context *ctx; + fz_document *doc = NULL; + char *password = ""; + int i, c, count; + + while ((c = fz_getopt(argc, argv, "p:W:H:S:U:Xd")) != -1) + { + switch (c) + { + default: usage(); break; + case 'p': password = fz_optarg; break; + + case 'W': layout_w = fz_atof(fz_optarg); break; + case 'H': layout_h = fz_atof(fz_optarg); break; + case 'S': layout_em = fz_atof(fz_optarg); break; + case 'U': layout_css = fz_optarg; break; + case 'X': layout_use_doc_css = 0; break; + + case 'd': use_display_list = 1; break; + } + } + + if (fz_optind == argc) + usage(); + + ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); + if (!ctx) + { + fprintf(stderr, "cannot create mupdf context\n"); + return EXIT_FAILURE; + } + + fz_try(ctx) + { + fz_register_document_handlers(ctx); + if (layout_css) + { + fz_buffer *buf = fz_read_file(ctx, layout_css); + fz_set_user_css(ctx, fz_string_from_buffer(ctx, buf)); + fz_drop_buffer(ctx, buf); + } + fz_set_use_document_css(ctx, layout_use_doc_css); + } + fz_catch(ctx) + { + fprintf(stderr, "cannot initialize mupdf: %s\n", fz_caught_message(ctx)); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + fz_var(doc); + fz_try(ctx) + { + for (i = fz_optind; i < argc; ++i) + { + doc = fz_open_document(ctx, argv[i]); + if (fz_needs_password(ctx, doc)) + if (!fz_authenticate_password(ctx, doc, password)) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", argv[i]); + fz_layout_document(ctx, doc, layout_w, layout_h, layout_em); + printf("\n", argv[i]); + count = fz_count_pages(ctx, doc); + if (i+1 < argc && fz_is_page_range(ctx, argv[i+1])) + runrange(ctx, doc, count, argv[++i]); + else + runrange(ctx, doc, count, "1-N"); + printf("\n"); + fz_drop_document(ctx, doc); + doc = NULL; + } + } + fz_catch(ctx) + { + fprintf(stderr, "cannot run document: %s\n", fz_caught_message(ctx)); + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + fz_drop_context(ctx); + return EXIT_SUCCESS; +} -- cgit v1.2.3