--- a/utils/pdftocairo.cc 2014-04-26 17:37:22.000000000 +0200 +++ b/utils/pdftocairo.cc 2014-06-12 10:53:00.834222128 +0200 @@ -70,6 +70,9 @@ #if CAIRO_HAS_SVG_SURFACE #include #endif +#ifdef _WIN32 +#include +#endif static GBool png = gFalse; @@ -78,8 +81,13 @@ static GBool eps = gFalse; static GBool pdf = gFalse; static GBool svg = gFalse; +static GBool prn = gFalse; static GBool tiff = gFalse; +#ifdef _WIN32 +static int prnSource = 0; +#endif + static int firstPage = 1; static int lastPage = 0; static GBool printOnlyOdd = gFalse; @@ -150,6 +158,12 @@ {"-svg", argFlag, &svg, 0, "generate a Scalable Vector Graphics (SVG) file"}, #endif +#ifdef _WIN32 + {"-prn", argFlag, &prn, 0, + "print to a Windows printer"}, + {"-prnsource", argInt, &prnSource, 0, + "select the paper source of the printer (0: default; 4: manual; 7: auto; see DMBIN_*)"}, +#endif {"-f", argInt, &firstPage, 0, "first page to print"}, @@ -468,6 +482,15 @@ // shrink to fit cairo_matrix_scale (m, scale, scale); } +#ifdef _WIN32 + if (prn) + { + 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 } static cairo_status_t writeStream(void *closure, const unsigned char *data, unsigned int length) @@ -483,14 +506,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 (!prn) { + 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 +542,54 @@ 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 (prn) { +#ifdef _WIN32 + char *devname; + if (outputFileName) + { + devname = outputFileName->getCString(); + } + else + { + DWORD szName = 0; + GetDefaultPrinter(NULL, &szName); + devname = (char*)malloc(szName); + GetDefaultPrinter(devname, &szName); + } + + LONG szProp = DocumentProperties(NULL, NULL, devname, NULL, NULL, 0); + if (szProp < 0) + { + fprintf(stderr, "Error: Printer \"%s\" not found", devname); + exit(99); + } + DEVMODE *pdevmode = (DEVMODE*)malloc(szProp); + memset(pdevmode, 0, szProp); + pdevmode->dmSize = sizeof(DEVMODE); + if (DocumentProperties(NULL, NULL, devname, pdevmode, NULL, DM_OUT_BUFFER) < 0) + { + fprintf(stderr, "Error: Printer \"%s\" not found", devname); + exit(99); + } + if (prnSource != 0) + pdevmode->dmDefaultSource = prnSource; + HDC hdc = CreateDC(NULL, devname, NULL, pdevmode); + free(pdevmode); + if (!hdc) + { + fprintf(stderr, "Error: Printer \"%s\" not found", devname); + exit(99); + } + if (!outputFileName) + free(devname); + + 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 +613,10 @@ if (pdf) cairo_pdf_surface_set_size (surface, w, h); #endif +#ifdef _WIN32 + if (prn) + StartPage(cairo_win32_surface_get_dc(surface)); +#endif cairo_surface_set_fallback_resolution (surface, x_resolution, y_resolution); @@ -610,6 +687,10 @@ if (printing) { cairo_surface_show_page(surface); +#ifdef _WIN32 + if (prn) + EndPage(cairo_win32_surface_get_dc(surface)); +#endif } else { writePageImage(imageFileName); cairo_surface_finish(surface); @@ -626,12 +707,21 @@ cairo_status_t status; if (printing) { +#ifdef _WIN32 + if (prn) + { + 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 +795,9 @@ return new GooString(outputName); } + if (prn) + 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 +901,14 @@ (ps ? 1 : 0) + (eps ? 1 : 0) + (pdf ? 1 : 0) + + (prn ? 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, -prn, -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, -prn, -svg).\n"); exit(99); } if (png || jpeg || tiff)