/* Write a UniqueID and/or XUID. */ static void write_uid(stream *s, const gs_uid *puid) { if (uid_is_UniqueID(puid)) pprintld1(s, "/UniqueID %ld def\n", puid->id); else if (uid_is_XUID(puid)) { uint i, n = uid_XUID_size(puid); stream_puts(s, "/XUID ["); for (i = 0; i < n; ++i) pprintld1(s, "%ld ", uid_XUID_values(puid)[i]); stream_puts(s, "] readonly def\n"); } }
/* Write one code map. */ static int cmap_put_code_map(const gs_memory_t *mem, stream *s, int which, const gs_cmap_t *pcmap, const cmap_operators_t *pcmo, psf_put_name_chars_proc_t put_name_chars, int font_index_only) { /* For simplicity, produce one entry for each lookup range. */ gs_cmap_lookups_enum_t lenum; int font_index = (pcmap->num_fonts <= 1 ? 0 : -1); int code; for (gs_cmap_lookups_enum_init(pcmap, which, &lenum); (code = gs_cmap_enum_next_lookup(&lenum)) == 0; ) { gs_cmap_lookups_enum_t counter; int num_entries = 0; int gi; if (font_index_only >= 0 && lenum.entry.font_index != font_index_only) continue; if (font_index_only < 0 && lenum.entry.font_index != font_index) { pprintd1(s, "%d usefont\n", lenum.entry.font_index); font_index = lenum.entry.font_index; } /* Count the number of entries in this lookup range. */ counter = lenum; while (gs_cmap_enum_next_entry(&counter) == 0) ++num_entries; for (gi = 0; gi < num_entries; gi += 100) { int i = gi, ni = min(i + 100, num_entries); const char *end; pprintd1(s, "%d ", ni - i); if (lenum.entry.key_is_range) { if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) { stream_puts(s, pcmo->beginrange); end = pcmo->endrange; } else { /* must be def, not notdef */ stream_puts(s, "beginbfrange\n"); end = "endbfrange\n"; } } else { if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) { stream_puts(s, pcmo->beginchar); end = pcmo->endchar; } else { /* must be def, not notdef */ stream_puts(s, "beginbfchar\n"); end = "endbfchar\n"; } } for (; i < ni; ++i) { int j; long value; int value_size; DISCARD(gs_cmap_enum_next_entry(&lenum)); /* can't fail */ value_size = lenum.entry.value.size; for (j = 0; j <= lenum.entry.key_is_range; ++j) { stream_putc(s, '<'); pput_hex(s, lenum.entry.key[j], lenum.entry.key_size); stream_putc(s, '>'); } for (j = 0, value = 0; j < value_size; ++j) value = (value << 8) + lenum.entry.value.data[j]; switch (lenum.entry.value_type) { case CODE_VALUE_CID: case CODE_VALUE_NOTDEF: pprintld1(s, "%ld", value); break; case CODE_VALUE_CHARS: stream_putc(s, '<'); pput_hex(s, lenum.entry.value.data, value_size); stream_putc(s, '>'); break; case CODE_VALUE_GLYPH: { gs_const_string str; int code = pcmap->glyph_name(mem, (gs_glyph)value, &str, pcmap->glyph_name_data); if (code < 0) return code; stream_putc(s, '/'); code = put_name_chars(s, str.data, str.size); if (code < 0) return code; } break; default: /* not possible */ return_error(gs_error_unregistered); } stream_putc(s, '\n'); } stream_puts(s, end); } } return code; }
/* Write a CMap in its standard (source) format. */ int psf_write_cmap(const gs_memory_t *mem, stream *s, const gs_cmap_t *pcmap, psf_put_name_chars_proc_t put_name_chars, const gs_const_string *alt_cmap_name, int font_index_only) { const gs_const_string *const cmap_name = (alt_cmap_name ? alt_cmap_name : &pcmap->CMapName); const gs_cid_system_info_t *const pcidsi = pcmap->CIDSystemInfo; switch (pcmap->CMapType) { case 0: case 1: case 2: break; default: return_error(gs_error_rangecheck); } /* Write the header. */ if (!pcmap->ToUnicode) { stream_puts(s, "%!PS-Adobe-3.0 Resource-CMap\n"); stream_puts(s, "%%DocumentNeededResources: ProcSet (CIDInit)\n"); stream_puts(s, "%%IncludeResource: ProcSet (CIDInit)\n"); pput_string_entry(s, "%%BeginResource: CMap (", cmap_name); pput_string_entry(s, ")\n%%Title: (", cmap_name); pput_string_entry(s, " ", &pcidsi->Registry); pput_string_entry(s, " ", &pcidsi->Ordering); pprintd1(s, " %d)\n", pcidsi->Supplement); pprintg1(s, "%%%%Version: %g\n", pcmap->CMapVersion); } stream_puts(s, "/CIDInit /ProcSet findresource begin\n"); stream_puts(s, "12 dict begin\nbegincmap\n"); /* Write the fixed entries. */ pprintd1(s, "/CMapType %d def\n", pcmap->CMapType); stream_puts(s, "/CMapName/"); put_name_chars(s, cmap_name->data, cmap_name->size); stream_puts(s, " def\n"); if (!pcmap->ToUnicode) { pprintg1(s, "/CMapVersion %g def\n", pcmap->CMapVersion); stream_puts(s, "/CIDSystemInfo"); if (font_index_only >= 0 && font_index_only < pcmap->num_fonts) { cmap_put_system_info(s, pcidsi + font_index_only); } else if (pcmap->num_fonts == 1) { cmap_put_system_info(s, pcidsi); } else { int i; pprintd1(s, " %d array\n", pcmap->num_fonts); for (i = 0; i < pcmap->num_fonts; ++i) { pprintd1(s, "dup %d", i); cmap_put_system_info(s, pcidsi + i); stream_puts(s, "put\n"); } } stream_puts(s, " def\n"); if (uid_is_XUID(&pcmap->uid)) { uint i, n = uid_XUID_size(&pcmap->uid); const long *values = uid_XUID_values(&pcmap->uid); stream_puts(s, "/XUID ["); for (i = 0; i < n; ++i) pprintld1(s, " %ld", values[i]); stream_puts(s, "] def\n"); } pprintld1(s, "/UIDOffset %ld def\n", pcmap->UIDOffset); pprintd1(s, "/WMode %d def\n", pcmap->WMode); } /* Write the code space ranges. */ { gs_cmap_ranges_enum_t renum; #define MAX_RANGES 100 gx_code_space_range_t ranges[MAX_RANGES]; int code, count = 0; for (gs_cmap_ranges_enum_init(pcmap, &renum); (code = gs_cmap_enum_next_range(&renum)) == 0; ) { if (count == MAX_RANGES) { cmap_put_ranges(s, ranges, count); count = 0; } ranges[count++] = renum.range; } if (code < 0) return code; if (count) cmap_put_ranges(s, ranges, count); #undef MAX_RANGES } /* Write the code and notdef data. */ { int code; code = cmap_put_code_map(mem, s, 1, pcmap, &cmap_notdef_operators, put_name_chars, font_index_only); if (code < 0) return code; code = cmap_put_code_map(mem, s, 0, pcmap, &cmap_cid_operators, put_name_chars, font_index_only); if (code < 0) return code; } /* Write the trailer. */ stream_puts(s, "endcmap\n"); stream_puts(s, "CMapName currentdict /CMap defineresource pop\nend end\n"); if (!pcmap->ToUnicode) { stream_puts(s, "%%EndResource\n"); stream_puts(s, "%%EOF\n"); } return 0; }
static int param_print_typed(gs_param_list * plist, gs_param_name pkey, gs_param_typed_value * pvalue) { printer_param_list_t *const prlist = (printer_param_list_t *)plist; stream *s = prlist->strm; if (!prlist->any) { if (prlist->params.prefix) stream_puts(s, prlist->params.prefix); prlist->any = true; } if (prlist->params.item_prefix) stream_puts(s, prlist->params.item_prefix); pprints1(s, "/%s", pkey); switch (pvalue->type) { case gs_param_type_null: stream_puts(s, " null"); break; case gs_param_type_bool: stream_puts(s, (pvalue->value.b ? " true" : " false")); break; case gs_param_type_int: pprintd1(s, " %d", pvalue->value.i); break; case gs_param_type_long: pprintld1(s, " %l", pvalue->value.l); break; case gs_param_type_float: pprintg1(s, " %g", pvalue->value.f); break; case gs_param_type_string: s_write_ps_string(s, pvalue->value.s.data, pvalue->value.s.size, prlist->params.print_ok); break; case gs_param_type_name: /****** SHOULD USE #-ESCAPES FOR PDF ******/ stream_putc(s, '/'); stream_write(s, pvalue->value.n.data, pvalue->value.n.size); break; case gs_param_type_int_array: { uint i; char sepr = (pvalue->value.ia.size <= 10 ? ' ' : '\n'); stream_putc(s, '['); for (i = 0; i < pvalue->value.ia.size; ++i) { pprintd1(s, "%d", pvalue->value.ia.data[i]); stream_putc(s, sepr); } stream_putc(s, ']'); } break; case gs_param_type_float_array: { uint i; char sepr = (pvalue->value.fa.size <= 10 ? ' ' : '\n'); stream_putc(s, '['); for (i = 0; i < pvalue->value.fa.size; ++i) { pprintg1(s, "%g", pvalue->value.fa.data[i]); stream_putc(s, sepr); } stream_putc(s, ']'); } break; /*case gs_param_type_string_array: */ /*case gs_param_type_name_array: */ default: return_error(gs_error_typecheck); } if (prlist->params.item_suffix) stream_puts(s, prlist->params.item_suffix); return 0; }
const char * pprintld3(stream * s, const char *format, long v1, long v2, long v3) { return pprintld2(s, pprintld1(s, format, v1), v2, v3); }
/* Write a FontDescriptor. */ int pdf_write_FontDescriptor(gx_device_pdf *pdev, pdf_resource_t *pres) { pdf_font_descriptor_t *pfd = (pdf_font_descriptor_t *)pres; font_type ftype = pfd->FontType; long cidset_id = 0; int code = 0; stream *s; if (pfd->common.object->written) return 0; if (pfd->common.object->id == -1) return 0; /* If this is a CIDFont subset, write the CIDSet now. */ switch (ftype) { case ft_CID_encrypted: case ft_CID_TrueType: if (pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid)) { if (pdev->PDFA < 2) { code = pdf_write_CIDSet(pdev, pfd->base_font, &cidset_id); if (code < 0) return code; } } default: break; } { /* * Hack: make all embedded TrueType fonts "symbolic" to * work around undocumented assumptions in Acrobat Reader. */ pdf_font_descriptor_common_t fd; fd = pfd->common; if (pfd->embed && pfd->FontType == ft_TrueType) fd.values.Flags = (fd.values.Flags & ~(FONT_IS_ADOBE_ROMAN)) | FONT_IS_SYMBOLIC; code = write_FontDescriptor_common(pdev, &fd, pfd->embed); } if (code < 0) return code; s = pdev->strm; if (cidset_id != 0) pprintld1(s, "/CIDSet %ld 0 R\n", cidset_id); else if (pdf_do_subset_font(pdev, pfd->base_font, pfd->common.rid) && (ftype == ft_encrypted || ftype == ft_encrypted2) ) { stream_puts(s, "/CharSet"); code = pdf_write_CharSet(pdev, pfd->base_font); if (code < 0) return code; } if (pfd->embed && pfd->base_font->FontFile) { code = pdf_write_FontFile_entry(pdev, pfd->base_font); if (code < 0) return code; } if (pfd->cid.Style) { stream_puts(s, "/Style"); COS_WRITE(pfd->cid.Style, pdev); } if (pfd->cid.Lang[0]) { pprints1(s, "/Lang(%s)", pfd->cid.Lang); } if (pfd->cid.FD) { stream_puts(s, "/FD"); COS_WRITE(pfd->cid.FD, pdev); } stream_puts(s, ">>\n"); pdf_end_separate(pdev, resourceFontDescriptor); pfd->common.object->written = true; { const cos_object_t *pco = (const cos_object_t *)pdf_get_FontFile_object(pfd->base_font); if (pco != NULL) { code = COS_WRITE_OBJECT(pco, pdev, resourceFontFile); if (code < 0) return code; } } return 0; }