diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2017-04-07 16:16:56 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2017-04-13 13:16:21 +0200 |
commit | 9c805cc9f934cd12e89014db8ad70e3191cdaf2d (patch) | |
tree | 5aece10eaccc25d060b2803c4d201341048caf96 /docs/examples | |
parent | 49d5a9856020627af1fc4063ff5a26b26e9270cf (diff) | |
download | mupdf-9c805cc9f934cd12e89014db8ad70e3191cdaf2d.tar.xz |
Move all examples to docs/examples directory.
Diffstat (limited to 'docs/examples')
-rw-r--r-- | docs/examples/create-thumbnail.js | 19 | ||||
-rw-r--r-- | docs/examples/draw-device.js | 45 | ||||
-rw-r--r-- | docs/examples/draw-document.js | 9 | ||||
-rw-r--r-- | docs/examples/example.c | 129 | ||||
-rw-r--r-- | docs/examples/multi-threaded.c | 289 | ||||
-rw-r--r-- | docs/examples/pdf-create-lowlevel.js | 63 | ||||
-rw-r--r-- | docs/examples/pdf-create.js | 35 | ||||
-rw-r--r-- | docs/examples/pdf-merge.js | 67 | ||||
-rw-r--r-- | docs/examples/trace-device.js | 102 |
9 files changed, 758 insertions, 0 deletions
diff --git a/docs/examples/create-thumbnail.js b/docs/examples/create-thumbnail.js new file mode 100644 index 00000000..120a8e88 --- /dev/null +++ b/docs/examples/create-thumbnail.js @@ -0,0 +1,19 @@ +// Create a PDF containing thumbnails of pages rendered from another PDF. + +var pdf = new PDFDocument() + +var subdoc = new Document("pdfref17.pdf") + +var resources = { XObject: {} } + +var contents = new Buffer() +for (var i=0; i < 5; ++i) { + var pixmap = subdoc.loadPage(1140+i).toPixmap([0.2,0,0,0.2,0,0], DeviceRGB, true) + resources.XObject["Im" + i] = pdf.addImage(new Image(pixmap)) + contents.writeLine("q 100 0 0 150 " + (50+100*i) + " 50 cm /Im" + i + " Do Q") +} + +var page = pdf.addPage([0,0,100+i*100,250], 0, resources, contents) +pdf.insertPage(-1, page) + +pdf.save("out.pdf") diff --git a/docs/examples/draw-device.js b/docs/examples/draw-device.js new file mode 100644 index 00000000..42ec263d --- /dev/null +++ b/docs/examples/draw-device.js @@ -0,0 +1,45 @@ +// Use device interface to draw some graphics and save as a PNG. + +var font = new Font("Times-Roman"); +var image = new Image("example.png"); +var path, text; + +var pixmap = new Pixmap(DeviceRGB, [0,0,500,600], false); +pixmap.clear(255); +var device = new DrawDevice(Identity, pixmap); +var transform = [2,0,0,2,0,0] +{ + text = new Text(); + { + text.showString(font, [16,0,0,-16,100,30], "Hello, world!"); + text.showString(font, [0,16,16,0,15,100], "Hello, world!"); + } + device.fillText(text, transform, DeviceGray, [0], 1); + + path = new Path(); + { + path.moveTo(10, 10); + path.lineTo(90, 10); + path.lineTo(90, 90); + path.lineTo(10, 90); + path.closePath(); + } + device.fillPath(path, false, transform, DeviceRGB, [1,0,0], 1); + device.strokePath(path, {dashes:[5,10], lineWidth:3, lineCap:'Round'}, transform, DeviceRGB, [0,0,0], 1); + + path = new Path(); + { + path.moveTo(100,100); + path.curveTo(150,100, 200,150, 200,200); + path.curveTo(200,300, 0,300, 100,100); + path.closePath(); + } + device.clipPath(path, true, transform); + { + device.fillImage(image, Concat(transform, [300,0,0,300,0,0]), 1); + } + device.popClip(); +} +device.close(); + +pixmap.saveAsPNG("out.png"); diff --git a/docs/examples/draw-document.js b/docs/examples/draw-document.js new file mode 100644 index 00000000..1e285ede --- /dev/null +++ b/docs/examples/draw-document.js @@ -0,0 +1,9 @@ +// Draw all pages in a document and save them as PNG files. + +var doc = new Document(argv[1]); +var n = doc.countPages(); +for (var i = 0; i < n; ++i) { + var page = doc.loadPage(i); + var pixmap = page.toPixmap(Identity, DeviceRGB); + pixmap.saveAsPNG("out" + (i+1) + ".png"); +} diff --git a/docs/examples/example.c b/docs/examples/example.c new file mode 100644 index 00000000..1bf67635 --- /dev/null +++ b/docs/examples/example.c @@ -0,0 +1,129 @@ +/* + How to use MuPDF to render a single page and print the result as a PPM to stdout. + + Build the mupdf library using make, then either run 'make examples' or + compile the example manually: + + gcc -Iinclude -o example.exe docs/example.c \ + build/debug/libmupdf.a \ + build/debug/libmupdfthird.a + -lcrypto \ + -lm + + ./example.exe document.pdf 100 0 1 +*/ + +#include <mupdf/fitz.h> + +int main(int argc, char **argv) +{ + char *input; + float zoom, rotate; + int page_number, page_count; + fz_context *ctx; + fz_document *doc; + fz_pixmap *pix; + fz_matrix ctm; + int x, y; + + if (argc < 3) + { + fprintf(stderr, "usage: example input-file page-number [ zoom [ rotate ] ]\n"); + fprintf(stderr, "\tinput-file: path of PDF, XPS, CBZ or EPUB document to open\n"); + fprintf(stderr, "\tPage numbering starts from one.\n"); + fprintf(stderr, "\tZoom level is in percent (100 percent is 72 dpi).\n"); + fprintf(stderr, "\tRotation is in degrees clockwise.\n"); + return EXIT_FAILURE; + } + + input = argv[1]; + page_number = atoi(argv[2]) - 1; + zoom = argc > 3 ? atof(argv[3]) : 100; + rotate = argc > 4 ? atof(argv[4]) : 0; + + /* Create a context to hold the exception stack and various caches. */ + ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); + if (!ctx) + { + fprintf(stderr, "cannot create mupdf context\n"); + return EXIT_FAILURE; + } + + /* Register the default file types to handle. */ + fz_try(ctx) + fz_register_document_handlers(ctx); + fz_catch(ctx) + { + fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx)); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + /* Open the document. */ + fz_try(ctx) + doc = fz_open_document(ctx, input); + fz_catch(ctx) + { + fprintf(stderr, "cannot open document: %s\n", fz_caught_message(ctx)); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + /* Count the number of pages. */ + fz_try(ctx) + page_count = fz_count_pages(ctx, doc); + fz_catch(ctx) + { + fprintf(stderr, "cannot count number of pages: %s\n", fz_caught_message(ctx)); + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + if (page_number < 0 || page_number >= page_count) + { + fprintf(stderr, "page number out of range: %d (page count %d)\n", page_number + 1, page_count); + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + /* Compute a transformation matrix for the zoom and rotation desired. */ + /* The default resolution without scaling is 72 dpi. */ + fz_scale(&ctm, zoom / 100, zoom / 100); + fz_pre_rotate(&ctm, rotate); + + /* Render page to an RGB pixmap. */ + fz_try(ctx) + pix = fz_new_pixmap_from_page_number(ctx, doc, page_number, &ctm, fz_device_rgb(ctx), 0); + fz_catch(ctx) + { + fprintf(stderr, "cannot render page: %s\n", fz_caught_message(ctx)); + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + return EXIT_FAILURE; + } + + /* Print image data in ascii PPM format. */ + printf("P3\n"); + printf("%d %d\n", pix->w, pix->h); + printf("255\n"); + for (y = 0; y < pix->h; ++y) + { + unsigned char *p = &pix->samples[y * pix->stride]; + for (x = 0; x < pix->w; ++x) + { + if (x > 0) + printf(" "); + printf("%3d %3d %3d", p[0], p[1], p[2]); + p += pix->n; + } + printf("\n"); + } + + /* Clean up. */ + fz_drop_pixmap(ctx, pix); + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + return EXIT_SUCCESS; +} diff --git a/docs/examples/multi-threaded.c b/docs/examples/multi-threaded.c new file mode 100644 index 00000000..15fdcba2 --- /dev/null +++ b/docs/examples/multi-threaded.c @@ -0,0 +1,289 @@ +// Multi-threaded rendering of all pages in a document to PNG images. + +// First look at doc/example.c and make sure you understand it. +// Then read the multi-threading section in doc/overview.txt, +// before coming back here to see an example of multi-threading. + +// This example will create one main thread for reading pages from the +// document, and one thread per page for rendering. After rendering +// the main thread will wait for each rendering thread to complete before +// writing that thread's rendered image to a PNG image. There is +// nothing in MuPDF requiring a rendering thread to only render a +// single page, this is just a design decision taken for this example. + +// Compile a debug build of mupdf, then compile and run this example: +// +// gcc -g -o build/debug/example-mt -Iinclude docs/multi-threaded.c \ +// build/debug/libmupdf.a \ +// build/debug/libmupdfthird.a \ +// -lpthread -lcrypto -lm +// +// build/debug/example-mt /path/to/document.pdf +// +// Caution! As all pages are rendered simultaneously, please choose a +// file with just a few pages to avoid stressing your machine too +// much. Also you may run in to a limitation on the number of threads +// depending on your environment. + +// Include the MuPDF header file, and pthread's header file. +#include <mupdf/fitz.h> +#include <pthread.h> + +// A convenience function for dying abruptly on pthread errors. + +void +fail(char *msg) +{ + fprintf(stderr, "%s\n", msg); + abort(); +} + +// The data structure passed between the requesting main thread and +// each rendering thread. + +struct data { + // A pointer to the original context in the main thread sent + // from main to rendering thread. It will be used to create + // each rendering thread's context clone. + fz_context *ctx; + + // Page number sent from main to rendering thread for printing + int pagenumber; + + // The display list as obtained by the main thread and sent + // from main to rendering thread. This contains the drawing + // commands (text, images, etc.) for the page that should be + // rendered. + fz_display_list *list; + + // The area of the page to render as obtained by the main + // thread and sent from main to rendering thread. + fz_rect bbox; + + // This is the result, a pixmap containing the rendered page. + // It is passed first from main thread to the rendering + // thread, then its samples are changed by the rendering + // thread, and then back from the rendering thread to the main + // thread. + fz_pixmap *pix; +}; + +// This is the function run by each rendering function. It takes +// pointer to an instance of the data structure described above and +// renders the display list into the pixmap before exiting. + +void * +renderer(void *data) +{ + int pagenumber = ((struct data *) data)->pagenumber; + fz_context *ctx = ((struct data *) data)->ctx; + fz_display_list *list = ((struct data *) data)->list; + fz_rect bbox = ((struct data *) data)->bbox; + fz_pixmap *pix = ((struct data *) data)->pix; + fz_device *dev; + + fprintf(stderr, "thread at page %d loading!\n", pagenumber); + + // The context pointer is pointing to the main thread's + // context, so here we create a new context based on it for + // use in this thread. + + ctx = fz_clone_context(ctx); + + // Next we run the display list through the draw device which + // will render the request area of the page to the pixmap. + + fprintf(stderr, "thread at page %d rendering!\n", pagenumber); + dev = fz_new_draw_device(ctx, &fz_identity, pix); + fz_run_display_list(ctx, list, dev, &fz_identity, &bbox, NULL); + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + + // This threads context is freed. + + fz_drop_context(ctx); + + fprintf(stderr, "thread at page %d done!\n", pagenumber); + + return data; +} + +// These are the two locking functions required by MuPDF when +// operating in a multi-threaded environment. They each take a user +// argument that can be used to transfer some state, in this case a +// pointer to the array of mutexes. + +void lock_mutex(void *user, int lock) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *) user; + + if (pthread_mutex_lock(&mutex[lock]) != 0) + fail("pthread_mutex_lock()"); +} + +void unlock_mutex(void *user, int lock) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *) user; + + if (pthread_mutex_unlock(&mutex[lock]) != 0) + fail("pthread_mutex_unlock()"); +} + +int main(int argc, char **argv) +{ + char *filename = argc >= 2 ? argv[1] : ""; + pthread_t *thread = NULL; + fz_locks_context locks; + pthread_mutex_t mutex[FZ_LOCK_MAX]; + fz_context *ctx; + fz_document *doc; + int threads; + int i; + + // Initialize FZ_LOCK_MAX number of non-recursive mutexes. + + for (i = 0; i < FZ_LOCK_MAX; i++) + { + if (pthread_mutex_init(&mutex[i], NULL) != 0) + fail("pthread_mutex_init()"); + } + + // Initialize the locking structure with function pointers to + // the locking functions and to the user data. In this case + // the user data is a pointer to the array of mutexes so the + // locking functions can find the relevant lock to change when + // they are called. This way we avoid global variables. + + locks.user = mutex; + locks.lock = lock_mutex; + locks.unlock = unlock_mutex; + + // This is the main threads context function, so supply the + // locking structure. This context will be used to parse all + // the pages from the document. + + ctx = fz_new_context(NULL, &locks, FZ_STORE_UNLIMITED); + + // Register default file types. + + fz_register_document_handlers(ctx); + + // Open the PDF, XPS or CBZ document. Note, this binds doc to ctx. + // You must only ever use doc with ctx - never a clone of it! + + doc = fz_open_document(ctx, filename); + + // Retrieve the number of pages, which translates to the + // number of threads used for rendering pages. + + threads = fz_count_pages(ctx, doc); + fprintf(stderr, "spawning %d threads, one per page...\n", threads); + + thread = malloc(threads * sizeof (pthread_t)); + + for (i = 0; i < threads; i++) + { + fz_page *page; + fz_rect bbox; + fz_irect rbox; + fz_display_list *list; + fz_device *dev; + fz_pixmap *pix; + struct data *data; + + // Load the relevant page for each thread. Note, that this + // cannot be done on the worker threads, as each use of doc + // uses ctx, and only one thread can be using ctx at a time. + + page = fz_load_page(ctx, doc, i); + + // Compute the bounding box for each page. + + fz_bound_page(ctx, page, &bbox); + + // Create a display list that will hold the drawing + // commands for the page. Once we have the display list + // this can safely be used on any other thread as it is + // not bound to a given context. + + list = fz_new_display_list(ctx, &bbox); + + // Run the loaded page through a display list device + // to populate the page's display list. + + dev = fz_new_list_device(ctx, list); + fz_run_page(ctx, page, dev, &fz_identity, NULL); + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + + // The page is no longer needed, all drawing commands + // are now in the display list. + + fz_drop_page(ctx, page); + + // Create a white pixmap using the correct dimensions. + + pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), fz_round_rect(&rbox, &bbox), 0); + fz_clear_pixmap_with_value(ctx, pix, 0xff); + + // Populate the data structure to be sent to the + // rendering thread for this page. + + data = malloc(sizeof (struct data)); + + data->pagenumber = i + 1; + data->ctx = ctx; + data->list = list; + data->bbox = bbox; + data->pix = pix; + + // Create the thread and pass it the data structure. + + if (pthread_create(&thread[i], NULL, renderer, data) != 0) + fail("pthread_create()"); + } + + // Now each thread is rendering pages, so wait for each thread + // to complete its rendering. + + fprintf(stderr, "joining %d threads...\n", threads); + for (i = threads - 1; i >= 0; i--) + { + char filename[42]; + struct data *data; + + if (pthread_join(thread[i], (void **) &data) != 0) + fail("pthread_join"); + + sprintf(filename, "out%04d.png", i); + fprintf(stderr, "\tSaving %s...\n", filename); + + // Write the rendered image to a PNG file + + fz_save_pixmap_as_png(ctx, data->pix, filename); + + // Free the thread's pixmap and display list since + // they were allocated by the main thread above. + + fz_drop_pixmap(ctx, data->pix); + fz_drop_display_list(ctx, data->list); + + // Free the data structured passed back and forth + // between the main thread and rendering thread. + + free(data); + } + + fprintf(stderr, "finally!\n"); + fflush(NULL); + + free(thread); + + // Finally the document is closed and the main thread's + // context is freed. + + fz_drop_document(ctx, doc); + fz_drop_context(ctx); + + return 0; +} diff --git a/docs/examples/pdf-create-lowlevel.js b/docs/examples/pdf-create-lowlevel.js new file mode 100644 index 00000000..658adfb5 --- /dev/null +++ b/docs/examples/pdf-create-lowlevel.js @@ -0,0 +1,63 @@ +// Create a PDF from scratch. + +// This example creates a new PDF file from scratch, using only the low level APIs. +// This assumes a basic working knowledge of the PDF file format. + +// Create a new empty document with no pages. +var pdf = new PDFDocument() + +// Create and add a font resource. +var font = pdf.addObject({ + Type: "Font", + Subtype: "Type1", + Encoding: "WinAnsiEncoding", + BaseFont: "Times-Roman", +}) + +// Create and add an image resource: +// Allocate a slot for a new object and get a reference to it. +var image = pdf.createObject() +// Write a dictionary object into the slot. +image.writeObject({ + Type: "XObject", + Subtype: "Image", + Width: 4, + Height: 2, + BitsPerComponent: 8, + ColorSpace: "DeviceGray", + // The compression filter to be used: + Filter: "ASCIIHexDecode", +}) +// Write raw stream data into the slot; hex encoded +// to match the Filter entry in the dictionary. +image.writeRawStream("004488CCEEBB7733>") + +// Create resource dictionary. +var resources = pdf.addObject({ + Font: { Tm: font }, + XObject: { Im0: image }, +}) + +// Create content stream. +var buffer = new Buffer() +buffer.writeLine("10 10 280 330 re s") +buffer.writeLine("q 200 0 0 200 50 100 cm /Im0 Do Q") +buffer.writeLine("BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET") +var contents = pdf.addStream(buffer) + +// Create page object. +var page = pdf.addObject({ + Type: "Page", + MediaBox: [0,0,300,350], + Contents: contents, + Resources: resources, +}) + +// Insert page object into page tree. +var pagetree = pdf.getTrailer().Root.Pages +pagetree.Count = 1 +pagetree.Kids = [ page ] +page.Parent = pagetree + +// Save the document. +pdf.save("out.pdf") diff --git a/docs/examples/pdf-create.js b/docs/examples/pdf-create.js new file mode 100644 index 00000000..290d1737 --- /dev/null +++ b/docs/examples/pdf-create.js @@ -0,0 +1,35 @@ +// Create a PDF from scratch using helper functions. + +// This example creates a new PDF file from scratch, using helper +// functions to create resources and page objects. +// This assumes a basic working knowledge of the PDF file format. + +// Create a new empty document with no pages. +var pdf = new PDFDocument() + +// Load built-in font and create WinAnsi encoded simple font resource. +var font = pdf.addSimpleFont(new Font("Times-Roman")) + +// Load PNG file and create image resource. +var image = pdf.addImage(new Image("example.png")) + +// Create resource dictionary. +var resources = pdf.addObject({ + Font: { Tm: font }, + XObject: { Im0: image }, +}) + +// Create content stream data. +var contents = + "10 10 280 330 re s\n" + + "q 200 0 0 200 50 100 cm /Im0 Do Q\n" + + "BT /Tm 16 Tf 50 50 TD (Hello, world!) Tj ET\n" + +// Create a new page object. +var page = pdf.addPage([0,0,300,350], 0, resources, contents) + +// Insert page object at the end of the document. +pdf.insertPage(-1, page) + +// Save the document to file. +pdf.save("out.pdf", "pretty,ascii,compress-images,compress-fonts") diff --git a/docs/examples/pdf-merge.js b/docs/examples/pdf-merge.js new file mode 100644 index 00000000..d8cdcfcb --- /dev/null +++ b/docs/examples/pdf-merge.js @@ -0,0 +1,67 @@ +// A re-implementation of "mutool merge" in JavaScript. + +function graftObject(dstDoc, srcDoc, srcObj, map) { + var srcNum, dstRef, dstObj + if (!map) + map = [] + if (srcObj.isIndirect()) { + srcNum = srcObj.toIndirect() + if (map[srcNum]) + return map[srcNum] + map[srcNum] = dstRef = dstDoc.createObject() + dstRef.writeObject(graftObject(dstDoc, srcDoc, srcObj.resolve(), map)) + if (srcObj.isStream()) + dstRef.writeRawStream(srcObj.readRawStream()) + return dstRef + } + if (srcObj.isArray()) { + dstObj = dstDoc.newArray() + srcObj.forEach(function (key, val) { + dstObj[key] = graftObject(dstDoc, srcDoc, val, map) + }) + return dstObj + } + if (srcObj.isDictionary()) { + dstObj = dstDoc.newDictionary() + srcObj.forEach(function (key, val) { + dstObj[key] = graftObject(dstDoc, srcDoc, val, map) + }) + return dstObj + } + return srcObj /* primitive objects are not bound to a document */ +} + +function copyPage(dstDoc, srcDoc, pageNumber, map) { + var srcPage, dstPage + srcPage = srcDoc.findPage(pageNumber) + dstPage = dstDoc.newDictionary() + dstPage.Type = dstDoc.newName("Page") + if (srcPage.MediaBox) dstPage.MediaBox = graftObject(dstDoc, srcDoc, srcPage.MediaBox, map) + if (srcPage.Rotate) dstPage.Rotate = graftObject(dstDoc, srcDoc, srcPage.Rotate, map) + if (srcPage.Resources) dstPage.Resources = graftObject(dstDoc, srcDoc, srcPage.Resources, map) + if (srcPage.Contents) dstPage.Contents = graftObject(dstDoc, srcDoc, srcPage.Contents, map) + dstDoc.insertPage(-1, dstDoc.addObject(dstPage)) +} + +function copyAllPages(dstDoc, srcDoc) { + var k, n = srcDoc.countPages() + var srcMap = [] + for (k = 0; k < n; ++k) + copyPage(dstDoc, srcDoc, k, srcMap) +} + +function pdfmerge() { + var srcDoc, dstDoc, i + + dstDoc = new PDFDocument() + for (i = 2; i < argv.length; ++i) { + srcDoc = new PDFDocument(argv[i]) + copyAllPages(dstDoc, srcDoc) + } + dstDoc.save(argv[1], "compress") +} + +if (argv.length < 3) + print("usage: mutool run pdf-merge.js output.pdf input1.pdf input2.pdf ...") +else + pdfmerge() diff --git a/docs/examples/trace-device.js b/docs/examples/trace-device.js new file mode 100644 index 00000000..9d7d4373 --- /dev/null +++ b/docs/examples/trace-device.js @@ -0,0 +1,102 @@ +var Q = JSON.stringify + +var pathPrinter = { + moveTo: function (x,y) { print("moveTo", x, y) }, + lineTo: function (x,y) { print("lineTo", x, y) }, + curveTo: function (x1,y1,x2,y2,x3,y3) { print("curveTo", x1, y1, x2, y2, x3 ,y3) }, + closePath: function () { print("closePath") }, +} + +var textPrinter = { + showGlyph: function (f,m,g,u,v,b) { print("glyph",f,m,g,u,v,b) }, +} + +var traceDevice = { + fillPath: function (path, evenOdd, ctm, colorSpace, color, alpha) { + print("fillPath", evenOdd, ctm, colorSpace, color, alpha) + path.walk(pathPrinter) + }, + clipPath: function (path, evenOdd, ctm) { + print("clipPath", evenOdd, ctm) + path.walk(pathPrinter) + }, + strokePath: function (path, stroke, ctm, colorSpace, color, alpha) { + print("strokePath", Q(stroke), ctm, colorSpace, color, alpha) + path.walk(pathPrinter) + }, + clipStrokePath: function (path, stroke, ctm) { + print("clipStrokePath", Q(stroke), ctm) + path.walk(pathPrinter) + }, + + fillText: function (text, ctm, colorSpace, color, alpha) { + print("fillText", ctm, colorSpace, color, alpha) + text.walk(textPrinter) + }, + clipText: function (text, ctm) { + print("clipText", ctm) + text.walk(textPrinter) + }, + strokeText: function (text, stroke, ctm, colorSpace, color, alpha) { + print("strokeText", Q(stroke), ctm, colorSpace, color, alpha) + text.walk(textPrinter) + }, + clipStrokeText: function (text, stroke, ctm) { + print("clipStrokeText", Q(stroke), ctm) + text.walk(textPrinter) + }, + ignoreText: function (text, ctm) { + print("ignoreText", ctm) + text.walk(textPrinter) + }, + + fillShade: function (shade, ctm, alpha) { + print("fillShade", shade, ctm, alpha) + }, + fillImage: function (image, ctm, alpha) { + print("fillImage", image, ctm, alpha) + }, + fillImageMask: function (image, ctm, colorSpace, color, alpha) { + print("fillImageMask", image, ctm, colorSpace, color, alpha) + }, + clipImageMask: function (image, ctm) { + print("clipImageMask", image, ctm) + }, + + beginMask: function (area, luminosity, colorspace, color) { + print("beginMask", area, luminosity, colorspace, color) + }, + endMask: function () { + print("endMask") + }, + + popClip: function () { + print("popClip") + }, + + beginGroup: function (area, isolated, knockout, blendmode, alpha) { + print("beginGroup", area, isolated, knockout, blendmode, alpha) + }, + endGroup: function () { + print("endGroup") + }, + beginTile: function (area, view, xstep, ystep, ctm, id) { + print("beginTile", area, view, xstep, ystep, ctm, id) + return 0 + }, + endTile: function () { + print("endTile") + }, + + close: function () { + print("close") + }, +} + +if (argv.length != 3) + print("usage: mutool run trace-device.js document.pdf pageNumber") +else { + var doc = new Document(argv[1]); + var page = doc.loadPage(parseInt(argv[2])-1); + page.run(traceDevice, Identity); +} |