From d4a41014bbcd57f8746da89065b09aff38110462 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 20 Mar 2014 17:25:10 +0100 Subject: Split mjs script generation to separate tool. It has no real reason to live in mudraw, and it does pull in the javascript dependency via pdf-form.c. --- source/tools/mjsgen.c | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++ source/tools/mudraw.c | 210 +---------------------------------- 2 files changed, 306 insertions(+), 206 deletions(-) create mode 100644 source/tools/mjsgen.c (limited to 'source/tools') diff --git a/source/tools/mjsgen.c b/source/tools/mjsgen.c new file mode 100644 index 00000000..3e11fde3 --- /dev/null +++ b/source/tools/mjsgen.c @@ -0,0 +1,302 @@ +/* + * mjs test file generation tool + */ + +#include "mupdf/fitz.h" +#include "mupdf/pdf.h" + +/* + A useful bit of bash script to call this to generate mjs files: + for f in tests_private/pdf/forms/v1.3/ *.pdf ; do g=${f%.*} ; echo $g ; ./mjsgen $g.pdf $g.mjs ; done + + Remove the space from "/ *.pdf" before running - can't leave that + in here, as it causes a warning about a possibly malformed comment. +*/ + +static char lorem[] = +"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum " +"vehicula augue id est lobortis mollis. Aenean vestibulum metus sed est " +"gravida non tempus lacus aliquet. Nulla vehicula lobortis tincidunt. " +"Donec malesuada nisl et lacus condimentum nec tincidunt urna gravida. " +"Sed dapibus magna eu velit ultrices non rhoncus risus lacinia. Fusce " +"vitae nulla volutpat elit dictum ornare at eu libero. Maecenas felis " +"enim, tempor a tincidunt id, commodo consequat lectus.\n" +"Morbi tincidunt adipiscing lacus eu dignissim. Pellentesque augue elit, " +"ultrices vitae fermentum et, faucibus et purus. Nam ante libero, lacinia " +"id tincidunt at, ultricies a lorem. Donec non neque at purus condimentum " +"eleifend quis sit amet libero. Sed semper, mi ut tempus tincidunt, lacus " +"eros pellentesque lacus, id vehicula est diam eu quam. Integer tristique " +"fringilla rhoncus. Phasellus convallis, justo ut mollis viverra, dui odio " +"euismod ante, nec fringilla nisl mi ac diam.\n" +"Maecenas mi urna, ornare commodo feugiat id, cursus in massa. Vivamus " +"augue augue, aliquam at varius eu, venenatis fermentum felis. Sed varius " +"turpis a felis ultrices quis aliquet nunc tincidunt. Suspendisse posuere " +"commodo nunc non viverra. Praesent condimentum varius quam, vel " +"consectetur odio volutpat in. Sed malesuada augue ut lectus commodo porta. " +"Vivamus eget mauris sit amet diam ultrices sollicitudin. Cras pharetra leo " +"non elit lacinia vulputate.\n" +"Donec ac enim justo, ornare scelerisque diam. Ut vel ante at lorem " +"placerat bibendum ultricies mattis metus. Phasellus in imperdiet odio. " +"Proin semper lacinia libero, sed rutrum eros blandit non. Duis tincidunt " +"ligula est, non pellentesque mauris. Aliquam in erat scelerisque lacus " +"dictum suscipit eget semper magna. Nullam luctus imperdiet risus a " +"semper.\n" +"Curabitur sit amet tempor sapien. Quisque et tortor in lacus dictum " +"pulvinar. Nunc at nisl ut velit vehicula hendrerit. Mauris elementum " +"sollicitudin leo ac ullamcorper. Proin vel leo nec justo tempus aliquet " +"nec ut mi. Pellentesque vel nisl id dui hendrerit fermentum nec quis " +"tortor. Proin eu sem luctus est consequat euismod. Vestibulum ante ipsum " +"primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce " +"consectetur ultricies nisl ornare dictum. Cras sagittis consectetur lorem " +"sed posuere. Mauris accumsan laoreet arcu, id molestie lorem faucibus eu. " +"Vivamus commodo, neque nec imperdiet pretium, lorem metus viverra turpis, " +"malesuada vulputate justo eros sit amet neque. Nunc quis justo elit, non " +"rutrum mauris. Maecenas blandit condimentum nibh, nec vulputate orci " +"pulvinar at. Proin sed arcu vel odio tempus lobortis sed posuere ipsum. Ut " +"feugiat pellentesque tortor nec ornare.\n"; + +static char *filename; +fz_output *out = NULL; + +static char *mujstest_filename = NULL; +static FILE *mujstest_file = NULL; +static int mujstest_count = 0; + +static void usage(void) +{ + fprintf(stderr, "usage: mjsgen [-p password] input.pdf output.mjs\n"); + exit(1); +} + +static void escape_string(FILE *out, int len, const char *string) +{ + while (len-- && *string) + { + char c = *string++; + switch (c) + { + case '\n': + fputc('\\', out); + fputc('n', out); + break; + case '\r': + fputc('\\', out); + fputc('r', out); + break; + case '\t': + fputc('\\', out); + fputc('t', out); + break; + default: + fputc(c, out); + } + } +} + +static void processpage(fz_context *ctx, fz_document *doc, int pagenum) +{ + fz_page *page; + int needshot = 0; + + fz_try(ctx) + { + page = fz_load_page(doc, pagenum - 1); + } + fz_catch(ctx) + { + fz_rethrow_message(ctx, "cannot load page %d in file '%s'", pagenum, filename); + } + + pdf_document *inter = pdf_specifics(doc); + pdf_widget *widget = NULL; + + if (inter) + widget = pdf_first_widget(inter, (pdf_page *)page); + + if (widget) + { + fprintf(mujstest_file, "GOTO %d\n", pagenum); + needshot = 1; + } + for (;widget; widget = pdf_next_widget(widget)) + { + fz_rect rect; + int w, h, len; + int type = pdf_widget_get_type(widget); + + pdf_bound_widget(widget, &rect); + w = (rect.x1 - rect.x0); + h = (rect.y1 - rect.y0); + ++mujstest_count; + switch (type) + { + default: + fprintf(mujstest_file, "%% UNKNOWN %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + case PDF_WIDGET_TYPE_PUSHBUTTON: + fprintf(mujstest_file, "%% PUSHBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + case PDF_WIDGET_TYPE_CHECKBOX: + fprintf(mujstest_file, "%% CHECKBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + case PDF_WIDGET_TYPE_RADIOBUTTON: + fprintf(mujstest_file, "%% RADIOBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + case PDF_WIDGET_TYPE_TEXT: + { + int maxlen = pdf_text_widget_max_len(inter, widget); + int texttype = pdf_text_widget_content_type(inter, widget); + + /* If height is low, assume a single row, and base + * the width off that. */ + if (h < 10) + { + w = (w+h-1) / (h ? h : 1); + h = 1; + } + /* Otherwise, if width is low, work off height */ + else if (w < 10) + { + h = (w+h-1) / (w ? w : 1); + w = 1; + } + else + { + w = (w+9)/10; + h = (h+9)/10; + } + len = w*h; + if (len < 2) + len = 2; + if (len > maxlen) + len = maxlen; + fprintf(mujstest_file, "%% TEXT %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + switch (texttype) + { + default: + case PDF_WIDGET_CONTENT_UNRESTRAINED: + fprintf(mujstest_file, "TEXT %d ", mujstest_count); + escape_string(mujstest_file, len-3, lorem); + fprintf(mujstest_file, "\n"); + break; + case PDF_WIDGET_CONTENT_NUMBER: + fprintf(mujstest_file, "TEXT %d\n", mujstest_count); + break; + case PDF_WIDGET_CONTENT_SPECIAL: +#ifdef __MINGW32__ + fprintf(mujstest_file, "TEXT %I64d\n", 46702919800LL + mujstest_count); +#else + fprintf(mujstest_file, "TEXT %lld\n", 46702919800LL + mujstest_count); +#endif + break; + case PDF_WIDGET_CONTENT_DATE: + fprintf(mujstest_file, "TEXT Jun %d 1979\n", 1 + ((13 + mujstest_count) % 30)); + break; + case PDF_WIDGET_CONTENT_TIME: + ++mujstest_count; + fprintf(mujstest_file, "TEXT %02d:%02d\n", ((mujstest_count/60) % 24), mujstest_count % 60); + break; + } + break; + } + case PDF_WIDGET_TYPE_LISTBOX: + fprintf(mujstest_file, "%% LISTBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + case PDF_WIDGET_TYPE_COMBOBOX: + fprintf(mujstest_file, "%% COMBOBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); + break; + } + fprintf(mujstest_file, "CLICK %0.2f %0.2f\n", (rect.x0+rect.x1)/2, (rect.y0+rect.y1)/2); + } + + fz_flush_warnings(ctx); + + if (mujstest_file && needshot) + { + fprintf(mujstest_file, "SCREENSHOT\n"); + } +} + +static void processpages(fz_context *ctx, fz_document *doc) +{ + int page, pagecount; + pagecount = fz_count_pages(doc); + for (page = 1; page <= pagecount; ++page) + processpage(ctx, doc, page); +} + +int main(int argc, char **argv) +{ + char *password = ""; + fz_document *doc = NULL; + fz_context *ctx; + int c; + + fz_var(doc); + + while ((c = fz_getopt(argc, argv, "p:")) != -1) + { + switch (c) + { + default: usage(); break; + case 'p': password = fz_optarg; break; + } + } + + if (fz_optind + 2 != argc) + usage(); + + filename = argv[fz_optind]; + mujstest_filename = argv[fz_optind+1]; + + if (strcmp(mujstest_filename, "-") == 0) + mujstest_file = stdout; + else + mujstest_file = fopen(mujstest_filename, "wb"); + + ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); + if (!ctx) + { + fprintf(stderr, "cannot initialise context\n"); + exit(1); + } + + fz_register_document_handlers(ctx); + + fz_try(ctx) + { + doc = fz_open_document(ctx, filename); + + if (fz_needs_password(doc)) + { + if (!fz_authenticate_password(doc, password)) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename); + fprintf(mujstest_file, "PASSWORD %s\n", password); + } + + fprintf(mujstest_file, "OPEN %s\n", filename); + + processpages(ctx, doc); + + fz_close_document(doc); + } + fz_catch(ctx) + { + fprintf(stderr, "mjsgen: cannot process document: %s\n", filename); + return 1; + } + + fclose(mujstest_file); + fz_free_context(ctx); + return 0; +} + +#ifdef _MSC_VER +int wmain(int argc, wchar_t *wargv[]) +{ + char **argv = fz_argv_from_wargv(argc, wargv); + int ret = main(argc, argv); + fz_free_argv(argc, argv); + return ret; +} +#endif diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 914f6ba5..0eb5e477 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -3,7 +3,7 @@ */ #include "mupdf/fitz.h" -#include "mupdf/pdf.h" /* for mujstest */ +#include "mupdf/pdf.h" /* for pdf output */ #ifdef _MSC_VER #include @@ -93,48 +93,6 @@ static const format_cs_table_t format_cs_table[] = in here, as it causes a warning about a possibly malformed comment. */ -static char lorem[] = -"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum " -"vehicula augue id est lobortis mollis. Aenean vestibulum metus sed est " -"gravida non tempus lacus aliquet. Nulla vehicula lobortis tincidunt. " -"Donec malesuada nisl et lacus condimentum nec tincidunt urna gravida. " -"Sed dapibus magna eu velit ultrices non rhoncus risus lacinia. Fusce " -"vitae nulla volutpat elit dictum ornare at eu libero. Maecenas felis " -"enim, tempor a tincidunt id, commodo consequat lectus.\n" -"Morbi tincidunt adipiscing lacus eu dignissim. Pellentesque augue elit, " -"ultrices vitae fermentum et, faucibus et purus. Nam ante libero, lacinia " -"id tincidunt at, ultricies a lorem. Donec non neque at purus condimentum " -"eleifend quis sit amet libero. Sed semper, mi ut tempus tincidunt, lacus " -"eros pellentesque lacus, id vehicula est diam eu quam. Integer tristique " -"fringilla rhoncus. Phasellus convallis, justo ut mollis viverra, dui odio " -"euismod ante, nec fringilla nisl mi ac diam.\n" -"Maecenas mi urna, ornare commodo feugiat id, cursus in massa. Vivamus " -"augue augue, aliquam at varius eu, venenatis fermentum felis. Sed varius " -"turpis a felis ultrices quis aliquet nunc tincidunt. Suspendisse posuere " -"commodo nunc non viverra. Praesent condimentum varius quam, vel " -"consectetur odio volutpat in. Sed malesuada augue ut lectus commodo porta. " -"Vivamus eget mauris sit amet diam ultrices sollicitudin. Cras pharetra leo " -"non elit lacinia vulputate.\n" -"Donec ac enim justo, ornare scelerisque diam. Ut vel ante at lorem " -"placerat bibendum ultricies mattis metus. Phasellus in imperdiet odio. " -"Proin semper lacinia libero, sed rutrum eros blandit non. Duis tincidunt " -"ligula est, non pellentesque mauris. Aliquam in erat scelerisque lacus " -"dictum suscipit eget semper magna. Nullam luctus imperdiet risus a " -"semper.\n" -"Curabitur sit amet tempor sapien. Quisque et tortor in lacus dictum " -"pulvinar. Nunc at nisl ut velit vehicula hendrerit. Mauris elementum " -"sollicitudin leo ac ullamcorper. Proin vel leo nec justo tempus aliquet " -"nec ut mi. Pellentesque vel nisl id dui hendrerit fermentum nec quis " -"tortor. Proin eu sem luctus est consequat euismod. Vestibulum ante ipsum " -"primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce " -"consectetur ultricies nisl ornare dictum. Cras sagittis consectetur lorem " -"sed posuere. Mauris accumsan laoreet arcu, id molestie lorem faucibus eu. " -"Vivamus commodo, neque nec imperdiet pretium, lorem metus viverra turpis, " -"malesuada vulputate justo eros sit amet neque. Nunc quis justo elit, non " -"rutrum mauris. Maecenas blandit condimentum nibh, nec vulputate orci " -"pulvinar at. Proin sed arcu vel odio tempus lobortis sed posuere ipsum. Ut " -"feugiat pellentesque tortor nec ornare.\n"; - static char *output = NULL; static char *format = NULL; static float resolution = 72; @@ -170,10 +128,6 @@ static char *filename; static int files = 0; fz_output *out = NULL; -static char *mujstest_filename = NULL; -static FILE *mujstest_file = NULL; -static int mujstest_count = 0; - static struct { int count, total; int min, max; @@ -208,7 +162,6 @@ static void usage(void) "\t-G -\tgamma correct output\n" "\t-I\tinvert output\n" "\t-l\tprint outline\n" - "\t-j -\tOutput mujstest file\n" "\t-i\tignore errors and continue with the next file\n" "\tpages\tcomma separated list of ranges\n"); exit(1); @@ -239,31 +192,6 @@ static int isrange(char *s) return 1; } -static void escape_string(FILE *out, int len, const char *string) -{ - while (len-- && *string) - { - char c = *string++; - switch (c) - { - case '\n': - fputc('\\', out); - fputc('n', out); - break; - case '\r': - fputc('\\', out); - fputc('r', out); - break; - case '\t': - fputc('\\', out); - fputc('t', out); - break; - default: - fputc(c, out); - } - } -} - static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) { fz_page *page; @@ -271,7 +199,6 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_device *dev = NULL; int start; fz_cookie cookie = { 0 }; - int needshot = 0; fz_var(list); fz_var(dev); @@ -290,111 +217,6 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_rethrow_message(ctx, "cannot load page %d in file '%s'", pagenum, filename); } - if (mujstest_file) - { - pdf_document *inter = pdf_specifics(doc); - pdf_widget *widget = NULL; - - if (inter) - widget = pdf_first_widget(inter, (pdf_page *)page); - - if (widget) - { - fprintf(mujstest_file, "GOTO %d\n", pagenum); - needshot = 1; - } - for (;widget; widget = pdf_next_widget(widget)) - { - fz_rect rect; - int w, h, len; - int type = pdf_widget_get_type(widget); - - pdf_bound_widget(widget, &rect); - w = (rect.x1 - rect.x0); - h = (rect.y1 - rect.y0); - ++mujstest_count; - switch (type) - { - default: - fprintf(mujstest_file, "%% UNKNOWN %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - case PDF_WIDGET_TYPE_PUSHBUTTON: - fprintf(mujstest_file, "%% PUSHBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - case PDF_WIDGET_TYPE_CHECKBOX: - fprintf(mujstest_file, "%% CHECKBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - case PDF_WIDGET_TYPE_RADIOBUTTON: - fprintf(mujstest_file, "%% RADIOBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - case PDF_WIDGET_TYPE_TEXT: - { - int maxlen = pdf_text_widget_max_len(inter, widget); - int texttype = pdf_text_widget_content_type(inter, widget); - - /* If height is low, assume a single row, and base - * the width off that. */ - if (h < 10) - { - w = (w+h-1) / (h ? h : 1); - h = 1; - } - /* Otherwise, if width is low, work off height */ - else if (w < 10) - { - h = (w+h-1) / (w ? w : 1); - w = 1; - } - else - { - w = (w+9)/10; - h = (h+9)/10; - } - len = w*h; - if (len < 2) - len = 2; - if (len > maxlen) - len = maxlen; - fprintf(mujstest_file, "%% TEXT %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - switch (texttype) - { - default: - case PDF_WIDGET_CONTENT_UNRESTRAINED: - fprintf(mujstest_file, "TEXT %d ", mujstest_count); - escape_string(mujstest_file, len-3, lorem); - fprintf(mujstest_file, "\n"); - break; - case PDF_WIDGET_CONTENT_NUMBER: - fprintf(mujstest_file, "TEXT %d\n", mujstest_count); - break; - case PDF_WIDGET_CONTENT_SPECIAL: -#ifdef __MINGW32__ - fprintf(mujstest_file, "TEXT %I64d\n", 46702919800LL + mujstest_count); -#else - fprintf(mujstest_file, "TEXT %lld\n", 46702919800LL + mujstest_count); -#endif - break; - case PDF_WIDGET_CONTENT_DATE: - fprintf(mujstest_file, "TEXT Jun %d 1979\n", 1 + ((13 + mujstest_count) % 30)); - break; - case PDF_WIDGET_CONTENT_TIME: - ++mujstest_count; - fprintf(mujstest_file, "TEXT %02d:%02d\n", ((mujstest_count/60) % 24), mujstest_count % 60); - break; - } - break; - } - case PDF_WIDGET_TYPE_LISTBOX: - fprintf(mujstest_file, "%% LISTBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - case PDF_WIDGET_TYPE_COMBOBOX: - fprintf(mujstest_file, "%% COMBOBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); - break; - } - fprintf(mujstest_file, "CLICK %0.2f %0.2f\n", (rect.x0+rect.x1)/2, (rect.y0+rect.y1)/2); - } - } - if (uselist) { fz_try(ctx) @@ -844,11 +666,6 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) fz_flush_warnings(ctx); - if (mujstest_file && needshot) - { - fprintf(mujstest_file, "SCREENSHOT\n"); - } - if (cookie.errors) errored = 1; } @@ -994,7 +811,7 @@ int main(int argc, char **argv) fz_var(doc); - while ((c = fz_getopt(argc, argv, "lo:F:p:r:R:b:c:dgmtx5G:Iw:h:fij:MB:")) != -1) + while ((c = fz_getopt(argc, argv, "lo:F:p:r:R:b:c:dgmtx5G:Iw:h:fiMB:")) != -1) { switch (c) { @@ -1019,7 +836,6 @@ int main(int argc, char **argv) case 'h': height = atof(fz_optarg); break; case 'f': fit = 1; break; case 'I': invert++; break; - case 'j': mujstest_filename = fz_optarg; break; case 'i': ignore_errors = 1; break; default: usage(); break; } @@ -1028,20 +844,12 @@ int main(int argc, char **argv) if (fz_optind == argc) usage(); - if (!showtext && !showxml && !showtime && !showmd5 && !showoutline && !output && !mujstest_filename) + if (!showtext && !showxml && !showtime && !showmd5 && !showoutline && !output) { printf("nothing to do\n"); exit(0); } - if (mujstest_filename) - { - if (strcmp(mujstest_filename, "-") == 0) - mujstest_file = stdout; - else - mujstest_file = fopen(mujstest_filename, "wb"); - } - ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), NULL, FZ_STORE_DEFAULT); if (!ctx) { @@ -1215,13 +1023,6 @@ int main(int argc, char **argv) { if (!fz_authenticate_password(doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", filename); - if (mujstest_file) - fprintf(mujstest_file, "PASSWORD %s\n", password); - } - - if (mujstest_file) - { - fprintf(mujstest_file, "OPEN %s\n", filename); } if (showxml || showtext == TEXT_XML) @@ -1230,7 +1031,7 @@ int main(int argc, char **argv) if (showoutline) drawoutline(ctx, doc); - if (showtext || showxml || showtime || showmd5 || output || mujstest_file) + if (showtext || showxml || showtime || showmd5 || output) { if (fz_optind == argc || !isrange(argv[fz_optind])) drawrange(ctx, doc, "1-"); @@ -1305,9 +1106,6 @@ int main(int argc, char **argv) } } - if (mujstest_file && mujstest_file != stdout) - fclose(mujstest_file); - fz_free_context(ctx); if (showmemory) -- cgit v1.2.3