void pdf_write_page_shadings(PDF *p) { int i, total = 0; for (i = 0; i < p->shadings_number; i++) if (p->shadings[i].used_on_current_page) total++; if (total > 0) { pdc_puts(p->out, "/Shading"); pdc_begin_dict(p->out); } if (total > 0) { for (i = 0; i < p->shadings_number; i++) { if (p->shadings[i].used_on_current_page) { p->shadings[i].used_on_current_page = pdc_false; /* reset */ pdc_printf(p->out, "/Sh%d", i); pdc_objref(p->out, "", p->shadings[i].obj_id); } } pdc_end_dict(p->out); } }
void pdf_write_page_extgstates(PDF *p) { int i, total = 0; for (i = 0; i < p->extgstates_number; i++) if (p->extgstates[i].used_on_current_page) total++; if (total > 0) { pdc_puts(p->out, "/ExtGState"); pdc_begin_dict(p->out); /* ExtGState names */ for (i = 0; i < p->extgstates_number; i++) { if (p->extgstates[i].used_on_current_page) { p->extgstates[i].used_on_current_page = pdc_false; /* reset */ pdc_printf(p->out, "/GS%d %ld 0 R\n", i, p->extgstates[i].obj_id); } } pdc_end_dict(p->out); /* ExtGState names */ } }
void pdf_write_outlines(PDF *p) { int i; if (p->outline_count == 0) /* no outlines: return */ return; pdc_begin_obj(p->out, p->outlines[0].obj_id); /* root outline object */ pdc_begin_dict(p->out); if (p->outlines[0].count != 0) pdc_printf(p->out, "/Count %d\n", COUNT(0)); pdc_objref(p->out, "/First", OBJ_ID(FIRST(0))); pdc_objref(p->out, "/Last", OBJ_ID(LAST(0))); pdc_end_dict(p->out); pdc_end_obj(p->out); /* root outline object */ #define PDF_FLUSH_AFTER_MANY_OUTLINES 1000 /* ca. 50-100 KB */ for (i = 1; i <= p->outline_count; i++) { /* reduce memory usage for many outline entries */ if (i % PDF_FLUSH_AFTER_MANY_OUTLINES == 0) pdc_flush_stream(p->out); pdf_write_outline_dict(p, i); } }
void pdf_write_page_extgstates(PDF *p) { int i, total = 0; int bias = p->curr_ppt->eg_bias; for (i = 0; i < p->extgstates_number; i++) if (p->extgstates[i].used_on_current_page) total++; if (total > 0 || bias) { pdc_puts(p->out, "/ExtGState"); pdc_begin_dict(p->out); } if (total > 0) { for (i = 0; i < p->extgstates_number; i++) { if (p->extgstates[i].used_on_current_page) { p->extgstates[i].used_on_current_page = pdc_false; /* reset */ pdc_printf(p->out, "/GS%d", bias + i); pdc_objref(p->out, "", p->extgstates[i].obj_id); } } if (!bias) pdc_end_dict(p->out); } }
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; }
void pdf__end_font(PDF *p) { int i; pdc_t3font *t3font; PDF_SET_STATE(p, pdf_state_document); t3font = p->t3font; t3font->charprocs_id = pdc_alloc_id(p->out); pdc_begin_obj(p->out, t3font->charprocs_id); /* CharProcs dict */ pdc_begin_dict(p->out); for (i = 0; i < t3font->next_glyph; i++) { pdc_put_pdfname(p->out, t3font->glyphs[i].name, strlen(t3font->glyphs[i].name)); pdc_printf(p->out, " %ld 0 R\n", t3font->glyphs[i].charproc_id); } pdc_end_dict(p->out); pdc_end_obj(p->out); /* CharProcs dict */ pdc_begin_obj(p->out, t3font->res_id); pdc_begin_dict(p->out); /* Resource dict */ 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 */ pdc_end_dict(p->out); /* Resource dict */ pdc_end_obj(p->out); /* Resource object */ p->t3font = (pdc_t3font *) NULL; if (p->flush & pdf_flush_content) pdc_flush_stream(p->out); }
void pdf_write_colormap(PDF *p, int slot) { PDF_data_source src; pdf_colorspace *cs, *base; pdc_id length_id; cs = &p->colorspaces[slot]; if (cs->type != Indexed || cs->val.indexed.colormap_done == pdc_true) return; base = &p->colorspaces[cs->val.indexed.base]; pdc_begin_obj(p->out, cs->val.indexed.colormap_id); /* colormap object */ pdc_begin_dict(p->out); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); /* Length of colormap object */ length_id = pdc_alloc_id(p->out); pdc_objref(p->out, "/Length", length_id); pdc_end_dict(p->out); src.init = NULL; src.fill = pdf_data_source_buf_fill; src.terminate = NULL; src.buffer_start = (unsigned char *) cs->val.indexed.colormap; src.buffer_length = (size_t) (cs->val.indexed.palette_size * pdf_color_components(p, cs->val.indexed.base)); src.bytes_available = 0; src.next_byte = NULL; /* Write colormap data */ pdf_copy_stream(p, &src, pdc_true); /* colormap data */ pdc_end_obj(p->out); /* colormap object */ pdc_put_pdfstreamlength(p->out, length_id); /* free the colormap now that it's written */ pdc_free(p->pdc, cs->val.indexed.colormap); cs->val.indexed.colormap = NULL; cs->val.indexed.colormap_done = pdc_true; } /* pdf_write_colormap */
void pdf_write_page_colorspaces(PDF *p) { int i, total = 0; for (i = 0; i < p->colorspaces_number; i++) if (p->colorspaces[i].used_on_current_page) total++; if (total > 0 ) { pdc_puts(p->out, "/ColorSpace"); pdc_begin_dict(p->out); if (total > 0) { for (i = 0; i < p->colorspaces_number; i++) { pdf_colorspace *cs = &p->colorspaces[i]; if (cs->used_on_current_page) { cs->used_on_current_page = pdc_false; /* reset */ /* don't write simple color spaces as resource */ if (!PDF_SIMPLE_COLORSPACE(cs)) { pdc_printf(p->out, "/C%d", i); pdc_objref(p->out, "", cs->obj_id); } } } } pdc_end_dict(p->out); /* color space names */ } } /* pdf_write_page_colorspaces */
/* Finish the pattern definition. */ void pdf__end_pattern(PDF *p) { /* check whether pdf__save() and pdf__restore() calls are balanced */ if (p->curr_ppt->sl > 0) pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0); pdf_end_text(p); pdc_end_pdfstream(p->out); pdc_end_obj(p->out); /* pattern */ pdc_put_pdfstreamlength(p->out, p->length_id); pdc_begin_obj(p->out, p->res_id); /* Resource object */ pdc_begin_dict(p->out); /* Resource dict */ 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_write_page_extgstates(p); /* ExtGState resources */ pdc_end_dict(p->out); /* resource dict */ pdc_end_obj(p->out); /* resource object */ pdf_pg_resume(p, -1); if (p->flush & pdc_flush_content) pdc_flush_stream(p->out); if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[End pattern %d]\n", p->pattern_number -1); }
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_write_doc_extgstates(PDF *p) { int i, j; pdf_extgstateresource *gs; for (i = 0; i < p->extgstates_number; i++) { gs = &p->extgstates[i]; pdc_begin_obj(p->out, gs->obj_id); /* ExtGState resource */ pdc_begin_dict(p->out); pdc_puts(p->out, "/Type/ExtGState\n"); if (gs->font_obj != PDC_NEW_ID) { pdc_puts(p->out, "/Font"); pdc_begin_array(p->out); pdc_objref(p->out, "", gs->font_obj); pdc_printf(p->out, "%f", gs->font_size); pdc_end_array(p->out); } if (gs->line_width != pdc_undef) pdc_printf(p->out, "/LW %f\n", gs->line_width); if (gs->line_cap != pdc_undef) pdc_printf(p->out, "/LC %d\n", gs->line_cap); if (gs->line_join != pdc_undef) pdc_printf(p->out, "/LJ %d\n", gs->line_join); if (gs->miter_limit != pdc_undef) pdc_printf(p->out, "/ML %f\n", gs->miter_limit); if (gs->dash_count > 0) { pdc_printf(p->out, "/D"); pdc_begin_array(p->out); pdc_begin_array(p->out); for (j = 0; j < gs->dash_count; ++j) pdc_printf(p->out, "%f ", gs->dash_array[j]); pdc_end_array_c(p->out); pdc_printf(p->out, "%f", gs->dash_phase); pdc_end_array(p->out); /* but see page 157 of PDF Reference: integer */ } if (gs->ri != AutoIntent) pdc_printf(p->out, "/RI/%s\n", pdc_get_keyword((long) gs->ri, pdf_renderingintent_pdfkeylist)); if (gs->stroke_adjust != pdc_undef) pdc_printf(p->out, "/SA %s\n", PDC_BOOLSTR(gs->stroke_adjust)); if (gs->overprint_stroke != pdc_undef) pdc_printf(p->out, "/OP %s\n", PDC_BOOLSTR(gs->overprint_stroke)); if (gs->overprint_fill != pdc_undef) pdc_printf(p->out, "/op %s\n", PDC_BOOLSTR(gs->overprint_fill)); else if (gs->overprint_stroke == pdc_true) pdc_puts(p->out, "/op false\n"); if (gs->overprint_mode != pdc_undef) pdc_printf(p->out, "/OPM %d\n", gs->overprint_mode); if (gs->flatness != pdc_undef) pdc_printf(p->out, "/FL %f\n", gs->flatness); if (gs->smoothness != pdc_undef) pdc_printf(p->out, "/SM %f\n", gs->smoothness); if (gs->opacity_fill != pdc_undef) pdc_printf(p->out, "/ca %f\n", gs->opacity_fill); if (gs->blendmode != BM_None) { const char *modename; int modecount=0; for (j = 0; ; j++) { if (!pdf_blendmode_pdfkeylist[j].word) break; if (gs->blendmode & pdf_blendmode_pdfkeylist[j].code) modecount++; } pdc_printf(p->out, "/BM"); /* * ACROBUG: Acrobat 7 doesn't like Blend mode arrays with a * singly entry under some circumstances (many entries? images * involved?) so we avoid the array if we have only one entry. */ if (modecount > 1) pdc_begin_array(p->out); for (j = 0; ; j++) { modename = pdf_blendmode_pdfkeylist[j].word; if (!modename) break; if (gs->blendmode & pdf_blendmode_pdfkeylist[j].code) pdc_printf(p->out, "/%s", modename); } if (modecount > 1) pdc_end_array(p->out); } if (gs->opacity_stroke != pdc_undef) pdc_printf(p->out, "/CA %f\n", gs->opacity_stroke); if (gs->alpha_is_shape != pdc_undef) pdc_printf(p->out, "/AIS %s\n", PDC_BOOLSTR(gs->alpha_is_shape)); if (gs->text_knockout != pdc_undef) pdc_printf(p->out, "/TK %s\n", PDC_BOOLSTR(gs->text_knockout)); pdc_end_dict(p->out); pdc_end_obj(p->out); /* ExtGState resource */ } }
static pdc_id pdf_write_action(PDF *p, pdf_action *action, pdc_id next_id) { pdc_id ret_id = PDC_BAD_ID; int i, flags = 0; ret_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Action object */ pdc_begin_dict(p->out); /* Action dict */ pdc_puts(p->out, "/Type/Action\n"); pdc_printf(p->out, "/S/%s\n", pdc_get_keyword(action->atype, pdf_action_pdfkeylist)); /* next action */ if (next_id != PDC_BAD_ID) pdc_objref(p->out, "/Next", next_id); else action->obj_id = ret_id; /* destination */ switch (action->atype) { case pdf_goto: case pdf_gotor: pdc_puts(p->out, "/D"); pdf_write_destination(p, action->dest); default: break; } /* file specification */ switch (action->atype) { case pdf_gotor: case pdf_launch: if (action->newwindow != pdc_undef) pdc_printf(p->out, "/NewWindow %s\n", PDC_BOOLSTR(action->newwindow)); case pdf_importdata: if (action->parameters || action->operation || action->defaultdir) { /* Windows-specific launch parameters */ pdc_puts(p->out, "/Win"); pdc_begin_dict(p->out); /* Win dict */ pdc_puts(p->out, "/F"); pdf_put_pdffilename(p, action->nativefilename); pdc_puts(p->out, "\n"); if (p->compatibility >= PDC_1_7) { pdc_puts(p->out, "/UF"); pdf_put_pdfunifilename(p, action->filename); pdc_puts(p->out, "\n"); } if (action->parameters) { pdc_puts(p->out, "/P"); pdf_put_hypertext(p, action->parameters); pdc_puts(p->out, "\n"); pdc_free(p->pdc, action->parameters); action->parameters = NULL; } if (action->operation) { pdc_puts(p->out, "/O"); pdf_put_hypertext(p, action->operation); pdc_puts(p->out, "\n"); action->operation = NULL; } if (action->defaultdir) { pdc_puts(p->out, "/D"); pdf_put_hypertext(p, action->defaultdir); pdc_puts(p->out, "\n"); pdc_free(p->pdc, action->defaultdir); action->defaultdir = NULL; } pdc_end_dict(p->out); /* Win dict */ } else { pdc_puts(p->out, "/F"); pdc_begin_dict(p->out); /* F dict */ pdc_puts(p->out, "/Type/Filespec\n"); pdc_puts(p->out, "/F"); pdf_put_pdffilename(p, action->nativefilename); pdc_puts(p->out, "\n"); if (p->compatibility >= PDC_1_7) { pdc_puts(p->out, "/UF"); pdf_put_pdfunifilename(p, action->filename); pdc_puts(p->out, "\n"); } pdc_end_dict(p->out); /* F dict */ } default: break; } /* URI */ switch (action->atype) { case pdf_uri: pdc_puts(p->out, "/URI"); pdf_put_hypertext(p, action->filename); pdc_puts(p->out, "\n"); /* IsMap */ if (action->ismap == pdc_true) pdc_puts(p->out, "/IsMap true\n"); default: break; } /* Named */ switch (action->atype) { case pdf_named: pdc_puts(p->out, "/N"); pdf_put_pdfname(p, action->menuname); pdc_puts(p->out, "\n"); default: break; } /* name list */ switch (action->atype) { case pdf_hide: if (action->hide == pdc_false) pdc_puts(p->out, "/H false\n"); case pdf_submitform: case pdf_resetform: if (action->nsnames) { pdc_printf(p->out, "/%s", (action->atype == pdf_hide) ? "T" : "Fields"); pdc_begin_array(p->out); for (i = 0; i < action->nsnames; i++) { pdf_put_hypertext(p, action->namelist[i]); if (i < action->nsnames - 1) pdc_puts(p->out, "\n"); else pdc_end_array(p->out); } } default: break; } /* URL */ switch (action->atype) { case pdf_submitform: pdc_puts(p->out, "/F"); pdc_begin_dict(p->out); /* F dict */ pdc_puts(p->out, "/FS/URL\n"); pdc_printf(p->out, "/F"); pdf_put_hypertext(p, action->filename); pdc_puts(p->out, "\n"); pdc_end_dict(p->out); /* F dict */ default: break; } /* Trans */ switch (action->atype) { case pdf_trans: pdc_puts(p->out, "/Trans"); pdc_begin_dict(p->out); /* Trans dict */ pdc_puts(p->out, "/Type/Trans\n"); if (action->transition != trans_replace) pdc_printf(p->out, "/S/%s", pdc_get_keyword(action->transition, pdf_transition_pdfkeylist)); if (action->duration > 0) pdc_printf(p->out, "/D %f\n", action->duration); pdc_end_dict(p->out); /* Trans dict */ default: break; } /* Flags */ switch (action->atype) { case pdf_submitform: flags = (int) action->exportmethod; if (action->submitemptyfields) flags |= (1<<1); if (action->canonicaldate) flags |= (1<<9); case pdf_resetform: if (action->exclude) flags |= (1<<0); if (flags) pdc_printf(p->out, "/Flags %d\n", flags); default: break; } /* Movie */ pdc_end_dict(p->out); /* Action dict */ pdc_end_obj(p->out); /* Action object */ return ret_id; }
pdc_bool pdf_write_action_entries(PDF *p, pdf_event_object eventobj, pdc_id *act_idlist) { const pdc_keyconn *keyconntable = NULL; const char *keyword; pdc_id act_id = PDC_BAD_ID; pdc_bool adict = pdc_false; pdc_bool aadict = pdc_false; int code; switch(eventobj) { case event_annotation: keyconntable = pdf_annotevent_pdfkeylist; break; case event_bookmark: keyconntable = pdf_bookmarkevent_pdfkeylist; break; case event_document: keyconntable = pdf_documentevent_pdfkeylist; break; case event_page: keyconntable = pdf_pageevent_pdfkeylist; break; default: break; } for (code = 0; ; code++) { keyword = pdc_get_keyword(code, keyconntable); if (keyword) { act_id = act_idlist[code]; if (act_id != PDC_BAD_ID) { if (code && !aadict) { pdc_puts(p->out, "/AA"); pdc_begin_dict(p->out); /* AA dict */ aadict = pdc_true; } else if (!code) adict = pdc_true; pdc_printf(p->out, "/%s", keyword); pdc_objref_c(p->out, act_id); } } else break; } if (aadict) pdc_end_dict(p->out); /* AA dict */ else if (adict) pdc_puts(p->out, "\n"); return adict; }
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); }
pdc_id pdf_write_info(PDF *p, pdc_bool moddate) { pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_xmp); char time_str[PDC_TIME_SBUF_SIZE]; char producer[PDC_GEN_BUFSIZE]; pdf_info *info; pdc_id info_id; const char *product = "PDFlib Lite"; const char *security = ""; (void) logg3; if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[Full product name: \"%s\"]\n", product); info_id = pdc_begin_obj(p->out, PDC_NEW_ID); /* Info object */ pdc_begin_dict(p->out); /* * Although it would be syntactically correct, we must not remove * the space characters after the dictionary keys since this * would break the PDF properties feature in Windows Explorer. */ if (p->userinfo) { for (info = p->userinfo; info != NULL; info = info->next) { pdf_put_pdfname(p, info->key); pdc_puts(p->out, " "); if (strcmp(info->key, "Trapped")) pdf_put_hypertext(p, info->value); else pdf_put_pdfname(p, info->value); pdc_puts(p->out, "\n"); } } pdc_get_timestr(time_str, pdc_false); /* creation date and time */ pdc_puts(p->out, "/CreationDate "); pdf_put_hypertext(p, time_str); pdc_puts(p->out, "\n"); /* modification date and time */ if (moddate) { pdc_puts(p->out, "/ModDate "); pdf_put_hypertext(p, time_str); pdc_puts(p->out, "\n"); } /* * If you change the /Producer entry your license to use * PDFlib will be void! */ if (p->pdc->binding) pdc_sprintf(p->pdc, pdc_false, producer, "%s %s%s (%s/%s)", product, PDFLIB_VERSIONSTRING, security, p->pdc->binding, PDF_PLATFORM); else pdc_sprintf(p->pdc, pdc_false, producer, "%s %s%s (%s)", product, PDFLIB_VERSIONSTRING, security, PDF_PLATFORM); pdc_puts(p->out, "/Producer "); pdf_put_hypertext(p, producer); pdc_puts(p->out, "\n"); pdc_end_dict(p->out); pdc_end_obj(p->out); /* Info object */ return info_id; }
void pdf__end_font(PDF *p) { int ig; pdf_font *font; pdf_t3font *t3font; PDF_SET_STATE(p, pdf_state_document); font = &p->fonts[p->t3slot]; t3font = font->t3font; /* error message prefix */ pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0); if (t3font->pass == 0) { pdf_t3glyph glyph0 = t3font->glyphs[0]; /* search for .notdef glyph */ if (pdc_strcmp(glyph0.name, (char *) pdc_get_notdef_glyphname())) { for (ig = 0; ig < t3font->next_glyph; ig++) { if (!pdc_strcmp(t3font->glyphs[ig].name, (char *) pdc_get_notdef_glyphname())) break; } if (ig < t3font->next_glyph) { pdc_logg_cond(p->pdc, 2, trc_font, "\tGlyph id %d: \"%s\" will be exchanged " "with glyph id 0: \"%s\"\n", ig, t3font->glyphs[ig].name, glyph0.name); t3font->glyphs[0] = t3font->glyphs[ig]; t3font->glyphs[ig] = glyph0; } else { pdc_warning(p->pdc, PDF_E_T3_MISSNOTDEF, 0, 0, 0, 0); } } } if (t3font->pass != 1) { t3font->charprocs_id = pdc_alloc_id(p->out); pdc_begin_obj(p->out, t3font->charprocs_id); /* CharProcs dict */ pdc_begin_dict(p->out); for (ig = 0; ig < t3font->next_glyph; ig++) { pdf_t3glyph *glyph = &t3font->glyphs[ig]; if (glyph->charproc_id != PDC_BAD_ID) { pdf_put_pdfname(p, glyph->name); pdc_objref(p->out, "", glyph->charproc_id); } } pdc_end_dict(p->out); pdc_end_obj(p->out); /* CharProcs dict */ pdc_begin_obj(p->out, t3font->res_id); pdc_begin_dict(p->out); /* Resource dict */ 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 */ pdc_end_dict(p->out); /* Resource dict */ pdc_end_obj(p->out); /* Resource object */ pdf_pg_resume(p, -1); if (p->flush & pdc_flush_content) pdc_flush_stream(p->out); /* see pdf__begin_glyph */ pdf_init_tstate(p); pdf_init_gstate(p); pdf_init_cstate(p); } pdc_logg_cond(p->pdc, 1, trc_font, "\tEnd of Type3 font \"%s\"\n", font->apiname); pdc_pop_errmsg(p->pdc); if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[End font %d]\n", p->t3slot); p->t3slot = -1; }
static void pdf_write_outline_dict(PDF *p, int entry) { pdf_outline *outline = &p->outlines[entry]; pdc_id act_idlist[PDF_MAX_EVENTS]; /* write action objects */ if (outline->action) pdf_parse_and_write_actionlist(p, event_bookmark, act_idlist, (const char *) outline->action); pdc_begin_obj(p->out, OBJ_ID(entry)); /* outline object */ pdc_begin_dict(p->out); pdc_objref(p->out, "/Parent", OBJ_ID(PARENT(entry))); /* outline destination */ if (outline->dest) { pdc_puts(p->out, "/Dest"); pdf_write_destination(p, outline->dest); } /* write Action entries */ else if (outline->action) pdf_write_action_entries(p, event_bookmark, act_idlist); pdc_puts(p->out, "/Title"); /* outline text */ pdf_put_hypertext(p, outline->text); pdc_puts(p->out, "\n"); if (PREV(entry)) pdc_objref(p->out, "/Prev", OBJ_ID(PREV(entry))); if (NEXT(entry)) pdc_objref(p->out, "/Next", OBJ_ID(NEXT(entry))); if (FIRST(entry)) { pdc_objref(p->out, "/First", OBJ_ID(FIRST(entry))); pdc_objref(p->out, "/Last", OBJ_ID(LAST(entry))); } if (COUNT(entry)) { if (OPEN(entry)) pdc_printf(p->out, "/Count %d\n", COUNT(entry)); /* open */ else pdc_printf(p->out, "/Count %d\n", -COUNT(entry));/* closed */ } /* Color */ if (outline->textcolor[0] != 0.0 || outline->textcolor[1] != 0.0 || outline->textcolor[2] != 0.0) pdc_printf(p->out, "/C[%f %f %f]\n", outline->textcolor[0], outline->textcolor[1], outline->textcolor[2]); /* FontStyle */ if (outline->fontstyle != fnt_Normal) { int fontstyle = 0; if (outline->fontstyle == fnt_Bold) fontstyle = 2; if (outline->fontstyle == fnt_Italic) fontstyle = 1; if (outline->fontstyle == fnt_BoldItalic) fontstyle = 3; pdc_printf(p->out, "/F %d\n", fontstyle); } pdc_end_dict(p->out); pdc_end_obj(p->out); /* outline object */ }
void pdf__begin_glyph( PDF *p, const char *glyphname, float wx, float llx, float lly, float urx, float ury) { static const char fn[] = "pdf__begin_glyph"; pdc_t3font *t3font; pdc_t3glyph *glyph; int i; t3font = p->t3font; if (t3font->colorized == pdc_true && (llx != (float) 0 || lly != (float) 0 || urx != (float) 0 || ury != (float) 0)) pdc_error(p->pdc, PDF_E_T3_BADBBOX, t3font->fontname, 0, 0, 0); PDF_SET_STATE(p, pdf_state_glyph); for (i = 0; i < t3font->next_glyph; ++i) { if (!strcmp(t3font->glyphs[i].name, glyphname)) { pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, t3font->fontname, 0, 0); } } if (t3font->next_glyph == t3font->capacity) { t3font->capacity *= 2; t3font->glyphs = (pdc_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs, t3font->capacity * sizeof (pdc_t3glyph), fn); } glyph = &t3font->glyphs[t3font->next_glyph]; glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID); glyph->name = pdc_strdup(p->pdc, glyphname); /* see comment in p_font.c for explanation */ glyph->width = 1000 * wx * t3font->matrix.a; /* if the strdup above fails, cleanup won't touch this slot. */ ++t3font->next_glyph; p->contents = c_page; /* glyph description */ pdc_begin_dict(p->out); /* glyph description dict */ p->length_id = pdc_alloc_id(p->out); pdc_printf(p->out, "/Length %ld 0 R\n", p->length_id); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); pdc_end_dict(p->out); /* glyph description dict */ pdc_begin_pdfstream(p->out); /* glyph description stream */ p->next_content++; if (t3font->colorized == pdc_true) pdc_printf(p->out, "%f 0 d0\n", wx); else { pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", wx, llx, lly, urx, ury); /* adjust the font's bounding box */ if (llx < t3font->bbox.llx) t3font->bbox.llx = llx; if (lly < t3font->bbox.lly) t3font->bbox.lly = lly; if (urx > t3font->bbox.urx) t3font->bbox.urx = urx; if (ury > t3font->bbox.ury) t3font->bbox.ury = ury; } }
void pdf_write_doc_extgstates(PDF *p) { int i, j; pdf_extgstateresource *gs; for (i = 0; i < p->extgstates_number; i++) { gs = &p->extgstates[i]; pdc_begin_obj(p->out, gs->obj_id); /* ExtGState resource */ pdc_begin_dict(p->out); pdc_puts(p->out, "/Type/ExtGState\n"); if (gs->font_obj != PDC_NEW_ID) pdc_printf(p->out, "/Font[%ld 0 R %f]\n", gs->font_obj, gs->font_size); if (gs->line_width != pdc_undef) pdc_printf(p->out, "/LW %f\n", gs->line_width); if (gs->line_cap != pdc_undef) pdc_printf(p->out, "/LC %d\n", gs->line_cap); if (gs->line_join != pdc_undef) pdc_printf(p->out, "/LJ %d\n", gs->line_join); if (gs->miter_limit != pdc_undef) pdc_printf(p->out, "/ML %f\n", gs->miter_limit); if (gs->dash_count > 0) { pdc_printf(p->out, "/D[["); for (j = 0; j < gs->dash_count; ++j) pdc_printf(p->out, "%f ", gs->dash_array[j]); pdc_printf(p->out, "] %f]\n", gs->dash_phase); /* but see page 157 of PDF Reference: integer */ } if (gs->ri != AutoIntent) pdc_printf(p->out, "/RI/%s\n", pdc_get_keyword((long) gs->ri, gs_renderingintents)); if (gs->stroke_adjust != pdc_undef) pdc_printf(p->out, "/SA %s\n", gs->stroke_adjust ? "true" : "false"); if (gs->overprint_stroke != pdc_undef) pdc_printf(p->out, "/OP %s\n", gs->overprint_stroke ? "true" : "false"); if (gs->overprint_fill != pdc_undef) pdc_printf(p->out, "/op %s\n", gs->overprint_fill ? "true" : "false"); else if (gs->overprint_stroke == pdc_true) pdc_puts(p->out, "/op false\n"); if (gs->overprint_mode != pdc_undef) pdc_printf(p->out, "/OPM %d\n", gs->overprint_mode); if (gs->flatness != pdc_undef) pdc_printf(p->out, "/FL %f\n", gs->flatness); if (gs->smoothness != pdc_undef) pdc_printf(p->out, "/SM %f\n", gs->smoothness); if (gs->opacity_fill != pdc_undef) pdc_printf(p->out, "/ca %f\n", gs->opacity_fill); if (gs->blendmode != BM_None) { const char *modename; pdc_printf(p->out, "/BM["); for (j = 0; ; j++) { modename = gs_blendmodes[j].word; if (!modename) break; if (gs->blendmode & gs_blendmodes[j].code) pdc_printf(p->out, "/%s", modename); } pdc_printf(p->out, "]\n"); } if (gs->opacity_stroke != pdc_undef) pdc_printf(p->out, "/CA %f\n", gs->opacity_stroke); if (gs->alpha_is_shape != pdc_undef) pdc_printf(p->out, "/AIS %s\n", gs->alpha_is_shape ? "true" : "false"); if (gs->text_knockout != pdc_undef) pdc_printf(p->out, "/TK %s\n", gs->text_knockout ? "true" : "false"); pdc_end_dict(p->out); pdc_end_obj(p->out); /* ExtGState resource */ } }
/* Start a new pattern definition. */ int pdf__begin_pattern( PDF *p, pdc_scalar width, pdc_scalar height, pdc_scalar xstep, pdc_scalar ystep, int painttype) { int slot = -1; pdc_check_number_limits(p->pdc, "width", width, PDC_FLOAT_PREC, PDC_FLOAT_MAX); pdc_check_number_limits(p->pdc, "height", height, PDC_FLOAT_PREC, PDC_FLOAT_MAX); pdc_check_number_zero(p->pdc, "xstep", xstep); pdc_check_number_zero(p->pdc, "ystep", ystep); if (painttype != 1 && painttype != 2) pdc_error(p->pdc, PDC_E_ILLARG_INT, "painttype", pdc_errprintf(p->pdc, "%d", painttype), 0, 0); if (p->pattern_number == p->pattern_capacity) pdf_grow_pattern(p); pdf_pg_suspend(p); PDF_SET_STATE(p, pdf_state_pattern); p->pattern[p->pattern_number].obj_id = pdc_begin_obj(p->out, PDC_NEW_ID); p->pattern[p->pattern_number].painttype = painttype; pdc_begin_dict(p->out); /* pattern dict*/ p->res_id = pdc_alloc_id(p->out); pdc_puts(p->out, "/PatternType 1\n"); /* tiling pattern */ /* colored or uncolored pattern */ pdc_printf(p->out, "/PaintType %d\n", painttype); pdc_puts(p->out, "/TilingType 1\n"); /* constant spacing */ pdc_printf(p->out, "/BBox[0 0 %f %f]\n", width, height); pdc_printf(p->out, "/XStep %f\n", xstep); pdc_printf(p->out, "/YStep %f\n", ystep); pdc_objref(p->out, "/Resources", p->res_id); p->length_id = pdc_alloc_id(p->out); pdc_objref(p->out, "/Length", p->length_id); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); pdc_end_dict(p->out); /* pattern dict*/ pdc_begin_pdfstream(p->out); slot = p->pattern_number; p->pattern_number++; /* top-down y-coordinates */ pdf_set_topdownsystem(p, height); /* set color differing from PDF default */ pdf_set_default_color(p, pdc_false); if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[Begin pattern %d]\n", slot); return slot; }
void pdf__begin_glyph( PDF *p, const char *glyphname, pdc_scalar wx, pdc_scalar llx, pdc_scalar lly, pdc_scalar urx, pdc_scalar ury) { static const char fn[] = "pdf__begin_glyph"; pdf_font *font; pdf_t3font *t3font; pdf_t3glyph *glyph = NULL; pdc_scalar tbc; int ig; if (glyphname == NULL || *glyphname == '\0') pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "glyphname", 0, 0, 0); font = &p->fonts[p->t3slot]; t3font = font->t3font; /* error message prefix */ pdc_push_errmsg(p->pdc, PDF_E_T3_FONT_PREFIX, font->apiname, 0, 0, 0); for (ig = 0; ig < t3font->next_glyph; ig++) { glyph = &t3font->glyphs[ig]; if (!pdc_strcmp(glyph->name, glyphname)) { if (t3font->pass == glyph->pass) pdc_error(p->pdc, PDF_E_T3_GLYPH, glyphname, 0, 0, 0); else break; } } /* new glyph */ if (ig == t3font->next_glyph) { if (t3font->pass == 2) pdc_error(p->pdc, PDF_E_T3_UNKOWNGLYPH, glyphname, 0, 0, 0); pdc_check_number(p->pdc, "wx", wx); pdc_check_number(p->pdc, "llx", llx); pdc_check_number(p->pdc, "lly", lly); pdc_check_number(p->pdc, "urx", urx); pdc_check_number(p->pdc, "ury", ury); if (t3font->colorized == pdc_true && (llx != 0 || lly != 0 || urx != 0 || ury != 0)) pdc_error(p->pdc, PDF_E_T3_BADBBOX, 0, 0, 0, 0); if (urx < llx) { tbc = llx; llx = urx; urx = tbc; } if (ury < lly) { tbc = lly; lly = ury; ury = tbc; } if (ig == t3font->capacity) { t3font->capacity *= 2; t3font->glyphs = (pdf_t3glyph *) pdc_realloc(p->pdc, t3font->glyphs, t3font->capacity * sizeof (pdf_t3glyph), fn); } glyph = &t3font->glyphs[ig]; glyph->charproc_id = PDC_BAD_ID; glyph->name = pdc_strdup(p->pdc, glyphname); glyph->wx = wx; glyph->llx = llx; glyph->lly = lly; glyph->urx = urx; glyph->ury = ury; /* see comment in p_font.c for explanation */ glyph->width = 1000 * wx * font->ft.matrix.a; /* if the strdup above fails, cleanup won't touch this slot. */ t3font->next_glyph++; } glyph->pass = t3font->pass; t3font->curr_glyph = ig; pdc_logg_cond(p->pdc, 1, trc_font, "\tBegin of Type3 font glyph \"%s\"\n", glyphname); if (t3font->pass != 1) { if (t3font->pass == 2) pdc_logg_cond(p->pdc, 2, trc_font, "\t\tglyph [%d] was used in text\n", ig); glyph->charproc_id = pdc_begin_obj(p->out, PDC_NEW_ID); pdc_begin_dict(p->out); p->length_id = pdc_alloc_id(p->out); pdc_objref(p->out, "/Length", p->length_id); if (pdc_get_compresslevel(p->out)) pdc_puts(p->out, "/Filter/FlateDecode\n"); pdc_end_dict(p->out); pdc_begin_pdfstream(p->out); if (t3font->colorized == pdc_true) pdc_printf(p->out, "%f 0 d0\n", glyph->wx); else { pdc_printf(p->out, "%f 0 %f %f %f %f d1\n", glyph->wx, glyph->llx, glyph->lly, glyph->urx, glyph->ury); /* adjust the font's bounding box */ if (glyph->llx < font->ft.bbox.llx) font->ft.bbox.llx = glyph->llx; if (glyph->lly < font->ft.bbox.lly) font->ft.bbox.lly = glyph->lly; if (glyph->urx > font->ft.bbox.urx) font->ft.bbox.urx = glyph->urx; if (glyph->ury > font->ft.bbox.ury) font->ft.bbox.ury = glyph->ury; } /* we must initialize the text, graphics and color state * otherwise the user get unpredictable appearance of a * glyph because of optimizing outputting graphics properties. * Following statements were inserted due to bug #719 */ pdf_init_tstate(p); pdf_init_gstate(p); pdf_init_cstate(p); PDF_SET_STATE(p, pdf_state_glyph); } else { PDF_SET_STATE(p, pdf_state_glyphmetrics); } pdc_pop_errmsg(p->pdc); if (!p->pdc->smokerun) pdc_logg_cond(p->pdc, 1, trc_api, "[Begin glyph %d]\n", ig); }