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; } } }
void write_jpg(integer img) { long unsigned l; FILE *f; pdf_puts("/Type /XObject\n/Subtype /Image\n"); pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n", (int) img_width(img), (int) img_height(img), (int) jpg_ptr(img)->bits_per_component, (int) jpg_ptr(img)->length); pdf_puts("/ColorSpace "); if (img_colorspace_ref(img) != 0) { pdf_printf("%i 0 R\n", (int) img_colorspace_ref(img)); } else { switch (jpg_ptr(img)->color_space) { case JPG_GRAY: pdf_puts("/DeviceGray\n"); break; case JPG_RGB: pdf_puts("/DeviceRGB\n"); break; case JPG_CMYK: pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n"); break; default: pdftex_fail("Unsupported color space %i", (int) jpg_ptr(img)->color_space); } } pdf_puts("/Filter /DCTDecode\n>>\nstream\n"); for (l = jpg_ptr(img)->length, f = jpg_ptr(img)->file; l > 0; l--) pdfout(xgetc(f)); pdfendstream(); }
static void pdf_write_pnode(PDF *p, id node_id, id parent_id, id *kids, int n_kids, int n_pages) { pdf_begin_obj(p, node_id); pdf_begin_dict(p); pdf_puts(p, "/Type/Pages\n"); pdf_printf(p, "/Count %d\n", n_pages); if (parent_id != BAD_ID) pdf_printf(p, "/Parent %d 0 R\n", parent_id); pdf_puts(p, "/Kids["); do { pdf_printf(p, "%ld 0 R", *kids++); pdf_putc(p, PDF_NEWLINE); } while (--n_kids > 0); pdf_puts(p, "]"); pdf_end_dict(p); pdf_end_obj(p); }
static void set_font(PDF pdf) { pdfstructure *p = pdf->pstruct; if (p->need_width != 0) { pdf_printf(pdf, "%0.3f w\n",((7227.0/7200.0)/1000.0) * p->need_width ); p->done_width = 1; } else if (p->done_width) { pdf_puts(pdf, "0 w\n"); p->done_width = 0; } if (p->need_mode != 0) { pdf_printf(pdf, "%d Tr\n", (int) p->need_mode); p->done_mode = 1; } else if (p->done_mode) { pdf_puts(pdf, "0 Tr\n"); p->done_mode = 0; } pdf_printf(pdf, "/F%d", (int) p->f_pdf); pdf_print_resname_prefix(pdf); pdf_out(pdf, ' '); print_pdffloat(pdf, p->fs); pdf_puts(pdf, " Tf\n"); p->f_pdf_cur = p->f_pdf; p->fs_cur.m = p->fs.m; p->need_tf = false; /*tex Always follow |Tf| by |Tm|: */ p->need_tm = true; }
void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum) { int i_old, *p; struct avl_traverser t; assert(glyph_names != NULL); assert(tx_tree != NULL); assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); pdf_printf("/Differences ["); avl_t_init(&t, tx_tree); for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { if (*p == i_old + 1) /* no gap */ pdf_printf("/%s", glyph_names[*p]); else { if (i_old == -2) pdf_printf("%i/%s", *p, glyph_names[*p]); else pdf_printf(" %i/%s", *p, glyph_names[*p]); } i_old = *p; } pdf_puts("]\n"); pdf_end_dict(); }
static void pdf_write_pattern_color(PDF *p, pdf_bool fill) { pdf_color color; /* fetch the current fill or stroke color and apply it to the pattern */ if (fill) color = p->cstate[p->sl].fill; else color = p->cstate[p->sl].stroke; if (color.cs == DeviceGray || color.cs == Separation) { pdf_printf(p, "%f", color.val.gray); } else if (color.cs == DeviceRGB) { pdf_printf(p, "%f %f %f", color.val.rgb.r, color.val.rgb.g, color.val.rgb.b); } else if (color.cs == DeviceCMYK) { pdf_printf(p, "%f %f %f %f", color.val.cmyk.c, color.val.cmyk.m, color.val.cmyk.y, color.val.cmyk.k); } else { pdf_error(p, PDF_SystemError, "Unknown color space in pdf_write_pattern_color"); } }
static void write_fontname(fd_entry * fd, const char *key) { assert(fd->fontname != NULL); pdf_puts("/"); if (key != NULL) pdf_printf("%s /", key); if (fd->subset_tag != NULL) pdf_printf("%s+", fd->subset_tag); pdf_printf("%s\n", fd->fontname); }
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; } } }
static void write_fontmetrics(fd_entry * fd) { int i; fix_fontmetrics(fd); if (fd->font_dim[FONTBBOX1_CODE].set && fd->font_dim[FONTBBOX2_CODE].set && fd->font_dim[FONTBBOX3_CODE].set && fd->font_dim[FONTBBOX4_CODE].set) pdf_printf("/%s [%i %i %i %i]\n", font_key[FONTBBOX1_CODE].pdfname, (int) fd->font_dim[FONTBBOX1_CODE].val, (int) fd->font_dim[FONTBBOX2_CODE].val, (int) fd->font_dim[FONTBBOX3_CODE].val, (int) fd->font_dim[FONTBBOX4_CODE].val); for (i = 0; i < GEN_KEY_NUM; i++) if (fd->font_dim[i].set) pdf_printf("/%s %i\n", font_key[i].pdfname, fd->font_dim[i].val); }
void pdf_write_xobjects(PDF *p) { if (p->xobjects_number > 0) { pdf_bool hit = pdf_false; int i; for (i = 0; i < p->xobjects_capacity; ++i) { if (p->xobjects[i].flags & xobj_flag_write) { if (!hit) { pdf_puts(p, "/XObject"); pdf_begin_dict(p); hit = pdf_true; } pdf_printf(p, "/I%d %ld 0 R\n", i, p->xobjects[i].obj_id); p->xobjects[i].flags &= ~xobj_flag_write; } } if (hit) pdf_end_dict(p); } }
void pdf_dict_add_img_filename(PDF pdf, image_dict * idict) { char *p; if ((pdf_image_addfilename > 0) && ((pdf_suppress_optional_info & 2) == 0)) { /*tex For now |PTEX.FileName| is only used for \PDF, but we're prepared for \JPG, \PNG, ... */ if (! ( (img_type(idict) == IMG_TYPE_PDF) || (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) )) return; if (img_visiblefilename(idict) != NULL) { if (strlen(img_visiblefilename(idict)) == 0) { /*tex empty string blocks PTEX.FileName output */ return; } else { p = img_visiblefilename(idict); } } else { /*tex unset so let's use the default */ p = img_filepath(idict); } /*tex write additional information */ pdf_add_name(pdf, "PTEX.FileName"); pdf_printf(pdf, " (%s)", convertStringToPDFString(p, strlen(p))); } }
void write_pdfstream(PDF pdf, image_dict * idict) { pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); if (!img_notype(idict)) { pdf_dict_add_name(pdf, "Type", "XObject"); pdf_dict_add_name(pdf, "Subtype", "Form"); pdf_dict_add_int(pdf, "FormType", 1); } if (!img_nobbox(idict)) { pdf_add_name(pdf, "BBox"); pdf_begin_array(pdf); pdf_add_real(pdf, sp2bp(img_bbox(idict)[0])); pdf_add_real(pdf, sp2bp(img_bbox(idict)[1])); pdf_add_real(pdf, sp2bp(img_bbox(idict)[2])); pdf_add_real(pdf, sp2bp(img_bbox(idict)[3])); pdf_end_array(pdf); } if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) { pdf_printf(pdf, "\n%s\n", img_attr(idict)); } if (!img_nolength(idict)) { pdf_dict_add_streaminfo(pdf); } pdf_end_dict(pdf); pdf_begin_stream(pdf); if (img_pdfstream_stream(idict) != NULL) { pdf_out_block(pdf, (const char *) img_pdfstream_stream(idict), img_pdfstream_size(idict)); } pdf_end_stream(pdf); pdf_end_obj(pdf); }
PDFLIB_API void PDFLIB_CALL PDF_setcmykcolor_stroke(PDF *p, float cyan, float magenta, float yellow, float black) { char buf1[FLOATBUFSIZE], buf2[FLOATBUFSIZE], buf3[FLOATBUFSIZE]; char buf4[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (cyan < 0.0 || cyan > EPSILON || magenta < 0.0 || magenta > EPSILON || yellow < 0.0 || yellow > EPSILON || black < 0.0 || black > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f/%f) in PDF_setcmykcolor_stroke", cyan, magenta, yellow, black); return; } pdf_printf(p, "%s %s %s %s K\n", pdf_float(buf1, cyan), pdf_float(buf2, magenta), pdf_float(buf3, yellow), pdf_float(buf4, black)); p->cstate[p->sl].stroke.cs = DeviceCMYK; p->cstate[p->sl].fill.val.cmyk.c = cyan; p->cstate[p->sl].fill.val.cmyk.m = magenta; p->cstate[p->sl].fill.val.cmyk.y = yellow; p->cstate[p->sl].fill.val.cmyk.k = black; }
void pdf_begin_contents_section(PDF *p) { if (p->contents != c_none) return; if (p->next_content >= p->contents_ids_capacity) { p->contents_ids_capacity *= 2; p->contents_ids = (id *) p->realloc(p, p->contents_ids, sizeof(long) * p->contents_ids_capacity, "pdf_begin_contents_section"); } p->contents_ids[p->next_content] = pdf_begin_obj(p, NEW_ID); p->contents = c_page; pdf_begin_dict(p); p->contents_length_id = pdf_alloc_id(p); pdf_printf(p, "/Length %ld 0 R\n", p->contents_length_id); if (p->compresslevel) pdf_puts(p, "/Filter/FlateDecode\n"); pdf_end_dict(p); pdf_begin_stream(p); pdf_compress_init(p); /* Contents object */ p->start_contents_pos = pdf_tell(p); p->next_content++; }
PDFLIB_API void PDFLIB_CALL PDF_setrgbcolor_stroke(PDF *p, float red, float green, float blue) { char buf1[FLOATBUFSIZE], buf2[FLOATBUFSIZE], buf3[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (red < 0.0 || red > EPSILON || green < 0.0 || green > EPSILON || blue < 0.0 || blue > EPSILON) { pdf_error(p, PDF_NonfatalError, "Bogus color value (%f/%f/%f) in PDF_setrgbcolor_stroke", red, green, blue); return; } if (red == green && green == blue) PDF_setgray_stroke(p, red); else { pdf_printf(p, "%s %s %s RG\n", pdf_float(buf1, red), pdf_float(buf2, green), pdf_float(buf3, blue)); p->cstate[p->sl].stroke.cs = DeviceRGB; p->cstate[p->sl].stroke.val.rgb.r = red; p->cstate[p->sl].stroke.val.rgb.g = green; p->cstate[p->sl].stroke.val.rgb.b = blue; } }
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; } } }
id pdf_begin_obj(PDF *p, id obj_id) { if (obj_id == NEW_ID) obj_id = pdf_alloc_id(p); p->file_offset[obj_id] = pdf_tell(p); pdf_printf(p, "%ld 0 obj\n", obj_id); return obj_id; }
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; }
/* Finish the pattern definition. */ PDFLIB_API void PDFLIB_CALL PDF_end_pattern(PDF *p) { static const char fn[] = "PDF_end_pattern"; long length; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_pattern); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of pattern"); pdf_end_text(p); p->contents = c_none; if (p->compresslevel) pdf_compress_end(p); length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); pdf_end_obj(p); /* pattern */ pdf_begin_obj(p, p->contents_length_id); /* Length object */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); pdf_begin_obj(p, p->res_id); /* Resource object */ pdf_begin_dict(p); /* Resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ PDF_POP_STATE(p, fn); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }
/* Write annotation border style and color */ static void pdf_write_border_style(PDF *p, pdf_annot *ann) { /* don't write the default values */ if (ann->border_style == border_solid && ann->border_width == (float) 1.0 && p->border_red == (float) 0.0 && p->border_green == (float) 0.0 && p->border_blue == (float) 0.0 && p->border_dash1 == (float) 3.0 && p->border_dash2 == (float) 3.0) return; if (ann->type != ann_attach) { pdf_puts(p, "/BS"); pdf_begin_dict(p); /* BS dict */ pdf_puts(p, "/Type/Border\n"); if (ann->border_style != border_solid) pdf_printf(p, "/S/%s\n", pdf_border_style_names[ann->border_style]); if (ann->border_style == border_dashed) pdf_printf(p, "/D[%f %f]\n", ann->border_dash1, ann->border_dash2); pdf_end_dict(p); /* BS dict */ /* Write the Border key in old-style PDF 1.1 format */ pdf_printf(p, "/Border[0 0 %f", ann->border_width); if (ann->border_style == border_dashed && (ann->border_dash1 != (float) 0.0 || ann->border_dash2 != (float) 0.0)) /* set dashed border */ pdf_printf(p, "[%f %f]", ann->border_dash1, ann->border_dash2); pdf_puts(p, "]\n"); } /* write annotation color */ pdf_printf(p, "/C[%f %f %f]\n", ann->border_red, ann->border_green, ann->border_blue); }
void epdf_write_enc(char **glyph_names, integer fe_objnum) { int i, i_old; assert(glyph_names != NULL); assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); pdf_printf("/Differences ["); for (i = 0, i_old = -2; i < 256; i++) if (glyph_names[i] != notdef) { if (i == i_old + 1) /* no gap */ pdf_printf("/%s", glyph_names[i]); else { if (i_old == -2) pdf_printf("%i/%s", i, glyph_names[i]); else pdf_printf(" %i/%s", i, glyph_names[i]); } i_old = i; } pdf_puts("]\n"); pdf_end_dict(); }
void pdf_write_annots_root(PDF *p) { pdf_annot *ann; /* Annotations array */ if (p->annots) { pdf_puts(p, "/Annots["); for (ann = p->annots; ann != NULL; ann = ann->next) { ann->obj_id = pdf_alloc_id(p); pdf_printf(p, "%ld 0 R ", ann->obj_id); } pdf_puts(p, "]\n"); } }
PluginStatus PluginViewImpl::get_page_name_impl(IPluginUnknown *thiz, const UDSString *page_start_anchor, UDSString *name) { PluginViewImpl *instance = g_instances_table.get_object(thiz); unsigned int page_num = instance->document->get_page_number( page_start_anchor->get_buffer(page_start_anchor)); char buf[32] = {0}; pdf_printf(buf, "%d", page_num); name->assign(name, buf); return PLUGIN_OK; }
PDFLIB_API void PDFLIB_CALL PDF_setgray_stroke(PDF *p, float g) { char buf[FLOATBUFSIZE]; if (PDF_SANITY_CHECK_FAILED(p)) return; if (g < 0.0 || g > EPSILON ) { pdf_error(p, PDF_NonfatalError, "Bogus gray value (%f) in PDF_setgray_stroke", g); return; } pdf_printf(p, "%s G\n", pdf_float(buf, g)); p->cstate[p->sl].stroke.cs = DeviceGray; p->cstate[p->sl].stroke.val.gray = g; }
void pdf_end_contents_section(PDF *p) { long length; if (p->contents == c_none) return; pdf_end_text(p); p->contents = c_none; pdf_compress_end(p); /* Contents object */ length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); pdf_end_obj(p); pdf_begin_obj(p, p->contents_length_id); /* Length object */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); }
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) { pdf_puts(p, "/ColorSpace"); pdf_begin_dict(p); /* color space names */ for (i = 0; i < p->colorspaces_number; i++) { if (p->colorspaces[i].used_on_current_page) { p->colorspaces[i].used_on_current_page = pdf_false; /* reset */ pdf_printf(p, "/CS%d %ld 0 R\n", i, p->colorspaces[i].obj_id); } } pdf_end_dict(p); /* color space names */ } }
void pdf_write_page_pattern(PDF *p) { int i, total = 0; for (i = 0; i < p->pattern_number; i++) if (p->pattern[i].used_on_current_page) total++; if (total > 0) { pdf_puts(p, "/Pattern"); pdf_begin_dict(p); /* pattern */ for (i = 0; i < p->pattern_number; i++) { if (p->pattern[i].used_on_current_page) { p->pattern[i].used_on_current_page = pdf_false; /* reset */ pdf_printf(p, "/P%d %ld 0 R\n", i, p->pattern[i].obj_id); } } pdf_end_dict(p); /* pattern */ } }
integer write_tounicode(char **glyph_names, char *name) { char buf[SMALL_BUF_SIZE], *p; static char builtin_suffix[] = "-builtin"; short range_size[257]; glyph_unicode_entry gtab[257]; integer objnum; int i, j; int bfchar_count, bfrange_count, subrange_count; assert(strlen(name) + strlen(builtin_suffix) < SMALL_BUF_SIZE); if (glyph_unicode_tree == NULL) { pdftex_warn("no GlyphToUnicode entry has been inserted yet!"); fixedgentounicode = 0; return 0; } strcpy(buf, name); if ((p = strrchr(buf, '.')) != NULL && strcmp(p, ".enc") == 0) *p = 0; /* strip ".enc" from encoding name */ else strcat(buf, builtin_suffix); /* ".enc" not present, this is a builtin encoding so the name is eg "cmr10-builtin" */ objnum = pdfnewobjnum(); pdfbegindict(objnum, 0); pdfbeginstream(); pdf_printf("%%!PS-Adobe-3.0 Resource-CMap\n" "%%%%DocumentNeededResources: ProcSet (CIDInit)\n" "%%%%IncludeResource: ProcSet (CIDInit)\n" "%%%%BeginResource: CMap (TeX-%s-0)\n" "%%%%Title: (TeX-%s-0 TeX %s 0)\n" "%%%%Version: 1.000\n" "%%%%EndComments\n" "/CIDInit /ProcSet findresource begin\n" "12 dict begin\n" "begincmap\n" "/CIDSystemInfo\n" "<< /Registry (TeX)\n" "/Ordering (%s)\n" "/Supplement 0\n" ">> def\n" "/CMapName /TeX-%s-0 def\n" "/CMapType 2 def\n" "1 begincodespacerange\n" "<00> <FF>\n" "endcodespacerange\n", buf, buf, buf, buf, buf); /* set gtab */ for (i = 0; i < 256; ++i) { gtab[i].code = UNI_UNDEF; set_glyph_unicode(glyph_names[i], >ab[i]); } gtab[256].code = UNI_UNDEF; /* set range_size */ for (i = 0; i < 256;) { if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) { range_size[i] = 1; /* single entry */ i++; } else if (gtab[i].code == UNI_UNDEF) { range_size[i] = 0; /* no entry */ i++; } else { /* gtab[i].code >= 0 */ j = i; while (i < 256 && gtab[i + 1].code >= 0 && gtab[i].code + 1 == gtab[i + 1].code) i++; /* at this point i is the last entry of the subrange */ i++; /* move i to the next entry */ range_size[j] = i - j; } } /* calculate bfrange_count and bfchar_count */ bfrange_count = 0; bfchar_count = 0; for (i = 0; i < 256;) { if (range_size[i] == 1) { bfchar_count++; i++; } else if (range_size[i] > 1) { bfrange_count++; i += range_size[i]; } else i++; } /* write out bfrange */ i = 0; write_bfrange: if (bfrange_count > 100) subrange_count = 100; else subrange_count = bfrange_count; bfrange_count -= subrange_count; pdf_printf("%i beginbfrange\n", subrange_count); for (j = 0; j < subrange_count; j++) { while (range_size[i] <= 1 && i < 256) i++; assert(i < 256); pdf_printf("<%02X> <%02X> <%s>\n", i, i + range_size[i] - 1, utf16be_str(gtab[i].code)); i += range_size[i]; } pdf_printf("endbfrange\n"); if (bfrange_count > 0) goto write_bfrange; /* write out bfchar */ i = 0; write_bfchar: if (bfchar_count > 100) subrange_count = 100; else subrange_count = bfchar_count; bfchar_count -= subrange_count; pdf_printf("%i beginbfchar\n", subrange_count); for (j = 0; j < subrange_count; j++) { while (i < 256) { if (range_size[i] > 1) i += range_size[i]; else if (range_size[i] == 0) i++; else /* range_size[i] == 1 */ break; } assert(i < 256 && gtab[i].code != UNI_UNDEF); if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) { assert(gtab[i].unicode_seq != NULL); pdf_printf("<%02X> <%s>\n", i, gtab[i].unicode_seq); } else pdf_printf("<%02X> <%s>\n", i, utf16be_str(gtab[i].code)); i++; } pdf_printf("endbfchar\n"); if (bfchar_count > 0) goto write_bfchar; /* free strings allocated by set_glyph_unicode() */ for (i = 0; i < 256; ++i) { if (gtab[i].code == UNI_EXTRA_STRING) xfree(gtab[i].unicode_seq); } pdf_printf("endcmap\n" "CMapName currentdict /CMap defineresource pop\n" "end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n"); pdfendstream(); return objnum; }
/* Write all pending document information up to the xref table and trailer */ static void pdf_wrapup_document(PDF *p) { static const char bin2hex[] = PDF_STRING_0123456789ABCDEF; long pos; id i; id pages_id; unsigned char digest[MD5_DIGEST_LENGTH]; pdf_write_info(p); pdf_write_doc_fonts(p); /* font objects */ pdf_write_doc_colorspaces(p); /* color space resources */ pages_id = pdf_make_tree(p, BAD_ID, p->pnodes, p->pages+1, p->current_page); pdf_begin_obj(p, p->root_id); /* Catalog or Root object */ pdf_begin_dict(p); pdf_puts(p, "/Type/Catalog\n"); /* * specify the open action (display of the first page) * default = retain: top of the first page at default zoom level */ if (p->open_action == fitpage) { pdf_printf(p, "/OpenAction[%ld 0 R/Fit]\n", p->pages[1]); } else if (p->open_action == fitwidth) { pdf_printf(p, "/OpenAction[%ld 0 R/FitH]\n", p->pages[1]); } else if (p->open_action == fitheight) { pdf_printf(p, "/OpenAction[%ld 0 R/FitV 0]\n", p->pages[1]); } else if (p->open_action == fitbbox) { pdf_printf(p, "/OpenAction[%ld 0 R/FitB]\n", p->pages[1]); } /* * specify the document's open mode * default = open_none: open document with neither bookmarks nor * thumbnails visible */ if (p->open_mode == open_bookmarks) { pdf_printf(p, "/PageMode/UseOutlines\n"); } else if (p->open_mode == open_thumbnails) { pdf_printf(p, "/PageMode/UseThumbs\n"); } else if (p->open_mode == open_fullscreen) { pdf_printf(p, "/PageMode/FullScreen\n"); } if (p->base) { pdf_printf(p, "/URI<</Base", p->base); pdf_quote_string(p, p->base); pdf_printf(p, ">>\n", p->base); } /* Pages object */ pdf_printf(p, "/Pages %ld 0 R\n", pages_id); pdf_write_outline_root(p); pdf_end_dict(p); /* Catalog */ pdf_end_obj(p); pdf_write_outlines(p); #ifdef DEBUG if (p->debug['s']) { fprintf(stderr, "PDF document statistics:\n"); fprintf(stderr, " %d pages\n", p->current_page); fprintf(stderr, " %d fonts\n", p->fonts_number); fprintf(stderr, " %d xobjects\n", p->xobjects_number); fprintf(stderr, " %ld objects\n", p->currentobj + 1); } #endif /* Don't write any object after this check! */ for (i = 1; i <= p->currentobj; i++) { if (p->file_offset[i] == BAD_ID) { pdf_error(p, PDF_NonfatalError, "Object %ld allocated but not used", i); pdf_begin_obj(p, i); pdf_end_obj(p); } } pos = pdf_tell(p); /* xref table */ pdf_puts(p, "xref\n"); pdf_printf(p, "0 %ld\n", p->currentobj + 1); pdf_puts(p, "0000000000 65535 f \n"); for (i = 1; i <= p->currentobj; i++) { pdf_printf(p, "%010ld 00000 n \n", p->file_offset[i]); } pdf_puts(p, "trailer\n"); pdf_begin_dict(p); /* trailer */ pdf_printf(p, "/Size %ld\n", p->currentobj + 1); pdf_printf(p, "/Info %ld 0 R\n", p->info_id); pdf_printf(p, "/Root %ld 0 R\n", p->root_id); /* put some more data into the MD5 digest */ MD5_Update(p->md5, (unsigned char *) &pos, sizeof pos); MD5_Update(p->md5, (unsigned char *) p, sizeof (PDF)); if (p->filename && strcmp(p->filename, "-") != 0) MD5_Update(p->md5, (unsigned char *) p->filename, strlen(p->filename)); /* write the digest to the ID array */ MD5_Final(digest, p->md5); pdf_puts(p, "/ID[<"); for (i = 0; i < MD5_DIGEST_LENGTH; ++i) { pdf_putc(p, bin2hex[digest[i] >> 4]); pdf_putc(p, bin2hex[digest[i] & 0x0F]); } pdf_puts(p, "><"); for (i = 0; i < MD5_DIGEST_LENGTH; ++i) { pdf_putc(p, bin2hex[digest[i] >> 4]); pdf_putc(p, bin2hex[digest[i] & 0x0F]); } pdf_puts(p, ">]\n"); pdf_end_dict(p); /* trailer */ pdf_puts(p, "startxref\n"); pdf_printf(p, "%ld\n", pos); pdf_puts(p, "%%EOF\n"); }
PDFLIB_API void PDFLIB_CALL PDF_end_page(PDF *p) { static const char fn[] = "PDF_end_page"; int index; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of page"); /* restore text parameter and color defaults for out-of-page usage. */ pdf_init_tstate(p); pdf_init_cstate(p); pdf_end_contents_section(p); /* Page object */ pdf_begin_obj(p, p->pages[p->current_page]); pdf_begin_dict(p); pdf_puts(p, "/Type/Page\n"); pdf_printf(p, "/Parent %ld 0 R\n", pdf_get_pnode_id(p)); p->res_id = pdf_alloc_id(p); pdf_printf(p, "/Resources %ld 0 R\n", p->res_id); pdf_printf(p, "/MediaBox[0 0 %f %f]\n", p->width, p->height); if (p->CropBox.llx != (float) 0 || p->CropBox.lly != (float) 0 || p->CropBox.urx != (float) 0 || p->CropBox.ury != (float) 0 ) { if (p->CropBox.urx <= p->CropBox.llx || p->CropBox.ury <= p->CropBox.lly) pdf_error(p, PDF_ValueError, "Illegal CropBox dimensions"); pdf_printf(p, "/CropBox[%f %f %f %f]\n", p->CropBox.llx, p->CropBox.lly, p->CropBox.urx, p->CropBox.ury); } if (p->BleedBox.llx != (float) 0 || p->BleedBox.lly != (float) 0 || p->BleedBox.urx != (float) 0 || p->BleedBox.ury != (float) 0 ) { if (p->BleedBox.urx <= p->BleedBox.llx || p->BleedBox.ury <= p->BleedBox.lly) pdf_error(p, PDF_ValueError, "Illegal BleedBox dimensions"); pdf_printf(p, "/BleedBox[%f %f %f %f]\n", p->BleedBox.llx, p->BleedBox.lly, p->BleedBox.urx, p->BleedBox.ury); } if (p->TrimBox.llx != (float) 0 || p->TrimBox.lly != (float) 0 || p->TrimBox.urx != (float) 0 || p->TrimBox.ury != (float) 0 ) { if (p->TrimBox.urx <= p->TrimBox.llx || p->TrimBox.ury <= p->TrimBox.lly) pdf_error(p, PDF_ValueError, "Illegal TrimBox dimensions"); pdf_printf(p, "/TrimBox[%f %f %f %f]\n", p->TrimBox.llx, p->TrimBox.lly, p->TrimBox.urx, p->TrimBox.ury); } if (p->ArtBox.llx != (float) 0 || p->ArtBox.lly != (float) 0 || p->ArtBox.urx != (float) 0 || p->ArtBox.ury != (float) 0 ) { if (p->ArtBox.urx <= p->ArtBox.llx || p->ArtBox.ury <= p->ArtBox.lly) pdf_error(p, PDF_ValueError, "Illegal ArtBox dimensions"); pdf_printf(p, "/ArtBox[%f %f %f %f]\n", p->ArtBox.llx, p->ArtBox.lly, p->ArtBox.urx, p->ArtBox.ury); } /* * The duration can be placed in the transition dictionary (/D) * or in the page dictionary (/Dur). We put it here so it can * be used without setting a transition effect. */ if (p->duration > 0) pdf_printf(p, "/Dur %f\n", p->duration); pdf_write_page_transition(p); pdf_puts(p, "/Contents["); for (index = 0; index < p->next_content; index++) { pdf_printf(p, "%ld 0 R", p->contents_ids[index]); pdf_putc(p, (char) (index + 1 % 8 ? PDF_SPACE : PDF_NEWLINE)); } pdf_puts(p, "]\n"); /* Thumbnail image */ if (p->thumb_id != BAD_ID) pdf_printf(p, "/Thumb %ld 0 R\n", p->thumb_id); pdf_write_annots_root(p); pdf_end_dict(p); /* Page object */ pdf_end_obj(p); pdf_write_page_annots(p); /* Annotation dicts */ pdf_begin_obj(p, p->res_id); /* resource object */ pdf_begin_dict(p); /* resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ pdf_cleanup_page(p); PDF_SET_STATE(p, fn, pdf_state_document); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }