static void pdf_setgraycolor(PDF *p, const char *type, float g) { pdf_cstate *cs = &p->cstate[p->sl]; if (g < 0.0 || g > EPSILON ) { pdf_error(p, PDF_NonfatalError, "Bogus gray value (%f) in PDF_setcolor", g); return; } if (!strcmp(type, "fill") || !strcmp(type, "both")) { if (cs->fill.cs != DeviceGray || cs->fill.val.gray != g) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f g\n", g); cs->fill.cs = DeviceGray; cs->fill.val.gray = g; } } if (!strcmp(type, "stroke") || !strcmp(type, "both")) { if (cs->stroke.cs != DeviceGray || cs->stroke.val.gray != g) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f G\n", g); cs->stroke.cs = DeviceGray; cs->stroke.val.gray = g; } } }
int pdf__shading_pattern(PDF *p, int shading, const char *optlist) { pdc_resopt *results; pdc_clientdata data; int gstate = -1; int retval = -1; if (p->compatibility == PDC_1_3) pdc_error(p->pdc, PDF_E_SHADING13, 0, 0, 0, 0); pdf_check_handle(p, shading, pdc_shadinghandle); if (optlist && strlen(optlist)) { pdf_set_clientdata(p, &data); results = pdc_parse_optionlist(p->pdc, optlist, pdf_shading_pattern_options, &data, pdc_true); (void) pdc_get_optvalues("gstate", results, &gstate, NULL); pdc_cleanup_optionlist(p->pdc, results); } if (p->pattern_number == p->pattern_capacity) pdf_grow_pattern(p); if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); /* Pattern object */ p->pattern[p->pattern_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Shadings don't have a painttype, but this signals to the * code which writes the pattern usage that no color values * will be required when setting the pattern color space. */ p->pattern[p->pattern_number].painttype = 1; pdc_begin_dict(p->out); /* Pattern dict*/ pdc_puts(p->out, "/PatternType 2\n"); /* shading pattern */ pdc_objref(p->out, "/Shading", p->shadings[shading].obj_id); p->shadings[shading].used_on_current_page = pdc_true; if (gstate != -1) pdc_objref(p->out, "/ExtGState", pdf_get_gstate_id(p, gstate)); pdc_end_dict(p->out); /* Pattern dict*/ pdc_end_obj(p->out); /* Pattern object */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); retval = p->pattern_number; p->pattern_number++; return retval; }
const char * pdf_current_scope(PDF *p) { const char *scopename = pdc_get_keyword(PDF_GET_STATE(p), pdf_scope_keylist); if (!scopename) pdc_error(p->pdc, PDF_E_INT_BADSCOPE, pdc_errprintf(p->pdc, " (0x%08X)", PDF_GET_STATE(p)), 0, 0, 0); return (char *) scopename; /* be happy, compiler! */ }
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); }
static void pdf_setcmykcolor( PDF *p, const char *type, float cyan, float magenta, float yellow, float black) { pdf_cstate *cs = &p->cstate[p->sl]; 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 CMYK color value (%f/%f/%f/%f) in PDF_setcolor", cyan, magenta, yellow, black); return; } if (!strcmp(type, "fill") || !strcmp(type, "both")) { if (cs->fill.cs != DeviceCMYK || cs->fill.val.cmyk.c != cyan || cs->fill.val.cmyk.m != magenta || cs->fill.val.cmyk.y != yellow || cs->fill.val.cmyk.k != black) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f %f %f %f k\n", cyan, magenta, yellow, black); cs->fill.cs = DeviceCMYK; cs->fill.val.cmyk.c = cyan; cs->fill.val.cmyk.m = magenta; cs->fill.val.cmyk.y = yellow; cs->fill.val.cmyk.k = black; } } if (!strcmp(type, "stroke") || !strcmp(type, "both")) { if (cs->stroke.cs != DeviceCMYK || cs->stroke.val.cmyk.c != cyan || cs->stroke.val.cmyk.m != magenta || cs->stroke.val.cmyk.y != yellow || cs->stroke.val.cmyk.k != black) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f %f %f %f K\n", cyan, magenta, yellow, black); cs->stroke.cs = DeviceCMYK; cs->stroke.val.cmyk.c = cyan; cs->stroke.val.cmyk.m = magenta; cs->stroke.val.cmyk.y = yellow; cs->stroke.val.cmyk.k = black; } } }
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); }
void pdf_error(PDF *p, int type, const char *fmt, ...) { static const char fn[] = "pdf_error"; char msg[2048]; va_list ap; va_start(ap, fmt); vsprintf(msg, fmt, ap); PDF_TRACE(("\n[%s\t(pdf(%p), %d (%s), \"%s\");]\n", fn, (void *) p, type, pdf_error_names[type], msg)); /* * We catch non-fatals here since user-supplied error handlers * don't know about the debug level. */ if (PDF_GET_STATE(p) != pdf_state_error /* avoid recursive errors */ && (type != PDF_NonfatalError || ((PDF *)p)->debug['w'])) { PDF_PUSH_STATE(p, fn, pdf_state_error); (p->errorhandler)(p, type, msg); /* If the error handler returns the error was non-fatal */ PDF_POP_STATE(p, fn); } PDF_TRACE(("[error handler returned]\n")); va_end(ap); }
static void pdf_setrgbcolor2(PDF *p, const char *type, float red, float green, float blue) { pdf_cstate *cs = &p->cstate[p->sl]; if (red < 0.0 || red > EPSILON || green < 0.0 || green > EPSILON || blue < 0.0 || blue > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus RGB color value (%f/%f/%f) in PDF_setcolor", red, green, blue); return; } if (red == green && green == blue) { pdf_setgraycolor(p, type, red); return; } if (!strcmp(type, "fill") || !strcmp(type, "both")) { if (cs->fill.cs != DeviceRGB || cs->fill.val.rgb.r != red || cs->fill.val.rgb.g != green || cs->fill.val.rgb.b != blue) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f %f %f rg\n", red, green, blue); cs->fill.cs = DeviceRGB; cs->fill.val.rgb.r = red; cs->fill.val.rgb.g = green; cs->fill.val.rgb.b = blue; } } if (!strcmp(type, "stroke") || !strcmp(type, "both")) { if (cs->stroke.cs != DeviceRGB || cs->stroke.val.rgb.r != red || cs->stroke.val.rgb.g != green || cs->stroke.val.rgb.b != blue) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "%f %f %f RG\n", red, green, blue); cs->stroke.cs = DeviceRGB; cs->stroke.val.rgb.r = red; cs->stroke.val.rgb.g = green; cs->stroke.val.rgb.b = blue; } } }
void pdf_scope_error(PDF *p, const char *funame) { if (PDF_GET_STATE(p) == pdf_state_error) return; pdf_error(p, PDF_RuntimeError, "function '%s' must not be called in '%s' scope", funame, pdf_current_scope(p)); }
static void pdf_setspotcolor(PDF *p, const char *type, int spotcolor, float tint) { pdf_cstate *cs = &p->cstate[p->sl]; if (spotcolor < 0 || spotcolor >= p->colorspaces_number) pdf_error(p, PDF_ValueError, "Invalid spot color number %d in PDF_setcolor", spotcolor); if (tint < 0.0 || tint > EPSILON ) pdf_error(p, PDF_ValueError, "Bogus spot color tint value (%f) in PDF_setcolor", tint); if (!strcmp(type, "fill") || !strcmp(type, "both")) { if (cs->fill.cs != Separation || cs->fill.val.sep.cs != spotcolor || cs->fill.val.sep.tint != tint) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "/CS%d cs %f scn\n", spotcolor, tint); p->cstate[p->sl].fill.cs = Separation; p->cstate[p->sl].fill.val.sep.cs = spotcolor; p->cstate[p->sl].fill.val.sep.tint = tint; } } if (!strcmp(type, "stroke") || !strcmp(type, "both")) { if (cs->fill.cs != Separation || cs->fill.val.sep.cs != spotcolor || cs->fill.val.sep.tint != tint) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_printf(p, "/CS%d CS %f SCN\n", spotcolor, tint); p->cstate[p->sl].stroke.cs = Separation; p->cstate[p->sl].stroke.val.sep.cs = spotcolor; p->cstate[p->sl].stroke.val.sep.tint = tint; } } p->colorspaces[spotcolor].used_on_current_page = pdf_true; }
static void pdf_set_color_values(PDF *p, pdf_color *cfill, pdf_color *cstroke, pdf_drawmode drawmode) { pdf_colorspace *cs; if (drawmode == pdf_stroke || drawmode == pdf_fillstroke) { pdf_color *strokecolor = pdf_get_cstate(p, pdf_stroke); if (!pdf_color_equal(p, strokecolor, cstroke) || PDF_FORCE_OUTPUT()) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_write_color_values(p, cstroke, pdf_stroke); *strokecolor = *cstroke; } cs = &p->colorspaces[cstroke->cs]; if (!PDF_SIMPLE_COLORSPACE(cs)) cs->used_on_current_page = pdc_true; } if (drawmode == pdf_fill || drawmode == pdf_fillstroke) { pdf_color *fillcolor = pdf_get_cstate(p, pdf_fill); if (!pdf_color_equal(p, fillcolor, cfill) || PDF_FORCE_OUTPUT()) { if (PDF_GET_STATE(p) != pdf_state_document) pdf_write_color_values(p, cfill, pdf_fill); *fillcolor = *cfill; } cs = &p->colorspaces[cfill->cs]; if (!PDF_SIMPLE_COLORSPACE(cs)) cs->used_on_current_page = pdc_true; } } /* pdf_set_color_values */
static void pdf_begin_path(PDF *p) { if (PDF_GET_STATE(p) == pdf_state_path) return; pdf_end_text(p); PDF_PUSH_STATE(p, "pdf_begin_path", pdf_state_path); }
static void pdf_orient_arc(PDF *p, pdc_scalar x, pdc_scalar y, pdc_scalar r, pdc_scalar alpha, pdc_scalar beta, pdc_scalar orient) { pdf_ppt *ppt = p->curr_ppt; pdc_scalar rad_a = alpha * PDC_DEG2RAD; pdc_scalar startx = (x + r * cos(rad_a)); pdc_scalar starty = (y + r * sin(rad_a)); if (PDF_GET_STATE(p) != pdf_state_path) { pdf__moveto(p, startx, starty); /* this enters pdf_state_path */ } else if ((ppt->gstate[ppt->sl].x != startx || ppt->gstate[ppt->sl].y != starty)) { pdf__lineto(p, startx, starty); } if (orient > 0) { while (beta < alpha) beta += 360; if (alpha == beta) return; while (beta - alpha > 90) { pdf_short_arc(p, x, y, r, alpha, alpha + 90); alpha += 90; } } else { while (alpha < beta) alpha += 360; if (alpha == beta) return; while (alpha - beta > 90) { pdf_short_arc(p, x, y, r, alpha, alpha - 90); alpha -= 90; } } if (alpha != beta) pdf_short_arc(p, x, y, r, alpha, beta); }
const char * pdf_current_scope(PDF *p) { static const char *scope_names[] = { "object", "document", "page", "pattern", "template", "path" }; int i; for (i = 0; i < 6; ++i) if (PDF_GET_STATE(p) == (1 << i)) return scope_names[i]; pdf_error(p, PDF_SystemError, "illegal state 0x%08X", PDF_GET_STATE(p)); return (char *) 0; /* be happy, compiler! */ }
static void pdf_check_color_values( PDF *p, pdf_colorspacetype type, pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4) { switch (type) { case DeviceGray: pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); break; case DeviceRGB: pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); pdc_check_number_limits(p->pdc, "c3", c3, 0.0, EPSILON); break; case DeviceCMYK: pdc_check_number_limits(p->pdc, "c1", c1, 0.0, EPSILON); pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); pdc_check_number_limits(p->pdc, "c3", c3, 0.0, EPSILON); pdc_check_number_limits(p->pdc, "c4", c4, 0.0, EPSILON); break; case PatternCS: pdf_check_handle(p, (int) c1, pdc_patternhandle); if (c1 == p->pattern_number - 1 && PDF_GET_STATE(p) & pdf_state_pattern) { pdc_error(p->pdc, PDF_E_PATTERN_SELF, 0, 0, 0, 0); } break; case Separation: pdf_check_handle(p, (int) c1, pdc_colorhandle); pdc_check_number_limits(p->pdc, "c2", c2, 0.0, EPSILON); break; case Indexed: default: break; } } /* pdf_check_color_values */
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 */
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; }
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 */
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); }
static void pdf_setcolor_internal(PDF *p, int drawmode, int colortype, pdc_scalar c1, pdc_scalar c2, pdc_scalar c3, pdc_scalar c4, pdf_color *fcolor) { pdf_color c, cstroke; pdf_colorspace cs; if (PDF_GET_STATE(p) == pdf_state_pattern && pdf_get_shading_painttype(p) == 2) { pdc_error(p->pdc, PDF_E_COLOR_INVALSPEC, 0, 0, 0, 0); } /* TODO: synchronize the PDF/X checks below with pdf_check_pdfx_colorspaces */ switch (colortype) { case color_gray: cs.type = DeviceGray; c.cs = cs.type; c.val.gray = c1; pdf_check_color_values(p, cs.type, c1, c2, c3, c4); break; case color_rgb: cs.type = DeviceRGB; c.cs = cs.type; c.val.rgb.r = c1; c.val.rgb.g = c2; c.val.rgb.b = c3; pdf_check_color_values(p, cs.type, c1, c2, c3, c4); break; case color_cmyk: cs.type = DeviceCMYK; c.cs = cs.type; c.val.cmyk.c = c1; c.val.cmyk.m = c2; c.val.cmyk.y = c3; c.val.cmyk.k = c4; pdf_check_color_values(p, cs.type, c1, c2, c3, c4); break; case color_spotname: case color_spot: pdc_error(p->pdc, PDF_E_UNSUPP_SPOTCOLOR, 0, 0, 0, 0); break; case color_pattern: cs.type = PatternCS; if (p->pdc->hastobepos) c1 -= 1; c.val.pattern = (int) c1; pdf_check_color_values(p, cs.type, c1, c2, c3, c4); if (p->pattern[c.val.pattern].painttype == 1) { cs.val.pattern.base = pdc_undef; c.cs = pdf_add_colorspace(p, &cs, pdc_false); cstroke = c; } else if (p->pattern[c.val.pattern].painttype == 2) { if (drawmode == pdf_stroke || drawmode == pdf_fillstroke) { pdf_color *strokecolor = pdf_get_cstate(p, pdf_stroke); if (p->colorspaces[strokecolor->cs].type == PatternCS) pdc_error(p->pdc, PDF_E_COLOR_INVALPATT, 0, 0, 0, 0); cstroke.val.pattern = (int) c1; cs.val.pattern.base = strokecolor->cs; cstroke.cs = pdf_add_colorspace(p, &cs, pdc_true); } if (drawmode == pdf_fill || drawmode == pdf_fillstroke) { pdf_color *fillcolor = pdf_get_cstate(p, pdf_fill); if (p->colorspaces[fillcolor->cs].type == PatternCS) pdc_error(p->pdc, PDF_E_COLOR_INVALPATT, 0, 0, 0, 0); cs.val.pattern.base = fillcolor->cs; c.cs = pdf_add_colorspace(p, &cs, pdc_true); } } break; case color_iccbasedgray: case color_iccbasedrgb: case color_iccbasedcmyk: case color_lab: pdc_error(p->pdc, PDF_E_UNSUPP_ICCBASEDCOLOR, 0, 0, 0, 0); break; } if (fcolor == NULL) { if (colortype != color_pattern) cstroke = c; pdf_set_color_values(p, &c, &cstroke, (pdf_drawmode) drawmode); } else { *fcolor = c; } }
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 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_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); }