1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
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.
12 */
13 
14 /* $Id: gdevpsf1.c 9386 2009-01-22 13:53:18Z ken $ */
15 /* Write an embedded Type 1 font */
16 #include "memory_.h"
17 #include "gx.h"
18 #include "gserrors.h"
19 #include "gsccode.h"
20 #include "gsmatrix.h"
21 #include "gxfixed.h"
22 #include "gxfont.h"
23 #include "gxfont1.h"
24 #include "gxmatrix.h"		/* for gxtype1.h */
25 #include "gxtype1.h"
26 #include "strimpl.h"		/* required by Watcom compiler (why?) */
27 #include "stream.h"
28 #include "sfilter.h"
29 #include "spsdf.h"
30 #include "sstring.h"
31 #include "spprint.h"
32 #include "gdevpsf.h"
33 
34 /* ------ Utilities shared with CFF writer ------ */
35 
36 /* Gather glyph information for a Type 1 or Type 2 font. */
37 int
psf_type1_glyph_data(gs_font_base * pbfont,gs_glyph glyph,gs_glyph_data_t * pgd,gs_font_type1 ** ppfont)38 psf_type1_glyph_data(gs_font_base *pbfont, gs_glyph glyph,
39 		     gs_glyph_data_t *pgd, gs_font_type1 **ppfont)
40 {
41     gs_font_type1 *const pfont = (gs_font_type1 *)pbfont;
42 
43     *ppfont = pfont;
44     return pfont->data.procs.glyph_data(pfont, glyph, pgd);
45 }
46 int
psf_get_type1_glyphs(psf_outline_glyphs_t * pglyphs,gs_font_type1 * pfont,gs_glyph * subset_glyphs,uint subset_size)47 psf_get_type1_glyphs(psf_outline_glyphs_t *pglyphs, gs_font_type1 *pfont,
48 		     gs_glyph *subset_glyphs, uint subset_size)
49 {
50     return psf_get_outline_glyphs(pglyphs, (gs_font_base *)pfont,
51 				  subset_glyphs, subset_size,
52 				  psf_type1_glyph_data);
53 }
54 
55 /* ------ Main program ------ */
56 
57 /* Write a (named) array of floats. */
58 static int
write_float_array(gs_param_list * plist,const char * key,const float * values,int count)59 write_float_array(gs_param_list *plist, const char *key, const float *values,
60 		  int count)
61 {
62     if (count != 0) {
63 	gs_param_float_array fa;
64 
65 	fa.persistent = false;
66 	fa.size = count;
67 	fa.data = values;
68 	return param_write_float_array(plist, key, &fa);
69     }
70     return 0;
71 }
72 
73 /* Write a UniqueID and/or XUID. */
74 static void
write_uid(stream * s,const gs_uid * puid)75 write_uid(stream *s, const gs_uid *puid)
76 {
77     if (uid_is_UniqueID(puid))
78 	pprintld1(s, "/UniqueID %ld def\n", puid->id);
79     else if (uid_is_XUID(puid)) {
80 	uint i, n = uid_XUID_size(puid);
81 
82 	stream_puts(s, "/XUID [");
83 	for (i = 0; i < n; ++i)
84 	    pprintld1(s, "%ld ", uid_XUID_values(puid)[i]);
85 	stream_puts(s, "] readonly def\n");
86     }
87 }
88 
89 /* Write the font name. */
90 static void
write_font_name(stream * s,const gs_font_type1 * pfont,const gs_const_string * alt_font_name,bool as_name)91 write_font_name(stream *s, const gs_font_type1 *pfont,
92 		const gs_const_string *alt_font_name, bool as_name)
93 {
94     const byte *c;
95     const byte *name = (alt_font_name ? alt_font_name->data : pfont->font_name.chars);
96     int         n    = (alt_font_name ? alt_font_name->size : pfont->font_name.size);
97 
98     if (n == 0)
99 	/* empty name, may need to write it as empty string */
100 	stream_puts(s, (as_name ? "/" : "()"));
101     else {
102 	for (c = (byte *)"()<>[]{}/% \n\r\t\b\f\004\033"; *c; c++)
103 	    if (memchr(name, *c, n))
104 		break;
105 	if (*c || memchr(name, 0, n)) {
106 	    /* name contains whitespace (NUL included) or a PostScript separator */
107 	    byte pssebuf[1 + 4 * gs_font_name_max + 1]; /* "(" + "\ooo" * gs_font_name_max + ")" */
108 	    stream_cursor_read  r;
109 	    stream_cursor_write w;
110 
111 	    pssebuf[0] = '(';
112 	    r.limit = (r.ptr = name - 1) + n;
113 	    w.limit = (w.ptr = pssebuf) + sizeof pssebuf - 1;
114 	    s_PSSE_template.process(NULL, &r, &w, true);
115 	    stream_write(s, pssebuf, w.ptr - pssebuf + 1);
116 	    if (as_name)
117 		stream_puts(s, " cvn");
118 	} else {
119 	    /* name without any special characters */
120 	    if (as_name)
121 		stream_putc(s, '/');
122 	    stream_write(s, name, n);
123 	}
124     }
125 }
126 /*
127  * Write the Encoding array.  This is a separate procedure only for
128  * readability.
129  */
130 static int
write_Encoding(stream * s,gs_font_type1 * pfont,int options,gs_glyph * subset_glyphs,uint subset_size,gs_glyph notdef)131 write_Encoding(stream *s, gs_font_type1 *pfont, int options,
132 	      gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef)
133 {
134     stream_puts(s, "/Encoding ");
135     switch (pfont->encoding_index) {
136 	case ENCODING_INDEX_STANDARD:
137 	    stream_puts(s, "StandardEncoding");
138 	    break;
139 	case ENCODING_INDEX_ISOLATIN1:
140 	    /* ATM only recognizes StandardEncoding. */
141 	    if (options & WRITE_TYPE1_POSTSCRIPT) {
142 		stream_puts(s, "ISOLatin1Encoding");
143 		break;
144 	    }
145 	default:{
146 		gs_char i;
147 
148 		stream_puts(s, "256 array\n");
149 		stream_puts(s, "0 1 255 {1 index exch /.notdef put} for\n");
150 		for (i = 0; i < 256; ++i) {
151 		    gs_glyph glyph =
152 			(*pfont->procs.encode_char)
153 			((gs_font *)pfont, (gs_char)i, GLYPH_SPACE_NAME);
154 		    gs_const_string namestr;
155 
156 		    if (subset_glyphs && subset_size) {
157 			/*
158 			 * Only write Encoding entries for glyphs in the
159 			 * subset.  Use binary search to check each glyph,
160 			 * since subset_glyphs are sorted.
161 			 */
162 			if (!psf_sorted_glyphs_include(subset_glyphs,
163 							subset_size, glyph))
164 			    continue;
165 		    }
166 		    if (glyph != gs_no_glyph && glyph != notdef &&
167 			pfont->procs.glyph_name((gs_font *)pfont, glyph,
168 						&namestr) >= 0
169 			) {
170 			pprintd1(s, "dup %d /", (int)i);
171 			stream_write(s, namestr.data, namestr.size);
172 			stream_puts(s, " put\n");
173 		    }
174 		}
175 		stream_puts(s, "readonly");
176 	    }
177     }
178     stream_puts(s, " def\n");
179     return 0;
180 }
181 
182 /*
183  * Write the Private dictionary.  This is a separate procedure only for
184  * readability.  write_CharString is a parameter so that we can encrypt
185  * Subrs and CharStrings when the font's lenIV == -1 but we are writing
186  * the font with lenIV = 0.
187  */
188 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)189 write_Private(stream *s, gs_font_type1 *pfont,
190 	      gs_glyph *subset_glyphs, uint subset_size,
191 	      gs_glyph notdef, int lenIV,
192 	      int (*write_CharString)(stream *, const void *, uint),
193 	      const param_printer_params_t *ppp)
194 {
195     const gs_type1_data *const pdata = &pfont->data;
196     printer_param_list_t rlist;
197     gs_param_list *const plist = (gs_param_list *)&rlist;
198     int code = s_init_param_printer(&rlist, ppp, s);
199 
200     if (code < 0)
201 	return 0;
202     stream_puts(s, "dup /Private 17 dict dup begin\n");
203     stream_puts(s, "/-|{string currentfile exch readstring pop}executeonly def\n");
204     stream_puts(s, "/|-{noaccess def}executeonly def\n");
205     stream_puts(s, "/|{noaccess put}executeonly def\n");
206     {
207 	static const gs_param_item_t private_items[] = {
208 	    {"BlueFuzz", gs_param_type_int,
209 	     offset_of(gs_type1_data, BlueFuzz)},
210 	    {"BlueScale", gs_param_type_float,
211 	     offset_of(gs_type1_data, BlueScale)},
212 	    {"BlueShift", gs_param_type_float,
213 	     offset_of(gs_type1_data, BlueShift)},
214 	    {"ExpansionFactor", gs_param_type_float,
215 	     offset_of(gs_type1_data, ExpansionFactor)},
216 	    {"ForceBold", gs_param_type_bool,
217 	     offset_of(gs_type1_data, ForceBold)},
218 	    {"LanguageGroup", gs_param_type_int,
219 	     offset_of(gs_type1_data, LanguageGroup)},
220 	    {"RndStemUp", gs_param_type_bool,
221 	     offset_of(gs_type1_data, RndStemUp)},
222 	    gs_param_item_end
223 	};
224 	gs_type1_data defaults;
225 
226 	defaults.BlueFuzz = 1;
227 	defaults.BlueScale = (float)0.039625;
228 	defaults.BlueShift = 7.0;
229 	defaults.ExpansionFactor = (float)0.06;
230 	defaults.ForceBold = false;
231 	defaults.LanguageGroup = 0;
232 	defaults.RndStemUp = true;
233 	code = gs_param_write_items(plist, pdata, &defaults, private_items);
234 	if (code < 0)
235 	    return code;
236 	if (lenIV != 4) {
237 	    code = param_write_int(plist, "lenIV", &lenIV);
238 	    if (code < 0)
239 		return code;
240 	}
241 	write_float_array(plist, "BlueValues", pdata->BlueValues.values,
242 			  pdata->BlueValues.count);
243 	write_float_array(plist, "OtherBlues", pdata->OtherBlues.values,
244 			  pdata->OtherBlues.count);
245 	write_float_array(plist, "FamilyBlues", pdata->FamilyBlues.values,
246 			  pdata->FamilyBlues.count);
247 	write_float_array(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values,
248 			  pdata->FamilyOtherBlues.count);
249 	write_float_array(plist, "StdHW", pdata->StdHW.values,
250 			  pdata->StdHW.count);
251 	write_float_array(plist, "StdVW", pdata->StdVW.values,
252 			  pdata->StdVW.count);
253 	write_float_array(plist, "StemSnapH", pdata->StemSnapH.values,
254 			  pdata->StemSnapH.count);
255 	write_float_array(plist, "StemSnapV", pdata->StemSnapV.values,
256 			  pdata->StemSnapV.count);
257     }
258     write_uid(s, &pfont->UID);
259     stream_puts(s, "/MinFeature{16 16} def\n");
260     stream_puts(s, "/password 5839 def\n");
261 
262     /*
263      * Write the Subrs.  We always write them all, even for subsets.
264      * (We will fix this someday.)
265      */
266 
267     {
268 	int n, i;
269 	gs_glyph_data_t gdata;
270 	int code;
271 
272 	gdata.memory = pfont->memory;
273 	for (n = 0;
274 	     (code = pdata->procs.subr_data(pfont, n, false, &gdata)) !=
275 		 gs_error_rangecheck;
276 	     ) {
277 	    ++n;
278 	    if (code >= 0)
279 		gs_glyph_data_free(&gdata, "write_Private(Subrs)");
280 	}
281 	pprintd1(s, "/Subrs %d array\n", n);
282 	for (i = 0; i < n; ++i)
283 	    if ((code = pdata->procs.subr_data(pfont, i, false, &gdata)) >= 0) {
284 		char buf[50];
285 
286 		if (gdata.bits.size) {
287 		    sprintf(buf, "dup %d %u -| ", i, gdata.bits.size);
288 		    stream_puts(s, buf);
289 		    write_CharString(s, gdata.bits.data, gdata.bits.size);
290 		    stream_puts(s, " |\n");
291 		}
292 		gs_glyph_data_free(&gdata, "write_Private(Subrs)");
293 	    }
294 	stream_puts(s, "|-\n");
295     }
296 
297     /* We don't write OtherSubrs -- there had better not be any! */
298 
299     /* Write the CharStrings. */
300 
301     {
302 	int num_chars = 0;
303 	gs_glyph glyph;
304 	psf_glyph_enum_t genum;
305 	gs_glyph_data_t gdata;
306 	int code;
307 
308 	gdata.memory = pfont->memory;
309 	psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs,
310 				    (subset_glyphs ? subset_size : 0),
311 				    GLYPH_SPACE_NAME);
312 	for (glyph = gs_no_glyph;
313 	     (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
314 	     )
315 	    if (code == 0 &&
316 		(code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
317 		) {
318 		++num_chars;
319 		gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
320 	    }
321 	pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars);
322 	psf_enumerate_glyphs_reset(&genum);
323 	for (glyph = gs_no_glyph;
324 	     (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
325 	    )
326 	    if (code == 0 &&
327 		(code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
328 		) {
329 		gs_const_string gstr;
330 		int code;
331 
332 		code = pfont->procs.glyph_name((gs_font *)pfont, glyph, &gstr);
333 		if (code < 0)
334 		    return code;
335 		stream_puts(s, "/");
336 		stream_write(s, gstr.data, gstr.size);
337 		pprintd1(s, " %d -| ", gdata.bits.size);
338 		write_CharString(s, gdata.bits.data, gdata.bits.size);
339 		stream_puts(s, " |-\n");
340 		gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
341 	    }
342     }
343 
344     /* Wrap up. */
345 
346     stream_puts(s, "end\nend\nreadonly put\nnoaccess put\n");
347     s_release_param_printer(&rlist);
348     return 0;
349 }
350 
351 /* Encrypt and write a CharString. */
352 static int
stream_write_encrypted(stream * s,const void * ptr,uint count)353 stream_write_encrypted(stream *s, const void *ptr, uint count)
354 {
355     const byte *const data = ptr;
356     crypt_state state = crypt_charstring_seed;
357     byte buf[50];		/* arbitrary */
358     uint left, n;
359     int code = 0;
360 
361     for (left = count; left > 0; left -= n) {
362 	n = min(left, sizeof(buf));
363 	gs_type1_encrypt(buf, data + count - left, n, &state);
364 	code = stream_write(s, buf, n);
365     }
366     return code;
367 }
368 
369 /* Write one FontInfo entry. */
370 static void
write_font_info(stream * s,const char * key,const gs_const_string * pvalue,int do_write)371 write_font_info(stream *s, const char *key, const gs_const_string *pvalue,
372 		int do_write)
373 {
374     if (do_write) {
375 	pprints1(s, "\n/%s ", key);
376 	s_write_ps_string(s, pvalue->data, pvalue->size, PRINT_HEX_NOT_OK);
377 	stream_puts(s, " def");
378     }
379 }
380 
381 /* Write the definition of a Type 1 font. */
382 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])383 psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
384 		      gs_glyph *orig_subset_glyphs, uint orig_subset_size,
385 		      const gs_const_string *alt_font_name, int lengths[3])
386 {
387     stream *es = s;
388     long start = stell(s);
389     param_printer_params_t ppp;
390     printer_param_list_t rlist;
391     gs_param_list *const plist = (gs_param_list *)&rlist;
392     stream AXE_stream;
393     stream_AXE_state AXE_state;
394     byte AXE_buf[200];		/* arbitrary */
395     stream exE_stream;
396     stream_exE_state exE_state;
397     byte exE_buf[200];		/* arbitrary */
398     psf_outline_glyphs_t glyphs;
399     int lenIV = pfont->data.lenIV;
400     int (*write_CharString)(stream *, const void *, uint) = stream_write;
401     int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs,
402 				     orig_subset_size);
403 
404     if (code < 0)
405 	return code;
406 
407     /* Initialize the parameter printer. */
408 
409     ppp = param_printer_params_default;
410     ppp.item_suffix = " def\n";
411     ppp.print_ok =
412 	(options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) |
413 	PRINT_HEX_NOT_OK;
414     code = s_init_param_printer(&rlist, &ppp, s);
415     if (code < 0)
416 	return code;
417 
418     /* Write the font header. */
419 
420     stream_puts(s, "%!FontType1-1.0: ");
421     write_font_name(s, pfont, alt_font_name, false);
422     stream_puts(s, "\n11 dict begin\n");
423 
424     /* Write FontInfo. */
425 
426     stream_puts(s, "/FontInfo 5 dict dup begin");
427     {
428 	gs_font_info_t info;
429 	int code = pfont->procs.font_info((gs_font *)pfont, NULL,
430 			(FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
431 			 FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
432 					  &info);
433 
434 	if (code >= 0) {
435 	    write_font_info(s, "Copyright", &info.Copyright,
436 			    info.members & FONT_INFO_COPYRIGHT);
437 	    write_font_info(s, "Notice", &info.Notice,
438 			    info.members & FONT_INFO_NOTICE);
439 	    write_font_info(s, "FamilyName", &info.FamilyName,
440 			    info.members & FONT_INFO_FAMILY_NAME);
441 	    write_font_info(s, "FullName", &info.FullName,
442 			    info.members & FONT_INFO_FULL_NAME);
443 	}
444     }
445     stream_puts(s, "\nend readonly def\n");
446 
447     /* Write the main font dictionary. */
448 
449     stream_puts(s, "/FontName ");
450     write_font_name(s, pfont, alt_font_name, true);
451     stream_puts(s, " def\n");
452     code = write_Encoding(s, pfont, options, glyphs.subset_glyphs,
453 			  glyphs.subset_size, glyphs.notdef);
454     if (code < 0)
455 	return code;
456     pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
457 	     pfont->FontMatrix.xx, pfont->FontMatrix.xy,
458 	     pfont->FontMatrix.yx, pfont->FontMatrix.yy,
459 	     pfont->FontMatrix.tx, pfont->FontMatrix.ty);
460     write_uid(s, &pfont->UID);
461     pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n",
462 	     pfont->FontBBox.p.x, pfont->FontBBox.p.y,
463 	     pfont->FontBBox.q.x, pfont->FontBBox.q.y);
464     {
465 	static const gs_param_item_t font_items[] = {
466 	    {"FontType", gs_param_type_int,
467 	     offset_of(gs_font_type1, FontType)},
468 	    {"PaintType", gs_param_type_int,
469 	     offset_of(gs_font_type1, PaintType)},
470 	    {"StrokeWidth", gs_param_type_float,
471 	     offset_of(gs_font_type1, StrokeWidth)},
472 	    gs_param_item_end
473 	};
474 
475 	code = gs_param_write_items(plist, pfont, NULL, font_items);
476 	if (code < 0)
477 	    return code;
478     }
479     {
480 	const gs_type1_data *const pdata = &pfont->data;
481 
482 	write_float_array(plist, "WeightVector", pdata->WeightVector.values,
483 			  pdata->WeightVector.count);
484     }
485     stream_puts(s, "currentdict end\n");
486 
487     /* Write the Private dictionary. */
488 
489     if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) {
490 	/* We'll have to encrypt the CharStrings. */
491 	lenIV = 0;
492 	write_CharString = stream_write_encrypted;
493     }
494     if (options & WRITE_TYPE1_EEXEC) {
495 	stream_puts(s, "currentfile eexec\n");
496 	lengths[0] = stell(s) - start;
497 	start = stell(s);
498 	if (options & WRITE_TYPE1_ASCIIHEX) {
499 	    s_init(&AXE_stream, s->memory);
500 	    s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL);
501 	    AXE_state.EndOfData = false;
502 	    s_init_filter(&AXE_stream, (stream_state *)&AXE_state,
503 			  AXE_buf, sizeof(AXE_buf), es);
504 	    es = &AXE_stream;
505 	}
506 	s_init(&exE_stream, s->memory);
507 	s_init_state((stream_state *)&exE_state, &s_exE_template, NULL);
508 	exE_state.cstate = 55665;
509 	s_init_filter(&exE_stream, (stream_state *)&exE_state,
510 		      exE_buf, sizeof(exE_buf), es);
511 	es = &exE_stream;
512 	/*
513 	 * Note: eexec encryption always writes/skips 4 initial bytes, not
514 	 * the number of initial bytes given by pdata->lenIV.
515 	 */
516 	stream_puts(es, "****");
517     }
518     code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size,
519 			 glyphs.notdef, lenIV, write_CharString, &ppp);
520     if (code < 0)
521 	return code;
522     stream_puts(es, "dup/FontName get exch definefont pop\n");
523     if (options & WRITE_TYPE1_EEXEC) {
524 	if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK))
525 	    stream_puts(es, "mark ");
526 	stream_puts(es, "currentfile closefile\n");
527 	s_close_filters(&es, s);
528 	lengths[1] = stell(s) - start;
529 	start = stell(s);
530 	if (options & WRITE_TYPE1_EEXEC_PAD) {
531 	    int i;
532 
533 	    for (i = 0; i < 8; ++i)
534 		stream_puts(s, "\n0000000000000000000000000000000000000000000000000000000000000000");
535 	    stream_puts(s, "\ncleartomark\n");
536 	}
537 	lengths[2] = stell(s) - start;
538     } else {
539 	lengths[0] = stell(s) - start;
540 	lengths[1] = lengths[2] = 0;
541     }
542 
543     /* Wrap up. */
544 
545     s_release_param_printer(&rlist);
546     return 0;
547 }
548