1 /* Copyright (C) 1999, 2000, 2001 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevpsf2.c,v 1.33 2004/11/19 04:39:11 ray Exp $ */
18 /* Write an embedded CFF font with either Type 1 or Type 2 CharStrings */
19 #include "math_.h" /* for fabs */
20 #include "memory_.h"
21 #include "gx.h"
22 #include "gxarith.h"
23 #include "gscencs.h"
24 #include "gserrors.h"
25 #include "gsccode.h"
26 #include "gscrypt1.h"
27 #include "gsmatrix.h"
28 #include "gsutil.h"
29 #include "gxfixed.h"
30 #include "gxfont.h"
31 #include "gxfont1.h"
32 #include "gxfcid.h"
33 #include "stream.h"
34 #include "sfilter.h"
35 #include "gdevpsf.h"
36
37 /* Define additional opcodes used in Dicts, but not in CharStrings. */
38 #define CD_LONGINT 29
39 #define CD_REAL 30
40
41 /* Define the count of standard strings. */
42 #define NUM_STD_STRINGS 391
43
44 /* Define whether or not to skip writing an empty Subrs Index. */
45 #define SKIP_EMPTY_SUBRS
46
47 /* Define the structure for the string table. */
48 typedef struct cff_string_item_s {
49 gs_const_string key;
50 int index1; /* index + 1, 0 means empty */
51 } cff_string_item_t;
52 typedef struct cff_string_table_s {
53 cff_string_item_t *items;
54 int count;
55 int size;
56 uint total;
57 int reprobe;
58 } cff_string_table_t;
59
60 /* Define the state of the CFF writer. */
61 typedef struct cff_writer_s {
62 int options;
63 stream *strm;
64 gs_font_base *pfont; /* type1 or cid0 */
65 glyph_data_proc_t glyph_data;
66 int offset_size;
67 long start_pos;
68 cff_string_table_t std_strings;
69 cff_string_table_t strings;
70 gs_int_rect FontBBox;
71 } cff_writer_t;
72 typedef struct cff_glyph_subset_s {
73 psf_outline_glyphs_t glyphs;
74 int num_encoded; /* glyphs.subset_data[1..num_e] are encoded */
75 int num_encoded_chars; /* Encoding has num_e_chars defined entries */
76 } cff_glyph_subset_t;
77
78 /* ---------------- Output utilities ---------------- */
79
80 /* ------ String tables ------ */
81
82 /* Initialize a string table. */
83 private void
cff_string_table_init(cff_string_table_t * pcst,cff_string_item_t * items,int size)84 cff_string_table_init(cff_string_table_t *pcst, cff_string_item_t *items,
85 int size)
86 {
87 int reprobe = 17;
88
89 memset(items, 0, size * sizeof(*items));
90 pcst->items = items;
91 pcst->count = 0;
92 pcst->size = size;
93 while (reprobe != 1 && igcd(size, reprobe) != 1)
94 reprobe = (reprobe * 2 + 1) % size;
95 pcst->total = 0;
96 pcst->reprobe = reprobe;
97 }
98
99 /* Add a string to a string table. */
100 private int
cff_string_add(cff_string_table_t * pcst,const byte * data,uint size)101 cff_string_add(cff_string_table_t *pcst, const byte *data, uint size)
102 {
103 int index;
104
105 if (pcst->count >= pcst->size)
106 return_error(gs_error_limitcheck);
107 index = pcst->count++;
108 pcst->items[index].key.data = data;
109 pcst->items[index].key.size = size;
110 pcst->total += size;
111 return index;
112 }
113
114 /* Look up a string, optionally adding it. */
115 /* Return 1 if the string was added. */
116 private int
cff_string_index(cff_string_table_t * pcst,const byte * data,uint size,bool enter,int * pindex)117 cff_string_index(cff_string_table_t *pcst, const byte *data, uint size,
118 bool enter, int *pindex)
119 {
120 /****** FAILS IF TABLE FULL AND KEY MISSING ******/
121 int j = (size == 0 ? 0 : data[0] * 23 + data[size - 1] * 59 + size);
122 int index, c = 0;
123
124 while ((index = pcst->items[j %= pcst->size].index1) != 0) {
125 --index;
126 if (!bytes_compare(pcst->items[index].key.data,
127 pcst->items[index].key.size, data, size)) {
128 *pindex = index;
129 return 0;
130 }
131 j += pcst->reprobe;
132 if (++c >= pcst->size)
133 break;
134 }
135 if (!enter)
136 return_error(gs_error_undefined);
137 index = cff_string_add(pcst, data, size);
138 if (index < 0)
139 return index;
140 pcst->items[j].index1 = index + 1;
141 *pindex = index;
142 return 1;
143 }
144
145 /* Get the SID for a string or a glyph. */
146 private int
cff_string_sid(cff_writer_t * pcw,const byte * data,uint size)147 cff_string_sid(cff_writer_t *pcw, const byte *data, uint size)
148 {
149 int index;
150 int code = cff_string_index(&pcw->std_strings, data, size, false, &index);
151
152 if (code < 0) {
153 code = cff_string_index(&pcw->strings, data, size, true, &index);
154 if (code < 0)
155 return code;
156 index += NUM_STD_STRINGS;
157 }
158 return index;
159 }
160 private int
cff_glyph_sid(cff_writer_t * pcw,gs_glyph glyph)161 cff_glyph_sid(cff_writer_t *pcw, gs_glyph glyph)
162 {
163 gs_const_string str;
164 int code =
165 pcw->pfont->procs.glyph_name((gs_font *)pcw->pfont, glyph, &str);
166
167 if (code < 0)
168 return code;
169 return cff_string_sid(pcw, str.data, str.size);
170 }
171
172 /* ------ Low level ------ */
173
174 private void
put_card16(cff_writer_t * pcw,uint c16)175 put_card16(cff_writer_t *pcw, uint c16)
176 {
177 sputc(pcw->strm, (byte)(c16 >> 8));
178 sputc(pcw->strm, (byte)c16);
179 }
180 private int
offset_size(uint offset)181 offset_size(uint offset)
182 {
183 int size = 1;
184
185 while (offset > 255)
186 offset >>= 8, ++size;
187 return size;
188 }
189 private void
put_offset(cff_writer_t * pcw,int offset)190 put_offset(cff_writer_t *pcw, int offset)
191 {
192 int i;
193
194 for (i = pcw->offset_size - 1; i >= 0; --i)
195 sputc(pcw->strm, (byte)(offset >> (i * 8)));
196 }
197 private int
put_bytes(stream * s,const byte * ptr,uint count)198 put_bytes(stream * s, const byte *ptr, uint count)
199 {
200 uint used;
201
202 sputs(s, ptr, count, &used);
203 return (int)used;
204 }
205 private int
check_ioerror(stream * s)206 check_ioerror(stream * s)
207 {
208 uint used;
209
210 return sputs(s, (byte *)&used, 0, &used);
211 }
212
213 /* ------ Data types ------ */
214
215 #define CE_OFFSET 32
216 private void
cff_put_op(cff_writer_t * pcw,int op)217 cff_put_op(cff_writer_t *pcw, int op)
218 {
219 if (op >= CE_OFFSET) {
220 sputc(pcw->strm, cx_escape);
221 sputc(pcw->strm, (byte)(op - CE_OFFSET));
222 } else
223 sputc(pcw->strm, (byte)op);
224 }
225 private void
cff_put_int(cff_writer_t * pcw,int i)226 cff_put_int(cff_writer_t *pcw, int i)
227 {
228 stream *s = pcw->strm;
229
230 if (i >= -107 && i <= 107)
231 sputc(s, (byte)(i + 139));
232 else if (i <= 1131 && i >= 0)
233 put_card16(pcw, (c_pos2_0 << 8) + i - 108);
234 else if (i >= -1131 && i < 0)
235 put_card16(pcw, (c_neg2_0 << 8) - i - 108);
236 else if (i >= -32768 && i <= 32767) {
237 sputc(s, c2_shortint);
238 put_card16(pcw, i & 0xffff);
239 } else {
240 sputc(s, CD_LONGINT);
241 put_card16(pcw, i >> 16);
242 put_card16(pcw, i & 0xffff);
243 }
244 }
245 private void
cff_put_int_value(cff_writer_t * pcw,int i,int op)246 cff_put_int_value(cff_writer_t *pcw, int i, int op)
247 {
248 cff_put_int(pcw, i);
249 cff_put_op(pcw, op);
250 }
251 private void
cff_put_int_if_ne(cff_writer_t * pcw,int i,int i_default,int op)252 cff_put_int_if_ne(cff_writer_t *pcw, int i, int i_default, int op)
253 {
254 if (i != i_default)
255 cff_put_int_value(pcw, i, op);
256 }
257 private void
cff_put_bool(cff_writer_t * pcw,bool b)258 cff_put_bool(cff_writer_t *pcw, bool b)
259 {
260 cff_put_int(pcw, (b ? 1 : 0));
261 }
262 private void
cff_put_bool_value(cff_writer_t * pcw,bool b,int op)263 cff_put_bool_value(cff_writer_t *pcw, bool b, int op)
264 {
265 cff_put_bool(pcw, b);
266 cff_put_op(pcw, op);
267 }
268 private void
cff_put_real(cff_writer_t * pcw,floatp f)269 cff_put_real(cff_writer_t *pcw, floatp f)
270 {
271 if (f == (int)f)
272 cff_put_int(pcw, (int)f);
273 else {
274 /* Use decimal representation. */
275 char str[50];
276 byte b = 0xff;
277 const char *p;
278
279 sprintf(str, "%g", f);
280 sputc(pcw->strm, CD_REAL);
281 for (p = str; ; ++p) {
282 int digit;
283
284 switch (*p) {
285 case 0:
286 goto done;
287 case '.':
288 digit = 0xa; break;
289 case '-':
290 digit = 0xe; break;
291 case 'e': case 'E':
292 if (p[1] == '-')
293 digit = 0xc, ++p;
294 else
295 digit = 0xb;
296 break;
297 case '0': case '1': case '2': case '3': case '4':
298 case '5': case '6': case '7': case '8': case '9':
299 digit = *p - '0';
300 break;
301 default: /* can't happen */
302 digit = 0xd; /* invalid */
303 break;
304 }
305 if (b == 0xff)
306 b = (digit << 4) + 0xf;
307 else {
308 sputc(pcw->strm, (byte)((b & 0xf0) + digit));
309 b = 0xff;
310 }
311 }
312 done:
313 sputc(pcw->strm, b);
314 }
315 }
316 private void
cff_put_real_value(cff_writer_t * pcw,floatp f,int op)317 cff_put_real_value(cff_writer_t *pcw, floatp f, int op)
318 {
319 cff_put_real(pcw, f);
320 cff_put_op(pcw, op);
321 }
322 private void
cff_put_real_if_ne(cff_writer_t * pcw,floatp f,floatp f_default,int op)323 cff_put_real_if_ne(cff_writer_t *pcw, floatp f, floatp f_default, int op)
324 {
325 if ((float)f != (float)f_default)
326 cff_put_real_value(pcw, f, op);
327 }
328 private void
cff_put_real_deltarray(cff_writer_t * pcw,const float * pf,int count,int op)329 cff_put_real_deltarray(cff_writer_t *pcw, const float *pf, int count, int op)
330 {
331 float prev = 0;
332 int i;
333
334 if (count <= 0)
335 return;
336 for (i = 0; i < count; ++i) {
337 float f = pf[i];
338
339 cff_put_real(pcw, f - prev);
340 prev = f;
341 }
342 cff_put_op(pcw, op);
343 }
344 private int
cff_put_string(cff_writer_t * pcw,const byte * data,uint size)345 cff_put_string(cff_writer_t *pcw, const byte *data, uint size)
346 {
347 int sid = cff_string_sid(pcw, data, size);
348
349 if (sid < 0)
350 return sid;
351 cff_put_int(pcw, sid);
352 return 0;
353 }
354 private int
cff_put_string_value(cff_writer_t * pcw,const byte * data,uint size,int op)355 cff_put_string_value(cff_writer_t *pcw, const byte *data, uint size, int op)
356 {
357 int code = cff_put_string(pcw, data, size);
358
359 if (code >= 0)
360 cff_put_op(pcw, op);
361 return code;
362 }
363 private int
cff_extra_lenIV(const cff_writer_t * pcw,const gs_font_type1 * pfont)364 cff_extra_lenIV(const cff_writer_t *pcw, const gs_font_type1 *pfont)
365 {
366 return (pcw->options & WRITE_TYPE2_NO_LENIV ?
367 max(pfont->data.lenIV, 0) : 0);
368 }
369 private bool
cff_convert_charstrings(const cff_writer_t * pcw,const gs_font_base * pfont)370 cff_convert_charstrings(const cff_writer_t *pcw, const gs_font_base *pfont)
371 {
372 return (pfont->FontType != ft_encrypted2 &&
373 (pcw->options & WRITE_TYPE2_CHARSTRINGS) != 0);
374 }
375 private int
cff_put_CharString(cff_writer_t * pcw,const byte * data,uint size,gs_font_type1 * pfont)376 cff_put_CharString(cff_writer_t *pcw, const byte *data, uint size,
377 gs_font_type1 *pfont)
378 {
379 int lenIV = pfont->data.lenIV;
380 stream *s = pcw->strm;
381
382 if (cff_convert_charstrings(pcw, (gs_font_base *)pfont)) {
383 gs_glyph_data_t gdata;
384 int code;
385
386 gdata.memory = pfont->memory;
387 gs_glyph_data_from_string(&gdata, data, size, NULL);
388 code = psf_convert_type1_to_type2(s, &gdata, pfont);
389 if (code < 0)
390 return code;
391 } else if (lenIV < 0 || !(pcw->options & WRITE_TYPE2_NO_LENIV))
392 put_bytes(s, data, size);
393 else if (size >= lenIV) {
394 /* Remove encryption. */
395 crypt_state state = crypt_charstring_seed;
396 byte buf[50]; /* arbitrary */
397 uint left, n;
398
399 for (left = lenIV; left > 0; left -= n) {
400 n = min(left, sizeof(buf));
401 gs_type1_decrypt(buf, data + lenIV - left, n, &state);
402 }
403 for (left = size - lenIV; left > 0; left -= n) {
404 n = min(left, sizeof(buf));
405 gs_type1_decrypt(buf, data + size - left, n, &state);
406 put_bytes(s, buf, n);
407 }
408 }
409 return 0;
410 }
411 private uint
cff_Index_size(uint count,uint total)412 cff_Index_size(uint count, uint total)
413 {
414 return (count == 0 ? 2 :
415 3 + offset_size(total + 1) * (count + 1) + total);
416 }
417 private void
cff_put_Index_header(cff_writer_t * pcw,uint count,uint total)418 cff_put_Index_header(cff_writer_t *pcw, uint count, uint total)
419 {
420 put_card16(pcw, count);
421 if (count > 0) {
422 pcw->offset_size = offset_size(total + 1);
423 sputc(pcw->strm, (byte)pcw->offset_size);
424 put_offset(pcw, 1);
425 }
426 }
427 private void
cff_put_Index(cff_writer_t * pcw,const cff_string_table_t * pcst)428 cff_put_Index(cff_writer_t *pcw, const cff_string_table_t *pcst)
429 {
430 uint j, offset;
431
432 if (pcst->count == 0) {
433 put_card16(pcw, 0);
434 return;
435 }
436 cff_put_Index_header(pcw, pcst->count, pcst->total);
437 for (j = 0, offset = 1; j < pcst->count; ++j) {
438 offset += pcst->items[j].key.size;
439 put_offset(pcw, offset);
440 }
441 for (j = 0; j < pcst->count; ++j)
442 put_bytes(pcw->strm, pcst->items[j].key.data, pcst->items[j].key.size);
443 }
444
445 /* ---------------- Main code ---------------- */
446
447 /* ------ Header ------ */
448
449 /* Write the header, setting offset_size. */
450 private int
cff_write_header(cff_writer_t * pcw,uint end_offset)451 cff_write_header(cff_writer_t *pcw, uint end_offset)
452 {
453 pcw->offset_size = (end_offset > 0x7fff ? 3 : 2);
454 put_bytes(pcw->strm, (const byte *)"\001\000\004", 3);
455 sputc(pcw->strm, (byte)pcw->offset_size);
456 return 0;
457 }
458
459 /* ------ Top Dict ------ */
460
461 /*
462 * There are 3 variants of this: Type 1 / Type 2 font, CIDFontType 0
463 * CIDFont, and FDArray entry for CIDFont.
464 */
465
466 typedef enum {
467 TOP_version = 0,
468 TOP_Notice = 1,
469 TOP_FullName = 2,
470 TOP_FamilyName = 3,
471 TOP_Weight = 4,
472 TOP_FontBBox = 5,
473 TOP_UniqueID = 13,
474 TOP_XUID = 14,
475 TOP_charset = 15, /* (offset or predefined index) */
476 #define charset_ISOAdobe 0
477 #define charset_Expert 1
478 #define charset_ExpertSubset 2
479 #define charset_DEFAULT 0
480 TOP_Encoding = 16, /* (offset or predefined index) */
481 #define Encoding_Standard 0
482 #define Encoding_Expert 1
483 #define Encoding_DEFAULT 0
484 TOP_CharStrings = 17, /* (offset) */
485 TOP_Private = 18, /* (offset) */
486 TOP_Copyright = 32,
487 TOP_isFixedPitch = 33,
488 #define isFixedPitch_DEFAULT false
489 TOP_ItalicAngle = 34,
490 #define ItalicAngle_DEFAULT 0
491 TOP_UnderlinePosition = 35,
492 #define UnderlinePosition_DEFAULT (-100)
493 TOP_UnderlineThickness = 36,
494 #define UnderlineThickness_DEFAULT 50
495 TOP_PaintType = 37,
496 #define PaintType_DEFAULT 0
497 TOP_CharstringType = 38,
498 #define CharstringType_DEFAULT 2
499 TOP_FontMatrix = 39, /* default is [0.001 0 0 0.001 0 0] */
500 TOP_StrokeWidth = 40,
501 #define StrokeWidth_DEFAULT 0
502 TOP_ROS = 62,
503 TOP_CIDFontVersion = 63,
504 #define CIDFontVersion_DEFAULT 0
505 TOP_CIDFontRevision = 64,
506 #define CIDFontRevision_DEFAULT 0
507 TOP_CIDFontType = 65,
508 #define CIDFontType_DEFAULT 0
509 TOP_CIDCount = 66,
510 #define CIDCount_DEFAULT 8720
511 TOP_UIDBase = 67,
512 TOP_FDArray = 68, /* (offset) */
513 TOP_FDSelect = 69, /* (offset) */
514 TOP_FontName = 70 /* only used in FDArray "fonts" */
515 } Top_op;
516
517 private int
cff_get_Top_info_common(cff_writer_t * pcw,gs_font_base * pbfont,bool full_info,gs_font_info_t * pinfo)518 cff_get_Top_info_common(cff_writer_t *pcw, gs_font_base *pbfont,
519 bool full_info, gs_font_info_t *pinfo)
520 {
521 pinfo->Flags_requested = FONT_IS_FIXED_WIDTH;
522 /* Preset defaults */
523 pinfo->members = 0;
524 pinfo->Flags = pinfo->Flags_returned = 0;
525 pinfo->ItalicAngle = ItalicAngle_DEFAULT;
526 pinfo->UnderlinePosition = UnderlinePosition_DEFAULT;
527 pinfo->UnderlineThickness = UnderlineThickness_DEFAULT;
528 return pbfont->procs.font_info
529 ((gs_font *)pbfont, NULL,
530 (full_info ?
531 FONT_INFO_FLAGS | FONT_INFO_ITALIC_ANGLE |
532 FONT_INFO_UNDERLINE_POSITION |
533 FONT_INFO_UNDERLINE_THICKNESS : 0) |
534 (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
535 FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
536 pinfo);
537 }
538 private void
cff_write_Top_common(cff_writer_t * pcw,gs_font_base * pbfont,bool write_FontMatrix,const gs_font_info_t * pinfo)539 cff_write_Top_common(cff_writer_t *pcw, gs_font_base *pbfont,
540 bool write_FontMatrix, const gs_font_info_t *pinfo)
541 {
542 /*
543 * The Adobe documentation doesn't make it at all clear that if the
544 * FontMatrix is missing (defaulted) in a CFF CIDFont, all of the
545 * FontMatrices of the subfonts in FDArray are multiplied by 1000.
546 * (This is documented for ordinary CIDFonts, but not for CFF CIDFonts.)
547 * Because of this, the FontMatrix for a CFF CIDFont must be written
548 * even if if is the default. write_FontMatrix controls this.
549 */
550 /* (version) */
551 if (pinfo->members & FONT_INFO_NOTICE)
552 cff_put_string_value(pcw, pinfo->Notice.data, pinfo->Notice.size,
553 TOP_Notice);
554 if (pinfo->members & FONT_INFO_FULL_NAME)
555 cff_put_string_value(pcw, pinfo->FullName.data, pinfo->FullName.size,
556 TOP_FullName);
557 if (pinfo->members & FONT_INFO_FAMILY_NAME)
558 cff_put_string_value(pcw, pinfo->FamilyName.data,
559 pinfo->FamilyName.size, TOP_FamilyName);
560 if (pcw->FontBBox.p.x != 0 || pcw->FontBBox.p.y != 0 ||
561 pcw->FontBBox.q.x != 0 || pcw->FontBBox.q.y != 0
562 ) {
563 /* An omitted FontBBox is equivalent to an empty one. */
564 /*
565 * Since Acrobat Reader 4 on Solaris doesn't like
566 * an omitted FontBBox, we copy it here from
567 * the font descriptor, because the base font
568 * is allowed to omit it's FontBBox.
569 */
570 cff_put_real(pcw, pcw->FontBBox.p.x);
571 cff_put_real(pcw, pcw->FontBBox.p.y);
572 cff_put_real(pcw, pcw->FontBBox.q.x);
573 cff_put_real(pcw, pcw->FontBBox.q.y);
574 cff_put_op(pcw, TOP_FontBBox);
575 }
576 if (uid_is_UniqueID(&pbfont->UID))
577 cff_put_int_value(pcw, pbfont->UID.id, TOP_UniqueID);
578 else if (uid_is_XUID(&pbfont->UID)) {
579 int j;
580
581 for (j = 0; j < uid_XUID_size(&pbfont->UID); ++j)
582 cff_put_int(pcw, uid_XUID_values(&pbfont->UID)[j]);
583 cff_put_op(pcw, TOP_XUID);
584 }
585 /*
586 * Acrobat Reader 3 gives an error if a CFF font includes any of the
587 * following opcodes.
588 */
589 if (!(pcw->options & WRITE_TYPE2_AR3)) {
590 if (pinfo->members & FONT_INFO_COPYRIGHT)
591 cff_put_string_value(pcw, pinfo->Copyright.data,
592 pinfo->Copyright.size, TOP_Copyright);
593 if (pinfo->Flags & pinfo->Flags_returned & FONT_IS_FIXED_WIDTH)
594 cff_put_bool_value(pcw, true, TOP_isFixedPitch);
595 cff_put_real_if_ne(pcw, pinfo->ItalicAngle, ItalicAngle_DEFAULT,
596 TOP_ItalicAngle);
597 cff_put_int_if_ne(pcw, pinfo->UnderlinePosition,
598 UnderlinePosition_DEFAULT, TOP_UnderlinePosition);
599 cff_put_int_if_ne(pcw, pinfo->UnderlineThickness,
600 UnderlineThickness_DEFAULT, TOP_UnderlineThickness);
601 cff_put_int_if_ne(pcw, pbfont->PaintType, PaintType_DEFAULT,
602 TOP_PaintType);
603 }
604 {
605 static const gs_matrix fm_default = {
606 constant_matrix_body(0.001, 0, 0, 0.001, 0, 0)
607 };
608
609 if (write_FontMatrix ||
610 pbfont->FontMatrix.xx != fm_default.xx ||
611 pbfont->FontMatrix.xy != 0 || pbfont->FontMatrix.yx != 0 ||
612 pbfont->FontMatrix.yy != fm_default.yy ||
613 pbfont->FontMatrix.tx != 0 || pbfont->FontMatrix.ty != 0
614 ) {
615 cff_put_real(pcw, pbfont->FontMatrix.xx);
616 cff_put_real(pcw, pbfont->FontMatrix.xy);
617 cff_put_real(pcw, pbfont->FontMatrix.yx);
618 cff_put_real(pcw, pbfont->FontMatrix.yy);
619 cff_put_real(pcw, pbfont->FontMatrix.tx);
620 cff_put_real(pcw, pbfont->FontMatrix.ty);
621 cff_put_op(pcw, TOP_FontMatrix);
622 }
623 }
624 cff_put_real_if_ne(pcw, pbfont->StrokeWidth, StrokeWidth_DEFAULT,
625 TOP_StrokeWidth);
626 }
627
628 /* Type 1 or Type 2 font */
629 private void
cff_write_Top_font(cff_writer_t * pcw,uint Encoding_offset,uint charset_offset,uint CharStrings_offset,uint Private_offset,uint Private_size)630 cff_write_Top_font(cff_writer_t *pcw, uint Encoding_offset,
631 uint charset_offset, uint CharStrings_offset,
632 uint Private_offset, uint Private_size)
633 {
634 gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
635 gs_font_info_t info;
636
637 cff_get_Top_info_common(pcw, pbfont, true, &info);
638 cff_write_Top_common(pcw, pbfont, false, &info);
639 cff_put_int(pcw, Private_size);
640 cff_put_int_value(pcw, Private_offset, TOP_Private);
641 cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
642 cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
643 cff_put_int_if_ne(pcw, Encoding_offset, Encoding_DEFAULT, TOP_Encoding);
644 {
645 int type = (pcw->options & WRITE_TYPE2_CHARSTRINGS ? 2 :
646 pbfont->FontType == ft_encrypted2 ? 2 : 1);
647
648 cff_put_int_if_ne(pcw, type, CharstringType_DEFAULT,
649 TOP_CharstringType);
650 }
651 }
652
653 /* CIDFontType 0 CIDFont */
654 private void
cff_write_ROS(cff_writer_t * pcw,const gs_cid_system_info_t * pcidsi)655 cff_write_ROS(cff_writer_t *pcw, const gs_cid_system_info_t *pcidsi)
656 {
657 cff_put_string(pcw, pcidsi->Registry.data, pcidsi->Registry.size);
658 cff_put_string(pcw, pcidsi->Ordering.data, pcidsi->Ordering.size);
659 cff_put_int_value(pcw, pcidsi->Supplement, TOP_ROS);
660 }
661 private void
cff_write_Top_cidfont(cff_writer_t * pcw,uint charset_offset,uint CharStrings_offset,uint FDSelect_offset,uint Font_offset,const gs_font_info_t * pinfo)662 cff_write_Top_cidfont(cff_writer_t *pcw, uint charset_offset,
663 uint CharStrings_offset, uint FDSelect_offset,
664 uint Font_offset, const gs_font_info_t *pinfo)
665 {
666 gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
667 gs_font_cid0 *pfont = (gs_font_cid0 *)pbfont;
668
669 cff_write_ROS(pcw, &pfont->cidata.common.CIDSystemInfo);
670 cff_write_Top_common(pcw, pbfont, true, pinfo); /* full_info = true */
671 cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
672 cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
673 /*
674 * CIDFontVersion and CIDFontRevision aren't used consistently,
675 * so we don't currently write them. CIDFontType is always 0.
676 */
677 cff_put_int_if_ne(pcw, pfont->cidata.common.CIDCount, CIDCount_DEFAULT,
678 TOP_CIDCount);
679 /* We don't use UIDBase. */
680 cff_put_int_value(pcw, Font_offset, TOP_FDArray);
681 cff_put_int_value(pcw, FDSelect_offset, TOP_FDSelect);
682 }
683
684 /* FDArray Index for CIDFont (offsets only) */
685 private void
cff_write_FDArray_offsets(cff_writer_t * pcw,uint * FDArray_offsets,int num_fonts)686 cff_write_FDArray_offsets(cff_writer_t *pcw, uint *FDArray_offsets,
687 int num_fonts)
688 {
689 int j;
690
691 cff_put_Index_header(pcw, num_fonts,
692 FDArray_offsets[num_fonts] - FDArray_offsets[0]);
693 for (j = 1; j <= num_fonts; ++j)
694 put_offset(pcw, FDArray_offsets[j] - FDArray_offsets[0] + 1);
695 }
696
697 /* FDArray entry for CIDFont */
698 private void
cff_write_Top_fdarray(cff_writer_t * pcw,gs_font_base * pbfont,uint Private_offset,uint Private_size)699 cff_write_Top_fdarray(cff_writer_t *pcw, gs_font_base *pbfont,
700 uint Private_offset, uint Private_size)
701 {
702 const gs_font_name *pfname = &pbfont->font_name;
703 gs_font_info_t info;
704
705 cff_get_Top_info_common(pcw, pbfont, false, &info);
706 cff_write_Top_common(pcw, pbfont, false, &info);
707 cff_put_int(pcw, Private_size);
708 cff_put_int_value(pcw, Private_offset, TOP_Private);
709 if (pfname->size == 0)
710 pfname = &pbfont->key_name;
711 if (pfname->size) {
712 cff_put_string(pcw, pfname->chars, pfname->size);
713 cff_put_op(pcw, TOP_FontName);
714 }
715 }
716
717 /* ------ Private Dict ------ */
718
719 /* Defaults are noted in comments. */
720 typedef enum {
721 PRIVATE_BlueValues = 6, /* (deltarray) */
722 PRIVATE_OtherBlues = 7, /* (deltarray) */
723 PRIVATE_FamilyBlues = 8, /* (deltarray) */
724 PRIVATE_FamilyOtherBlues = 9, /* (deltarray) */
725 PRIVATE_StdHW = 10,
726 PRIVATE_StdVW = 11,
727 PRIVATE_Subrs = 19, /* (offset, relative to Private Dict) */
728 PRIVATE_defaultWidthX = 20,
729 #define defaultWidthX_DEFAULT fixed_0
730 PRIVATE_nominalWidthX = 21,
731 #define nominalWidthX_DEFAULT fixed_0
732 PRIVATE_BlueScale = 41,
733 #define BlueScale_DEFAULT 0.039625
734 PRIVATE_BlueShift = 42,
735 #define BlueShift_DEFAULT 7
736 PRIVATE_BlueFuzz = 43,
737 #define BlueFuzz_DEFAULT 1
738 PRIVATE_StemSnapH = 44, /* (deltarray) */
739 PRIVATE_StemSnapV = 45, /* (deltarray) */
740 PRIVATE_ForceBold = 46,
741 #define ForceBold_DEFAULT false
742 PRIVATE_ForceBoldThreshold = 47,
743 #define ForceBoldThreshold_DEFAULT 0
744 PRIVATE_lenIV = 48,
745 #define lenIV_DEFAULT (-1)
746 PRIVATE_LanguageGroup = 49,
747 #define LanguageGroup_DEFAULT 0
748 PRIVATE_ExpansionFactor = 50,
749 #define ExpansionFactor_DEFAULT 0.06
750 PRIVATE_initialRandomSeed = 51
751 #define initialRandomSeed_DEFAULT 0
752 } Private_op;
753
754 private void
cff_write_Private(cff_writer_t * pcw,uint Subrs_offset,const gs_font_type1 * pfont)755 cff_write_Private(cff_writer_t *pcw, uint Subrs_offset,
756 const gs_font_type1 *pfont)
757 {
758 #define PUT_FLOAT_TABLE(member, op)\
759 cff_put_real_deltarray(pcw, pfont->data.member.values,\
760 pfont->data.member.count, op)
761
762 PUT_FLOAT_TABLE(BlueValues, PRIVATE_BlueValues);
763 PUT_FLOAT_TABLE(OtherBlues, PRIVATE_OtherBlues);
764 PUT_FLOAT_TABLE(FamilyBlues, PRIVATE_FamilyBlues);
765 PUT_FLOAT_TABLE(FamilyOtherBlues, PRIVATE_FamilyOtherBlues);
766 if (pfont->data.StdHW.count > 0)
767 cff_put_real_value(pcw, pfont->data.StdHW.values[0], PRIVATE_StdHW);
768 if (pfont->data.StdVW.count > 0)
769 cff_put_real_value(pcw, pfont->data.StdVW.values[0], PRIVATE_StdVW);
770 if (Subrs_offset)
771 cff_put_int_value(pcw, Subrs_offset, PRIVATE_Subrs);
772 if (pfont->FontType != ft_encrypted) {
773 if (pfont->data.defaultWidthX != defaultWidthX_DEFAULT)
774 cff_put_real_value(pcw, fixed2float(pfont->data.defaultWidthX),
775 PRIVATE_defaultWidthX);
776 if (pfont->data.nominalWidthX != nominalWidthX_DEFAULT)
777 cff_put_real_value(pcw, fixed2float(pfont->data.nominalWidthX),
778 PRIVATE_nominalWidthX);
779 cff_put_int_if_ne(pcw, pfont->data.initialRandomSeed,
780 initialRandomSeed_DEFAULT,
781 PRIVATE_initialRandomSeed);
782 }
783 cff_put_real_if_ne(pcw, pfont->data.BlueScale, BlueScale_DEFAULT,
784 PRIVATE_BlueScale);
785 cff_put_real_if_ne(pcw, pfont->data.BlueShift, BlueShift_DEFAULT,
786 PRIVATE_BlueShift);
787 cff_put_int_if_ne(pcw, pfont->data.BlueFuzz, BlueFuzz_DEFAULT,
788 PRIVATE_BlueFuzz);
789 PUT_FLOAT_TABLE(StemSnapH, PRIVATE_StemSnapH);
790 PUT_FLOAT_TABLE(StemSnapV, PRIVATE_StemSnapV);
791 if (pfont->data.ForceBold != ForceBold_DEFAULT)
792 cff_put_bool_value(pcw, pfont->data.ForceBold,
793 PRIVATE_ForceBold);
794 /* (ForceBoldThreshold) */
795 if (!(pcw->options & WRITE_TYPE2_NO_LENIV))
796 cff_put_int_if_ne(pcw, pfont->data.lenIV, lenIV_DEFAULT,
797 PRIVATE_lenIV);
798 cff_put_int_if_ne(pcw, pfont->data.LanguageGroup, LanguageGroup_DEFAULT,
799 PRIVATE_LanguageGroup);
800 cff_put_real_if_ne(pcw, pfont->data.ExpansionFactor,
801 ExpansionFactor_DEFAULT, PRIVATE_ExpansionFactor);
802 /* initialRandomSeed was handled above */
803
804 #undef PUT_FLOAT_TABLE
805 }
806
807 /* ------ CharStrings Index ------ */
808
809 /* These are separate procedures only for readability. */
810 private int
cff_write_CharStrings_offsets(cff_writer_t * pcw,psf_glyph_enum_t * penum,uint * pcount)811 cff_write_CharStrings_offsets(cff_writer_t *pcw, psf_glyph_enum_t *penum,
812 uint *pcount)
813 {
814 gs_font_base *pfont = pcw->pfont;
815 int offset;
816 gs_glyph glyph;
817 uint count;
818 stream poss;
819 int code;
820
821 s_init(&poss, NULL);
822 psf_enumerate_glyphs_reset(penum);
823 for (glyph = gs_no_glyph, count = 0, offset = 1;
824 (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
825 ++count) {
826 gs_glyph_data_t gdata;
827 gs_font_type1 *pfd;
828 int gcode;
829
830 gdata.memory = pfont->memory;
831 if (code == 0 &&
832 (gcode = pcw->glyph_data(pfont, glyph, &gdata, &pfd)) >= 0
833 ) {
834 int extra_lenIV;
835
836 if (gdata.bits.size >= (extra_lenIV = cff_extra_lenIV(pcw, pfd))) {
837 if (cff_convert_charstrings(pcw, (gs_font_base *)pfd)) {
838 swrite_position_only(&poss);
839 code = psf_convert_type1_to_type2(&poss, &gdata, pfd);
840 if (code < 0)
841 return code;
842 offset += stell(&poss);
843 } else
844 offset += gdata.bits.size - extra_lenIV;
845 }
846 gs_glyph_data_free(&gdata, "cff_write_CharStrings_offsets");
847 }
848 put_offset(pcw, offset);
849 }
850 *pcount = count;
851 return offset - 1;
852 }
853 private void
cff_write_CharStrings(cff_writer_t * pcw,psf_glyph_enum_t * penum,uint charstrings_count,uint charstrings_size)854 cff_write_CharStrings(cff_writer_t *pcw, psf_glyph_enum_t *penum,
855 uint charstrings_count, uint charstrings_size)
856 {
857 gs_font_base *pfont = pcw->pfont;
858 uint ignore_count;
859 gs_glyph glyph;
860 int code;
861
862 cff_put_Index_header(pcw, charstrings_count, charstrings_size);
863 cff_write_CharStrings_offsets(pcw, penum, &ignore_count);
864 psf_enumerate_glyphs_reset(penum);
865 for (glyph = gs_no_glyph;
866 (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
867 ) {
868 gs_glyph_data_t gdata;
869 gs_font_type1 *pfd;
870
871 gdata.memory = pfont->memory;
872 if (code == 0 &&
873 (code = pcw->glyph_data(pfont, glyph, &gdata, &pfd)) >= 0
874 ) {
875 cff_put_CharString(pcw, gdata.bits.data, gdata.bits.size, pfd);
876 gs_glyph_data_free(&gdata, "cff_write_CharStrings");
877 }
878 }
879 }
880
881 /* ------ [G]Subrs Index ------ */
882
883 /*
884 * Currently, we always write all the Subrs, even for subsets.
885 * We will fix this someday.
886 */
887
888 private uint
cff_write_Subrs_offsets(cff_writer_t * pcw,uint * pcount,gs_font_type1 * pfont,bool global)889 cff_write_Subrs_offsets(cff_writer_t *pcw, uint *pcount, gs_font_type1 *pfont,
890 bool global)
891 {
892 int extra_lenIV = cff_extra_lenIV(pcw, pfont);
893 int j, offset;
894 int code;
895 gs_glyph_data_t gdata;
896
897 gdata.memory = pfont->memory;
898 for (j = 0, offset = 1;
899 (code = pfont->data.procs.subr_data(pfont, j, global, &gdata)) !=
900 gs_error_rangecheck;
901 ++j) {
902 if (code >= 0 && gdata.bits.size >= extra_lenIV)
903 offset += gdata.bits.size - extra_lenIV;
904 put_offset(pcw, offset);
905 if (code >= 0)
906 gs_glyph_data_free(&gdata, "cff_write_Subrs_offsets");
907 }
908 *pcount = j;
909 return offset - 1;
910 }
911
912 private void
cff_write_Subrs(cff_writer_t * pcw,uint subrs_count,uint subrs_size,gs_font_type1 * pfont,bool global)913 cff_write_Subrs(cff_writer_t *pcw, uint subrs_count, uint subrs_size,
914 gs_font_type1 *pfont, bool global)
915 {
916 int j;
917 uint ignore_count;
918 gs_glyph_data_t gdata;
919 int code;
920
921 gdata.memory = pfont->memory;
922 cff_put_Index_header(pcw, subrs_count, subrs_size);
923 cff_write_Subrs_offsets(pcw, &ignore_count, pfont, global);
924 for (j = 0;
925 (code = pfont->data.procs.subr_data(pfont, j, global, &gdata)) !=
926 gs_error_rangecheck;
927 ++j) {
928 if (code >= 0) {
929 cff_put_CharString(pcw, gdata.bits.data, gdata.bits.size, pfont);
930 gs_glyph_data_free(&gdata, "cff_write_Subrs");
931 }
932 }
933 }
934
935 /* ------ Encoding/charset ------ */
936
937 private uint
cff_Encoding_size(int num_encoded,int num_encoded_chars)938 cff_Encoding_size(int num_encoded, int num_encoded_chars)
939 {
940 int n = min(num_encoded, 255);
941
942 return 2 + n +
943 (num_encoded_chars > n ?
944 1 + (num_encoded_chars - n) * 3 : 0);
945 }
946
947 private int
cff_write_Encoding(cff_writer_t * pcw,cff_glyph_subset_t * pgsub)948 cff_write_Encoding(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
949 {
950 stream *s = pcw->strm;
951 /* This procedure is only used for Type 1 / Type 2 fonts. */
952 gs_font_type1 *pfont = (gs_font_type1 *)pcw->pfont;
953 byte used[255], index[255], supplement[256];
954 int num_enc = min(pgsub->num_encoded, sizeof(index));
955 int num_enc_chars = pgsub->num_encoded_chars;
956 int nsupp = 0;
957 int j;
958
959 memset(used, 0, num_enc);
960 for (j = 0; j < 256; ++j) {
961 gs_glyph glyph = pfont->procs.encode_char((gs_font *)pfont,
962 (gs_char)j,
963 GLYPH_SPACE_NAME);
964 int i;
965
966 if (glyph == gs_no_glyph || glyph == pgsub->glyphs.notdef)
967 continue;
968 i = psf_sorted_glyphs_index_of(pgsub->glyphs.subset_data + 1,
969 pgsub->num_encoded, glyph);
970 if (i < 0)
971 continue; /* encoded but not in subset */
972 if (i >= sizeof(used) || used[i])
973 supplement[nsupp++] = j;
974 else
975 index[i] = j, used[i] = 1;
976 }
977 sputc(s, (byte)(nsupp ? 0x80 : 0));
978 sputc(s, (byte)num_enc);
979 #ifdef DEBUG
980 if (nsupp != num_enc_chars - num_enc)
981 lprintf3("nsupp = %d, num_enc_chars = %d, num_enc = %d\n",
982 nsupp, num_enc_chars, num_enc);
983 for (j = 0; j < num_enc; ++j)
984 if (!used[j])
985 lprintf2("glyph %d = 0x%lx not used\n", j,
986 pgsub->glyphs.subset_data[j + 1]);
987 #endif
988 put_bytes(s, index, num_enc);
989 if (nsupp) {
990 /* Write supplementary entries for multiply-encoded glyphs. */
991 sputc(s, (byte)nsupp);
992 for (j = 0; j < nsupp; ++j) {
993 byte chr = supplement[j];
994
995 sputc(s, chr);
996 put_card16(pcw,
997 cff_glyph_sid(pcw,
998 pfont->procs.encode_char((gs_font *)pfont,
999 (gs_char)chr,
1000 GLYPH_SPACE_NAME)));
1001 }
1002 }
1003 return 0;
1004 }
1005
1006 private int
cff_write_charset(cff_writer_t * pcw,cff_glyph_subset_t * pgsub)1007 cff_write_charset(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
1008 {
1009 int j;
1010
1011 sputc(pcw->strm, 0);
1012 for (j = 1; j < pgsub->glyphs.subset_size; ++j)
1013 put_card16(pcw, cff_glyph_sid(pcw, pgsub->glyphs.subset_data[j]));
1014 return 0;
1015 }
1016 private int
cff_write_cidset(cff_writer_t * pcw,psf_glyph_enum_t * penum)1017 cff_write_cidset(cff_writer_t *pcw, psf_glyph_enum_t *penum)
1018 {
1019 gs_glyph glyph;
1020 int code;
1021
1022 sputc(pcw->strm, 0);
1023 psf_enumerate_glyphs_reset(penum);
1024 while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1025 /* Skip glyph 0 (the .notdef glyph), which is always first. */
1026 if (glyph != gs_min_cid_glyph)
1027 put_card16(pcw, (uint)(glyph - gs_min_cid_glyph));
1028 }
1029 return min(code, 0);
1030 }
1031
1032 /* ------ FDSelect ------ */
1033
1034 /* Determine the size of FDSelect. */
1035 private uint
cff_FDSelect_size(cff_writer_t * pcw,psf_glyph_enum_t * penum,uint * pformat)1036 cff_FDSelect_size(cff_writer_t *pcw, psf_glyph_enum_t *penum, uint *pformat)
1037 {
1038 gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
1039 gs_font_base *const pbfont = (gs_font_base *)pfont;
1040 gs_glyph glyph;
1041 int prev = -1;
1042 uint linear_size = 1, range_size = 5;
1043 int code;
1044
1045 /* Determine whether format 0 or 3 is more efficient. */
1046 psf_enumerate_glyphs_reset(penum);
1047 while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1048 int font_index;
1049
1050 code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1051 if (code >= 0) {
1052 if (font_index != prev)
1053 range_size += 3, prev = font_index;
1054 ++linear_size;
1055 }
1056 }
1057 if (range_size < linear_size) {
1058 *pformat = 3;
1059 return range_size;
1060 } else {
1061 *pformat = 0;
1062 return linear_size;
1063 }
1064 }
1065
1066 /* Write FDSelect. size and format were returned by cff_FDSelect_size. */
1067 private int
cff_write_FDSelect(cff_writer_t * pcw,psf_glyph_enum_t * penum,uint size,int format)1068 cff_write_FDSelect(cff_writer_t *pcw, psf_glyph_enum_t *penum, uint size,
1069 int format)
1070 {
1071 stream *s = pcw->strm;
1072 gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
1073 gs_font_base *const pbfont = (gs_font_base *)pfont;
1074 gs_glyph glyph;
1075 int prev = -1;
1076 uint cid_count = 0;
1077 int code;
1078
1079 spputc(s, (byte)format);
1080 psf_enumerate_glyphs_reset(penum);
1081 switch (format) {
1082 case 3: /* ranges */
1083 put_card16(pcw, (size - 5) / 3);
1084 while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1085 int font_index;
1086
1087 code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1088 if (code >= 0) {
1089 if (font_index != prev) {
1090 put_card16(pcw, cid_count);
1091 sputc(s, (byte)font_index);
1092 prev = font_index;
1093 }
1094 ++cid_count;
1095 }
1096 }
1097 put_card16(pcw, cid_count);
1098 break;
1099 case 0: /* linear table */
1100 while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0) {
1101 int font_index;
1102
1103 code = pfont->cidata.glyph_data(pbfont, glyph, NULL, &font_index);
1104 if (code >= 0)
1105 sputc(s, (byte)font_index);
1106 }
1107 break;
1108 default: /* not possible */
1109 return_error(gs_error_rangecheck);
1110 }
1111 return 0;
1112 }
1113
1114 /* ------ Main procedure ------ */
1115
1116 /* Write the CFF definition of a Type 1 or Type 2 font. */
1117 int
psf_write_type2_font(stream * s,gs_font_type1 * pfont,int options,gs_glyph * subset_glyphs,uint subset_size,const gs_const_string * alt_font_name,gs_int_rect * FontBBox)1118 psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
1119 gs_glyph *subset_glyphs, uint subset_size,
1120 const gs_const_string *alt_font_name,
1121 gs_int_rect *FontBBox)
1122 {
1123 gs_font_base *const pbfont = (gs_font_base *)pfont;
1124 cff_writer_t writer;
1125 cff_glyph_subset_t subset;
1126 cff_string_item_t *std_string_items;
1127 cff_string_item_t *string_items;
1128 gs_const_string font_name;
1129 stream poss;
1130 uint charstrings_count, charstrings_size;
1131 uint subrs_count, subrs_size;
1132 uint gsubrs_count, gsubrs_size, encoding_size, charset_size;
1133 uint number_of_glyphs = 0, number_of_strings;
1134 /*
1135 * Set the offsets and sizes to the largest reasonable values
1136 * (see below).
1137 */
1138 uint
1139 Top_size = 0x7fffff,
1140 GSubrs_offset,
1141 Encoding_offset,
1142 charset_offset,
1143 CharStrings_offset,
1144 Private_offset,
1145 Private_size = 0x7fffff,
1146 Subrs_offset,
1147 End_offset = 0x7fffff;
1148 int j;
1149 psf_glyph_enum_t genum;
1150 gs_glyph glyph;
1151 long start_pos;
1152 uint offset;
1153 int code;
1154
1155 /* Allocate the string tables. */
1156 psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1157 NULL, 0, GLYPH_SPACE_NAME);
1158 while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1159 number_of_glyphs++;
1160 subset.glyphs.subset_data = (gs_glyph *)gs_alloc_bytes(pfont->memory,
1161 number_of_glyphs * sizeof(glyph), "psf_write_type2_font");
1162 number_of_strings = number_of_glyphs + MAX_CFF_MISC_STRINGS;
1163 std_string_items = (cff_string_item_t *)gs_alloc_bytes(pfont->memory,
1164 (MAX_CFF_STD_STRINGS + number_of_strings) * sizeof(cff_string_item_t),
1165 "psf_write_type2_font");
1166 if (std_string_items == NULL || subset.glyphs.subset_data == NULL)
1167 return_error(gs_error_VMerror);
1168 string_items = std_string_items + MAX_CFF_STD_STRINGS;
1169
1170 /* Get subset glyphs. */
1171 code = psf_get_type1_glyphs(&subset.glyphs, pfont, subset_glyphs,
1172 subset_size);
1173 if (code < 0)
1174 return code;
1175 if (subset.glyphs.notdef == gs_no_glyph)
1176 return_error(gs_error_rangecheck); /* notdef is required */
1177
1178 /* If we're writing Type 2 CharStrings, don't encrypt them. */
1179 if (options & WRITE_TYPE2_CHARSTRINGS) {
1180 options |= WRITE_TYPE2_NO_LENIV;
1181 if (pfont->FontType != ft_encrypted2)
1182 pfont->data.defaultWidthX = pfont->data.nominalWidthX = 0;
1183 }
1184 writer.options = options;
1185 s_init(&poss, NULL);
1186 swrite_position_only(&poss);
1187 writer.strm = &poss;
1188 writer.pfont = pbfont;
1189 writer.glyph_data = psf_type1_glyph_data;
1190 writer.offset_size = 1; /* arbitrary */
1191 writer.start_pos = stell(s);
1192 writer.FontBBox = *FontBBox;
1193
1194 /* Initialize the enumeration of the glyphs. */
1195 psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1196 subset.glyphs.subset_glyphs,
1197 (subset.glyphs.subset_glyphs ?
1198 subset.glyphs.subset_size : 0),
1199 GLYPH_SPACE_NAME);
1200
1201 /* Shuffle the glyphs into the order .notdef, encoded, unencoded. */
1202 {
1203 gs_glyph encoded[256];
1204 int num_enc, num_enc_chars;
1205
1206 /* Get the list of encoded glyphs. */
1207 for (j = 0, num_enc_chars = 0; j < 256; ++j) {
1208 glyph = pfont->procs.encode_char((gs_font *)pfont, (gs_char)j,
1209 GLYPH_SPACE_NAME);
1210 if (glyph != gs_no_glyph && glyph != subset.glyphs.notdef &&
1211 (subset.glyphs.subset_glyphs == 0 ||
1212 psf_sorted_glyphs_include(subset.glyphs.subset_data,
1213 subset.glyphs.subset_size, glyph)))
1214 encoded[num_enc_chars++] = glyph;
1215 }
1216 subset.num_encoded_chars = num_enc_chars;
1217 subset.num_encoded = num_enc =
1218 psf_sort_glyphs(encoded, num_enc_chars);
1219
1220 /* Get the complete list of glyphs if we don't have it already. */
1221 if (!subset.glyphs.subset_glyphs) {
1222 int num_glyphs = 0;
1223
1224 psf_enumerate_glyphs_reset(&genum);
1225 while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1226 if (code == 0) {
1227 if (num_glyphs == number_of_glyphs)
1228 return_error(gs_error_limitcheck);
1229 subset.glyphs.subset_data[num_glyphs++] = glyph;
1230 }
1231 subset.glyphs.subset_size =
1232 psf_sort_glyphs(subset.glyphs.subset_data, num_glyphs);
1233 subset.glyphs.subset_glyphs = subset.glyphs.subset_data;
1234 }
1235
1236 /* Move the unencoded glyphs to the top of the list. */
1237 /*
1238 * We could do this in time N rather than N log N with a two-finger
1239 * algorithm, but it doesn't seem worth the trouble right now.
1240 */
1241 {
1242 int from = subset.glyphs.subset_size;
1243 int to = from;
1244
1245 while (from > 0) {
1246 glyph = subset.glyphs.subset_data[--from];
1247 if (glyph != subset.glyphs.notdef &&
1248 !psf_sorted_glyphs_include(encoded, num_enc, glyph))
1249 subset.glyphs.subset_data[--to] = glyph;
1250 }
1251 #ifdef DEBUG
1252 if (to != num_enc + 1)
1253 lprintf2("to = %d, num_enc + 1 = %d\n", to, num_enc + 1);
1254 #endif
1255 }
1256
1257 /* Move .notdef and the encoded glyphs to the bottom of the list. */
1258 subset.glyphs.subset_data[0] = subset.glyphs.notdef;
1259 memcpy(subset.glyphs.subset_data + 1, encoded,
1260 sizeof(encoded[0]) * num_enc);
1261 }
1262
1263 /* Set the font name. */
1264 if (alt_font_name)
1265 font_name = *alt_font_name;
1266 else
1267 font_name.data = pfont->font_name.chars,
1268 font_name.size = pfont->font_name.size;
1269
1270 /* Initialize the string tables. */
1271 cff_string_table_init(&writer.std_strings, std_string_items,
1272 MAX_CFF_STD_STRINGS);
1273 for (j = 0; (glyph = gs_c_known_encode((gs_char)j,
1274 ENCODING_INDEX_CFFSTRINGS)) != gs_no_glyph;
1275 ++j) {
1276 gs_const_string str;
1277 int ignore;
1278
1279 gs_c_glyph_name(glyph, &str);
1280 cff_string_index(&writer.std_strings, str.data, str.size, true,
1281 &ignore);
1282 }
1283 cff_string_table_init(&writer.strings, string_items, number_of_strings);
1284
1285 /* Enter miscellaneous strings in the string table. */
1286 cff_write_Top_font(&writer, 0, 0, 0, 0, 0);
1287
1288 /* Enter the glyph names in the string table. */
1289 /* (Note that we have changed the glyph list.) */
1290 psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
1291 subset.glyphs.subset_data,
1292 subset.glyphs.subset_size,
1293 GLYPH_SPACE_NAME);
1294 while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
1295 if (code == 0) {
1296 code = cff_glyph_sid(&writer, glyph);
1297 if (code < 0)
1298 return code;
1299 }
1300
1301 /*
1302 * The CFF specification says that the Encoding, charset, CharStrings,
1303 * Private, and Local Subr sections may be in any order. To minimize
1304 * the risk of incompatibility with Adobe software, we produce them in
1305 * the order just mentioned.
1306 */
1307
1308 /*
1309 * Compute the size of the GSubrs Index, if not omitted.
1310 */
1311 if ((options & WRITE_TYPE2_NO_GSUBRS) != 0 ||
1312 cff_convert_charstrings(&writer, pbfont) /* we expand all Subrs */
1313 )
1314 gsubrs_count = 0, gsubrs_size = 0;
1315 else
1316 gsubrs_size = cff_write_Subrs_offsets(&writer, &gsubrs_count,
1317 pfont, true);
1318
1319 /*
1320 * Compute the size of the Encoding. For simplicity, we currently
1321 * always store the Encoding explicitly. Note that because CFF stores
1322 * the Encoding in an "inverted" form, we need to count the number of
1323 * glyphs that occur at more than one place in the Encoding.
1324 */
1325 encoding_size = cff_Encoding_size(subset.num_encoded,
1326 subset.num_encoded_chars);
1327
1328 /*
1329 * Compute the size of the charset. For simplicity, we currently
1330 * always store the charset explicitly.
1331 */
1332 charset_size = 1 + (subset.glyphs.subset_size - 1) * 2;
1333
1334 /* Compute the size of the CharStrings Index. */
1335 code = cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
1336 if (code < 0)
1337 return code;
1338 charstrings_size = (uint)code;
1339
1340 /* Compute the size of the (local) Subrs Index. */
1341 #ifdef SKIP_EMPTY_SUBRS
1342 subrs_size =
1343 (cff_convert_charstrings(&writer, pbfont) ? 0 :
1344 cff_write_Subrs_offsets(&writer, &subrs_count, pfont, false));
1345 #else
1346 if (cff_convert_charstrings(&writer, pbfont))
1347 subrs_count = 0; /* we expand all Subrs */
1348 subrs_size = cff_write_Subrs_offsets(&writer, &subrs_count, pfont, false);
1349 #endif
1350
1351 /*
1352 * The offsets of the Private Dict and the CharStrings Index
1353 * depend on the size of the Top Dict; the offset of the Subrs also
1354 * depends on the size of the Private Dict. However, the size of the
1355 * Top Dict depends on the offsets of the CharStrings Index, the
1356 * charset, and the Encoding, and on the offset and size of the Private
1357 * Dict, because of the variable-length encoding of the offsets and
1358 * size; for the same reason, the size of the Private Dict depends on
1359 * the offset of the Subrs. Fortunately, the relationship between the
1360 * value of an offset or size and the size of its encoding is monotonic.
1361 * Therefore, we start by assuming the largest reasonable value for all
1362 * the sizes and iterate until everything converges.
1363 */
1364 iter:
1365 swrite_position_only(&poss);
1366 writer.strm = &poss;
1367
1368 /* Compute the offsets. */
1369 GSubrs_offset = 4 + cff_Index_size(1, font_name.size) +
1370 cff_Index_size(1, Top_size) +
1371 cff_Index_size(writer.strings.count, writer.strings.total);
1372 Encoding_offset = GSubrs_offset +
1373 cff_Index_size(gsubrs_count, gsubrs_size);
1374 charset_offset = Encoding_offset + encoding_size;
1375 CharStrings_offset = charset_offset + charset_size;
1376 Private_offset = CharStrings_offset +
1377 cff_Index_size(charstrings_count, charstrings_size);
1378 Subrs_offset = Private_size; /* relative to Private Dict */
1379
1380 write:
1381 if(check_ioerror(writer.strm))
1382 return_error(gs_error_ioerror);
1383 start_pos = stell(writer.strm);
1384 /* Write the header, setting offset_size. */
1385 cff_write_header(&writer, End_offset);
1386
1387 /* Write the names Index. */
1388 cff_put_Index_header(&writer, 1, font_name.size);
1389 put_offset(&writer, font_name.size + 1);
1390 put_bytes(writer.strm, font_name.data, font_name.size);
1391
1392 /* Write the Top Index. */
1393 cff_put_Index_header(&writer, 1, Top_size);
1394 put_offset(&writer, Top_size + 1);
1395 offset = stell(writer.strm) - start_pos;
1396 cff_write_Top_font(&writer, Encoding_offset, charset_offset,
1397 CharStrings_offset,
1398 Private_offset, Private_size);
1399 Top_size = stell(writer.strm) - start_pos - offset;
1400
1401 /* Write the strings Index. */
1402 cff_put_Index(&writer, &writer.strings);
1403 if(check_ioerror(writer.strm))
1404 return_error(gs_error_ioerror);
1405
1406 /* Write the GSubrs Index, if any, checking the offset. */
1407 offset = stell(writer.strm) - start_pos;
1408 if_debug2('l', "[l]GSubrs = %u => %u\n", GSubrs_offset, offset);
1409 if (offset > GSubrs_offset)
1410 return_error(gs_error_rangecheck);
1411 GSubrs_offset = offset;
1412 if (gsubrs_count == 0 || cff_convert_charstrings(&writer, pbfont))
1413 cff_put_Index_header(&writer, 0, 0);
1414 else
1415 cff_write_Subrs(&writer, gsubrs_count, gsubrs_size, pfont, true);
1416
1417 /* Write the Encoding. */
1418 cff_write_Encoding(&writer, &subset);
1419
1420 /* Write the charset. */
1421 cff_write_charset(&writer, &subset);
1422
1423 /* Write the CharStrings Index, checking the offset. */
1424 offset = stell(writer.strm) - start_pos;
1425 if (offset > CharStrings_offset)
1426 return_error(gs_error_rangecheck);
1427 CharStrings_offset = offset;
1428 cff_write_CharStrings(&writer, &genum, charstrings_count,
1429 charstrings_size);
1430 if(check_ioerror(writer.strm))
1431 return_error(gs_error_ioerror);
1432
1433 /* Write the Private Dict, checking the offset. */
1434 offset = stell(writer.strm) - start_pos;
1435 if (offset > Private_offset)
1436 return_error(gs_error_rangecheck);
1437 Private_offset = offset;
1438 cff_write_Private(&writer, (subrs_size == 0 ? 0 : Subrs_offset), pfont);
1439 Private_size = stell(writer.strm) - start_pos - offset;
1440
1441 /* Write the Subrs Index, checking the offset. */
1442 offset = stell(writer.strm) - (start_pos + Private_offset);
1443 if (offset > Subrs_offset)
1444 return_error(gs_error_rangecheck);
1445 Subrs_offset = offset;
1446 if (cff_convert_charstrings(&writer, pbfont))
1447 cff_put_Index_header(&writer, 0, 0);
1448 else if (subrs_size != 0)
1449 cff_write_Subrs(&writer, subrs_count, subrs_size, pfont, false);
1450
1451 /* Check the final offset. */
1452 if(check_ioerror(writer.strm))
1453 return_error(gs_error_ioerror);
1454 offset = stell(writer.strm) - start_pos;
1455 if (offset > End_offset)
1456 return_error(gs_error_rangecheck);
1457 if (offset == End_offset) {
1458 /* The iteration has converged. Write the result. */
1459 if (writer.strm == &poss) {
1460 writer.strm = s;
1461 goto write;
1462 }
1463 } else {
1464 /* No convergence yet. */
1465 End_offset = offset;
1466 goto iter;
1467 }
1468
1469 /* All done. */
1470 gs_free_object(pfont->memory, std_string_items, "psf_write_type2_font");
1471 gs_free_object(pfont->memory, subset.glyphs.subset_data, "psf_write_type2_font");
1472 return 0;
1473 }
1474
1475 /* Write the CFF definition of a CIDFontType 0 font (CIDFont). */
1476 private int
cid0_glyph_data(gs_font_base * pbfont,gs_glyph glyph,gs_glyph_data_t * pgd,gs_font_type1 ** ppfont)1477 cid0_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd,
1478 gs_font_type1 **ppfont)
1479 {
1480 gs_font_cid0 *const pfont = (gs_font_cid0 *)pbfont;
1481 int font_index;
1482 int code = pfont->cidata.glyph_data(pbfont, glyph, pgd, &font_index);
1483
1484 if (code >= 0)
1485 *ppfont = pfont->cidata.FDArray[font_index];
1486 return code;
1487 }
1488 #ifdef DEBUG
1489 private int
offset_error(const char * msg)1490 offset_error(const char *msg)
1491 {
1492 if_debug1('l', "[l]%s offset error\n", msg);
1493 return gs_error_rangecheck;
1494 }
1495 #else
1496 # define offset_error(msg) gs_error_rangecheck
1497 #endif
1498 int
psf_write_cid0_font(stream * s,gs_font_cid0 * pfont,int options,const byte * subset_cids,uint subset_size,const gs_const_string * alt_font_name)1499 psf_write_cid0_font(stream *s, gs_font_cid0 *pfont, int options,
1500 const byte *subset_cids, uint subset_size,
1501 const gs_const_string *alt_font_name)
1502 {
1503 /*
1504 * CIDFontType 0 fonts differ from ordinary Type 1 / Type 2 fonts
1505 * as follows:
1506 * The TOP Dict starts with a ROS operator.
1507 * The TOP Dict must include FDArray and FDSelect operators.
1508 * The TOP Dict may include CIDFontVersion, CIDFontRevision,
1509 * CIDFontType, CIDCount, and UIDBase operators.
1510 * The TOP Dict must not include an Encoding operator.
1511 * The charset is defined in terms of CIDs rather than SIDs.
1512 * FDArray references a Font Index in which each element is a Dict
1513 * defining a font without charset, Encoding, or CharStrings.
1514 * FDSelect references a structure mapping CIDs to font numbers.
1515 */
1516 gs_font_base *const pbfont = (gs_font_base *)pfont;
1517 cff_writer_t writer;
1518 cff_string_item_t std_string_items[500]; /* 391 entries used */
1519 /****** HOW TO DETERMINE THE SIZE OF STRINGS? ******/
1520 cff_string_item_t string_items[500 /* character names */ +
1521 40 /* misc. values */];
1522 gs_const_string font_name;
1523 stream poss;
1524 uint charstrings_count, charstrings_size;
1525 uint gsubrs_count, gsubrs_size;
1526 uint charset_size, fdselect_size, fdselect_format;
1527 uint subrs_count[256], subrs_size[256];
1528 /*
1529 * Set the offsets and sizes to the largest reasonable values
1530 * (see below).
1531 */
1532 uint
1533 Top_size = 0x7fffff,
1534 GSubrs_offset = 0x7fffff,
1535 charset_offset = 0x7fffff,
1536 FDSelect_offset = 0x7fffff,
1537 CharStrings_offset = 0x7fffff,
1538 Font_offset = 0x7fffff,
1539 FDArray_offsets[257],
1540 Private_offsets[257],
1541 Subrs_offsets[257],
1542 End_offset = 0x7fffff;
1543 int j;
1544 psf_glyph_enum_t genum;
1545 gs_font_info_t info;
1546 long start_pos;
1547 uint offset;
1548 int num_fonts = pfont->cidata.FDArray_size;
1549 int code;
1550
1551
1552 /* Initialize the enumeration of the glyphs. */
1553 psf_enumerate_cids_begin(&genum, (gs_font *)pfont, subset_cids,
1554 subset_size);
1555
1556 /* Check that the font can be written. */
1557 code = psf_check_outline_glyphs((gs_font_base *)pfont, &genum,
1558 cid0_glyph_data);
1559 if (code < 0)
1560 return code;
1561 /* The .notdef glyph (glyph 0) must be included. */
1562 if (subset_cids && subset_size > 0 && !(subset_cids[0] & 0x80))
1563 return_error(gs_error_rangecheck);
1564
1565 writer.options = options;
1566 s_init(&poss, NULL);
1567 swrite_position_only(&poss);
1568 writer.strm = &poss;
1569 writer.pfont = pbfont;
1570 writer.glyph_data = cid0_glyph_data;
1571 writer.offset_size = 1; /* arbitrary */
1572 writer.start_pos = stell(s);
1573 writer.FontBBox.p.x = writer.FontBBox.p.y = 0;
1574 writer.FontBBox.q.x = writer.FontBBox.q.y = 0;
1575
1576 /* Set the font name. */
1577 if (alt_font_name)
1578 font_name = *alt_font_name;
1579 else if (pfont->font_name.size)
1580 font_name.data = pfont->font_name.chars,
1581 font_name.size = pfont->font_name.size;
1582 else
1583 font_name.data = pfont->key_name.chars,
1584 font_name.size = pfont->key_name.size;
1585
1586 /* Initialize the string tables. */
1587 cff_string_table_init(&writer.std_strings, std_string_items,
1588 countof(std_string_items));
1589 cff_string_table_init(&writer.strings, string_items,
1590 countof(string_items));
1591
1592 /* Make all entries in the string table. */
1593 cff_write_ROS(&writer, &pfont->cidata.common.CIDSystemInfo);
1594 for (j = 0; j < num_fonts; ++j) {
1595 gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1596
1597 cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, 0, 0);
1598 }
1599
1600 /*
1601 * The CFF specification says that sections after the initial Indexes
1602 * may be in any order. To minimize the risk of incompatibility with
1603 * Adobe software, we produce them in the order illustrated in the
1604 * specification.
1605 */
1606
1607 /* Initialize the offset arrays. */
1608 for (j = 0; j <= num_fonts; ++j)
1609 FDArray_offsets[j] = Private_offsets[j] = Subrs_offsets[j] =
1610 0x7effffff / num_fonts * j + 0x1000000;
1611
1612 /*
1613 * Compute the size of the GSubrs Index, if not omitted.
1614 * Arbitrarily use FDArray[0] to access the GSubrs and to determine
1615 * the CharString type.
1616 */
1617 if ((options & WRITE_TYPE2_NO_GSUBRS) != 0 ||
1618 cff_convert_charstrings(&writer,
1619 (const gs_font_base *)pfont->cidata.FDArray[0])
1620 /* we expand all Subrs */
1621 )
1622 gsubrs_count = 0, gsubrs_size = 0;
1623 else
1624 gsubrs_size = cff_write_Subrs_offsets(&writer, &gsubrs_count,
1625 pfont->cidata.FDArray[0], true);
1626
1627 /*
1628 * Compute the size of the charset. For simplicity, we currently
1629 * always store the charset explicitly.
1630 */
1631 swrite_position_only(&poss);
1632 cff_write_cidset(&writer, &genum);
1633 charset_size = stell(&poss);
1634
1635 /* Compute the size of the FDSelect strucure. */
1636 fdselect_size = cff_FDSelect_size(&writer, &genum, &fdselect_format);
1637
1638 /* Compute the size of the CharStrings Index. */
1639 charstrings_size =
1640 cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
1641
1642 /* Compute the size of the (local) Subrs Indexes. */
1643 for (j = 0; j < num_fonts; ++j) {
1644 gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1645
1646 #ifdef SKIP_EMPTY_SUBRS
1647 subrs_size[j] =
1648 (cff_convert_charstrings(&writer, (gs_font_base *)pfd) ? 0 :
1649 cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd, false));
1650 #else
1651 if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
1652 subrs_count[j] = 0; /* we expand all Subrs */
1653 subrs_size[j] = cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd, false);
1654 #endif
1655 }
1656
1657 /* Get the font_info once, since it may be expensive. */
1658 cff_get_Top_info_common(&writer, (gs_font_base *)pfont, true, &info);
1659
1660 /*
1661 * The offsets of the Private Dict and the CharStrings Index
1662 * depend on the size of the Top Dict; the offset of the Subrs also
1663 * depends on the size of the Private Dict. However, the size of the
1664 * Top Dict depends on the offsets of the CharStrings Index and the
1665 * charset, and on the offset and size of the Private Dict,
1666 * because of the variable-length encoding of the offsets and
1667 * size; for the same reason, the size of the Private Dict depends on
1668 * the offset of the Subrs. Fortunately, the relationship between the
1669 * value of an offset or size and the size of its encoding is monotonic.
1670 * Therefore, we start by assuming the largest reasonable value for all
1671 * the sizes and iterate until everything converges.
1672 */
1673 iter:
1674 swrite_position_only(&poss);
1675 writer.strm = &poss;
1676
1677 /* Compute the offsets. */
1678 GSubrs_offset = 4 + cff_Index_size(1, font_name.size) +
1679 cff_Index_size(1, Top_size) +
1680 cff_Index_size(writer.strings.count, writer.strings.total);
1681 charset_offset = GSubrs_offset +
1682 cff_Index_size(gsubrs_count, gsubrs_size);
1683 FDSelect_offset = charset_offset + charset_size;
1684 CharStrings_offset = FDSelect_offset + fdselect_size;
1685 if_debug4('l', "[l]GSubrs at %u, charset at %u, FDSelect at %u, CharStrings at %u\n",
1686 GSubrs_offset, charset_offset, FDSelect_offset, CharStrings_offset);
1687
1688 write:
1689 start_pos = stell(writer.strm);
1690 if_debug1('l', "[l]start_pos = %ld\n", start_pos);
1691 /* Write the header, setting offset_size. */
1692 cff_write_header(&writer, End_offset);
1693
1694 /* Write the names Index. */
1695 cff_put_Index_header(&writer, 1, font_name.size);
1696 put_offset(&writer, font_name.size + 1);
1697 put_bytes(writer.strm, font_name.data, font_name.size);
1698
1699 /* Write the Top Index. */
1700 cff_put_Index_header(&writer, 1, Top_size);
1701 put_offset(&writer, Top_size + 1);
1702 offset = stell(writer.strm) - start_pos;
1703 cff_write_Top_cidfont(&writer, charset_offset, CharStrings_offset,
1704 FDSelect_offset, Font_offset, &info);
1705 Top_size = stell(writer.strm) - start_pos - offset;
1706 if_debug1('l', "[l]Top_size = %u\n", Top_size);
1707
1708 /* Write the strings Index. */
1709 cff_put_Index(&writer, &writer.strings);
1710
1711 /* Write the GSubrs Index, if any, checking the offset. */
1712 offset = stell(writer.strm) - start_pos;
1713 if_debug2('l', "[l]GSubrs = %u => %u\n", GSubrs_offset, offset);
1714 if (offset > GSubrs_offset)
1715 return_error(gs_error_rangecheck);
1716 GSubrs_offset = offset;
1717 if (gsubrs_count == 0 ||
1718 cff_convert_charstrings(&writer,
1719 (const gs_font_base *)pfont->cidata.FDArray[0])
1720 )
1721 cff_put_Index_header(&writer, 0, 0);
1722 else
1723 cff_write_Subrs(&writer, gsubrs_count, gsubrs_size,
1724 pfont->cidata.FDArray[0], true);
1725
1726 /* Write the charset. */
1727 if_debug1('l', "[l]charset = %u\n", stell(writer.strm) - start_pos);
1728 cff_write_cidset(&writer, &genum);
1729
1730 /* Write the FDSelect structure, checking the offset. */
1731 offset = stell(writer.strm) - start_pos;
1732 if_debug2('l', "[l]FDSelect = %u => %u\n", FDSelect_offset, offset);
1733 if (offset > FDSelect_offset)
1734 return_error(offset_error("FDselect"));
1735 FDSelect_offset = offset;
1736 cff_write_FDSelect(&writer, &genum, fdselect_size, fdselect_format);
1737
1738 /* Write the CharStrings Index, checking the offset. */
1739 offset = stell(writer.strm) - start_pos;
1740 if_debug2('l', "[l]CharStrings = %u => %u\n", CharStrings_offset, offset);
1741 if (offset > CharStrings_offset)
1742 return_error(offset_error("CharStrings"));
1743 CharStrings_offset = offset;
1744 cff_write_CharStrings(&writer, &genum, charstrings_count,
1745 charstrings_size);
1746
1747 /* Write the Font Dict Index. */
1748 offset = stell(writer.strm) - start_pos;
1749 if_debug2('l', "[l]Font = %u => %u\n", Font_offset, offset);
1750 if (offset > Font_offset)
1751 return_error(offset_error("Font"));
1752 Font_offset = offset;
1753 cff_write_FDArray_offsets(&writer, FDArray_offsets, num_fonts);
1754 offset = stell(writer.strm) - start_pos;
1755 if_debug2('l', "[l]FDArray[0] = %u => %u\n", FDArray_offsets[0], offset);
1756 if (offset > FDArray_offsets[0])
1757 return_error(offset_error("FDArray[0]"));
1758 FDArray_offsets[0] = offset;
1759 for (j = 0; j < num_fonts; ++j) {
1760 gs_font_type1 *pfd = pfont->cidata.FDArray[j];
1761
1762 /* If we're writing Type 2 CharStrings, don't encrypt them. */
1763 if (options & WRITE_TYPE2_CHARSTRINGS) {
1764 options |= WRITE_TYPE2_NO_LENIV;
1765 if (pfd->FontType != ft_encrypted2)
1766 pfd->data.defaultWidthX = pfd->data.nominalWidthX = 0;
1767 }
1768 cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, Private_offsets[j],
1769 Private_offsets[j + 1] - Private_offsets[j]);
1770 offset = stell(writer.strm) - start_pos;
1771 if_debug3('l', "[l]FDArray[%d] = %u => %u\n", j + 1,
1772 FDArray_offsets[j + 1], offset);
1773 if (offset > FDArray_offsets[j + 1])
1774 return_error(offset_error("FDArray"));
1775 FDArray_offsets[j + 1] = offset;
1776 }
1777
1778 /* Write the Private Dicts, checking the offset. */
1779 for (j = 0; ; ++j) {
1780 gs_font_type1 *pfd;
1781
1782 offset = stell(writer.strm) - start_pos;
1783 if_debug3('l', "[l]Private[%d] = %u => %u\n",
1784 j, Private_offsets[j], offset);
1785 if (offset > Private_offsets[j])
1786 return_error(offset_error("Private"));
1787 Private_offsets[j] = offset;
1788 if (j == num_fonts)
1789 break;
1790 pfd = pfont->cidata.FDArray[j];
1791 cff_write_Private(&writer,
1792 (subrs_size[j] == 0 ? 0 : Subrs_offsets[j]), pfd);
1793 }
1794
1795 /* Write the Subrs Indexes, checking the offsets. */
1796 for (j = 0; ; ++j) {
1797 gs_font_type1 *pfd;
1798
1799 offset = stell(writer.strm) - (start_pos + Private_offsets[j]);
1800 if_debug3('l', "[l]Subrs[%d] = %u => %u\n",
1801 j, Subrs_offsets[j], offset);
1802 if (offset > Subrs_offsets[j])
1803 return_error(offset_error("Subrs"));
1804 Subrs_offsets[j] = offset;
1805 if (j == num_fonts)
1806 break;
1807 pfd = pfont->cidata.FDArray[j];
1808 if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
1809 cff_put_Index_header(&writer, 0, 0);
1810 else if (subrs_size[j] != 0)
1811 cff_write_Subrs(&writer, subrs_count[j], subrs_size[j], pfd, false);
1812 }
1813
1814 /* Check the final offset. */
1815 offset = stell(writer.strm) - start_pos;
1816 if_debug2('l', "[l]End = %u => %u\n", End_offset, offset);
1817 if (offset > End_offset)
1818 return_error(offset_error("End"));
1819 if (offset == End_offset) {
1820 /* The iteration has converged. Write the result. */
1821 if (writer.strm == &poss) {
1822 writer.strm = s;
1823 goto write;
1824 }
1825 } else {
1826 /* No convergence yet. */
1827 End_offset = offset;
1828 goto iter;
1829 }
1830
1831 /* All done. */
1832 return 0;
1833 }
1834