コード例 #1
0
ファイル: pdf.c プロジェクト: MaChao5/pdfviewer-win32
static void set_matrix(internal_t*i, double m00, double m01, double m10, double m11)
{
    restore_matrix(i);

    i->m00 = m00;
    i->m01 = m01;
    i->m10 = m10;
    i->m11 = m11;

    PDF_save(i->p);
    PDF_setmatrix(i->p, m00, -m01, m10, -m11, 0, i->height+2*i->config_ypad);
    i->has_matrix = 1;
}
コード例 #2
0
ファイル: pdf.c プロジェクト: MaChao5/pdfviewer-win32
void pdf_startclip(gfxdevice_t*dev, gfxline_t*line)
{
    internal_t*i = (internal_t*)dev->internal;
    
    restore_matrix(i);
    PDF_save(i->p);
    
    if(mkline(line, i->p, i->config_xpad, i->config_ypad, 1.0, 1))
	PDF_clip(i->p);
    else   
	; // TODO: strictly speaking, an empty clip clears everything
    
    reset_matrix(i);
}
コード例 #3
0
ファイル: PDFText.cpp プロジェクト: AmirAbrams/haiku
void
PDFWriter::DrawChar(uint16 unicode, const char* utf8, int16 size)
{
	// try to convert from utf8 to MacRoman encoding schema...
	int32 srcLen  = size;
	int32 destLen = 1;
	char dest[3] = "\0\0";
	int32 state = 0;
	bool embed = true;
	font_encoding encoding = macroman_encoding;
	char fontName[B_FONT_FAMILY_LENGTH+B_FONT_STYLE_LENGTH+1];

	if (convert_from_utf8(B_MAC_ROMAN_CONVERSION, utf8, &srcLen, dest, &destLen,
			&state, 0) != B_OK || dest[0] == 0) {
		// could not convert to MacRoman
		font_encoding fenc;
		uint16 index = 0;
		uint8 enc;

		GetFontName(&fState->beFont, fontName);
		embed = EmbedFont(fontName);

		REPORT(kDebug, -1, "find_encoding unicode %d\n", (int)unicode);
		if (find_encoding(unicode, enc, index)) {
			// is code point in the Adobe Glyph List?
			// Note if rendering the glyphs only would be desired, we could
			// always use the second method below (MakeUserDefinedEncoding),
			// but extracting text from the generated PDF would be almost
			// impossible (OCR!)
			REPORT(kDebug, -1, "encoding for %x -> %d %d", unicode, (int)enc,
				(int)index);
			// use one of the user pre-defined encodings
			if (fState->beFont.FileFormat() == B_TRUETYPE_WINDOWS) {
				encoding = font_encoding(enc + tt_encoding0);
			} else {
				encoding = font_encoding(enc + t1_encoding0);
			}
			*dest = index;
		} else if (embed) {
			// if the font is embedded, create a user defined encoding at runtime
			uint8 index;
			MakeUserDefinedEncoding(unicode, enc, index);
			*dest = index;
			encoding = font_encoding(user_defined_encoding_start + enc);
		} else if (find_in_cid_tables(unicode, fenc, index, fFontSearchOrder)) {
			// font is not embedded use one of the CJK fonts for substitution
			REPORT(kDebug, -1, "cid table %d index = %d", (int)fenc, (int)index);
			dest[0] = unicode / 256;
			dest[1] = unicode % 256;
			destLen = 2;
			encoding = fenc;
			embed = false;
		} else {
			static bool found = false;
			REPORT(kDebug, -1, "encoding for %x not found!", (int)unicode);
			if (!found) {
				found = true;
				REPORT(kError, fPage, "Could not find an encoding for character "
					"with unicode %d! Message is not repeated for other unicode "
					"values.", (int)unicode);
			}
			*dest = 0; // paint a box (is 0 a box in MacRoman) or
			return; // simply skip character
		}
	} else {
		REPORT(kDebug, -1, "macroman srcLen=%d destLen=%d dest= %d %d!", srcLen,
			destLen, (int)dest[0], (int)dest[1]);
	}

	// Note we have to build the user defined encoding before it is used in
	// PDF_find_font!
	if (!MakesPDF()) return;

	int		font;

	GetFontName(&fState->beFont, fontName, embed, encoding);
	font = FindFont(fontName, embed, encoding);
	if (font < 0) {
		REPORT(kWarning, fPage, "**** PDF_findfont(%s) failed, back to default "
			"font", fontName);
		font = PDF_findfont(fPdf, "Helvetica", "macroman", 0);
	}

	fState->font = font;

	uint16 face = fState->beFont.Face();
	PDF_set_parameter(fPdf, "underline", (face & B_UNDERSCORE_FACE) != 0
		? "true" : "false");
	PDF_set_parameter(fPdf, "strikeout", (face & B_STRIKEOUT_FACE) != 0
		? "true" : "false");
	PDF_set_value(fPdf, "textrendering", (face & B_OUTLINED_FACE) != 0 ? 1 : 0);

	PDF_setfont(fPdf, fState->font, scale(fState->beFont.Size()));

	const float x = tx(fState->penX);
	const float y = ty(fState->penY);
	const float rotation = fState->beFont.Rotation();
	const bool rotate = rotation != 0.0;

	if (rotate) {
		PDF_save(fPdf);
		PDF_translate(fPdf, x, y);
		PDF_rotate(fPdf, rotation);
	    PDF_set_text_pos(fPdf, 0, 0);
	} else
	    PDF_set_text_pos(fPdf, x, y);

	PDF_show2(fPdf, dest, destLen);

	if (rotate) {
		PDF_restore(fPdf);
	}
}
コード例 #4
0
ファイル: document.c プロジェクト: Amaury/Carta-Genius
/*
** cg_cut_lines()
** Write the cut lines in a page.
*/
yerr_t cg_cut_lines(cg_t *carta, cg_deck_t *deck, cg_back_t back)
{
  int i;
  double color_luminance = 0;

  /* hidden-ditch */
  PDF_save(carta->p);
  if ((back == BACK_NO && deck->ditch_odd) ||
      (back != BACK_NO && deck->ditch_even))
    {
      unsigned int hex1, hex2, hex3;
      double col1, col2, col3;
      char *used_color = (back == BACK_NO) ? deck->ditch_odd : deck->ditch_even;

      sscanf(used_color, "#%02x%02x%02x", &hex1, &hex2, &hex3);
      col1 = (double)hex1 / 255;
      col2 = (double)hex2 / 255;
      col3 = (double)hex3 / 255;
      color_luminance = (col1 * LUMINANCE_RED) + (col2 * LUMINANCE_GREEN) +
	(col3 * LUMINANCE_BLUE);
      PDF_setcolor(carta->p, "fill", "rgb", col1, col2, col3, 0.0);
      PDF_rect(carta->p, YVAL2PT(deck->paper_margin_w) / 2.0,
	       YVAL2PT(deck->paper_margin_h) / 2.0,
	       YVAL2PT(deck->paper_width) - YVAL2PT(deck->paper_margin_w),
	       YVAL2PT(deck->paper_height) - YVAL2PT(deck->paper_margin_h));
      PDF_fill(carta->p);
    }
  PDF_restore(carta->p);

  /* external cut lines */
  PDF_save(carta->p);
  PDF_setcolor(carta->p, "fillstroke", "rgb", 0.0, 0.0, 0.0, 0.0);
  for (i = 0; i <= deck->cols; ++i)
    {
      double x, y;

      if (i == deck->cols && YVAL2PT(deck->space_width))
	break ;
      x = YVAL2PT(deck->paper_margin_w) + (i * YVAL2PT(deck->card_width)) +
	(i * YVAL2PT(deck->space_width));
      if (back == BACK_HEIGHT || back == BACK_WIDTH)
	x = YVAL2PT(deck->paper_width) - YVAL2PT(deck->paper_margin_w) -
	  (i * YVAL2PT(deck->card_width)) - (i * YVAL2PT(deck->space_width));
      y = 0.0;
      PDF_moveto(carta->p, x, y);
      y = YVAL2PT(deck->paper_margin_h) / 2.0;
      PDF_lineto(carta->p, x, y);
      y = YVAL2PT(deck->paper_height);
      PDF_moveto(carta->p, x, y);
      y = YVAL2PT(deck->paper_height) -
	(YVAL2PT(deck->paper_margin_h) / 2.0);
      PDF_lineto(carta->p, x, y);
      /* second cut line - space between cards */
      if (i < deck->cols && YVAL2PT(deck->space_width))
	{
	  if (back == BACK_HEIGHT || back == BACK_WIDTH)
	    x -= YVAL2PT(deck->card_width);
	  else
	    x += YVAL2PT(deck->card_width);
	  y = 0.0;
	  PDF_moveto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_margin_h) / 2.0;
	  PDF_lineto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_height);
	  PDF_moveto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_height) -
	    (YVAL2PT(deck->paper_margin_h) / 2.0);
	  PDF_lineto(carta->p, x, y);
	}
    }
  for (i = 0; i <= deck->rows; ++i)
    {
      double x, y;

      if (i == deck->rows && YVAL2PT(deck->space_height))
	break ;
      x = 0.0;
      y = YVAL2PT(deck->paper_margin_h) + (i * YVAL2PT(deck->card_height)) +
	(i * YVAL2PT(deck->space_height));
      PDF_moveto(carta->p, x, y);
      x = YVAL2PT(deck->paper_margin_w) / 2.0;
      PDF_lineto(carta->p, x, y);
      x = YVAL2PT(deck->paper_width);
      PDF_moveto(carta->p, x, y);
      x = YVAL2PT(deck->paper_width) -
	(YVAL2PT(deck->paper_margin_w) / 2.0);
      PDF_lineto(carta->p, x, y);
      /* second cut line - space between cards */
      if (i < deck->rows && YVAL2PT(deck->space_height))
	{
	  x = 0.0;
	  y += YVAL2PT(deck->card_height);
	  PDF_moveto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_margin_w) / 2.0;
	  PDF_lineto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_width);
	  PDF_moveto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_width) -
	    (YVAL2PT(deck->paper_margin_w) / 2.0);
	  PDF_lineto(carta->p, x, y);
	}
    }
  PDF_stroke(carta->p);
  PDF_restore(carta->p);

  /* internal cut lines */
  PDF_save(carta->p);
  if (color_luminance >= LUMINANCE_THRESHOLD)
    PDF_setcolor(carta->p, "fillstroke", "rgb", 0.0, 0.0, 0.0, 0.0);
  else
    PDF_setcolor(carta->p, "fillstroke", "rgb", 1.0, 1.0, 1.0, 0.0);
  for (i = 0; i <= deck->cols; ++i)
    {
      double x, y;

      if (i == deck->cols && YVAL2PT(deck->space_width))
	break ;
      x = YVAL2PT(deck->paper_margin_w) + (i * YVAL2PT(deck->card_width)) +
	(i * YVAL2PT(deck->space_width));
      if (back == BACK_HEIGHT || back == BACK_WIDTH)
	x = YVAL2PT(deck->paper_width) - YVAL2PT(deck->paper_margin_w) -
	  (i * YVAL2PT(deck->card_width)) - (i * YVAL2PT(deck->space_width));
      y = YVAL2PT(deck->paper_margin_h) / 2.0;
      PDF_moveto(carta->p, x, y);
      y = YVAL2PT(deck->paper_margin_h) * 2.0 / 3.0;
      PDF_lineto(carta->p, x, y);
      y = YVAL2PT(deck->paper_height) -
	(YVAL2PT(deck->paper_margin_h) / 2.0);
      PDF_moveto(carta->p, x, y);
      y = YVAL2PT(deck->paper_height) -
	(YVAL2PT(deck->paper_margin_h) * 2.0 / 3.0);
      PDF_lineto(carta->p, x, y);
      /* second cut line - space between cards */
      if (i < deck->cols && YVAL2PT(deck->space_width))
	{
	  if (back == BACK_HEIGHT || back == BACK_WIDTH)
	    x -= YVAL2PT(deck->card_width);
	  else
	    x += YVAL2PT(deck->card_width);
	  y = YVAL2PT(deck->paper_margin_h) / 2.0;
	  PDF_moveto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_margin_h) * 2.0 / 3.0;
	  PDF_lineto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_height) -
	    (YVAL2PT(deck->paper_margin_h) / 2.0);
	  PDF_moveto(carta->p, x, y);
	  y = YVAL2PT(deck->paper_height) -
	    (YVAL2PT(deck->paper_margin_h) * 2.0 / 3.0);
	  PDF_lineto(carta->p, x, y);
	}
    }
  for (i = 0; i <= deck->rows; ++i)
    {
      double x, y;

      if (i == deck->rows && YVAL2PT(deck->space_height))
	break ;
      x = YVAL2PT(deck->paper_margin_w) / 2.0;
      y = YVAL2PT(deck->paper_margin_h) + (i * YVAL2PT(deck->card_height)) +
	(i * YVAL2PT(deck->space_height));
      PDF_moveto(carta->p, x, y);
      x = YVAL2PT(deck->paper_margin_w) * 2.0 / 3.0;
      PDF_lineto(carta->p, x, y);
      x = YVAL2PT(deck->paper_width) - (YVAL2PT(deck->paper_margin_w) / 2.0);
      PDF_moveto(carta->p, x, y);
      x = YVAL2PT(deck->paper_width) -
	(YVAL2PT(deck->paper_margin_w) * 2.0 / 3.0);
      PDF_lineto(carta->p, x, y);
      /* second cut line - space between cards */
      if (i < deck->rows && YVAL2PT(deck->space_height))
	{
	  x = YVAL2PT(deck->paper_margin_w) / 2.0;
	  y += YVAL2PT(deck->card_height);
	  PDF_moveto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_margin_w) * 2.0 / 3.0;
	  PDF_lineto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_width) -
	    (YVAL2PT(deck->paper_margin_w) / 2.0);
	  PDF_moveto(carta->p, x, y);
	  x = YVAL2PT(deck->paper_width) -
	    (YVAL2PT(deck->paper_margin_w) * 2.0 / 3.0);
	  PDF_lineto(carta->p, x, y);
	}
    }
  PDF_stroke(carta->p);
  PDF_restore(carta->p);
  return (YENOERR);
}
コード例 #5
0
ファイル: pdfclock.c プロジェクト: AmirAbrams/haiku
int
main(void)
{
    PDF		*p;
    float	alpha;
    time_t	timer;
    struct tm	ltime;

    /* create a new PDFlib object */
    if ((p = PDF_new()) == (PDF *) 0)
    {
        printf("Couldn't create PDFlib object (out of memory)!\n");
        return(2);
    }

    PDF_TRY(p) {
	/* open new PDF file */
	if (PDF_open_file(p, "pdfclock.pdf") == -1) {
	    printf("Error: %s\n", PDF_get_errmsg(p));
	    return(2);
	}

	/* This line is required to avoid problems on Japanese systems */
	PDF_set_parameter(p, "hypertextencoding", "host");

	PDF_set_info(p, "Creator", "pdfclock.c");
	PDF_set_info(p, "Author", "Thomas Merz");
	PDF_set_info(p, "Title", "PDF clock (C)");

	PDF_begin_page(p, (float) (2 * (RADIUS + MARGIN)),
			  (float) (2 * (RADIUS + MARGIN)));
	
	PDF_translate(p, RADIUS + MARGIN, RADIUS + MARGIN);
	PDF_setcolor(p, "fillstroke", "rgb", 0, 0, 1, 0);
	PDF_save(p);

	/* minute strokes */
	PDF_setlinewidth(p, 2);
	for (alpha = 0; alpha < 360; alpha += 6)
	{
	    PDF_rotate(p, 6);
	    PDF_moveto(p, RADIUS, 0);
	    PDF_lineto(p, (float) (RADIUS-MARGIN/3), 0);
	    PDF_stroke(p);
	}

	PDF_restore(p);
	PDF_save(p);

	/* 5 minute strokes */
	PDF_setlinewidth(p, 3);
	for (alpha = 0; alpha < 360; alpha += 30)
	{
	    PDF_rotate(p, 30);
	    PDF_moveto(p, RADIUS, 0);
	    PDF_lineto(p, RADIUS-MARGIN, 0);
	    PDF_stroke(p);
	}

	time(&timer);
	ltime = *localtime(&timer);

	/* draw hour hand */
	PDF_save(p);
	PDF_rotate(p, 
		(float)(-((ltime.tm_min/60.0) + ltime.tm_hour - 3.0) * 30.0));
	PDF_moveto(p, -RADIUS/10, -RADIUS/20);
	PDF_lineto(p, RADIUS/2, 0);
	PDF_lineto(p, -RADIUS/10, RADIUS/20);
	PDF_closepath(p);
	PDF_fill(p);
	PDF_restore(p);

	/* draw minute hand */
	PDF_save(p);
	PDF_rotate(p,
		(float) (-((ltime.tm_sec/60.0) + ltime.tm_min - 15.0) * 6.0));
	PDF_moveto(p, -RADIUS/10, -RADIUS/20);
	PDF_lineto(p, RADIUS * 0.8f, 0);
	PDF_lineto(p, -RADIUS/10, RADIUS/20);
	PDF_closepath(p);
	PDF_fill(p);
	PDF_restore(p);

	/* draw second hand */
	PDF_setcolor(p, "fillstroke", "rgb", 1, 0, 0, 0);
	PDF_setlinewidth(p, 2);
	PDF_save(p);
	PDF_rotate(p, (float) -((ltime.tm_sec - 15.0) * 6.0));
	PDF_moveto(p, -RADIUS/5, 0);
	PDF_lineto(p, RADIUS, 0);
	PDF_stroke(p);
	PDF_restore(p);

	/* draw little circle at center */
	PDF_circle(p, 0, 0, (float) RADIUS/30);
	PDF_fill(p);

	PDF_restore(p);

	PDF_end_page(p);

	PDF_close(p);
    }

    PDF_CATCH(p) {
        printf("PDFlib exception occurred in pdfclock sample:\n");
        printf("[%d] %s: %s\n",
	    PDF_get_errnum(p), PDF_get_apiname(p), PDF_get_errmsg(p));
        PDF_delete(p);
        return(2);
    }

    PDF_delete(p);				/* delete the PDFlib object */

    return 0;
}
コード例 #6
0
ファイル: p_image.c プロジェクト: jimmccurdy/ArchiveGit
PDFLIB_API void PDFLIB_CALL
PDF_place_image(PDF *p, int im, float x, float y, float scale)
{
    static const char fn[] = "PDF_place_image";
    pdf_matrix m;
    pdf_image *image;
    int row;
    int imageno;

    PDF_TRACE(("%s\t(pdf[%p], %d, %f, %f, %f);\n",
	fn, (void *) p, im, x, y, scale));

    if (PDF_SANITY_CHECK_FAILED(p))
	return;

    if (im < 0 || im >= p->images_capacity || !p->images[im].in_use
	|| p->xobjects[p->images[im].no].type == pdi_xobject)
    {
    	pdf_error(p, PDF_ValueError,
		"Bad image or template handle %d in PDF_place_image", im);
    }

    PDF_CHECK_SCOPE(p, fn, pdf_state_ppt);

    if (PDF_GET_STATE(p) == pdf_state_template && im == p->templ)
	pdf_error(p, PDF_ValueError,
		"Can't use template within its own definition");

    image = &p->images[im];

    if (fabs(scale) < (float) PDF_SMALLREAL)
	pdf_error(p, PDF_ValueError,
		"Scaling factor 0 for image %s", image->filename);

    if (p->xobjects[image->no].type == form_xobject) {
	pdf_end_text(p);
	pdf_begin_contents_section(p);

	imageno = image->no;
	
	m.a = scale;
	m.d = scale;
	m.b = m.c = (float) 0.0;
	m.e = x;
	m.f = y;

	PDF_save(p);

	    pdf_concat_raw(p, &m);
	    if (!p->inheritgs)
		pdf_reset_gstate(p);

	    pdf_printf(p, "/I%d Do\n", imageno);
	    p->xobjects[imageno].flags |= xobj_flag_write;

	PDF_restore(p);

	return;
    }

    switch (image->colorspace) {
        case ImageMask:
        case DeviceGray:
	    p->procset	|= ImageB;
	    break;

	/*
	 * It appears that indexed images require both, although this is
	 * not documented.
	 */
        case Indexed:
	    p->procset	|= ImageI;
	    p->procset	|= ImageC;
	    break;

        case DeviceRGB:
        case DeviceCMYK:
	    p->procset	|= ImageC;
	    break;

	case CalGray:
        case CalRGB:
        case Lab:
        case PatternCS:
        case Separation:
            pdf_error(p, PDF_SystemError,
                "Bogus colorspace (%d) in PDF_place_image",
                    (int) image->colorspace);

        /* image has been colorized with a spot color */
        default:
            break;
    
	/* york: check the above carefully!
	** original version:
	default:
	    pdf_error(p, PDF_SystemError,
	    	"Bogus colorspace (%d) in PDF_place_image",
		    (int) image->colorspace);
	*/
    }

    pdf_end_text(p);
    pdf_begin_contents_section(p);

    imageno = image->no;	/* number of first strip */

    if (image->strips == 1)
	image->rowsperstrip = (int) image->height;

    for (row = 0; row < image->height; row += image->rowsperstrip, imageno++) {
	int height;	/* height of the current strip */

	height = (row + image->rowsperstrip > image->height ? 
		    (int) image->height - row : image->rowsperstrip);

	PDF_save(p);

	m.a = image->width * scale;
	m.d = height * scale;
	m.b = m.c = (float) 0.0;
	m.e = x;
	m.f = y + scale * (image->height - row - height);
	pdf_concat_raw(p, &m);

	pdf_printf(p, "/I%d Do\n", imageno);
	p->xobjects[imageno].flags |= xobj_flag_write;

	if (image->mask != -1)
	    p->xobjects[p->images[image->mask].no].flags |= xobj_flag_write;

	PDF_restore(p);
    }
}
コード例 #7
0
ファイル: pdfimpose.c プロジェクト: AmirAbrams/haiku
int
main(int argc, char *argv[])
{
    char	*pdffilename = NULL;
    char	*pdfversion = NULL;
    PDF		*p;
    int		opt;
    int		doc, page;
    int		pageno, docpages;
    char	*filename;
    int		quiet = 0, landscape = 0, boxes = 0, newpage = 0;
    int		cols = 1, rows = 1;
    int		c = 0, r = 0;
    float	sheetwidth = 595.0f, sheetheight = 842.0f;
    float	width, height, scale = 1.0f;
    float	rowheight = 0.0f, colwidth = 0.0f;
    
    while ((opt = getopt(argc, argv, "bg:lnp:o:qv:")) != -1)
	switch (opt) {
	    case 'b':
		boxes = 1;
		break;

	    case 'g':
		if (sscanf(optarg, "%dx%d", &rows, &cols) != 2) {
		    fprintf(stderr, "Error: Couldn't parse -g option.\n");
		    usage();
		}
		if (rows <= 0 || cols <= 0) {
		    fprintf(stderr, "Bad row or column number.\n");
		    usage();
		}
		break;

	    case 'l':
		landscape = 1;
		break;

	    case 'n':
		newpage = 1;
		break;

	    case 'p':
		for(c = 0; c < PAGESIZELISTLEN; c++)
		if (!strcmp((const char *) optarg, PageSizes[c].name)) {
		    sheetheight = PageSizes[c].height;
		    sheetwidth = PageSizes[c].width;
		    break;
		}
		if (c == PAGESIZELISTLEN) {  /* page size name not found */
		    fprintf(stderr, "Error: Unknown page size '%s'.\n", optarg);
		    usage();
		}
		break;

	    case 'o':
		pdffilename = optarg;
		break;

	    case 'v':
		pdfversion = optarg;
		if (strcmp(pdfversion, "1.3") && strcmp(pdfversion, "1.4") &&
		    strcmp(pdfversion, "1.5")) {
		    fprintf(stderr, "Error: bad PDF version number '%s'.\n",
		    	optarg);
		    usage();
		}

		break;

	    case 'q':
		quiet = 1;
		break;

	    case '?':
	    default:
		usage();
	}

    if (optind == argc) {
	fprintf(stderr, "Error: no PDF files given.\n");
	usage();
    }

    if (pdffilename == NULL) {
	fprintf(stderr, "Error: no PDF output file given.\n");
	usage();
    }

    p = PDF_new();

    if (pdfversion)
	PDF_set_parameter(p, "compatibility", pdfversion);

    if (PDF_open_file(p, pdffilename) == -1) {
	fprintf(stderr, "Error: %s.\n", PDF_get_errmsg(p));
	exit(1);
    }

    PDF_set_info(p, "Creator", "pdfimpose by PDFlib GmbH");

    PDF_set_parameter(p, "openaction", "fitpage");

    if (!quiet)
	PDF_set_parameter(p, "pdiwarning", "true"); /* report PDI problems */

    /* multi-page imposition: calculate scaling factor and cell dimensions */
    if (rows != 1 || cols != 1) {
	if (landscape) {
	    height = sheetheight;
	    sheetheight = sheetwidth;
	    sheetwidth = height;
	}

	if (rows > cols)
	    scale = 1.0f / rows;
	else
	    scale = 1.0f / cols;

	rowheight = sheetheight * scale;
	colwidth = sheetwidth * scale;
    }

    /* process all PDF documents */
    while (optind++ < argc) {
	filename = argv[optind-1];

	if (!quiet)
	    fprintf(stderr, "Imposing '%s'...\n", filename);

	if ((doc = PDF_open_pdi(p, filename, "", 0)) == -1) {
	    if (quiet)
		fprintf(stderr, "Error: %s.\n", PDF_get_errmsg(p));
	    continue;
	}

	/* query number of pages in the document */
	docpages = (int) PDF_get_pdi_value(p, "/Root/Pages/Count", doc, -1, 0);

	/* single cell only: concatenate, using original page dimensions */
	if (rows == 1 && cols == 1) {
	    /* open all pages and add to the output file */
	    for (pageno = 1; pageno <= docpages ; pageno++) {

		page = PDF_open_pdi_page(p, doc, pageno, "");

		if (page == -1) {
		    /* we'll get an exception in verbose mode anyway */
		    if (quiet)
			fprintf(stderr,
			    "Couldn't open page %d of PDF file '%s' (%s)\n",
			    pageno, filename, PDF_get_errmsg(p));
		    break;
		}

		sheetwidth = PDF_get_pdi_value(p, "width", doc, page, 0);
		sheetheight = PDF_get_pdi_value(p, "height", doc, page, 0);

		PDF_begin_page(p, sheetwidth, sheetheight);

		/* define bookmark with filename */
		if (pageno == 1)
		    PDF_add_bookmark(p, argv[optind-1], 0, 0);

		PDF_place_pdi_page(p, page, 0.0f, 0.0f, 1.0f, 1.0f);
		PDF_close_pdi_page(p, page);
		PDF_end_page(p);
	    }

	} else {		/* impose multiple pages */

	    if (newpage)
		r = c = 0;

	    /* open all pages and add to the output file */
	    for (pageno = 1; pageno <= docpages ; pageno++) {

		page = PDF_open_pdi_page(p, doc, pageno, "");

		if (page == -1) {
		    /* we'll get an exception in verbose mode anyway */
		    if (quiet)
			fprintf(stderr,
			    "Couldn't open page %d of PDF file '%s' (%s)\n",
			    pageno, filename, PDF_get_errmsg(p));
		    break;
		}

		/* start a new page */
		if (r == 0 && c == 0)
		    PDF_begin_page(p, sheetwidth, sheetheight);
		
		/* define bookmark with filename */
		if (pageno == 1)
		    PDF_add_bookmark(p, argv[optind-1], 0, 0);

		width = PDF_get_pdi_value(p, "width", doc, page, 0);
		height = PDF_get_pdi_value(p, "height", doc, page, 0);

		/*
		 * The save/restore pair is required to get the clipping right,
		 * and helps PostScript printing manage its memory efficiently.
		 */
		PDF_save(p);
		PDF_rect(p, c * colwidth, sheetheight - (r + 1) * rowheight,
		    colwidth, rowheight);
		PDF_clip(p);

		PDF_setcolor(p, "stroke", "gray", 0.0f, 0.0f, 0.0f, 0.0f);

		/* TODO: adjust scaling factor if page doesn't fit into  cell */
		PDF_place_pdi_page(p, page,
		    c * colwidth, sheetheight - (r + 1) * rowheight,
		    scale, scale);

		PDF_close_pdi_page(p, page);

		/* only half of the linewidth will be drawn due to clip() */
		if (boxes) {
		    PDF_setlinewidth(p, 1.0f * scale);
		    PDF_rect(p, c * colwidth,
			sheetheight - (r + 1) * rowheight,
			colwidth, rowheight);
		    PDF_stroke(p);
		}

		PDF_restore(p);

		c++;
		if (c == cols) {
		    c = 0;
		    r++;
		}
		if (r == rows) {
		    r = 0;
		    PDF_end_page(p);
		}
	    }
	}

	PDF_close_pdi(p, doc);
    }

    /* finish last page if multi-page imposition */
    if ((rows != 1 || cols != 1) && (r != 0 || c != 0))
	PDF_end_page(p);

    PDF_close(p);
    PDF_delete(p);
    exit(0);
}