diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | docs/index.html | 4 | ||||
-rw-r--r-- | docs/manual-mutool-trace.html | 102 | ||||
-rw-r--r-- | source/fitz/trace-device.c | 2 | ||||
-rw-r--r-- | source/tools/mutool.c | 2 | ||||
-rw-r--r-- | source/tools/mutrace.c | 170 |
6 files changed, 279 insertions, 3 deletions
@@ -351,7 +351,7 @@ INSTALL_LIBS := $(MUPDF_LIB) $(THIRD_LIB) # --- Tools and Apps --- MUTOOL_EXE := $(OUT)/mutool -MUTOOL_SRC := source/tools/mutool.c source/tools/muconvert.c source/tools/mudraw.c source/tools/murun.c +MUTOOL_SRC := source/tools/mutool.c source/tools/muconvert.c source/tools/mudraw.c source/tools/murun.c source/tools/mutrace.c MUTOOL_SRC += $(sort $(wildcard source/tools/pdf*.c)) MUTOOL_OBJ := $(MUTOOL_SRC:%.c=$(OUT)/%.o) $(MUTOOL_OBJ) : $(FITZ_HDR) $(PDF_HDR) diff --git a/docs/index.html b/docs/index.html index 314578f3..f91906d4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -61,7 +61,7 @@ The iOS viewer is available on the <a href="https://itunes.apple.com/us/app/mupd The command line tools are all gathered into one umbrella command: mutool. <p> -For rendering and converting documents there are two commands available: +For rendering and converting documents there are three commands available: <dl> <dt><a href="manual-mutool-draw.html">mutool draw</a> @@ -69,6 +69,8 @@ For rendering and converting documents there are two commands available: It is primarily used for rendering a document to image files. <dt><a href="manual-mutool-convert.html">mutool convert</a> <dd>This tool is used for converting documents into other formats, and is easier to use. +<dt><a href="manual-mutool-trace.html">mutool trace</a> +<dd>This is a debugging tool used for printing a trace of the graphics device calls on a page. </dl> <p> diff --git a/docs/manual-mutool-trace.html b/docs/manual-mutool-trace.html new file mode 100644 index 00000000..05e324c1 --- /dev/null +++ b/docs/manual-mutool-trace.html @@ -0,0 +1,102 @@ +<!DOCTYPE html> +<html> +<head> +<title>mutool trace</title> +<link rel="stylesheet" href="style.css" type="text/css"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +</head> + +<body> + +<header> +<h1>mutool trace</h1> +</header> + +<nav> +<a href="http://mupdf.com/index.html">ABOUT</a> +<a href="http://mupdf.com/news.html">NEWS</a> +<a href="index.html">DOCUMENTATION</a> +<a href="http://mupdf.com/downloads/">DOWNLOAD</a> +<a href="http://git.ghostscript.com/?p=mupdf.git;a=summary">SOURCE</a> +<a href="https://bugs.ghostscript.com/">BUGS</a> +</nav> + +<article> + +<p> +The 'mutool trace' command prints a trace of device calls needed to render a page. + +<pre> +mutool trace [options] input [pages] +</pre> + +<p> +The command line options are: + +<dl> +<dt><i>input</i> + <dd>Input file name. + The input can be any of the document formats supported by MuPDF: PDF, XPS, CBZ, unprotected EPUB, FB2, etc. +<dt>[pages] + <dd>Comma separated list of page ranges. The first page is "1", and the last page is "N". The default is "1-N". +<dt>-p <i>password</i> + <dd>Password to use for password protected PDF documents. +</dl> + +<dl> +<dt>-W <i>width</i> + <dd>Page width in points for EPUB layout. +<dt>-H <i>height</i> + <dd>Page height in points for EPUB layout. +<dt>-S <i>font-size</i> + <dd>Font size in points for EPUB layout. +<dt>-U <i>stylesheet.css</i> + <dd>File name of user style sheet for EPUB layout. +<dt>-X + <dd>Disable document styles for EPUB layout. +</dl> + +<dl> +<dt>-d + <dd>Use display list. Run the page to a display list first, then trace running the display list. +</dl> + +<p> +The trace takes the form of an XML document, with the root element being the document, +its children each page, and one page child element for each device call on that page. + +<p> +An example trace: + +<pre> +<document filename="hello.pdf"> +<page number="1" mediabox="0 0 595 842"> +<fill_path winding="nonzero" colorspace="DeviceRGB" color="1 0 0" matrix="1 0 0 -1 0 842"> +<moveto x="50" y="50"/> +<lineto x="100" y="200"/> +<lineto x="200" y="50"/> +</fill_path> +<fill_text colorspace="DeviceRGB" color="0" matrix="1 0 0 -1 0 842"> +<span font="Times-Roman" wmode="0" trm="100 0 0 100"> +<g unicode="H" glyph="H" x="50" y="500" /> +<g unicode="e" glyph="e" x="122.2" y="500" /> +<g unicode="l" glyph="l" x="166.6" y="500" /> +<g unicode="l" glyph="l" x="194.4" y="500" /> +<g unicode="o" glyph="o" x="222.2" y="500" /> +<g unicode="!" glyph="exclam" x="272.2" y="500" /> +</span> +</fill_text> +</page> +</document> + +</pre> + +</article> + +<footer> +<a href="http://artifex.com"><img src="artifex-logo.png" align="right"></a> +Copyright © 2006-2017 Artifex Software Inc. +</footer> + +</body> +</html> 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, "<tile"); + fz_write_printf(ctx, out, "<tile id=\"%d\"", id); fz_write_printf(ctx, out, " area=\"%g %g %g %g\"", area->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 <string.h> +#include <stdlib.h> +#include <stdio.h> + +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("<page number=\"%d\" mediabox=\"%g %g %g %g\">\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("</page>\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("<document filename=\"%s\">\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("</document>\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; +} |