int s_alloc_param_printer(gs_param_list ** pplist, const param_printer_params_t * ppp, stream * s, gs_memory_t * mem) { printer_param_list_t *prlist = gs_alloc_struct(mem, printer_param_list_t, &st_printer_param_list, "s_alloc_param_printer"); int code; *pplist = (gs_param_list *)prlist; if (prlist == 0) return_error(gs_error_VMerror); code = s_init_param_printer(prlist, ppp, s); prlist->memory = mem; return code; }
/* * 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 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; }