1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gdevpsf1.c 8296 2007-10-16 07:54:08Z ken $ */
15
/* Write an embedded Type 1 font */
24
#include "gxmatrix.h" /* for gxtype1.h */
26
#include "strimpl.h" /* required by Watcom compiler (why?) */
34
/* ------ Utilities shared with CFF writer ------ */
36
/* Gather glyph information for a Type 1 or Type 2 font. */
38
psf_type1_glyph_data(gs_font_base *pbfont, gs_glyph glyph,
39
gs_glyph_data_t *pgd, gs_font_type1 **ppfont)
41
gs_font_type1 *const pfont = (gs_font_type1 *)pbfont;
44
return pfont->data.procs.glyph_data(pfont, glyph, pgd);
47
psf_get_type1_glyphs(psf_outline_glyphs_t *pglyphs, gs_font_type1 *pfont,
48
gs_glyph *subset_glyphs, uint subset_size)
50
return psf_get_outline_glyphs(pglyphs, (gs_font_base *)pfont,
51
subset_glyphs, subset_size,
52
psf_type1_glyph_data);
55
/* ------ Main program ------ */
57
/* Write a (named) array of floats. */
59
write_float_array(gs_param_list *plist, const char *key, const float *values,
63
gs_param_float_array fa;
67
return param_write_float_array(plist, key, &fa);
72
/* Write a UniqueID and/or XUID. */
74
write_uid(stream *s, const gs_uid *puid)
76
if (uid_is_UniqueID(puid))
77
pprintld1(s, "/UniqueID %ld def\n", puid->id);
78
else if (uid_is_XUID(puid)) {
79
uint i, n = uid_XUID_size(puid);
81
stream_puts(s, "/XUID [");
82
for (i = 0; i < n; ++i)
83
pprintld1(s, "%ld ", uid_XUID_values(puid)[i]);
84
stream_puts(s, "] readonly def\n");
88
/* Write the font name. */
90
write_font_name(stream *s, const gs_font_type1 *pfont,
91
const gs_const_string *alt_font_name, bool as_name)
94
const byte *name = (alt_font_name ? alt_font_name->data : pfont->font_name.chars);
95
int n = (alt_font_name ? alt_font_name->size : pfont->font_name.size);
98
/* empty name, may need to write it as empty string */
99
stream_puts(s, (as_name ? "/" : "()"));
101
for (c = (byte *)"()<>[]{}/% \n\r\t\b\f\004\033"; *c; c++)
102
if (memchr(name, *c, n))
104
if (*c || memchr(name, 0, n)) {
105
/* name contains whitespace (NUL included) or a PostScript separator */
106
byte pssebuf[1 + 4 * gs_font_name_max + 1]; /* "(" + "\ooo" * gs_font_name_max + ")" */
107
stream_cursor_read r;
108
stream_cursor_write w;
111
r.limit = (r.ptr = name - 1) + n;
112
w.limit = (w.ptr = pssebuf) + sizeof pssebuf - 1;
113
s_PSSE_template.process(NULL, &r, &w, true);
114
stream_write(s, pssebuf, w.ptr - pssebuf + 1);
116
stream_puts(s, " cvn");
118
/* name without any special characters */
121
stream_write(s, name, n);
126
* Write the Encoding array. This is a separate procedure only for
130
write_Encoding(stream *s, gs_font_type1 *pfont, int options,
131
gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef)
133
stream_puts(s, "/Encoding ");
134
switch (pfont->encoding_index) {
135
case ENCODING_INDEX_STANDARD:
136
stream_puts(s, "StandardEncoding");
138
case ENCODING_INDEX_ISOLATIN1:
139
/* ATM only recognizes StandardEncoding. */
140
if (options & WRITE_TYPE1_POSTSCRIPT) {
141
stream_puts(s, "ISOLatin1Encoding");
147
stream_puts(s, "256 array\n");
148
stream_puts(s, "0 1 255 {1 index exch /.notdef put} for\n");
149
for (i = 0; i < 256; ++i) {
151
(*pfont->procs.encode_char)
152
((gs_font *)pfont, (gs_char)i, GLYPH_SPACE_NAME);
153
gs_const_string namestr;
155
if (subset_glyphs && subset_size) {
157
* Only write Encoding entries for glyphs in the
158
* subset. Use binary search to check each glyph,
159
* since subset_glyphs are sorted.
161
if (!psf_sorted_glyphs_include(subset_glyphs,
165
if (glyph != gs_no_glyph && glyph != notdef &&
166
pfont->procs.glyph_name((gs_font *)pfont, glyph,
169
pprintd1(s, "dup %d /", (int)i);
170
stream_write(s, namestr.data, namestr.size);
171
stream_puts(s, " put\n");
174
stream_puts(s, "readonly");
177
stream_puts(s, " def\n");
182
* Write the Private dictionary. This is a separate procedure only for
183
* readability. write_CharString is a parameter so that we can encrypt
184
* Subrs and CharStrings when the font's lenIV == -1 but we are writing
185
* the font with lenIV = 0.
188
write_Private(stream *s, gs_font_type1 *pfont,
189
gs_glyph *subset_glyphs, uint subset_size,
190
gs_glyph notdef, int lenIV,
191
int (*write_CharString)(stream *, const void *, uint),
192
const param_printer_params_t *ppp)
194
const gs_type1_data *const pdata = &pfont->data;
195
printer_param_list_t rlist;
196
gs_param_list *const plist = (gs_param_list *)&rlist;
197
int code = s_init_param_printer(&rlist, ppp, s);
201
stream_puts(s, "dup /Private 17 dict dup begin\n");
202
stream_puts(s, "/-|{string currentfile exch readstring pop}executeonly def\n");
203
stream_puts(s, "/|-{noaccess def}executeonly def\n");
204
stream_puts(s, "/|{noaccess put}executeonly def\n");
206
static const gs_param_item_t private_items[] = {
207
{"BlueFuzz", gs_param_type_int,
208
offset_of(gs_type1_data, BlueFuzz)},
209
{"BlueScale", gs_param_type_float,
210
offset_of(gs_type1_data, BlueScale)},
211
{"BlueShift", gs_param_type_float,
212
offset_of(gs_type1_data, BlueShift)},
213
{"ExpansionFactor", gs_param_type_float,
214
offset_of(gs_type1_data, ExpansionFactor)},
215
{"ForceBold", gs_param_type_bool,
216
offset_of(gs_type1_data, ForceBold)},
217
{"LanguageGroup", gs_param_type_int,
218
offset_of(gs_type1_data, LanguageGroup)},
219
{"RndStemUp", gs_param_type_bool,
220
offset_of(gs_type1_data, RndStemUp)},
223
gs_type1_data defaults;
225
defaults.BlueFuzz = 1;
226
defaults.BlueScale = (float)0.039625;
227
defaults.BlueShift = 7.0;
228
defaults.ExpansionFactor = (float)0.06;
229
defaults.ForceBold = false;
230
defaults.LanguageGroup = 0;
231
defaults.RndStemUp = true;
232
code = gs_param_write_items(plist, pdata, &defaults, private_items);
236
code = param_write_int(plist, "lenIV", &lenIV);
240
write_float_array(plist, "BlueValues", pdata->BlueValues.values,
241
pdata->BlueValues.count);
242
write_float_array(plist, "OtherBlues", pdata->OtherBlues.values,
243
pdata->OtherBlues.count);
244
write_float_array(plist, "FamilyBlues", pdata->FamilyBlues.values,
245
pdata->FamilyBlues.count);
246
write_float_array(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values,
247
pdata->FamilyOtherBlues.count);
248
write_float_array(plist, "StdHW", pdata->StdHW.values,
250
write_float_array(plist, "StdVW", pdata->StdVW.values,
252
write_float_array(plist, "StemSnapH", pdata->StemSnapH.values,
253
pdata->StemSnapH.count);
254
write_float_array(plist, "StemSnapV", pdata->StemSnapV.values,
255
pdata->StemSnapV.count);
257
write_uid(s, &pfont->UID);
258
stream_puts(s, "/MinFeature{16 16} def\n");
259
stream_puts(s, "/password 5839 def\n");
262
* Write the Subrs. We always write them all, even for subsets.
263
* (We will fix this someday.)
268
gs_glyph_data_t gdata;
271
gdata.memory = pfont->memory;
273
(code = pdata->procs.subr_data(pfont, n, false, &gdata)) !=
278
gs_glyph_data_free(&gdata, "write_Private(Subrs)");
280
pprintd1(s, "/Subrs %d array\n", n);
281
for (i = 0; i < n; ++i)
282
if ((code = pdata->procs.subr_data(pfont, i, false, &gdata)) >= 0) {
285
if (gdata.bits.size) {
286
sprintf(buf, "dup %d %u -| ", i, gdata.bits.size);
288
write_CharString(s, gdata.bits.data, gdata.bits.size);
289
stream_puts(s, " |\n");
291
gs_glyph_data_free(&gdata, "write_Private(Subrs)");
293
stream_puts(s, "|-\n");
296
/* We don't write OtherSubrs -- there had better not be any! */
298
/* Write the CharStrings. */
303
psf_glyph_enum_t genum;
304
gs_glyph_data_t gdata;
307
gdata.memory = pfont->memory;
308
psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs,
309
(subset_glyphs ? subset_size : 0),
311
for (glyph = gs_no_glyph;
312
(code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
315
(code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
318
gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
320
pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars);
321
psf_enumerate_glyphs_reset(&genum);
322
for (glyph = gs_no_glyph;
323
(code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
326
(code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
328
gs_const_string gstr;
331
code = pfont->procs.glyph_name((gs_font *)pfont, glyph, &gstr);
335
stream_write(s, gstr.data, gstr.size);
336
pprintd1(s, " %d -| ", gdata.bits.size);
337
write_CharString(s, gdata.bits.data, gdata.bits.size);
338
stream_puts(s, " |-\n");
339
gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
345
stream_puts(s, "end\nend\nreadonly put\nnoaccess put\n");
346
s_release_param_printer(&rlist);
350
/* Encrypt and write a CharString. */
352
stream_write_encrypted(stream *s, const void *ptr, uint count)
354
const byte *const data = ptr;
355
crypt_state state = crypt_charstring_seed;
356
byte buf[50]; /* arbitrary */
360
for (left = count; left > 0; left -= n) {
361
n = min(left, sizeof(buf));
362
gs_type1_encrypt(buf, data + count - left, n, &state);
363
code = stream_write(s, buf, n);
368
/* Write one FontInfo entry. */
370
write_font_info(stream *s, const char *key, const gs_const_string *pvalue,
374
pprints1(s, "\n/%s ", key);
375
s_write_ps_string(s, pvalue->data, pvalue->size, PRINT_HEX_NOT_OK);
376
stream_puts(s, " def");
380
/* Write the definition of a Type 1 font. */
382
psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
383
gs_glyph *orig_subset_glyphs, uint orig_subset_size,
384
const gs_const_string *alt_font_name, int lengths[3])
387
long start = stell(s);
388
param_printer_params_t ppp;
389
printer_param_list_t rlist;
390
gs_param_list *const plist = (gs_param_list *)&rlist;
392
stream_AXE_state AXE_state;
393
byte AXE_buf[200]; /* arbitrary */
395
stream_exE_state exE_state;
396
byte exE_buf[200]; /* arbitrary */
397
psf_outline_glyphs_t glyphs;
398
int lenIV = pfont->data.lenIV;
399
int (*write_CharString)(stream *, const void *, uint) = stream_write;
400
int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs,
406
/* Initialize the parameter printer. */
408
ppp = param_printer_params_default;
409
ppp.item_suffix = " def\n";
411
(options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) |
413
code = s_init_param_printer(&rlist, &ppp, s);
417
/* Write the font header. */
419
stream_puts(s, "%!FontType1-1.0: ");
420
write_font_name(s, pfont, alt_font_name, false);
421
stream_puts(s, "\n11 dict begin\n");
423
/* Write FontInfo. */
425
stream_puts(s, "/FontInfo 5 dict dup begin");
428
int code = pfont->procs.font_info((gs_font *)pfont, NULL,
429
(FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
430
FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
434
write_font_info(s, "Copyright", &info.Copyright,
435
info.members & FONT_INFO_COPYRIGHT);
436
write_font_info(s, "Notice", &info.Notice,
437
info.members & FONT_INFO_NOTICE);
438
write_font_info(s, "FamilyName", &info.FamilyName,
439
info.members & FONT_INFO_FAMILY_NAME);
440
write_font_info(s, "FullName", &info.FullName,
441
info.members & FONT_INFO_FULL_NAME);
444
stream_puts(s, "\nend readonly def\n");
446
/* Write the main font dictionary. */
448
stream_puts(s, "/FontName ");
449
write_font_name(s, pfont, alt_font_name, true);
450
stream_puts(s, " def\n");
451
code = write_Encoding(s, pfont, options, glyphs.subset_glyphs,
452
glyphs.subset_size, glyphs.notdef);
455
pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
456
pfont->FontMatrix.xx, pfont->FontMatrix.xy,
457
pfont->FontMatrix.yx, pfont->FontMatrix.yy,
458
pfont->FontMatrix.tx, pfont->FontMatrix.ty);
459
write_uid(s, &pfont->UID);
460
pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n",
461
pfont->FontBBox.p.x, pfont->FontBBox.p.y,
462
pfont->FontBBox.q.x, pfont->FontBBox.q.y);
464
static const gs_param_item_t font_items[] = {
465
{"FontType", gs_param_type_int,
466
offset_of(gs_font_type1, FontType)},
467
{"PaintType", gs_param_type_int,
468
offset_of(gs_font_type1, PaintType)},
469
{"StrokeWidth", gs_param_type_float,
470
offset_of(gs_font_type1, StrokeWidth)},
474
code = gs_param_write_items(plist, pfont, NULL, font_items);
479
const gs_type1_data *const pdata = &pfont->data;
481
write_float_array(plist, "WeightVector", pdata->WeightVector.values,
482
pdata->WeightVector.count);
484
stream_puts(s, "currentdict end\n");
486
/* Write the Private dictionary. */
488
if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) {
489
/* We'll have to encrypt the CharStrings. */
491
write_CharString = stream_write_encrypted;
493
if (options & WRITE_TYPE1_EEXEC) {
494
stream_puts(s, "currentfile eexec\n");
495
lengths[0] = stell(s) - start;
497
if (options & WRITE_TYPE1_ASCIIHEX) {
498
s_init(&AXE_stream, s->memory);
499
s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL);
500
AXE_state.EndOfData = false;
501
s_init_filter(&AXE_stream, (stream_state *)&AXE_state,
502
AXE_buf, sizeof(AXE_buf), es);
505
s_init(&exE_stream, s->memory);
506
s_init_state((stream_state *)&exE_state, &s_exE_template, NULL);
507
exE_state.cstate = 55665;
508
s_init_filter(&exE_stream, (stream_state *)&exE_state,
509
exE_buf, sizeof(exE_buf), es);
512
* Note: eexec encryption always writes/skips 4 initial bytes, not
513
* the number of initial bytes given by pdata->lenIV.
515
stream_puts(es, "****");
517
code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size,
518
glyphs.notdef, lenIV, write_CharString, &ppp);
521
stream_puts(es, "dup/FontName get exch definefont pop\n");
522
if (options & WRITE_TYPE1_EEXEC) {
523
if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK))
524
stream_puts(es, "mark ");
525
stream_puts(es, "currentfile closefile\n");
526
s_close_filters(&es, s);
527
lengths[1] = stell(s) - start;
529
if (options & WRITE_TYPE1_EEXEC_PAD) {
532
for (i = 0; i < 8; ++i)
533
stream_puts(s, "\n0000000000000000000000000000000000000000000000000000000000000000");
534
stream_puts(s, "\ncleartomark\n");
536
lengths[2] = stell(s) - start;
538
lengths[0] = stell(s) - start;
539
lengths[1] = lengths[2] = 0;
544
s_release_param_printer(&rlist);