PDFLIB_API void PDFLIB_CALL PDF_setrgbcolor_stroke(PDF *p, float red, float green, float blue) { char buf1[FLOATBUFSIZE], buf2[FLOATBUFSIZE], buf3[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (red < 0.0 || red > EPSILON || green < 0.0 || green > EPSILON || blue < 0.0 || blue > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f) in PDF_setrgbcolor_stroke", red, green, blue); return; } if (red == green && green == blue) PDF_setgray_stroke(p, red); else { pdf_printf(p, "%s %s %s RG\n", pdf_float(buf1, red), pdf_float(buf2, green), pdf_float(buf3, blue)); p->cstate[p->sl].stroke.cs = DeviceRGB; p->cstate[p->sl].stroke.val.rgb.r = red; p->cstate[p->sl].stroke.val.rgb.g = green; p->cstate[p->sl].stroke.val.rgb.b = blue; } }
/* Add a link to an arbitrary Internet resource (URL) */ PDFLIB_API void PDFLIB_CALL PDF_add_weblink( PDF *p, float llx, float lly, float urx, float ury, const char *url) { static const char fn[] = "PDF_add_weblink"; pdf_annot *ann; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f, %f, \"%s\");\n", fn, (void *) p, llx, lly, urx, ury, url)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); if (url == NULL || *url == '\0') pdf_error(p, PDF_ValueError, "NULL URL in PDF_add_weblink"); ann = (pdf_annot *) p->malloc(p, sizeof(pdf_annot), "PDF_add_weblink"); ann->filename = pdf_strdup(p, url); ann->type = ann_weblink; ann->rect.llx = llx; ann->rect.lly = lly; ann->rect.urx = urx; ann->rect.ury = ury; pdf_add_annot(p, ann); }
PDFLIB_API void PDFLIB_CALL PDF_setcmykcolor_stroke(PDF *p, float cyan, float magenta, float yellow, float black) { char buf1[FLOATBUFSIZE], buf2[FLOATBUFSIZE], buf3[FLOATBUFSIZE]; char buf4[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (cyan < 0.0 || cyan > EPSILON || magenta < 0.0 || magenta > EPSILON || yellow < 0.0 || yellow > EPSILON || black < 0.0 || black > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f/%f) in PDF_setcmykcolor_stroke", cyan, magenta, yellow, black); return; } pdf_printf(p, "%s %s %s %s K\n", pdf_float(buf1, cyan), pdf_float(buf2, magenta), pdf_float(buf3, yellow), pdf_float(buf4, black)); p->cstate[p->sl].stroke.cs = DeviceCMYK; p->cstate[p->sl].fill.val.cmyk.c = cyan; p->cstate[p->sl].fill.val.cmyk.m = magenta; p->cstate[p->sl].fill.val.cmyk.y = yellow; p->cstate[p->sl].fill.val.cmyk.k = black; }
PDFLIB_API void PDFLIB_CALL PDF_set_border_style(PDF *p, const char *style, float width) { static const char fn[] = "PDF_set_border_style"; PDF_TRACE(("%s\t(pdf[%p], \"%s\", %f);\n", fn, (void *) p, style, width)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document | pdf_state_page); if (style == NULL) p->border_style = border_solid; else if (!strcmp(style, "solid")) p->border_style = border_solid; else if (!strcmp(style, "dashed")) p->border_style = border_dashed; else pdf_error(p, PDF_ValueError, "Unknown annotation border style '%s'", style); if (width < 0.0) pdf_error(p, PDF_ValueError, "Negative annotation border width %f", width); p->border_width = width; }
PDFLIB_API void PDFLIB_CALL PDF_close(PDF *p) { static const char fn[] = "PDF_close"; PDF_TRACE(("%s\t\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document); if (PDF_GET_STATE(p) != pdf_state_error) { if (p->current_page == 0) pdf_error(p, PDF_RuntimeError, "Empty document"); pdf_wrapup_document(p); /* dump the remaining PDF structures */ } pdf_flush_stream(p); pdf_cleanup_document(p); /* UPR stuff not released here but in PDF_delete() */ PDF_SET_STATE(p, fn, pdf_state_object); }
PDFLIB_API void PDFLIB_CALL PDF_set_border_color(PDF *p, float red, float green, float blue) { static const char fn[] = "PDF_set_border_color"; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f);\n", fn, (void *) p, red, green, blue)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document | pdf_state_page); if (red < 0.0 || red > 1.0) pdf_error(p, PDF_ValueError, "Bogus red color value %f for annotation border", red); if (green < 0.0 || green > 1.0) pdf_error(p, PDF_ValueError, "Bogus green color value %f for annotation border", green); if (blue < 0.0 || blue > 1.0) pdf_error(p, PDF_ValueError, "Bogus blue color value %f for annotation border", blue); p->border_red = red; p->border_green = green; p->border_blue = blue; }
/* Add a link to another PDF file */ PDFLIB_API void PDFLIB_CALL PDF_add_pdflink( PDF *p, float llx, float lly, float urx, float ury, const char *filename, int page, const char *desttype) { static const char fn[] = "PDF_add_pdflink"; pdf_annot *ann; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f, %f, \"%s\", %d, \"%s\");\n", fn, (void *) p, llx, lly, urx, ury, filename, page, desttype)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); if (filename == NULL) pdf_error(p, PDF_ValueError, "NULL filename in PDF_add_pdflink"); ann = (pdf_annot *) p->malloc(p, sizeof(pdf_annot), "PDF_add_pdflink"); ann->filename = pdf_strdup(p, filename); ann->type = ann_pdflink; ann->dest.page = page; if (desttype == NULL) ann->dest.type = fitpage; else if (!strcmp(desttype, "retain")) ann->dest.type = retain; else if (!strcmp(desttype, "fitpage")) ann->dest.type = fitpage; else if (!strcmp(desttype, "fitwidth")) ann->dest.type = fitwidth; else if (!strcmp(desttype, "fitheight")) ann->dest.type = fitheight; else if (!strcmp(desttype, "fitbbox")) ann->dest.type = fitbbox; else pdf_error(p, PDF_ValueError, "Unknown destination type '%s' in PDF_add_pdflink", desttype); ann->rect.llx = llx; ann->rect.lly = lly; ann->rect.urx = urx; ann->rect.ury = ury; pdf_add_annot(p, ann); }
PDFLIB_API void * PDFLIB_CALL PDF_get_opaque(PDF *p) { PDF_TRACE(("PDF_get_opaque\t(pdf[%p]);", (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return ((void *) NULL); PDF_TRACE((" [%p]\n", p->opaque)); return p->opaque; }
/* Finish the pattern definition. */ PDFLIB_API void PDFLIB_CALL PDF_end_pattern(PDF *p) { static const char fn[] = "PDF_end_pattern"; long length; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_pattern); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of pattern"); pdf_end_text(p); p->contents = c_none; if (p->compresslevel) pdf_compress_end(p); length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); pdf_end_obj(p); /* pattern */ pdf_begin_obj(p, p->contents_length_id); /* Length object */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); pdf_begin_obj(p, p->res_id); /* Resource object */ pdf_begin_dict(p); /* Resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ PDF_POP_STATE(p, fn); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }
PDFLIB_API void PDFLIB_CALL PDF_delete(PDF *p) { static const char fn[] = "PDF_delete"; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; if (p->errorhandler == NULL) return; /* nothing to do with dummy PDF struct (see PDF_new2()) */ PDF_CHECK_SCOPE(p, fn, pdf_state_object); /* check whether the caller forgot to fetch the last chunk of data */ if (PDF_GET_STATE(p) != pdf_state_error && pdf_buffer_not_empty(p)) { pdf_error(p, PDF_RuntimeError, "Must call PDF_get_buffer() after PDF_close()"); } /* * Clean up page-related stuff if necessary. Do not raise * an error here since we may be called from the error handler. */ if (PDF_GET_STATE(p) != pdf_state_object) { pdf_cleanup_document(p); } /* close the output stream. * This can't be done in PDF_close() because the caller may fetch * the buffer only after PDF_close()ing the document. */ pdf_close_stream(p); pdf_cleanup_resources(p); /* release the resources tree */ #ifdef HAVE_PDI pdf_cleanup_pdi(p); #endif if (p->binding) p->free(p, p->binding); if (p->prefix) p->free(p, p->prefix); /* free the PDF structure and try to protect against duplicated calls */ p->magic = 0L; /* we don't reach this with the wrong magic */ p->free(p, (void *)p); }
PDFLIB_API void PDFLIB_CALL PDF_setgray(PDF *p, float g) { static const char fn[] = "PDF_setgray"; PDF_TRACE(("%s\t(pdf[%p], %f);\n", fn, (void *) p, g)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_ppt); pdf_setgraycolor(p, "both", g); }
PDFLIB_API int PDFLIB_CALL PDF_open_file(PDF *p, const char *filename) { static const char fn[] = "PDF_open_file"; PDF_TRACE(("%s\t(pdf[%p], \"%s\");", fn, (void *) p, filename)); if (PDF_SANITY_CHECK_FAILED(p)) return -1; PDF_CHECK_SCOPE(p, fn, pdf_state_object); pdf_init_all(p); if (filename == NULL || *filename == '\0') { /* no file name supplied ==> in-core PDF generation requested */ p->writeproc = NULL; p->filename = NULL; } else { #if !(defined(MAC) && defined(__MWERKS__)) if (filename && !strcmp(filename, "-")) { p->filename = NULL; p->fp = stdout; #if !defined(__MWERKS__) && (defined(WIN32) || defined(OS2)) #if defined WINCE _setmode(fileno(stdout), _O_BINARY); #else _setmode(_fileno(stdout), O_BINARY); #endif /* !WINCE */ #endif } else #endif /* MAC */ if ((p->fp = fopen(filename, WRITEMODE)) == NULL) { PDF_SET_STATE(p, "PDF_open_file", pdf_state_object); PDF_TRACE((" [%d]\n", -1)); return -1; } p->writeproc = pdf_writeproc_file; p->filename = pdf_strdup(p, filename); } pdf_write_header(p); PDF_TRACE((" [%d]\n", pdf_true)); return pdf_true; }
PDFLIB_API void PDFLIB_CALL PDF_setgray(PDF *p, float g) { if (PDF_SANITY_CHECK_FAILED(p)) return; if (g < 0.0 || g > EPSILON ) { pdf_error(p, PDF_NonfatalError, "Bogus gray value (%f) in PDF_setgray", g); return; } PDF_setgray_stroke(p, g); PDF_setgray_fill(p, g); }
PDFLIB_API void PDFLIB_CALL PDF_setrgbcolor(PDF *p, float red, float green, float blue) { static const char fn[] = "PDF_setrgbcolor"; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f);\n", fn, (void *) p, red, green, blue)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_ppt); pdf_setrgbcolor2(p, "both", red, green, blue); }
PDFLIB_API void PDFLIB_CALL PDF_setcmykcolor(PDF *p, float cyan, float magenta, float yellow, float black) { if (PDF_SANITY_CHECK_FAILED(p)) return; if (cyan < 0.0 || cyan > EPSILON || magenta < 0.0 || magenta > EPSILON || yellow < 0.0 || yellow > EPSILON || black < 0.0 || black > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f/%f) in PDF_setcmykcolor", cyan, magenta, yellow, black); return; } PDF_setcmykcolor_fill(p, cyan, magenta, yellow, black); PDF_setcmykcolor_stroke(p, cyan, magenta, yellow, black); }
PDFLIB_API void PDFLIB_CALL PDF_setcolor( PDF *p, const char *fstype, const char *colorspace, float c1, float c2, float c3, float c4) { static const char fn[] = "PDF_setcolor"; PDF_TRACE(("%s\t(pdf[%p], \"%s\", \"%s\", %f, %f, %f, %f);\n", fn, (void *) p, fstype, colorspace, c1, c2, c3, c4)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_ppt | pdf_state_document); if (!fstype || !*fstype) pdf_error(p, PDF_ValueError, "Missing type in PDF_setcolor"); if (strcmp(fstype, "fill") && strcmp(fstype, "stroke") && strcmp(fstype, "both")) pdf_error(p, PDF_ValueError, "Unknown type in PDF_setcolor"); if (!colorspace || !*colorspace) pdf_error(p, PDF_ValueError, "Missing color space in PDF_setcolor"); if (!strcmp(colorspace, "gray")) pdf_setgraycolor(p, fstype, c1); else if (!strcmp(colorspace, "rgb")) pdf_setrgbcolor2(p, fstype, c1, c2, c3); else if (!strcmp(colorspace, "cmyk")) pdf_setcmykcolor(p, fstype, c1, c2, c3, c4); else if (!strcmp(colorspace, "spot")) pdf_setspotcolor(p, fstype, (int) c1, c2); else if (!strcmp(colorspace, "pattern")) pdf_setpatterncolor(p, fstype, (int) c1); else pdf_error(p, PDF_ValueError, "Unknown color space '%s' in PDF_setcolor", colorspace); }
PDFLIB_API void PDFLIB_CALL PDF_close_image(PDF *p, int im) { static const char fn[] = "PDF_close_image"; PDF_TRACE(("%s\t(pdf[%p], %d);\n", fn, (void *) p, im)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document | pdf_state_page); 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 number %d in PDF_close_image", im); pdf_cleanup_image(p, im); }
PDFLIB_API void PDFLIB_CALL PDF_setgray_stroke(PDF *p, float g) { char buf[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (g < 0.0 || g > EPSILON ) { pdf_error(p, PDF_NonfatalError, "Bogus gray value (%f) in PDF_setgray_stroke", g); return; } pdf_printf(p, "%s G\n", pdf_float(buf, g)); p->cstate[p->sl].stroke.cs = DeviceGray; p->cstate[p->sl].stroke.val.gray = g; }
PDFLIB_API void PDFLIB_CALL PDF_setrgbcolor(PDF *p, float red, float green, float blue) { if (PDF_SANITY_CHECK_FAILED(p)) return; if (red < 0.0 || red > EPSILON || green < 0.0 || green > EPSILON || blue < 0.0 || blue > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f) in PDF_setrgbcolor", red, green, blue); return; } if (red == green && green == blue) PDF_setgray(p, red); else { PDF_setrgbcolor_fill(p, red, green, blue); PDF_setrgbcolor_stroke(p, red, green, blue); } }
PDFLIB_API void PDFLIB_CALL PDF_open_mem(PDF *p, size_t (*writeproc)(PDF *p, void *data, size_t size)) { static const char fn[] = "PDF_open_mem"; PDF_TRACE(("%s\t(pdf[%p], wp[%p]);\n", fn, (void *) p, (void *) writeproc)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_object); if (writeproc == NULL) pdf_error(p, PDF_ValueError, "NULL write procedure in PDF_open_mem()"); p->writeproc = writeproc; p->filename = NULL; pdf_init_all(p); pdf_write_header(p); }
PDFLIB_API int PDFLIB_CALL PDF_makespotcolor(PDF *p, const char *spotname, int len) { static const char fn[] = "PDF_makespotcolor"; char *quotedspotname; int ret; PDF_TRACE(("%s\t(pdf[%p], \"%s\");\n", fn, (void *) p, spotname)); if (PDF_SANITY_CHECK_FAILED(p)) return -1; PDF_CHECK_SCOPE(p, fn, pdf_state_ppt | pdf_state_document); if (spotname == NULL || *spotname == 0) pdf_error(p, PDF_ValueError, "Empty spot color name"); if (p->cstate[p->sl].fill.cs == PatternCS || p->cstate[p->sl].fill.cs == Indexed || p->cstate[p->sl].fill.cs == Separation) pdf_error(p, PDF_RuntimeError, "Spot colors can only be based on simple color spaces"); if (len == 0) len = (int) strlen(spotname); if (len > PDF_MAX_SPOTNAME) pdf_error(p, PDF_ValueError, "Spot color name too long"); quotedspotname = (char *) p->malloc(p, (size_t) (3*len + 1), "PDF_makespotcolor"); pdf_make_quoted_name(p, spotname, (size_t) len, quotedspotname); ret = pdf_add_colorspace(p, Separation, quotedspotname); p->free(p, quotedspotname); return ret; }
PDFLIB_API void PDFLIB_CALL PDF_add_thumbnail(PDF *p, int im) { static const char fn[] = "PDF_add_thumbnail"; pdf_image *image; PDF_TRACE(("%s\t(pdf[%p], %d);\n", fn, (void *) p, im)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); if (im < 0 || im >= p->images_capacity || !p->images[im].in_use) pdf_error(p, PDF_ValueError, "Bad image number %d in PDF_add_thumbnail", im); if (p->thumb_id != BAD_ID) pdf_error(p, PDF_RuntimeError, "More than one thumbnail for this page (PDF_add_thumbnail)"); image = &p->images[im]; if (image->strips > 1) pdf_error(p, PDF_RuntimeError, "Can't use multi-strip images as thumbnails"); if (image->width > MAX_THUMBNAIL_SIZE || image->height > MAX_THUMBNAIL_SIZE) pdf_error(p, PDF_ValueError, "Thumbnail image larger than %d pixels", MAX_THUMBNAIL_SIZE); if (image->colorspace != DeviceGray && image->colorspace != DeviceRGB && image->colorspace != Indexed) pdf_error(p, PDF_RuntimeError, "Unsupported color space in thumbnail image"); /* Add the image to the thumbnail key of the current page. */ p->thumb_id = p->xobjects[image->no].obj_id; }
PDFLIB_API int PDFLIB_CALL PDF_open_fp(PDF *p, FILE *fp) { static const char fn[] = "PDF_open_fp"; PDF_TRACE(("%s\t(pdf[%p], fp[%p]);", fn, (void *) p, (void *) fp)); if (PDF_SANITY_CHECK_FAILED(p)) return -1; PDF_CHECK_SCOPE(p, fn, pdf_state_object); if (fp == NULL) { PDF_TRACE((" [%d]\n", -1)); return -1; } /* * It is the callers responsibility to open the file in binary mode, * but it doesn't hurt to make sure it really is. * The Intel version of the Metrowerks compiler doesn't have setmode(). */ #if !defined(__MWERKS__) && (defined(WIN32) || defined(OS2)) #if defined WINCE _setmode(fileno(fp), _O_BINARY); #else _setmode(_fileno(fp), O_BINARY); #endif #endif pdf_init_all(p); p->writeproc = pdf_writeproc_file; p->fp = fp; p->filename = NULL; /* marker to remember not to close fp */ pdf_write_header(p); PDF_TRACE((" [%d]\n", pdf_true)); return pdf_true; }
PDFLIB_API void PDFLIB_CALL PDF_set_border_dash(PDF *p, float b, float w) { static const char fn[] = "PDF_set_border_dash"; PDF_TRACE(("%s\t(pdf[%p], %f, %f);\n", fn, (void *) p, b, w)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document | pdf_state_page); if (b < 0.0) pdf_error(p, PDF_ValueError, "Negative first annotation border dash value %f", b); if (w < 0.0) pdf_error(p, PDF_ValueError, "Negative second annotation border dash value %f", w); p->border_dash1 = b; p->border_dash2 = w; }
PDFLIB_API void PDFLIB_CALL PDF_add_note( PDF *p, float llx, float lly, float urx, float ury, const char *contents, const char *title, const char *icon, int open) { static const char fn[] = "PDF_add_note"; pdf_annot *ann; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f, %f, \"%s\", \"%s\", \"%s\", %d);\n", fn, (void *) p, llx, lly, urx, ury, contents, title, icon, open)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); ann = (pdf_annot *) p->malloc(p, sizeof(pdf_annot), "pdf_add_note"); ann->type = ann_text; ann->open = open; ann->rect.llx = llx; ann->rect.lly = lly; ann->rect.urx = urx; ann->rect.ury = ury; if (p->compatibility == PDF_1_2 && icon != NULL && *icon != '\0') pdf_error(p, PDF_RuntimeError, "Note icons are not supported in PDF 1.2"); if (icon == NULL || *icon == '\0') ann->icon = icon_text_note; else if (!strcmp(icon, "comment")) ann->icon = icon_text_comment; else if (!strcmp(icon, "insert")) ann->icon = icon_text_insert; else if (!strcmp(icon, "note")) ann->icon = icon_text_note; else if (!strcmp(icon, "paragraph")) ann->icon = icon_text_paragraph; else if (!strcmp(icon, "newparagraph")) ann->icon = icon_text_newparagraph; else if (!strcmp(icon, "key")) ann->icon = icon_text_key; else if (!strcmp(icon, "help")) ann->icon = icon_text_help; else pdf_error(p, PDF_ValueError, "Unknown icon type '%s' for text note", icon); /* title may be NULL */ if (title != NULL) { ann->title = pdf_strdup(p, title); #ifdef PDFLIB_EBCDIC if (!pdf_is_unicode(ann->title)) pdf_make_ascii(ann->title); #endif } else ann->title = NULL; /* It is legal to create an empty text annnotation */ if (contents != NULL) { ann->contents = pdf_strdup(p, contents); #ifdef PDFLIB_EBCDIC if (!pdf_is_unicode(ann->contents)) pdf_make_ascii(ann->contents); #endif } else ann->contents = NULL; pdf_add_annot(p, ann); }
void pdf_setpatterncolor(PDF *p, const char *type, int pattern) { if (PDF_SANITY_CHECK_FAILED(p)) return; if (!type || !*type) pdf_error(p, PDF_ValueError, "Missing type in pdf_setspotcolor"); if (strcmp(type, "fill") && strcmp(type, "stroke") && strcmp(type, "both")) pdf_error(p, PDF_ValueError, "Unknown type in pdf_spotcolor"); if (pattern < 0 || pattern >= p->pattern_number) pdf_error(p, PDF_ValueError, "Invalid pattern number %d in PDF_setcolor", pattern); if (PDF_GET_STATE(p) == pdf_state_pattern && pattern == p->pattern_number-1) { pdf_error(p, PDF_ValueError, "Can't use pattern within its own definition"); } if (!strcmp(type, "fill") || !strcmp(type, "both")) { if (p->pattern[pattern].painttype == 1) { pdf_puts(p, "/Pattern cs\n"); } else if (p->pattern[pattern].painttype == 2) { /* TODO: find spot color name */ if (p->cstate[p->sl].fill.cs == Separation) pdf_error(p, PDF_ValueError, "Separation NYI for patterns"); pdf_printf(p, "/CS%d cs\n", pdf_add_colorspace(p, PatternCS, (char *) NULL)); /* TODO: add spot name if based on separation color space */ pdf_write_pattern_color(p, pdf_true); } pdf_printf(p, "/P%d scn\n", pattern); if (p->pattern[pattern].painttype == 1) { p->cstate[p->sl].fill.cs = PatternCS; p->cstate[p->sl].fill.val.pattern = pattern; } else if (p->pattern[pattern].painttype == 2) { /* TODO: deal with color */ } } if (!strcmp(type, "stroke") || !strcmp(type, "both")) { if (p->pattern[pattern].painttype == 1) { pdf_puts(p, "/Pattern CS\n"); } else if (p->pattern[pattern].painttype == 2) { /* TODO */ if (p->cstate[p->sl].fill.cs == Separation) pdf_error(p, PDF_ValueError, "Separation NYI for patterns"); pdf_printf(p, "/CS%d CS\n", pdf_add_colorspace(p, PatternCS, (char *) NULL)); /* TODO: add spot name if based on separation color space */ pdf_write_pattern_color(p, pdf_false); } pdf_printf(p, "/P%d SCN\n", pattern); if (p->pattern[pattern].painttype == 1) { p->cstate[p->sl].stroke.cs = PatternCS; p->cstate[p->sl].stroke.val.pattern = pattern; } else if (p->pattern[pattern].painttype == 2) { /* TODO */ } } p->pattern[pattern].used_on_current_page = pdf_true; }
/* Attach an arbitrary file to the PDF. Note that the actual * embedding takes place in PDF_end_page(). * description, author, and mimetype may be NULL. */ PDFLIB_API void PDFLIB_CALL PDF_attach_file( PDF *p, float llx, float lly, float urx, float ury, const char *filename, const char *description, const char *author, const char *mimetype, const char *icon) { static const char fn[] = "PDF_attach_file"; pdf_annot *ann; PDF_TRACE(("%s\t(pdf[%p], %f, %f, %f, %f, ", fn, (void *) p, llx, lly, urx, ury)); PDF_TRACE(("\"%s\", \"%s\", \"%s\", \"%s\", \"%s\");\n", filename, description, author, mimetype, icon)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); if (p->compatibility == PDF_1_2) pdf_error(p, PDF_RuntimeError, "File attachments are not supported in PDF 1.2"); if (filename == NULL) pdf_error(p, PDF_ValueError, "Empty file name for file attachment"); ann = (pdf_annot *) p->malloc(p, sizeof(pdf_annot),"PDF_attach_file"); ann->type = ann_attach; ann->rect.llx = llx; ann->rect.lly = lly; ann->rect.urx = urx; ann->rect.ury = ury; if (icon == NULL) ann->icon = icon_file_pushpin; else if (!strcmp(icon, "graph")) ann->icon = icon_file_graph; else if (!strcmp(icon, "paperclip")) ann->icon = icon_file_paperclip; else if (!strcmp(icon, "pushpin")) ann->icon = icon_file_pushpin; else if (!strcmp(icon, "tag")) ann->icon = icon_file_tag; else pdf_error(p, PDF_ValueError, "Unknown icon type '%s'for embedded file", icon); ann->filename = (char *) pdf_strdup(p, filename); if (description != NULL) { ann->contents = (char *) pdf_strdup(p, description); #ifdef PDFLIB_EBCDIC if (!pdf_is_unicode(ann->contents)) pdf_make_ascii(ann->contents); #endif } if (author != NULL) { ann->title = (char *) pdf_strdup(p, author); #ifdef PDFLIB_EBCDIC if (!pdf_is_unicode(ann->title)) pdf_make_ascii(ann->title); #endif } if (mimetype != NULL) ann->mimetype = (char *) pdf_strdup(p, mimetype); pdf_add_annot(p, ann); }
PDFLIB_API void PDFLIB_CALL PDF_end_page(PDF *p) { static const char fn[] = "PDF_end_page"; int index; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of page"); /* restore text parameter and color defaults for out-of-page usage. */ pdf_init_tstate(p); pdf_init_cstate(p); pdf_end_contents_section(p); /* Page object */ pdf_begin_obj(p, p->pages[p->current_page]); pdf_begin_dict(p); pdf_puts(p, "/Type/Page\n"); pdf_printf(p, "/Parent %ld 0 R\n", pdf_get_pnode_id(p)); p->res_id = pdf_alloc_id(p); pdf_printf(p, "/Resources %ld 0 R\n", p->res_id); pdf_printf(p, "/MediaBox[0 0 %f %f]\n", p->width, p->height); if (p->CropBox.llx != (float) 0 || p->CropBox.lly != (float) 0 || p->CropBox.urx != (float) 0 || p->CropBox.ury != (float) 0 ) { if (p->CropBox.urx <= p->CropBox.llx || p->CropBox.ury <= p->CropBox.lly) pdf_error(p, PDF_ValueError, "Illegal CropBox dimensions"); pdf_printf(p, "/CropBox[%f %f %f %f]\n", p->CropBox.llx, p->CropBox.lly, p->CropBox.urx, p->CropBox.ury); } if (p->BleedBox.llx != (float) 0 || p->BleedBox.lly != (float) 0 || p->BleedBox.urx != (float) 0 || p->BleedBox.ury != (float) 0 ) { if (p->BleedBox.urx <= p->BleedBox.llx || p->BleedBox.ury <= p->BleedBox.lly) pdf_error(p, PDF_ValueError, "Illegal BleedBox dimensions"); pdf_printf(p, "/BleedBox[%f %f %f %f]\n", p->BleedBox.llx, p->BleedBox.lly, p->BleedBox.urx, p->BleedBox.ury); } if (p->TrimBox.llx != (float) 0 || p->TrimBox.lly != (float) 0 || p->TrimBox.urx != (float) 0 || p->TrimBox.ury != (float) 0 ) { if (p->TrimBox.urx <= p->TrimBox.llx || p->TrimBox.ury <= p->TrimBox.lly) pdf_error(p, PDF_ValueError, "Illegal TrimBox dimensions"); pdf_printf(p, "/TrimBox[%f %f %f %f]\n", p->TrimBox.llx, p->TrimBox.lly, p->TrimBox.urx, p->TrimBox.ury); } if (p->ArtBox.llx != (float) 0 || p->ArtBox.lly != (float) 0 || p->ArtBox.urx != (float) 0 || p->ArtBox.ury != (float) 0 ) { if (p->ArtBox.urx <= p->ArtBox.llx || p->ArtBox.ury <= p->ArtBox.lly) pdf_error(p, PDF_ValueError, "Illegal ArtBox dimensions"); pdf_printf(p, "/ArtBox[%f %f %f %f]\n", p->ArtBox.llx, p->ArtBox.lly, p->ArtBox.urx, p->ArtBox.ury); } /* * The duration can be placed in the transition dictionary (/D) * or in the page dictionary (/Dur). We put it here so it can * be used without setting a transition effect. */ if (p->duration > 0) pdf_printf(p, "/Dur %f\n", p->duration); pdf_write_page_transition(p); pdf_puts(p, "/Contents["); for (index = 0; index < p->next_content; index++) { pdf_printf(p, "%ld 0 R", p->contents_ids[index]); pdf_putc(p, (char) (index + 1 % 8 ? PDF_SPACE : PDF_NEWLINE)); } pdf_puts(p, "]\n"); /* Thumbnail image */ if (p->thumb_id != BAD_ID) pdf_printf(p, "/Thumb %ld 0 R\n", p->thumb_id); pdf_write_annots_root(p); pdf_end_dict(p); /* Page object */ pdf_end_obj(p); pdf_write_page_annots(p); /* Annotation dicts */ pdf_begin_obj(p, p->res_id); /* resource object */ pdf_begin_dict(p); /* resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ pdf_cleanup_page(p); PDF_SET_STATE(p, fn, pdf_state_document); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }
PDFLIB_API void PDFLIB_CALL PDF_begin_page(PDF *p, float width, float height) { static const char fn[] = "PDF_begin_page"; PDF_TRACE(("%s\t(pdf[%p], %f, %f);\n", fn, (void *) p, width, height)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document); if (width <= 0 || height <= 0) pdf_error(p, PDF_ValueError, "Page size must be positive"); if (p->compatibility >= PDF_1_3 && (height < PDF_ACRO4_MINPAGE || width < PDF_ACRO4_MINPAGE || height > PDF_ACRO4_MAXPAGE || width > PDF_ACRO4_MAXPAGE)) pdf_error(p, PDF_NonfatalError, "Page size incompatible with Acrobat 4"); else if (p->compatibility == PDF_1_2 && (height < PDF_ACRO3_MINPAGE || width < PDF_ACRO3_MINPAGE || height > PDF_ACRO3_MAXPAGE || width > PDF_ACRO3_MAXPAGE)) pdf_error(p, PDF_RuntimeError, "Page size incompatible with Acrobat 3"); if (++(p->current_page) >= p->pages_capacity) pdf_grow_pages(p); /* no id has been preallocated */ if (p->pages[p->current_page] == BAD_ID) p->pages[p->current_page] = pdf_alloc_id(p); p->height = height; p->width = width; p->thumb_id = BAD_ID; p->next_content = 0; p->contents = c_none; p->procset = 0; p->sl = 0; p->CropBox.llx = (float) 0; p->CropBox.lly = (float) 0; p->CropBox.urx = (float) 0; p->CropBox.ury = (float) 0; p->BleedBox.llx = (float) 0; p->BleedBox.lly = (float) 0; p->BleedBox.urx = (float) 0; p->BleedBox.ury = (float) 0; p->TrimBox.llx = (float) 0; p->TrimBox.lly = (float) 0; p->TrimBox.urx = (float) 0; p->TrimBox.ury = (float) 0; p->ArtBox.llx = (float) 0; p->ArtBox.lly = (float) 0; p->ArtBox.urx = (float) 0; p->ArtBox.ury = (float) 0; PDF_SET_STATE(p, fn, pdf_state_page); pdf_init_page_annots(p); pdf_init_tstate(p); pdf_init_gstate(p); pdf_init_cstate(p); pdf_begin_contents_section(p); }
PDFLIB_API int PDFLIB_CALL PDF_open_CCITT(PDF *p, const char *filename, int width, int height, int BitReverse, int K, int BlackIs1) { pdf_image *image; int im; char scratch[30]; if (PDF_SANITY_CHECK_FAILED(p)) return -1; for (im = 0; im < p->images_capacity; im++) if (!p->images[im].in_use) /* found free slot */ break; if (im == p->images_capacity) pdf_grow_images(p); image = &p->images[im]; if ((image->fp = fopen(filename, READMODE)) == NULL) { if (p->debug['i']) { pdf_error(p, PDF_NonfatalError, "Couldn't open CCITT file '%s'", filename); } return -1; } /* Grab the image parameters and pack them into image struct */ image->filename = pdf_strdup(p, filename); /* CCITT specific information */ image->width = width; image->height = height; image->info.ccitt.BitReverse = BitReverse; if (BlackIs1 == 0 && K == 0) /* default values */ image->params = NULL; else { scratch[0] = '\0'; if (K != 0) { sprintf(scratch, "/K %d", K); } if (BlackIs1 == 1) strcat(scratch, "/BlackIs1 true"); image->params = pdf_strdup(p, scratch); } /* The following are fixed for CCITT images */ image->compression = ccitt; image->colorspace = DeviceGray; image->components = 1; image->bpc = 1; image->src.init = pdf_data_source_CCITT_init; image->src.fill = pdf_data_source_CCITT_fill; image->src.terminate = pdf_data_source_CCITT_terminate; image->src.private_data = (void *) image; image->in_use = pdf_true; /* mark slot as used */ pdf_put_image(p, im, pdf_true); fclose(image->fp); return im; }