--- poppler-0.26.3.orig/configure.ac 2014-07-20 18:18:46.000000000 +0200 +++ poppler-0.26.3/configure.ac 2014-07-24 13:06:44.253222194 +0200 @@ -48,7 +48,7 @@ ;; mingw*) os_win32=yes - win32_libs="-lgdi32" + win32_libs="-lgdi32 -lwinspool" create_shared_lib="-no-undefined" auto_import_flags="-Wl,--enable-auto-import" --- poppler-0.26.3.orig/utils/pdftocairo.cc 2014-04-26 17:37:22.000000000 +0200 +++ poppler-0.26.3/utils/pdftocairo.cc 2014-07-24 15:41:21.454064316 +0200 @@ -70,6 +70,9 @@ #if CAIRO_HAS_SVG_SURFACE #include #endif +#ifdef _WIN32 +#include +#endif static GBool png = gFalse; @@ -78,8 +81,14 @@ static GBool eps = gFalse; static GBool pdf = gFalse; static GBool svg = gFalse; +static GBool print = gFalse; static GBool tiff = gFalse; +#ifdef _WIN32 +static GooString printer; +static GooString printOpt; +#endif + static int firstPage = 1; static int lastPage = 0; static GBool printOnlyOdd = gFalse; @@ -150,6 +159,14 @@ {"-svg", argFlag, &svg, 0, "generate a Scalable Vector Graphics (SVG) file"}, #endif +#ifdef _WIN32 + {"-print", argFlag, &print, 0, + "print to a Windows printer"}, + {"-printer", argGooString, &printer, 0, + "printer name or use default if this option is not specified"}, + {"-printopt", argGooString, &printOpt, 0, + "printer options, with format =[,=]*"}, +#endif {"-f", argInt, &firstPage, 0, "first page to print"}, @@ -468,8 +485,115 @@ // shrink to fit cairo_matrix_scale (m, scale, scale); } +#ifdef _WIN32 + if (print) + { + HDC hdc = cairo_win32_surface_get_dc(surface); + int logx = GetDeviceCaps(hdc, LOGPIXELSX); + int logy = GetDeviceCaps(hdc, LOGPIXELSY); + cairo_matrix_scale (m, logx / 72.0, logy / 72.0); + } +#endif +} + +#ifdef _WIN32 +static void parseSource(DEVMODE *devmode, GooString *source) +{ + short src; + if (source->cmp("upper") == 0) + src = DMBIN_UPPER; + else if (source->cmp("onlyone") == 0) + src = DMBIN_ONLYONE; + else if (source->cmp("lower") == 0) + src = DMBIN_LOWER; + else if (source->cmp("middle") == 0) + src = DMBIN_MIDDLE; + else if (source->cmp("manual") == 0) + src = DMBIN_MANUAL; + else if (source->cmp("envelope") == 0) + src = DMBIN_ENVELOPE; + else if (source->cmp("envmanual") == 0) + src = DMBIN_ENVMANUAL; + else if (source->cmp("auto") == 0) + src = DMBIN_AUTO; + else if (source->cmp("tractor") == 0) + src = DMBIN_TRACTOR; + else if (source->cmp("smallfmt") == 0) + src = DMBIN_SMALLFMT; + else if (source->cmp("largefmt") == 0) + src = DMBIN_LARGEFMT; + else if (source->cmp("largecapacity") == 0) + src = DMBIN_LARGECAPACITY; + else if (source->cmp("formsource") == 0) + src = DMBIN_FORMSOURCE; + else if (isInt(source->getCString())) + src = atoi(source->getCString()); + else { + fprintf(stderr, "Warning: Unknown paper source \"%s\"\n", source->getCString()); + return; + } + + devmode->dmDefaultSource = src; + devmode->dmFields |= DM_DEFAULTSOURCE; +} + +static void parseDuplex(DEVMODE *devmode, GooString *source) +{ + short duplex; + + if (source->cmp("simplex") == 0) + duplex = DMDUP_SIMPLEX; + else if (source->cmp("horizontal") == 0) + duplex = DMDUP_HORIZONTAL; + else if (source->cmp("vertical") == 0) + duplex = DMDUP_VERTICAL; + else { + fprintf(stderr, "Warning: Unknown duplex mode \"%s\"\n", source->getCString()); + return; + } + + devmode->dmDuplex = duplex; + devmode->dmFields |= DM_DUPLEX; +} + +static void fillPrinterOptions(DEVMODE *devmode) +{ + //printOpt format is: =,=,... + const char *nextOpt = printOpt.getCString(); + while (nextOpt && *nextOpt) + { + const char *comma = strchr(nextOpt, ','); + GooString opt; + if (comma) { + opt.Set(nextOpt, comma - nextOpt); + nextOpt = comma + 1; + } else { + opt.Set(nextOpt); + nextOpt = NULL; + } + //here opt is "= " + const char *equal = strchr(opt.getCString(), '='); + if (!equal) { + fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.getCString()); + continue; + } + int iequal = equal - opt.getCString(); + GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1); + opt.del(iequal, opt.getLength() - iequal); + //here opt is "" and value is "" + + if (opt.cmp("source") == 0) { + parseSource(devmode, &value); + } else if (opt.cmp("duplex") == 0) { + parseDuplex(devmode, &value); + } else { + fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.getCString()); + } + } } +#endif + static cairo_status_t writeStream(void *closure, const unsigned char *data, unsigned int length) { FILE *file = (FILE *)closure; @@ -483,14 +607,16 @@ static void beginDocument(GooString *outputFileName, double w, double h) { if (printing) { - if (outputFileName->cmp("fd://0") == 0) - output_file = stdout; - else - { - output_file = fopen(outputFileName->getCString(), "wb"); - if (!output_file) { - fprintf(stderr, "Error opening output file %s\n", outputFileName->getCString()); - exit(2); + if (!print) { + if (outputFileName->cmp("fd://0") == 0) + output_file = stdout; + else + { + output_file = fopen(outputFileName->getCString(), "wb"); + if (!output_file) { + fprintf(stderr, "Error opening output file %s\n", outputFileName->getCString()); + exit(2); + } } } @@ -517,6 +643,52 @@ surface = cairo_svg_surface_create_for_stream(writeStream, output_file, w, h); cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2); #endif + } else if (print) { +#ifdef _WIN32 + if (printer.getCString()[0] == 0) + { + DWORD szName = 0; + GetDefaultPrinter(NULL, &szName); + char *devname = (char*)gmalloc(szName); + GetDefaultPrinter(devname, &szName); + printer.Set(devname); + gfree(devname); + } + char *cPrinter = printer.getCString(); + + //Query the size of the DEVMODE struct + LONG szProp = DocumentProperties(NULL, NULL, cPrinter, NULL, NULL, 0); + if (szProp < 0) + { + fprintf(stderr, "Error: Printer \"%s\" not found", cPrinter); + exit(99); + } + DEVMODE *devmode = (DEVMODE*)gmalloc(szProp); + memset(devmode, 0, szProp); + devmode->dmSize = sizeof(DEVMODE); + devmode->dmSpecVersion = DM_SPECVERSION; + //Load the current default configuration for the printer into devmode + if (DocumentProperties(NULL, NULL, cPrinter, devmode, NULL, DM_OUT_BUFFER) < 0) + { + fprintf(stderr, "Error: Printer \"%s\" not found", cPrinter); + exit(99); + } + fillPrinterOptions(devmode); + HDC hdc = CreateDC(NULL, cPrinter, NULL, devmode); + gfree(devmode); + if (!hdc) + { + fprintf(stderr, "Error: Printer \"%s\" not found", cPrinter); + exit(99); + } + + DOCINFO docinfo; + memset(&docinfo, 0, sizeof(docinfo)); + docinfo.cbSize = sizeof(docinfo); + docinfo.lpszDocName = "PDF document"; + StartDoc(hdc, &docinfo); + surface = cairo_win32_printing_surface_create(hdc); +#endif } } } @@ -540,6 +712,10 @@ if (pdf) cairo_pdf_surface_set_size (surface, w, h); #endif +#ifdef _WIN32 + if (print) + StartPage(cairo_win32_surface_get_dc(surface)); +#endif cairo_surface_set_fallback_resolution (surface, x_resolution, y_resolution); @@ -610,6 +786,10 @@ if (printing) { cairo_surface_show_page(surface); +#ifdef _WIN32 + if (print) + EndPage(cairo_win32_surface_get_dc(surface)); +#endif } else { writePageImage(imageFileName); cairo_surface_finish(surface); @@ -626,12 +806,21 @@ cairo_status_t status; if (printing) { +#ifdef _WIN32 + if (print) + { + HDC hdc = cairo_win32_surface_get_dc(surface); + EndDoc(hdc); + DeleteDC(hdc); + } +#endif cairo_surface_finish(surface); status = cairo_surface_status(surface); if (status) error(errInternal, -1, "cairo error: {0:s}\n", cairo_status_to_string(status)); cairo_surface_destroy(surface); - fclose(output_file); + if (output_file) + fclose(output_file); } } @@ -705,6 +894,9 @@ return new GooString(outputName); } + if (print) + return NULL; + if (fileName->cmp("fd://0") == 0) { fprintf(stderr, "Error: an output filename or '-' must be supplied when the PDF file is stdin.\n"); exit(99); @@ -808,13 +1000,14 @@ (ps ? 1 : 0) + (eps ? 1 : 0) + (pdf ? 1 : 0) + + (print ? 1 : 0) + (svg ? 1 : 0); if (num_outputs == 0) { - fprintf(stderr, "Error: one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -svg) must be used.\n"); + fprintf(stderr, "Error: one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -print, -svg) must be used.\n"); exit(99); } if (num_outputs > 1) { - fprintf(stderr, "Error: use only one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -svg).\n"); + fprintf(stderr, "Error: use only one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -print, -svg).\n"); exit(99); } if (png || jpeg || tiff)