home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / clients / pdfimpose.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  9.5 KB  |  333 lines  |  [TEXT/CWIE]

  1. /*---------------------------------------------------------------------------*
  2.  |              PDFlib - A library for generating PDF on the fly             |
  3.  +---------------------------------------------------------------------------+
  4.  | Copyright (c) 1997-2001 PDFlib GmbH and Thomas Merz. All rights reserved. |
  5.  +---------------------------------------------------------------------------+
  6.  |    This software is NOT in the public domain.  It can be used under two   |
  7.  |    substantially different licensing terms:                               |
  8.  |                                                                           |
  9.  |    The commercial license is available for a fee, and allows you to       |
  10.  |    - ship a commercial product based on PDFlib                            |
  11.  |    - implement commercial Web services with PDFlib                        |
  12.  |    - distribute (free or commercial) software when the source code is     |
  13.  |      not made available                                                   |
  14.  |    Details can be found in the file PDFlib-license.pdf.                   |
  15.  |                                                                           |
  16.  |    The "Aladdin Free Public License" doesn't require any license fee,     |
  17.  |    and allows you to                                                      |
  18.  |    - develop and distribute PDFlib-based software for which the complete  |
  19.  |      source code is made available                                        |
  20.  |    - redistribute PDFlib non-commercially under certain conditions        |
  21.  |    - redistribute PDFlib on digital media for a fee if the complete       |
  22.  |      contents of the media are freely redistributable                     |
  23.  |    Details can be found in the file aladdin-license.pdf.                  |
  24.  |                                                                           |
  25.  |    These conditions extend to ports to other programming languages.       |
  26.  |    PDFlib is distributed with no warranty of any kind. Commercial users,  |
  27.  |    however, will receive warranty and support statements in writing.      |
  28.  *---------------------------------------------------------------------------*/
  29.  
  30. /* $Id: pdfimpose.c,v 1.13 2001/04/04 12:55:57 tm Exp $
  31.  *
  32.  * Impose multiple PDF documents on a single sheet,
  33.  * or concatenate multiple PDFs (if no -g option is supplied)
  34.  * (requires the PDF import library PDI)
  35.  *
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41.  
  42. #if defined(__CYGWIN32__)
  43. #include <getopt.h>
  44. #elif defined(WIN32)
  45. int getopt(int argc, char * const argv[], const char *optstring);
  46. extern char *optarg;
  47. extern int optind;
  48. #elif !defined(WIN32) && !defined(MAC)
  49. #include <unistd.h>
  50. #endif
  51.  
  52. #include "pdflib.h"
  53.  
  54. /* Array of known page sizes including name, width, and height */
  55.  
  56. typedef struct { const char *name; float width; float height; } PageSize_s;
  57.  
  58. PageSize_s PageSizes[] = {
  59.     {"a0",      2380.0f, 3368.0f},
  60.     {"a1",      1684.0f, 2380.0f},
  61.     {"a2",      1190.0f, 1684.0f},
  62.     {"a3",      842.0f, 1190.0f},
  63.     {"a4",      595.0f, 842.0f},
  64.     {"a5",      421.0f, 595.0f},
  65.     {"a6",      297.0f, 421.0f},
  66.     {"b5",      501.0f, 709.0f},
  67.     {"letter",  612.0f, 792.0f},
  68.     {"legal",   612.0f, 1008.0f},
  69.     {"ledger",  1224.0f, 792.0f},
  70.     {"p11x17",  792.0f, 1224.0f}
  71. };
  72.  
  73. #define PAGESIZELISTLEN    (sizeof(PageSizes)/sizeof(PageSizes[0]))
  74.  
  75. static void
  76. usage(void)
  77. {
  78.     fprintf(stderr,
  79.     "pdfimpose: impose multiple PDF documents on a single sheet.\n");
  80.     fprintf(stderr, "(C) PDFlib GmbH and Thomas Merz 2001\n");
  81.     fprintf(stderr, "usage: pdfimpose [options] pdffiles(s)\n");
  82.     fprintf(stderr, "Available options:\n");
  83.     fprintf(stderr, "-b            print boxes around imposed pages\n");
  84.     fprintf(stderr,
  85.     "-g wxh        number of columns and rows per sheet (default: 1x1)\n");
  86.     fprintf(stderr, "-l            landscape mode\n");
  87.     fprintf(stderr, "-n            start each document on a new page\n");
  88.     fprintf(stderr, "-p <pagesize> page format (a0-a6, letter, legal, etc.)\n");
  89.     fprintf(stderr, "-o <file>     output file\n");
  90.     fprintf(stderr, "-q            quiet mode: do not emit info messages\n");
  91.  
  92.     exit(1);
  93. }
  94.  
  95. int
  96. main(int argc, char *argv[])
  97. {
  98.     char    *pdffilename = NULL;
  99.     PDF        *p;
  100.     int        opt;
  101.     int        doc, page;
  102.     int        pageno, docpages;
  103.     char    *filename;
  104.     int        quiet = 0, landscape = 0, boxes = 0, newpage = 0;
  105.     int        cols = 1, rows = 1;
  106.     int        c = 0, r = 0;
  107.     float    sheetwidth = 595.0f, sheetheight = 842.0f;
  108.     float    width, height, scale = 1.0f;
  109.     float    rowheight = 0.0f, colwidth = 0.0f;
  110.     
  111.     while ((opt = getopt(argc, argv, "bg:lnp:o:q")) != -1)
  112.     switch (opt) {
  113.         case 'b':
  114.         boxes = 1;
  115.         break;
  116.  
  117.         case 'g':
  118.         if (sscanf(optarg, "%dx%d", &rows, &cols) != 2) {
  119.             fprintf(stderr, "Error: Couldn't parse -g option.\n");
  120.             usage();
  121.         }
  122.         if (rows <= 0 || cols <= 0) {
  123.             fprintf(stderr, "Bad row or column number.\n");
  124.             usage();
  125.         }
  126.         break;
  127.  
  128.         case 'l':
  129.         landscape = 1;
  130.         break;
  131.  
  132.         case 'n':
  133.         newpage = 1;
  134.         break;
  135.  
  136.         case 'p':
  137.         for(c = 0; c < PAGESIZELISTLEN; c++)
  138.         if (!strcmp((const char *) optarg, PageSizes[c].name)) {
  139.             sheetheight = PageSizes[c].height;
  140.             sheetwidth = PageSizes[c].width;
  141.             break;
  142.         }
  143.         if (c == PAGESIZELISTLEN) {  /* page size name not found */
  144.             fprintf(stderr, "Error: Unknown page size %s.\n", optarg);
  145.             usage();
  146.         }
  147.         break;
  148.  
  149.         case 'o':
  150.         pdffilename = optarg;
  151.         break;
  152.  
  153.         case 'q':
  154.         quiet = 1;
  155.         break;
  156.  
  157.         case '?':
  158.         default:
  159.         usage();
  160.     }
  161.  
  162.     if (optind == argc) {
  163.     fprintf(stderr, "Error: no PDF files given.\n");
  164.     usage();
  165.     }
  166.  
  167.     if (pdffilename == NULL) {
  168.     fprintf(stderr, "Error: no PDF output file given.\n");
  169.     usage();
  170.     }
  171.  
  172.     p = PDF_new();
  173.  
  174.     if (PDF_open_file(p, pdffilename) == -1) {
  175.     fprintf(stderr, "Error: cannot open PDF output file '%s'.\n",
  176.         pdffilename);
  177.     exit(1);
  178.     }
  179.  
  180.     PDF_set_info(p, "Creator", "pdfimpose by PDFlib GmbH");
  181.  
  182.     PDF_set_parameter(p, "openaction", "fitpage");
  183.  
  184.     if (!quiet)
  185.     PDF_set_parameter(p, "pdiwarning", "true"); /* report PDI problems */
  186.  
  187.     /* multi-page imposition: calculate scaling factor and cell dimensions */
  188.     if (rows != 1 || cols != 1) {
  189.     if (landscape) {
  190.         height = sheetheight;
  191.         sheetheight = sheetwidth;
  192.         sheetwidth = height;
  193.     }
  194.  
  195.     if (rows > cols)
  196.         scale = 1.0f / rows;
  197.     else
  198.         scale = 1.0f / cols;
  199.  
  200.     rowheight = sheetheight * scale;
  201.     colwidth = sheetwidth * scale;
  202.     }
  203.  
  204.     /* process all PDF documents */
  205.     while (optind++ < argc) {
  206.     filename = argv[optind-1];
  207.  
  208.     if (!quiet)
  209.         fprintf(stderr, "Imposing '%s'...\n", filename);
  210.  
  211.     if ((doc = PDF_open_pdi(p, filename, "", 0)) == -1) {
  212.         if (quiet)
  213.         fprintf(stderr, "Couldn't open PDF input file '%s'\n",
  214.             filename);
  215.         continue;
  216.     }
  217.  
  218.     /* query number of pages in the document */
  219.     docpages = (int) PDF_get_pdi_value(p, "/Root/Pages/Count", doc, -1, 0);
  220.  
  221.     /* single cell only: concatenate, using original page dimensions */
  222.     if (rows == 1 && cols == 1) {
  223.         /* open all pages and add to the output file */
  224.         for (pageno = 1; pageno <= docpages ; pageno++) {
  225.  
  226.         page = PDF_open_pdi_page(p, doc, pageno, "");
  227.  
  228.         if (page == -1) {
  229.             /* we'll get an exception in verbose mode anyway */
  230.             if (quiet)
  231.             fprintf(stderr,
  232.                 "Couldn't open page %d of PDF file '%s'\n",
  233.                 pageno, filename);
  234.             break;
  235.         }
  236.  
  237.         sheetwidth = PDF_get_pdi_value(p, "width", doc, page, 0);
  238.         sheetheight = PDF_get_pdi_value(p, "height", doc, page, 0);
  239.  
  240.         PDF_begin_page(p, sheetwidth, sheetheight);
  241.  
  242.         /* define bookmark with filename */
  243.         if (pageno == 1)
  244.             PDF_add_bookmark(p, argv[optind-1], 0, 0);
  245.  
  246.         PDF_place_pdi_page(p, page, 0.0f, 0.0f, 1.0f, 1.0f);
  247.         PDF_close_pdi_page(p, page);
  248.         PDF_end_page(p);
  249.         }
  250.  
  251.     } else {        /* impose multiple pages */
  252.  
  253.         if (newpage)
  254.         r = c = 0;
  255.  
  256.         /* open all pages and add to the output file */
  257.         for (pageno = 1; pageno <= docpages ; pageno++) {
  258.  
  259.         page = PDF_open_pdi_page(p, doc, pageno, "");
  260.  
  261.         if (page == -1) {
  262.             /* we'll get an exception in verbose mode anyway */
  263.             if (quiet)
  264.             fprintf(stderr,
  265.                 "Couldn't open page %d of PDF file '%s'\n",
  266.                 pageno, filename);
  267.             break;
  268.         }
  269.  
  270.         /* start a new page */
  271.         if (r == 0 && c == 0)
  272.             PDF_begin_page(p, sheetwidth, sheetheight);
  273.         
  274.         /* define bookmark with filename */
  275.         if (pageno == 1)
  276.             PDF_add_bookmark(p, argv[optind-1], 0, 0);
  277.  
  278.         width = PDF_get_pdi_value(p, "width", doc, page, 0);
  279.         height = PDF_get_pdi_value(p, "height", doc, page, 0);
  280.  
  281.         /*
  282.          * The save/restore pair is required to get the clipping right,
  283.          * and helps PostScript printing manage its memory efficiently.
  284.          */
  285.         PDF_save(p);
  286.         PDF_rect(p, c * colwidth, sheetheight - (r + 1) * rowheight,
  287.             colwidth, rowheight);
  288.         PDF_clip(p);
  289.  
  290.         PDF_setcolor(p, "stroke", "gray", 0.0f, 0.0f, 0.0f, 0.0f);
  291.  
  292.         /* TODO: adjust scaling factor if page doesn't fit into  cell */
  293.         PDF_place_pdi_page(p, page,
  294.             c * colwidth, sheetheight - (r + 1) * rowheight,
  295.             scale, scale);
  296.  
  297.         PDF_close_pdi_page(p, page);
  298.  
  299.         /* only half of the linewidth will be drawn due to clip() */
  300.         if (boxes) {
  301.             PDF_setlinewidth(p, 1.0f * scale);
  302.             PDF_rect(p, c * colwidth,
  303.             sheetheight - (r + 1) * rowheight,
  304.             colwidth, rowheight);
  305.             PDF_stroke(p);
  306.         }
  307.  
  308.         PDF_restore(p);
  309.  
  310.         c++;
  311.         if (c == cols) {
  312.             c = 0;
  313.             r++;
  314.         }
  315.         if (r == rows) {
  316.             r = 0;
  317.             PDF_end_page(p);
  318.         }
  319.         }
  320.     }
  321.  
  322.     PDF_close_pdi(p, doc);
  323.     }
  324.  
  325.     /* finish last page if multi-page imposition */
  326.     if ((rows != 1 || cols != 1) && (r != 0 || c != 0))
  327.     PDF_end_page(p);
  328.  
  329.     PDF_close(p);
  330.     PDF_delete(p);
  331.     exit(0);
  332. }
  333.