int fputs (const char *s, FILE *stream) { if (stream == (FILE*)stdout) return stream_puts (to_stream (stdout), s); else if (stream == (FILE*)stderr) return stream_puts (to_stream (stderr), s); return 0; }
/* 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 CIDSystemInfo dictionary. */ static void cmap_put_system_info(stream *s, const gs_cid_system_info_t *pcidsi) { if (cid_system_info_is_null(pcidsi)) { stream_puts(s, " null "); } else { stream_puts(s, " 3 dict dup begin\n"); stream_puts(s, "/Registry "); s_write_ps_string(s, pcidsi->Registry.data, pcidsi->Registry.size, 0); stream_puts(s, " def\n/Ordering "); s_write_ps_string(s, pcidsi->Ordering.data, pcidsi->Ordering.size, 0); pprintd1(s, " def\n/Supplement %d def\nend ", pcidsi->Supplement); } }
/* Write a list of code space ranges. */ static void cmap_put_ranges(stream *s, const gx_code_space_range_t *pcsr, int count) { int i; pprintd1(s, "%d begincodespacerange\n", count); for (i = 0; i < count; ++i, ++pcsr) { stream_puts(s, "<"); pput_hex(s, pcsr->first, pcsr->size); stream_puts(s, "><"); pput_hex(s, pcsr->last, pcsr->size); stream_puts(s, ">\n"); } stream_puts(s, "endcodespacerange\n"); }
void s_release_param_printer(printer_param_list_t *prlist) { if (prlist) { if (prlist->any && prlist->params.suffix) stream_puts(prlist->strm, prlist->params.suffix); } }
/* * Write a string in its shortest form ( () or <> ). Note that * this form is different depending on whether binary data are allowed. * Currently we don't support ASCII85 strings ( <~ ~> ). */ void s_write_ps_string(stream * s, const byte * str, uint size, int print_ok) { uint added = 0; uint i; const stream_template *template; stream_AXE_state state; stream_state *st = NULL; if (print_ok & PRINT_BINARY_OK) { /* Only need to escape (, ), \, CR, EOL. */ stream_putc(s, '('); for (i = 0; i < size; ++i) { byte ch = str[i]; switch (ch) { case char_CR: stream_puts(s, "\\r"); continue; case char_EOL: stream_puts(s, "\\n"); continue; case '(': case ')': case '\\': stream_putc(s, '\\'); } stream_putc(s, ch); } stream_putc(s, ')'); return; } for (i = 0; i < size; ++i) { byte ch = str[i]; if (ch == 0 || ch >= 127) added += 3; else if (strchr("()\\\n\r\t\b\f", ch) != 0) ++added; else if (ch < 32) added += 3; } if (added < size || (print_ok & PRINT_HEX_NOT_OK)) {
/* Write one FontInfo entry. */ static void write_font_info(stream *s, const char *key, const gs_const_string *pvalue, int do_write) { if (do_write) { pprints1(s, "\n/%s ", key); s_write_ps_string(s, pvalue->data, pvalue->size, PRINT_HEX_NOT_OK); stream_puts(s, " def"); } }
result_t rm_name_action(cli_t *context, const char * name_) { result_t result; if(failed(result = reg_delete_value(get_context(context), name_))) { stream_puts(context->cfg.console_err, "Error when deleting value\r\n"); return result; } return s_ok; }
/* * Flush text from buffer. */ static int flush_text_buffer(gx_device_pdf *pdev) { pdf_text_state_t *pts = pdev->text->text_state; stream *s = pdev->strm; if (pts->buffer.count_chars != 0) { pdf_font_resource_t *pdfont = pts->in.pdfont; int code = pdf_assign_font_object_id(pdev, pdfont); if (code < 0) return code; code = pdf_add_resource(pdev, pdev->substream_Resources, "/Font", (pdf_resource_t *)pdfont); if (code < 0) return code; } if (pts->buffer.count_moves > 0) { int i, cur = 0; if (pts->use_leading) stream_puts(s, "T*"); stream_puts(s, "["); for (i = 0; i < pts->buffer.count_moves; ++i) { int next = pts->buffer.moves[i].index; pdf_put_string(pdev, pts->buffer.chars + cur, next - cur); pprintg1(s, "%g", pts->buffer.moves[i].amount); cur = next; } if (pts->buffer.count_chars > cur) pdf_put_string(pdev, pts->buffer.chars + cur, pts->buffer.count_chars - cur); stream_puts(s, "]TJ\n"); } else { pdf_put_string(pdev, pts->buffer.chars, pts->buffer.count_chars); stream_puts(s, (pts->use_leading ? "'\n" : "Tj\n")); } pts->buffer.count_chars = 0; pts->buffer.count_moves = 0; pts->use_leading = false; return 0; }
UINT32 stream_printf(imgtool_stream *stream, const char *fmt, ...) { va_list va; char buf[256]; va_start(va, fmt); vsprintf(buf, fmt, va); va_end(va); return stream_puts(stream, buf); }
/* * Write the Encoding array. This is a separate procedure only for * readability. */ static int write_Encoding(stream *s, gs_font_type1 *pfont, int options, gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef) { stream_puts(s, "/Encoding "); switch (pfont->encoding_index) { case ENCODING_INDEX_STANDARD: stream_puts(s, "StandardEncoding"); break; case ENCODING_INDEX_ISOLATIN1: /* ATM only recognizes StandardEncoding. */ if (options & WRITE_TYPE1_POSTSCRIPT) { stream_puts(s, "ISOLatin1Encoding"); break; } default:{ gs_char i; stream_puts(s, "256 array\n"); stream_puts(s, "0 1 255 {1 index exch /.notdef put} for\n"); for (i = 0; i < 256; ++i) { gs_glyph glyph = (*pfont->procs.encode_char) ((gs_font *)pfont, (gs_char)i, GLYPH_SPACE_NAME); gs_const_string namestr; if (subset_glyphs && subset_size) { /* * Only write Encoding entries for glyphs in the * subset. Use binary search to check each glyph, * since subset_glyphs are sorted. */ if (!psf_sorted_glyphs_include(subset_glyphs, subset_size, glyph)) continue; } if (glyph != gs_no_glyph && glyph != notdef && pfont->procs.glyph_name((gs_font *)pfont, glyph, &namestr) >= 0 ) { pprintd1(s, "dup %d /", (int)i); stream_write(s, namestr.data, namestr.size); stream_puts(s, " put\n"); } } stream_puts(s, "readonly"); } } stream_puts(s, " def\n"); return 0; }
result_t rmdir_path_action(cli_t *context, const char * name_) { result_t result; memid_t key; if(failed(result = open_key(get_context(context), name_, false, &key)) || failed(result = reg_delete_key(key))) { stream_puts(context->cfg.console_err, "Error when deleting key\r\n"); return result; } return s_ok; }
/* Write the font name. */ static void write_font_name(stream *s, const gs_font_type1 *pfont, const gs_const_string *alt_font_name, bool as_name) { const byte *c; const byte *name = (alt_font_name ? alt_font_name->data : pfont->font_name.chars); int n = (alt_font_name ? alt_font_name->size : pfont->font_name.size); if (n == 0) /* empty name, may need to write it as empty string */ stream_puts(s, (as_name ? "/" : "()")); else { for (c = (byte *)"()<>[]{}/% \n\r\t\b\f\004\033"; *c; c++) if (memchr(name, *c, n)) break; if (*c || memchr(name, 0, n)) { /* name contains whitespace (NUL included) or a PostScript separator */ byte pssebuf[1 + 4 * gs_font_name_max + 1]; /* "(" + "\ooo" * gs_font_name_max + ")" */ stream_cursor_read r; stream_cursor_write w; pssebuf[0] = '('; r.limit = (r.ptr = name - 1) + n; w.limit = (w.ptr = pssebuf) + sizeof pssebuf - 1; s_PSSE_template.process(NULL, &r, &w, true); stream_write(s, pssebuf, w.ptr - pssebuf + 1); if (as_name) stream_puts(s, " cvn"); } else { /* name without any special characters */ if (as_name) stream_putc(s, '/'); stream_write(s, name, n); } } }
void trace(uint16_t level, const char *msg, ...) { va_list args; va_start(args, msg); if (trace_stream != 0 && trace_level <= level) { // send the timestamp stream_printf(trace_stream, "%ld %s ", ticks(), levels[level]); // send the level stream_vprintf(trace_stream, msg, args); stream_puts(trace_stream, "\r\n"); } platform_trace(level, msg, args); }
result_t cat_name_action(cli_t *context, const char * name) { result_t result; if(name == 0) return e_bad_parameter; handle_t stream; if(failed(result = stream_open(get_context(context), name, &stream))) return result; stream_copy(stream, context->cfg.console_out); stream_close(stream); stream_puts(context->cfg.console_out, "\r\n"); return result; }
result_t cd_path_action(cli_t *context, const char * name_) { // open a sub-key result_t result; memid_t memid = 0; if(failed(result = open_key(get_context(context), name_, false, &memid))) { stream_puts(context->cfg.console_err, "Error when creating key\r\n"); return result; } // update the submode const char * dirname = get_full_path(memid); char prompt[MAX_PROMPT_LENGTH]; snprintf(prompt, MAX_PROMPT_LENGTH, "%s %s ", node_name, dirname); neutron_free((void *)dirname); strncpy(context->prompt[context->root_level], prompt, MAX_PROMPT_LENGTH); context->current[context->root_level] = memid; return s_ok; }
/* 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; }
/* 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; }
result_t ls_path_recursive_action(cli_t *context, const char * path) { uint16_t indent = 0; result_t result; memid_t key; handle_t matches = 0; bool recursive = strlen(context->tokens[2].token_buffer) != 0; if (strlen(path) == 0) { show_key(context->cfg.console_out, get_context(context), true, false, &indent); return s_ok; } // expand wildcards if (failed(result = match_path(context, path, true, &key, &matches))) return result; // work over each one. field_datatype dt = 0; memid_t child = 0; uint16_t i; char name[REG_NAME_MAX + 1]; if (matches == 0) { // this is the case when a directory is given and no search show_key(context->cfg.console_out, key, false, recursive, &indent); } else { // decide what to do uint16_t len; if (failed(result = vector_count(matches, &len))) { kfree_split(matches); return result; } for (i = 0; i < len; i++) { const char * name; if (failed(result = vector_at(matches, i, &name))) { kfree_split(matches); return result; } if (failed(result = reg_query_child(key, name, &child, &dt, 0))) { if (result == e_not_found) continue; // very weird! kfree_split(matches); return result; } if (dt > field_key) show_value(context->cfg.console_out, child, dt, name, &indent, 0); } bool needs_newline = true; // now the directories for (i = 0; i < len; i++) { const char * name; if (failed(result = vector_at(matches, i, &name))) { kfree_split(matches); return result; } if (failed(result = reg_query_child(key, name, &child, &dt, 0))) { if (result == e_not_found) continue; // very weird! kfree_split(matches); return result; } if (dt == field_key) { if (needs_newline) { stream_puts(context->cfg.console_out, cr_lf); stream_printf(context->cfg.console_out, "dir %s\r\n", name); } indent += 2; show_key(context->cfg.console_out, child, false, recursive, &indent); } } kfree_split(matches); } return s_ok; }
/* Write a gs_string with a prefix. */ static void pput_string_entry(stream *s, const char *prefix, const gs_const_string *pstr) { stream_puts(s, prefix); stream_write(s, pstr->data, pstr->size); }
/* 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; }
/* * Write the Private dictionary. This is a separate procedure only for * readability. write_CharString is a parameter so that we can encrypt * Subrs and CharStrings when the font's lenIV == -1 but we are writing * the font with lenIV = 0. */ static int write_Private(stream *s, gs_font_type1 *pfont, gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef, int lenIV, int (*write_CharString)(stream *, const void *, uint), const param_printer_params_t *ppp) { const gs_type1_data *const pdata = &pfont->data; printer_param_list_t rlist; gs_param_list *const plist = (gs_param_list *)&rlist; int code = s_init_param_printer(&rlist, ppp, s); if (code < 0) return 0; stream_puts(s, "dup /Private 17 dict dup begin\n"); stream_puts(s, "/-|{string currentfile exch readstring pop}executeonly def\n"); stream_puts(s, "/|-{noaccess def}executeonly def\n"); stream_puts(s, "/|{noaccess put}executeonly def\n"); { static const gs_param_item_t private_items[] = { {"BlueFuzz", gs_param_type_int, offset_of(gs_type1_data, BlueFuzz)}, {"BlueScale", gs_param_type_float, offset_of(gs_type1_data, BlueScale)}, {"BlueShift", gs_param_type_float, offset_of(gs_type1_data, BlueShift)}, {"ExpansionFactor", gs_param_type_float, offset_of(gs_type1_data, ExpansionFactor)}, {"ForceBold", gs_param_type_bool, offset_of(gs_type1_data, ForceBold)}, {"LanguageGroup", gs_param_type_int, offset_of(gs_type1_data, LanguageGroup)}, {"RndStemUp", gs_param_type_bool, offset_of(gs_type1_data, RndStemUp)}, gs_param_item_end }; gs_type1_data defaults; defaults.BlueFuzz = 1; defaults.BlueScale = (float)0.039625; defaults.BlueShift = 7.0; defaults.ExpansionFactor = (float)0.06; defaults.ForceBold = false; defaults.LanguageGroup = 0; defaults.RndStemUp = true; code = gs_param_write_items(plist, pdata, &defaults, private_items); if (code < 0) return code; if (lenIV != 4) { code = param_write_int(plist, "lenIV", &lenIV); if (code < 0) return code; } write_float_array(plist, "BlueValues", pdata->BlueValues.values, pdata->BlueValues.count); write_float_array(plist, "OtherBlues", pdata->OtherBlues.values, pdata->OtherBlues.count); write_float_array(plist, "FamilyBlues", pdata->FamilyBlues.values, pdata->FamilyBlues.count); write_float_array(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values, pdata->FamilyOtherBlues.count); write_float_array(plist, "StdHW", pdata->StdHW.values, pdata->StdHW.count); write_float_array(plist, "StdVW", pdata->StdVW.values, pdata->StdVW.count); write_float_array(plist, "StemSnapH", pdata->StemSnapH.values, pdata->StemSnapH.count); write_float_array(plist, "StemSnapV", pdata->StemSnapV.values, pdata->StemSnapV.count); } write_uid(s, &pfont->UID); stream_puts(s, "/MinFeature{16 16} def\n"); stream_puts(s, "/password 5839 def\n"); /* * Write the Subrs. We always write them all, even for subsets. * (We will fix this someday.) */ { int n, i; gs_glyph_data_t gdata; int code; gdata.memory = pfont->memory; for (n = 0; (code = pdata->procs.subr_data(pfont, n, false, &gdata)) != gs_error_rangecheck; ) { ++n; if (code >= 0) gs_glyph_data_free(&gdata, "write_Private(Subrs)"); } pprintd1(s, "/Subrs %d array\n", n); for (i = 0; i < n; ++i) if ((code = pdata->procs.subr_data(pfont, i, false, &gdata)) >= 0) { char buf[50]; if (gdata.bits.size) { sprintf(buf, "dup %d %u -| ", i, gdata.bits.size); stream_puts(s, buf); write_CharString(s, gdata.bits.data, gdata.bits.size); stream_puts(s, " |\n"); } gs_glyph_data_free(&gdata, "write_Private(Subrs)"); } stream_puts(s, "|-\n"); } /* We don't write OtherSubrs -- there had better not be any! */ /* Write the CharStrings. */ { int num_chars = 0; gs_glyph glyph; psf_glyph_enum_t genum; gs_glyph_data_t gdata; int code; gdata.memory = pfont->memory; psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs, (subset_glyphs ? subset_size : 0), GLYPH_SPACE_NAME); for (glyph = gs_no_glyph; (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1; ) if (code == 0 && (code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0 ) { ++num_chars; gs_glyph_data_free(&gdata, "write_Private(CharStrings)"); } pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars); psf_enumerate_glyphs_reset(&genum); for (glyph = gs_no_glyph; (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1; ) if (code == 0 && (code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0 ) { gs_const_string gstr; int code; code = pfont->procs.glyph_name((gs_font *)pfont, glyph, &gstr); if (code < 0) return code; stream_puts(s, "/"); stream_write(s, gstr.data, gstr.size); pprintd1(s, " %d -| ", gdata.bits.size); write_CharString(s, gdata.bits.data, gdata.bits.size); stream_puts(s, " |-\n"); gs_glyph_data_free(&gdata, "write_Private(CharStrings)"); } } /* Wrap up. */ stream_puts(s, "end\nend\nreadonly put\nnoaccess put\n"); s_release_param_printer(&rlist); return 0; }
/* * Write a string in its shortest form ( () or <> ). Note that * this form is different depending on whether binary data are allowed. * Currently we don't support ASCII85 strings ( <~ ~> ). */ void s_write_ps_string(stream * s, const byte * str, uint size, int print_ok) { uint added = 0; uint i; const stream_template *templat; stream_AXE_state state; stream_state *st = NULL; if (print_ok & PRINT_BINARY_OK) { /* Only need to escape (, ), \, CR, EOL. */ stream_putc(s, '('); for (i = 0; i < size; ++i) { byte ch = str[i]; switch (ch) { case char_CR: stream_puts(s, "\\r"); continue; case char_EOL: stream_puts(s, "\\n"); continue; case '(': case ')': case '\\': stream_putc(s, '\\'); } stream_putc(s, ch); } stream_putc(s, ')'); return; } for (i = 0; i < size; ++i) { byte ch = str[i]; if (ch == 0 || ch >= 127) added += 3; else if (strchr("()\\\n\r\t\b\f", ch) != 0) ++added; else if (ch < 32) added += 3; } if (added < size || (print_ok & PRINT_HEX_NOT_OK)) { /* More efficient, or mandatory, to represent as PostScript string. */ templat = &s_PSSE_template; stream_putc(s, '('); } else { /* More efficient, and permitted, to represent as hex string. */ templat = &s_AXE_template; st = (stream_state *) & state; s_AXE_init_inline(&state); stream_putc(s, '<'); } { byte buf[100]; /* size is arbitrary */ stream_cursor_read r; stream_cursor_write w; int status; r.ptr = str - 1; r.limit = r.ptr + size; w.limit = buf + sizeof(buf) - 1; do { /* One picky compiler complains if we initialize to buf - 1. */ w.ptr = buf; w.ptr--; status = (*templat->process) (st, &r, &w, true); stream_write(s, buf, (uint) (w.ptr + 1 - buf)); } while (status == 1); } }
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; }
/* Write the definition of a Type 1 font. */ int psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options, gs_glyph *orig_subset_glyphs, uint orig_subset_size, const gs_const_string *alt_font_name, int lengths[3]) { stream *es = s; long start = stell(s); param_printer_params_t ppp; printer_param_list_t rlist; gs_param_list *const plist = (gs_param_list *)&rlist; stream AXE_stream; stream_AXE_state AXE_state; byte AXE_buf[200]; /* arbitrary */ stream exE_stream; stream_exE_state exE_state; byte exE_buf[200]; /* arbitrary */ psf_outline_glyphs_t glyphs; int lenIV = pfont->data.lenIV; int (*write_CharString)(stream *, const void *, uint) = stream_write; int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs, orig_subset_size); if (code < 0) return code; /* Initialize the parameter printer. */ ppp = param_printer_params_default; ppp.item_suffix = " def\n"; ppp.print_ok = (options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) | PRINT_HEX_NOT_OK; code = s_init_param_printer(&rlist, &ppp, s); if (code < 0) return code; /* Write the font header. */ stream_puts(s, "%!FontType1-1.0: "); write_font_name(s, pfont, alt_font_name, false); stream_puts(s, "\n11 dict begin\n"); /* Write FontInfo. */ stream_puts(s, "/FontInfo 5 dict dup begin"); { gs_font_info_t info; int code = pfont->procs.font_info((gs_font *)pfont, NULL, (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE | FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME), &info); if (code >= 0) { write_font_info(s, "Copyright", &info.Copyright, info.members & FONT_INFO_COPYRIGHT); write_font_info(s, "Notice", &info.Notice, info.members & FONT_INFO_NOTICE); write_font_info(s, "FamilyName", &info.FamilyName, info.members & FONT_INFO_FAMILY_NAME); write_font_info(s, "FullName", &info.FullName, info.members & FONT_INFO_FULL_NAME); } } stream_puts(s, "\nend readonly def\n"); /* Write the main font dictionary. */ stream_puts(s, "/FontName "); write_font_name(s, pfont, alt_font_name, true); stream_puts(s, " def\n"); code = write_Encoding(s, pfont, options, glyphs.subset_glyphs, glyphs.subset_size, glyphs.notdef); if (code < 0) return code; pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", pfont->FontMatrix.xx, pfont->FontMatrix.xy, pfont->FontMatrix.yx, pfont->FontMatrix.yy, pfont->FontMatrix.tx, pfont->FontMatrix.ty); write_uid(s, &pfont->UID); pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n", pfont->FontBBox.p.x, pfont->FontBBox.p.y, pfont->FontBBox.q.x, pfont->FontBBox.q.y); { static const gs_param_item_t font_items[] = { {"FontType", gs_param_type_int, offset_of(gs_font_type1, FontType)}, {"PaintType", gs_param_type_int, offset_of(gs_font_type1, PaintType)}, {"StrokeWidth", gs_param_type_float, offset_of(gs_font_type1, StrokeWidth)}, gs_param_item_end }; code = gs_param_write_items(plist, pfont, NULL, font_items); if (code < 0) return code; } { const gs_type1_data *const pdata = &pfont->data; write_float_array(plist, "WeightVector", pdata->WeightVector.values, pdata->WeightVector.count); } stream_puts(s, "currentdict end\n"); /* Write the Private dictionary. */ if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) { /* We'll have to encrypt the CharStrings. */ lenIV = 0; write_CharString = stream_write_encrypted; } if (options & WRITE_TYPE1_EEXEC) { stream_puts(s, "currentfile eexec\n"); lengths[0] = stell(s) - start; start = stell(s); if (options & WRITE_TYPE1_ASCIIHEX) { s_init(&AXE_stream, s->memory); s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL); AXE_state.EndOfData = false; s_init_filter(&AXE_stream, (stream_state *)&AXE_state, AXE_buf, sizeof(AXE_buf), es); es = &AXE_stream; } s_init(&exE_stream, s->memory); s_init_state((stream_state *)&exE_state, &s_exE_template, NULL); exE_state.cstate = 55665; s_init_filter(&exE_stream, (stream_state *)&exE_state, exE_buf, sizeof(exE_buf), es); es = &exE_stream; /* * Note: eexec encryption always writes/skips 4 initial bytes, not * the number of initial bytes given by pdata->lenIV. */ stream_puts(es, "****"); } code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size, glyphs.notdef, lenIV, write_CharString, &ppp); if (code < 0) return code; stream_puts(es, "dup/FontName get exch definefont pop\n"); if (options & WRITE_TYPE1_EEXEC) { if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK)) stream_puts(es, "mark "); stream_puts(es, "currentfile closefile\n"); s_close_filters(&es, s); lengths[1] = stell(s) - start; start = stell(s); if (options & WRITE_TYPE1_EEXEC_PAD) { int i; for (i = 0; i < 8; ++i) stream_puts(s, "\n0000000000000000000000000000000000000000000000000000000000000000"); stream_puts(s, "\ncleartomark\n"); } lengths[2] = stell(s) - start; } else { lengths[0] = stell(s) - start; lengths[1] = lengths[2] = 0; } /* Wrap up. */ s_release_param_printer(&rlist); return 0; }
/* Write the common part of a FontDescriptor, aside from the final >>. */ static int write_FontDescriptor_common(gx_device_pdf *pdev, const pdf_font_descriptor_common_t *pfd, bool embed) { stream *s; int code; param_printer_params_t params; printer_param_list_t rlist; gs_param_list *const plist = (gs_param_list *)&rlist; char *base14_name = NULL; pdf_open_separate(pdev, pdf_font_descriptor_common_id(pfd), resourceFontDescriptor); s = pdev->strm; stream_puts(s, "<</Type/FontDescriptor/FontName"); if (!embed) { base14_name = (char *)pdf_find_base14_name(pfd->values.FontName.data, pfd->values.FontName.size); if(base14_name) pdf_put_name(pdev, (byte *)base14_name, strlen(base14_name)); else pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size); } else pdf_put_name(pdev, pfd->values.FontName.data, pfd->values.FontName.size); pdf_write_font_bbox(pdev, &pfd->values.FontBBox); params = param_printer_params_default; code = s_init_param_printer(&rlist, ¶ms, s); if (code >= 0) { #define DESC_INT(str, memb)\ {str, gs_param_type_int, offset_of(pdf_font_descriptor_common_t, values.memb)} static const gs_param_item_t required_items[] = { DESC_INT("Ascent", Ascent), DESC_INT("CapHeight", CapHeight), DESC_INT("Descent", Descent), DESC_INT("ItalicAngle", ItalicAngle), DESC_INT("StemV", StemV), gs_param_item_end }; static const gs_param_item_t optional_items[] = { DESC_INT("AvgWidth", AvgWidth), DESC_INT("Leading", Leading), DESC_INT("MaxWidth", MaxWidth), DESC_INT("MissingWidth", MissingWidth), DESC_INT("StemH", StemH), DESC_INT("XHeight", XHeight), gs_param_item_end }; #undef DESC_INT int Flags = pfd->values.Flags; pdf_font_descriptor_t defaults; if (base14_name) Flags |=FONT_USES_STANDARD_ENCODING; code = param_write_int(plist, "Flags", &Flags); if (code < 0) return code; code = gs_param_write_items(plist, pfd, NULL, required_items); if (code < 0) return code; memset(&defaults, 0, sizeof(defaults)); code = gs_param_write_items(plist, pfd, &defaults, optional_items); if (code < 0) return code; s_release_param_printer(&rlist); } return 0; }