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); }
int pdf__shading( PDF *p, const char *type, pdc_scalar x_0, pdc_scalar y_0, pdc_scalar x_1, pdc_scalar y_1, pdc_scalar c_1, pdc_scalar c_2, pdc_scalar c_3, pdc_scalar c_4, const char *optlist) { pdf_shadingtype_e shtype = shnone; pdf_color *color0, color1; pdf_colorspace *cs; pdc_resopt *results; pdc_scalar N = 1.0; pdc_scalar r_0, r_1; pdc_bool extend0 = pdc_false, extend1 = pdc_false, antialias = pdc_false; int retval = -1; if (p->compatibility == PDC_1_3) pdc_error(p->pdc, PDF_E_SHADING13, 0, 0, 0, 0); if (!pdc_stricmp(type, "axial")) { shtype = axial; } else if (!pdc_stricmp(type, "radial")) { shtype = radial; } else pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0); pdc_check_number(p->pdc, "x_0", x_0); pdc_check_number(p->pdc, "y_0", y_0); pdc_check_number(p->pdc, "x_1", x_1); pdc_check_number(p->pdc, "y_1", y_1); pdc_check_number(p->pdc, "c_1", c_1); pdc_check_number(p->pdc, "c_2", c_2); pdc_check_number(p->pdc, "c_3", c_3); pdc_check_number(p->pdc, "c_4", c_4); color0 = pdf_get_cstate(p, pdf_fill); color1.cs = color0->cs; cs = &p->colorspaces[color0->cs]; switch (cs->type) { case DeviceGray: color1.val.gray = c_1; break; case DeviceRGB: color1.val.rgb.r = c_1; color1.val.rgb.g = c_2; color1.val.rgb.b = c_3; break; case DeviceCMYK: color1.val.cmyk.c = c_1; color1.val.cmyk.m = c_2; color1.val.cmyk.y = c_3; color1.val.cmyk.k = c_4; break; default: pdc_error(p->pdc, PDF_E_INT_BADCS, pdc_errprintf(p->pdc, "%d", color0->cs), 0, 0, 0); } results = pdc_parse_optionlist(p->pdc, optlist, pdf_shading_options, NULL, pdc_true); (void) pdc_get_optvalues("N", results, &N, NULL); (void) pdc_get_optvalues("antialias", results, &antialias,NULL); if (shtype == radial) { if (pdc_get_optvalues("r0", results, &r_0, NULL) != 1) pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "r0", 0, 0, 0); if (pdc_get_optvalues("r1", results, &r_1, NULL) != 1) pdc_error(p->pdc, PDC_E_OPT_NOTFOUND, "r1", 0, 0, 0); } if (shtype == axial) { if (pdc_get_optvalues("r0", results, &r_0, NULL) == 1) pdc_warning(p->pdc, PDC_E_OPT_IGNORED, "r0", 0, 0, 0); if (pdc_get_optvalues("r1", results, &r_1, NULL) == 1) pdc_warning(p->pdc, PDC_E_OPT_IGNORED, "r1", 0, 0, 0); } if (shtype == radial || shtype == axial) { pdc_get_optvalues("extend0", results, &extend0, NULL); pdc_get_optvalues("extend1", results, &extend1, NULL); } pdc_cleanup_optionlist(p->pdc, results); if (p->shadings_number == p->shadings_capacity) pdf_grow_shadings(p); if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); /* Shading object */ p->shadings[p->shadings_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); pdc_begin_dict(p->out); /* Shading dict*/ pdc_printf(p->out, "/ShadingType %d\n", (int) shtype); pdc_printf(p->out, "/ColorSpace"); pdf_write_colorspace(p, color1.cs, pdc_false); pdc_puts(p->out, "\n"); if (antialias) pdc_printf(p->out, "/AntiAlias true\n"); switch (shtype) { case axial: /* Type 2 */ pdc_printf(p->out, "/Coords[%f %f %f %f]\n", x_0, y_0, x_1, y_1); if (extend0 || extend1) pdc_printf(p->out, "/Extend[%s %s]\n", extend0 ? "true" : "false", extend1 ? "true" : "false"); pdc_puts(p->out, "/Function"); pdf_write_function_dict(p, color0, &color1, N); break; case radial: /* Type 3 */ pdc_printf(p->out, "/Coords[%f %f %f %f %f %f]\n", x_0, y_0, r_0, x_1, y_1, r_1); if (extend0 || extend1) pdc_printf(p->out, "/Extend[%s %s]\n", extend0 ? "true" : "false", extend1 ? "true" : "false"); pdc_puts(p->out, "/Function"); pdf_write_function_dict(p, color0, &color1, N); break; default: break; } pdc_end_dict(p->out); /* Shading dict */ pdc_end_obj(p->out); /* Shading object */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); retval = p->shadings_number; p->shadings_number++; return retval; }
void pdf__add_nameddest( PDF *p, const char *name, int len, const char *optlist) { pdc_resopt *resopts = NULL; pdc_text_format hypertextformat = p->hypertextformat; pdc_encoding hypertextencoding; int hypertextcodepage; pdc_id obj_id = PDC_BAD_ID; char *name2 = NULL; pdf_dest *dest; int inum; len = pdc_check_text_length(p->pdc, &name, len, PDF_MAXSTRINGSIZE); if (!len) pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "name", 0, 0, 0); resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_destination_options, NULL, pdc_true); hypertextencoding = pdf_get_hypertextencoding_opt(p, resopts, &hypertextcodepage, pdc_true); if (pdc_get_optvalues("hypertextformat", resopts, &inum, NULL)) { hypertextformat = (pdc_text_format) inum; pdf_check_hypertextformat(p, hypertextformat); } pdc_cleanup_optionlist(p->pdc, resopts); /* create hypertext string */ name2 = pdf_convert_hypertext(p, name, len, hypertextformat, hypertextencoding, hypertextcodepage, &len, pdc_true, pdc_true); if (name2 == NULL || len == 0) pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "name", 0, 0, 0); /* parsing option list */ dest = pdf_parse_destination_optlist(p, optlist, 0, pdf_nameddest); /* interrupt the content stream if we are on a page */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Dest object */ pdc_begin_dict(p->out); /* Destination dict */ pdc_puts(p->out, "/D"); pdf_write_destination(p, dest); pdc_end_dict(p->out); /* Destination dict */ pdc_end_obj(p->out); /* Dest object */ /* continue the contents stream */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); pdf_cleanup_destination(p, dest); /* insert name in tree */ pdf_insert_name(p, name2, names_dests, obj_id); }
void pdf__set_value(PDF *p, const char *key, double value) { int i; int ivalue = (int) value; pdf_ppt *ppt; i = pdf_get_index(p, key, pdc_true); ppt = p->curr_ppt; pdc_check_number(p->pdc, "value", value); switch (i) { #if defined(WIN32) && !defined(__BORLANDC__) && !defined(__CYGWIN__) /* CDPDF */ case PDF_PARAMETER_MAXFILEHANDLES: ivalue = pdc_set_maxfilehandles(p->pdc, ivalue); if (ivalue == -1) pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, pdc_errprintf(p->pdc, "%f", value), key, 0, 0); break; #endif case PDF_PARAMETER_COMPRESS: if (ivalue < 0 || ivalue > 9) pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, pdc_errprintf(p->pdc, "%f", value), key, 0, 0); if (pdc_get_compresslevel(p->out) != ivalue) { /* * We must restart the compression engine and start a new * contents section if we're in the middle of a page. */ if (PDF_GET_STATE(p) == pdf_state_page) { pdf_end_contents_section(p); pdc_set_compresslevel(p->out, ivalue); pdf_begin_contents_section(p); } else pdc_set_compresslevel(p->out, ivalue); } break; case PDF_PARAMETER_FLOATDIGITS: if (3 <= ivalue && ivalue <= 6) { p->pdc->floatdigits = ivalue; } else pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, pdc_errprintf(p->pdc, "%d", ivalue), key, 0, 0); break; /* TODO (york): take /CropBox into account? */ case PDF_PARAMETER_PAGEWIDTH: { const pdc_rectangle *box = pdf_get_pagebox(p, pdf_mediabox); if (p->ydirection == -1) pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); if (value < PDF_ACRO_MINPAGE || value > PDF_ACRO_MAXPAGE) pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); pdf_set_pagebox_urx(p, pdf_mediabox, box->llx + pdf_pos_value(p, key, value, PDC_1_3)); break; } /* TODO (york): take /CropBox into account? */ case PDF_PARAMETER_PAGEHEIGHT: { const pdc_rectangle *box = pdf_get_pagebox(p, pdf_mediabox); if (p->ydirection == -1) pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); if (value < PDF_ACRO_MINPAGE || value > PDF_ACRO_MAXPAGE) pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0); pdf_set_pagebox_ury(p, pdf_mediabox, box->lly + pdf_pos_value(p, key, value, PDC_1_3)); break; } case PDF_PARAMETER_CROPBOX_LLX: pdf_set_pagebox_llx(p, pdf_cropbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_CROPBOX_LLY: pdf_set_pagebox_lly(p, pdf_cropbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_CROPBOX_URX: pdf_set_pagebox_urx(p, pdf_cropbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_CROPBOX_URY: pdf_set_pagebox_ury(p, pdf_cropbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_BLEEDBOX_LLX: pdf_set_pagebox_llx(p, pdf_bleedbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_BLEEDBOX_LLY: pdf_set_pagebox_lly(p, pdf_bleedbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_BLEEDBOX_URX: pdf_set_pagebox_urx(p, pdf_bleedbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_BLEEDBOX_URY: pdf_set_pagebox_ury(p, pdf_bleedbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_TRIMBOX_LLX: pdf_set_pagebox_llx(p, pdf_trimbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_TRIMBOX_LLY: pdf_set_pagebox_lly(p, pdf_trimbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_TRIMBOX_URX: pdf_set_pagebox_urx(p, pdf_trimbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_TRIMBOX_URY: pdf_set_pagebox_ury(p, pdf_trimbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_ARTBOX_LLX: pdf_set_pagebox_llx(p, pdf_artbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_ARTBOX_LLY: pdf_set_pagebox_lly(p, pdf_artbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_ARTBOX_URX: pdf_set_pagebox_urx(p, pdf_artbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_ARTBOX_URY: pdf_set_pagebox_ury(p, pdf_artbox, pdf_value(p, key, value, PDC_1_3)); break; case PDF_PARAMETER_LEADING: pdf_set_tstate(p, value, to_leading); break; case PDF_PARAMETER_TEXTRISE: pdf_set_tstate(p, value, to_textrise); break; case PDF_PARAMETER_HORIZSCALING: pdf_set_tstate(p, value /100, to_horizscaling); break; case PDF_PARAMETER_ITALICANGLE: pdf_set_tstate(p, value, to_italicangle); break; case PDF_PARAMETER_TEXTRENDERING: pdf_set_tstate(p, value, to_textrendering); break; case PDF_PARAMETER_CHARSPACING: pdf_set_tstate(p, value, to_charspacing); break; case PDF_PARAMETER_WORDSPACING: pdf_set_tstate(p, value, to_wordspacing); break; case PDF_PARAMETER_UNDERLINEWIDTH: pdf_set_tstate(p, value, to_underlinewidth); break; case PDF_PARAMETER_UNDERLINEPOSITION: pdf_set_tstate(p, value, to_underlineposition); break; case PDF_PARAMETER_DEFAULTGRAY: break; case PDF_PARAMETER_DEFAULTRGB: break; case PDF_PARAMETER_DEFAULTCMYK: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILEGRAY: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILERGB: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILECMYK: break; /*****************************************************************************/ /** deprecated historical parameters **/ /*****************************************************************************/ case PDF_PARAMETER_SUBSETLIMIT: case PDF_PARAMETER_SUBSETMINSIZE: { pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0); break; } case PDF_PARAMETER_DURATION: pdf_set_duration(p, value); break; default: pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); break; } /* switch */ } /* pdf__set_value */
PDFLIB_API void PDFLIB_CALL PDF_set_value(PDF *p, const char *key, float value) { static const char fn[] = "PDF_set_value"; int i; int ivalue = (int) value; if (key == NULL || !*key) pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "key", 0, 0, 0); i = get_index(key); if (!pdf_enter_api(p, fn, (pdf_state) pdf_state_all, "(p[%p], \"%s\", %g)\n", (void *) p, key, value)) return; if (i == -1) pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); if ((p->state_stack[p->state_sp] & parms[i].set_scope) == 0) pdc_error(p->pdc, PDF_E_DOC_SCOPE_SET, key, pdf_current_scope(p), 0, 0); switch (i) { case PDF_PARAMETER_COMPRESS: if (ivalue < 0 || ivalue > 9) pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, pdc_errprintf(p->pdc, "%f", value), key, 0, 0); if (pdc_get_compresslevel(p->out) != ivalue) { /* * We must restart the compression engine and start a new * contents section if we're in the middle of a page. */ if (PDF_GET_STATE(p) == pdf_state_page) { pdf_end_contents_section(p); pdc_set_compresslevel(p->out, ivalue); pdf_begin_contents_section(p); } else pdc_set_compresslevel(p->out, ivalue); } break; case PDF_PARAMETER_FLOATDIGITS: if (3 <= ivalue && ivalue <= 6) pdc_set_floatdigits(p->pdc, ivalue); else pdc_error(p->pdc, PDC_E_PAR_ILLVALUE, pdc_errprintf(p->pdc, "%d", ivalue), key, 0, 0); break; case PDF_PARAMETER_PAGEWIDTH: if (p->ydirection == -1) pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); if (p->compatibility >= PDC_1_3 && (value < PDF_ACRO4_MINPAGE || value > PDF_ACRO4_MAXPAGE)) pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO4, 0, 0, 0, 0); p->width = pdf_pos_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_PAGEHEIGHT: if (p->ydirection == -1) pdc_error(p->pdc, PDF_E_PAGE_ILLCHGSIZE, 0, 0, 0, 0); if (p->compatibility >= PDC_1_3 && (value < PDF_ACRO4_MINPAGE || value > PDF_ACRO4_MAXPAGE)) pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO4, 0, 0, 0, 0); p->height = pdf_pos_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_CROPBOX_LLX: p->CropBox.llx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_CROPBOX_LLY: p->CropBox.lly = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_CROPBOX_URX: p->CropBox.urx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_CROPBOX_URY: p->CropBox.ury = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_BLEEDBOX_LLX: p->BleedBox.llx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_BLEEDBOX_LLY: p->BleedBox.lly = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_BLEEDBOX_URX: p->BleedBox.urx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_BLEEDBOX_URY: p->BleedBox.ury = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_TRIMBOX_LLX: p->TrimBox.llx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_TRIMBOX_LLY: p->TrimBox.lly = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_TRIMBOX_URX: p->TrimBox.urx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_TRIMBOX_URY: p->TrimBox.ury = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_ARTBOX_LLX: p->ArtBox.llx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_ARTBOX_LLY: p->ArtBox.lly = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_ARTBOX_URX: p->ArtBox.urx = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_ARTBOX_URY: p->ArtBox.ury = pdf_value(p, key, value, PDC_1_3); break; case PDF_PARAMETER_LEADING: pdf_set_leading(p, value); break; case PDF_PARAMETER_TEXTRISE: pdf_set_text_rise(p, value); break; case PDF_PARAMETER_HORIZSCALING: pdf_set_horiz_scaling(p, value); break; case PDF_PARAMETER_TEXTRENDERING: pdf_set_text_rendering(p, (int) value); break; case PDF_PARAMETER_CHARSPACING: pdf_set_char_spacing(p, value); break; case PDF_PARAMETER_WORDSPACING: pdf_set_word_spacing(p, value); break; case PDF_PARAMETER_DURATION: pdf_set_duration(p, value); break; case PDF_PARAMETER_DEFAULTGRAY: break; case PDF_PARAMETER_DEFAULTRGB: break; case PDF_PARAMETER_DEFAULTCMYK: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILEGRAY: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILERGB: break; case PDF_PARAMETER_SETCOLOR_ICCPROFILECMYK: break; case PDF_PARAMETER_SUBSETLIMIT: pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0); break; case PDF_PARAMETER_SUBSETMINSIZE: pdc_warning(p->pdc, PDF_E_UNSUPP_SUBSET, 0, 0, 0, 0); break; default: pdc_error(p->pdc, PDC_E_PAR_UNKNOWNKEY, key, 0, 0, 0); break; } /* switch */ } /* PDF_set_value */
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); } }
void pdf_put_image(PDF *p, int im, pdf_bool firststrip) { id length_id; long length; pdf_image *image; int i; image = &p->images[im]; /* york: how to check? see also F-imagecolor! switch (image->colorspace) { case ImageMask: case DeviceGray: case Indexed: case DeviceRGB: case DeviceCMYK: break; default: pdf_error(p, PDF_SystemError, "Unknown color space"); break; } */ /* Images may also be written to the output before the first page */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); /* Image object */ image->no = pdf_new_xobject(p, image_xobject, NEW_ID); pdf_begin_dict(p); /* XObject */ pdf_puts(p, "/Type/XObject\n"); pdf_puts(p, "/Subtype/Image\n"); pdf_printf(p,"/Width %d\n", (int) image->width); pdf_printf(p,"/Height %d\n", (int) image->height); pdf_printf(p,"/BitsPerComponent %d\n", image->bpc); /* * Transparency handling */ /* Masking by color: single transparent color value */ if (image->transparent) { if (image->colorspace == Indexed || image->colorspace == DeviceGray) pdf_printf(p,"/Mask[%d %d]\n", (int) image->transval[0], (int) image->transval[0]); else if (image->colorspace == DeviceRGB) pdf_printf(p,"/Mask[%d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2]); else if (image->colorspace == DeviceCMYK) pdf_printf(p,"/Mask[%d %d %d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2], (int) image->transval[3], (int) image->transval[3]); else pdf_error(p, PDF_SystemError, "Unknown color space with transparency"); /* Masking by position: separate bitmap mask */ } else if (image->mask != -1) { pdf_printf(p, "/Mask %ld 0 R\n", p->xobjects[p->images[image->mask].no].obj_id); } switch (image->colorspace) { case ImageMask: pdf_puts(p, "/ImageMask true\n"); break; case Indexed: if (firststrip) image->colormap_id = pdf_alloc_id(p); pdf_puts(p, "/ColorSpace[/Indexed/DeviceRGB "); pdf_printf(p, "%d %ld 0 R]\n", image->palette_size - 1, image->colormap_id); break; default: /* colorize the image with a spot color */ if (image->colorspace >= LastCS) { /* TODO: reconsider spot color numbering scheme */ int spot = image->colorspace - LastCS; p->colorspaces[spot].used_on_current_page = pdf_true; pdf_printf(p, "/ColorSpace %ld 0 R\n", p->colorspaces[spot].obj_id); /* the following is tricky: /Separation color space * always works as a subtractive color space. The * image, however, is Grayscale, and therefore * additive. */ if (firststrip) { image->invert = !image->invert; } } else { pdf_printf(p, "/ColorSpace/%s\n", pdf_colorspace_names[image->colorspace]); } break; } /* special case: referenced image data instead of direct data */ if (image->reference != pdf_ref_direct) { if (image->compression != none) { pdf_printf(p, "/FFilter[/%s]\n", pdf_filter_names[image->compression]); } if (image->compression == ccitt) { pdf_puts(p, "/FDecodeParms[<<"); if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); /* write CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); pdf_puts(p, ">>]\n"); } if (image->reference == pdf_ref_file) { /* LATER: make image file name platform-neutral: * Change : to / on the Mac * Change \ to / on Windows */ pdf_printf(p, "/F(%s)/Length 0", image->filename); } else if (image->reference == pdf_ref_url) { pdf_printf(p, "/F<</FS/URL/F(%s)>>/Length 0", image->filename); } pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* dummy image data */ pdf_end_stream(p); /* dummy image data */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); pdf_end_obj(p); /* XObject */ return; } /* * Now the (more common) handling of actual image * data to be included in the PDF output. */ /* do we need a filter (either ASCII or decompression)? */ if (p->debug['a']) { pdf_puts(p, "/Filter[/ASCIIHexDecode"); if (image->compression != none) pdf_printf(p, "/%s", pdf_filter_names[image->compression]); pdf_puts(p, "]\n"); } else { /* force compression if not a recognized precompressed image format */ if (!image->use_raw && p->compresslevel) image->compression = flate; if (image->compression != none) pdf_printf(p, "/Filter[/%s]\n", pdf_filter_names[image->compression]); } /* prepare precompressed (raw) image data */ if (image->use_raw) { pdf_printf(p, "/DecodeParms[%s<<", (p->debug['a'] ? "null" : "")); /* write EarlyChange or CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); if (image->compression == flate || image->compression == lzw) { if (image->predictor != pred_default) { pdf_printf(p, "/Predictor %d", (int) image->predictor); pdf_printf(p, "/Columns %d", (int) image->width); if (image->bpc != 8) pdf_printf(p, "/BitsPerComponent %d", image->bpc); if (image->colorspace < LastCS) { switch (image->colorspace) { case Indexed: case ImageMask: case DeviceGray: /* 1 is default */ break; case DeviceRGB: pdf_puts(p, "/Colors 3"); break; case DeviceCMYK: pdf_puts(p, "/Colors 4"); break; default: pdf_error(p, PDF_SystemError, "Unknown colorspace (%d)", (int )image->colorspace); break; } } } } if (image->compression == ccitt) { if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); } pdf_puts(p, ">>]\n"); /* DecodeParms dict and array */ } if (image->invert) { pdf_puts(p, "/Decode[1 0"); for (i = 1; i < image->components; i++) pdf_puts(p, " 1 0"); pdf_puts(p, "]\n"); } /* Write the actual image data */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* image data */ p->start_contents_pos = pdf_tell(p); /* image data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { if (image->use_raw) pdf_copy(p, &image->src); else pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* image data */ pdf_end_obj(p); /* XObject */ pdf_begin_obj(p, length_id); /* Length object */ pdf_printf(p,"%ld\n", length); pdf_end_obj(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); /* Image data done */ /* * Write colormap information for indexed color spaces */ if (firststrip && image->colorspace == Indexed) { pdf_begin_obj(p, image->colormap_id); /* colormap object */ pdf_begin_dict(p); if (p->debug['a']) pdf_puts(p, "/Filter[/ASCIIHexDecode]\n"); else if (p->compresslevel) pdf_puts(p, "/Filter[/FlateDecode]\n"); /* Length of colormap object */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); pdf_begin_stream(p); /* colormap data */ p->start_contents_pos = pdf_tell(p); if (image->components != 1) { pdf_error(p, PDF_SystemError, "Bogus indexed colorspace (%d color components)", image->components); } image->src.init = pdf_noop; image->src.fill = pdf_data_source_buf_fill; image->src.terminate = pdf_noop; image->src.buffer_start = (unsigned char *) image->colormap; image->src.buffer_length= (size_t) (image->palette_size * 3); image->src.bytes_available = 0; image->src.next_byte = NULL; /* Write colormap data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* Colormap data */ pdf_end_obj(p); /* Colormap object */ pdf_begin_obj(p, length_id); /* Length object for colormap */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); /* Length object for colormap */ } if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); }