static void restore_matrix(internal_t*i) { if(i->has_matrix) { PDF_restore(i->p); i->has_matrix=0; i->m00 = 0; i->m01 = 0; i->m10 = 0; i->m11 = 0; } }
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); } }
void pdf_endclip(gfxdevice_t*dev) { internal_t*i = (internal_t*)dev->internal; restore_matrix(i); PDF_restore(i->p); }
/* ** 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); }
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; }
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); } }
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); }