1 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
2 
3     Copyright (C) 2008-2014 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
4     the dvipdfmx project team.
5 
6     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <string.h>
28 #include <math.h>
29 
30 #include "system.h"
31 #include "mem.h"
32 #include "error.h"
33 
34 #include "dpxfile.h"
35 
36 #include "numbers.h"
37 
38 #include "pdfobj.h"
39 #include "pdffont.h"
40 
41 #include "pdfencoding.h"
42 #include "unicode.h"
43 
44 #include "dpxutil.h"
45 
46 #include "pst_obj.h"
47 #include "pst.h"
48 
49 #include "cff_limits.h"
50 #include "cff_types.h"
51 #include "cff_dict.h"
52 #include "cff.h"
53 
54 #include "t1_load.h"
55 #include "t1_char.h"
56 
57 #include "type1.h"
58 
59 #include "tfm.h"
60 
61 #define FONT_FLAG_FIXEDPITCH (1 << 0)  /* Fixed-width font */
62 #define FONT_FLAG_SERIF      (1 << 1)  /* Serif font */
63 #define FONT_FLAG_SYMBOLIC   (1 << 2)  /* Symbolic font */
64 #define FONT_FLAG_SCRIPT     (1 << 3)  /* Script font */
65 #define FONT_FLAG_STANDARD   (1 << 5)  /* Adobe Standard Character Set */
66 #define FONT_FLAG_ITALIC     (1 << 6)  /* Italic */
67 #define FONT_FLAG_ALLCAP     (1 << 16) /* All-cap font */
68 #define FONT_FLAG_SMALLCAP   (1 << 17) /* Small-cap font */
69 #define FONT_FLAG_FORCEBOLD  (1 << 18) /* Force bold at small text sizes */
70 
71 static int
is_basefont(const char * name)72 is_basefont (const char *name)
73 {
74   static const char *basefonts[] = {
75     "Courier",                  "Courier-Bold",          "Courier-Oblique",
76     "Courier-BoldOblique",      "Helvetica",             "Helvetica-Bold",
77     "Helvetica-Oblique",        "Helvetica-BoldOblique", "Symbol",
78     "Times-Roman",              "Times-Bold",            "Times-Italic",
79     "Times-BoldItalic",         "ZapfDingbats"
80   };
81   int i;
82 
83   for (i = 0; i < 14; i++) {
84     if (!strcmp(name, basefonts[i]))
85       return 1;
86   }
87 
88   return 0;
89 }
90 
91 int
pdf_font_open_type1(pdf_font * font)92 pdf_font_open_type1 (pdf_font *font)
93 {
94   char    *ident;
95   FILE    *fp;
96   char     fontname[PDF_NAME_LEN_MAX+1];
97 
98   ASSERT(font);
99 
100   ident = pdf_font_get_ident(font);
101 
102   if (is_basefont(ident)) {
103     pdf_font_set_fontname(font, ident);
104     pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1);
105     pdf_font_set_flags   (font,
106 			  (PDF_FONT_FLAG_NOEMBED|PDF_FONT_FLAG_BASEFONT));
107   } else {
108     fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
109     if (!fp)
110       return -1;
111 
112     memset(fontname, 0, PDF_NAME_LEN_MAX+1);
113     if (!is_pfb(fp) || t1_get_fontname(fp, fontname) < 0) {
114       ERROR("Failed to read Type 1 font \"%s\".", ident);
115     }
116     DPXFCLOSE(fp);
117 
118     pdf_font_set_fontname(font, fontname);
119     pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1);
120   }
121 
122   return 0;
123 }
124 
125 static void
get_font_attr(pdf_font * font,cff_font * cffont)126 get_font_attr (pdf_font *font, cff_font *cffont)
127 {
128   char    *fontname;
129   pdf_obj *descriptor;
130   double   capheight, ascent, descent;
131   double   italicangle, stemv;
132   double   defaultwidth, nominalwidth;
133   long     flags = 0, gid, i;
134   static const char *L_c[] = {
135     "H", "P", "Pi", "Rho", NULL
136   };
137   static const char *L_d[] = {
138     "p", "q", "mu", "eta", NULL
139   };
140   static const char *L_a[] = {
141     "b", "h", "lambda", NULL
142   };
143   t1_ginfo gm;
144 
145   defaultwidth = 500.0;
146   nominalwidth = 0.0;
147 
148   /*
149    * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
150    * The BlueValues and OtherBlues also have those information.
151    */
152   if (cff_dict_known(cffont->topdict, "FontBBox")) {
153     /* Default values */
154     capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
155     descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
156   } else {
157     capheight =  680.0;
158     ascent    =  690.0;
159     descent   = -190.0;
160   }
161   if (cff_dict_known(cffont->private[0], "StdVW")) {
162     stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
163   } else {
164     /*
165      * We may use the following values for StemV:
166      *  Thin - ExtraLight: <= 50
167      *  Light: 71
168      *  Regular(Normal): 88
169      *  Medium: 109
170      *  SemiBold(DemiBold): 135
171      *  Bold - Heavy: >= 166
172      */
173     stemv = 88.0;
174   }
175   if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
176     italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
177     if (italicangle != 0.0)
178       flags |= FONT_FLAG_ITALIC;
179   } else {
180     italicangle = 0.0;
181   }
182 
183   /*
184    * Use "space", "H", "p", and "b" for various values.
185    * Those characters should not "seac". (no accent)
186    */
187   gid = cff_glyph_lookup(cffont, "space");
188   if (gid >= 0 && gid < cffont->cstrings->count) {
189     t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
190 		       cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
191 		       cffont->subrs[0], &gm);
192     defaultwidth = gm.wx;
193   }
194 
195   for (i = 0; L_c[i] != NULL; i++) {
196     gid = cff_glyph_lookup(cffont, L_c[i]);
197     if (gid >= 0 && gid < cffont->cstrings->count) {
198       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
199 		      cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
200 		      cffont->subrs[0], &gm);
201       capheight = gm.bbox.ury;
202       break;
203     }
204   }
205 
206   for (i = 0; L_d[i] != NULL; i++) {
207     gid = cff_glyph_lookup(cffont, L_d[i]);
208     if (gid >= 0 && gid < cffont->cstrings->count) {
209       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
210 			 cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
211 			 cffont->subrs[0], &gm);
212       descent = gm.bbox.lly;
213       break;
214     }
215   }
216 
217   for (i = 0; L_a[i] != NULL; i++) {
218     gid = cff_glyph_lookup(cffont, L_a[i]);
219     if (gid >= 0 && gid < cffont->cstrings->count) {
220       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
221 			 cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
222 			 cffont->subrs[0], &gm);
223       ascent = gm.bbox.ury;
224       break;
225     }
226   }
227 
228   if (defaultwidth != 0.0) {
229     cff_dict_add(cffont->private[0], "defaultWidthX", 1);
230     cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
231   }
232   if (nominalwidth != 0.0) {
233     cff_dict_add(cffont->private[0], "nominalWidthX", 1);
234     cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
235   }
236   if (cff_dict_known(cffont->private[0], "ForceBold") &&
237       cff_dict_get(cffont->private[0], "ForceBold", 0)) {
238     flags |= FONT_FLAG_FORCEBOLD;
239   }
240   if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
241       cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
242     flags |= FONT_FLAG_FIXEDPITCH;
243   }
244 
245   fontname   = pdf_font_get_fontname  (font);
246   descriptor = pdf_font_get_descriptor(font);
247 
248   if (fontname && !strstr(fontname, "Sans")) {
249     flags |= FONT_FLAG_SERIF;
250   }
251   if (fontname &&  strstr(fontname, "Caps")) {
252     flags |= FONT_FLAG_SMALLCAP;
253   }
254   flags |= FONT_FLAG_SYMBOLIC; /* FIXME */
255 
256   pdf_add_dict(descriptor,
257 	       pdf_new_name("CapHeight"), pdf_new_number(capheight));
258   pdf_add_dict(descriptor,
259 	       pdf_new_name("Ascent"), pdf_new_number(ascent));
260   pdf_add_dict(descriptor,
261 	       pdf_new_name("Descent"), pdf_new_number(descent));
262   pdf_add_dict(descriptor,
263 	       pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
264   pdf_add_dict(descriptor,
265 	       pdf_new_name("StemV"), pdf_new_number(stemv));
266   pdf_add_dict(descriptor,
267 	       pdf_new_name("Flags"), pdf_new_number(flags));
268 }
269 
270 static void
add_metrics(pdf_font * font,cff_font * cffont,char ** enc_vec,double * widths,long num_glyphs)271 add_metrics (pdf_font *font, cff_font *cffont, char **enc_vec, double *widths, long num_glyphs)
272 {
273   pdf_obj *fontdict, *descriptor;
274   pdf_obj *tmp_array;
275   int      code, firstchar, lastchar;
276   double   val;
277   int      i, tfm_id;
278   char    *usedchars;
279   double   scaling;
280 
281   fontdict   = pdf_font_get_resource  (font);
282   descriptor = pdf_font_get_descriptor(font);
283   usedchars  = pdf_font_get_usedchars (font);
284 
285   /*
286    * The original FontBBox of the font is preserved, instead
287    * of replacing it with tight bounding box calculated from
288    * charstrings, to prevent Acrobat 4 from greeking text as
289    * much as possible.
290    */
291   if (!cff_dict_known(cffont->topdict, "FontBBox")) {
292     ERROR("No FontBBox?");
293   }
294 
295   /* The widhts array in the font dictionary must be given relative
296    * to the default scaling of 1000:1, not relative to the scaling
297    * given by the font matrix.
298    */
299   if (cff_dict_known(cffont->topdict, "FontMatrix"))
300     scaling = 1000*cff_dict_get(cffont->topdict, "FontMatrix", 0);
301   else
302     scaling = 1;
303 
304   tmp_array = pdf_new_array();
305   for (i = 0; i < 4; i++) {
306     val = cff_dict_get(cffont->topdict, "FontBBox", i);
307     pdf_add_array(tmp_array, pdf_new_number(ROUND(val, 1.0)));
308   }
309   pdf_add_dict(descriptor, pdf_new_name("FontBBox"), tmp_array);
310 
311   tmp_array = pdf_new_array();
312   if (num_glyphs <= 1) { /* This must be an error. */
313     firstchar = lastchar = 0;
314     pdf_add_array(tmp_array, pdf_new_number(0.0));
315   } else {
316     for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) {
317       if (usedchars[code]) {
318 	if (code < firstchar) firstchar = code;
319 	if (code > lastchar)  lastchar  = code;
320       }
321     }
322     if (firstchar > lastchar) {
323       WARN("No glyphs actually used???");
324       pdf_release_obj(tmp_array);
325       return;
326     }
327     tfm_id = tfm_open(pdf_font_get_mapname(font), 0);
328     for (code = firstchar; code <= lastchar; code++) {
329       if (usedchars[code]) {
330         double width;
331         if (tfm_id < 0) /* tfm is not found */
332 	  width = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])];
333         else
334           width = 1000. * tfm_get_width(tfm_id, code);
335 	pdf_add_array(tmp_array,
336 		      pdf_new_number(ROUND(width, 0.1)));
337       } else {
338 	pdf_add_array(tmp_array, pdf_new_number(0.0));
339       }
340     }
341   }
342 
343   if (pdf_array_length(tmp_array) > 0) {
344     pdf_add_dict(fontdict,
345 		 pdf_new_name("Widths"),  pdf_ref_obj(tmp_array));
346   }
347   pdf_release_obj(tmp_array);
348 
349   pdf_add_dict(fontdict,
350 	       pdf_new_name("FirstChar"), pdf_new_number(firstchar));
351   pdf_add_dict(fontdict,
352 	       pdf_new_name("LastChar"),  pdf_new_number(lastchar));
353 
354   return;
355 }
356 
357 
358 static long
write_fontfile(pdf_font * font,cff_font * cffont)359 write_fontfile (pdf_font *font, cff_font *cffont)
360 {
361   pdf_obj   *descriptor;
362   pdf_obj   *fontfile, *stream_dict;
363   cff_index *topdict;
364   long       private_size, stream_data_len, charstring_len;
365   long       topdict_offset, offset;
366 #define  WBUF_SIZE 1024
367   card8     *stream_data_ptr, wbuf[WBUF_SIZE];
368 
369   descriptor = pdf_font_get_descriptor(font);
370 
371   topdict = cff_new_index(1);
372   /*
373    * Force existence of Encoding.
374    */
375   if (!cff_dict_known(cffont->topdict, "CharStrings"))
376     cff_dict_add(cffont->topdict, "CharStrings", 1);
377   if (!cff_dict_known(cffont->topdict, "charset"))
378     cff_dict_add(cffont->topdict, "charset", 1);
379   if (!cff_dict_known(cffont->topdict, "Encoding"))
380     cff_dict_add(cffont->topdict, "Encoding", 1);
381   private_size = cff_dict_pack((cffont->private)[0], wbuf, WBUF_SIZE);
382   /* Private dict is required (but may have size 0) */
383   if (!cff_dict_known(cffont->topdict, "Private"))
384     cff_dict_add(cffont->topdict, "Private", 2);
385   topdict->offset[1] = cff_dict_pack(cffont->topdict, wbuf, WBUF_SIZE) + 1;
386 
387   /*
388    * Estimate total size of fontfile.
389    */
390   charstring_len = cff_index_size(cffont->cstrings);
391 
392   stream_data_len = 4; /* header size */
393   stream_data_len += cff_index_size(cffont->name);
394   stream_data_len += cff_index_size(topdict);
395   stream_data_len += cff_index_size(cffont->string);
396   stream_data_len += cff_index_size(cffont->gsubr);
397   /* We are using format 1 for Encoding and format 0 for charset.
398    * TODO: Should implement cff_xxx_size().
399    */
400   stream_data_len += 2 + (cffont->encoding->num_entries)*2 + 1 + (cffont->encoding->num_supps)*3;
401   stream_data_len += 1 + (cffont->charsets->num_entries)*2;
402   stream_data_len += charstring_len;
403   stream_data_len += private_size;
404 
405   /*
406    * Now we create FontFile data.
407    */
408   stream_data_ptr = NEW(stream_data_len, card8);
409   /*
410    * Data Layout order as described in CFF spec., sec 2 "Data Layout".
411    */
412   offset = 0;
413   /* Header */
414   offset += cff_put_header(cffont,
415 			   stream_data_ptr + offset, stream_data_len - offset);
416   /* Name */
417   offset += cff_pack_index(cffont->name,
418 			   stream_data_ptr + offset, stream_data_len - offset);
419   /* Top DICT */
420   topdict_offset = offset;
421   offset += cff_index_size(topdict);
422   /* Strings */
423   offset += cff_pack_index(cffont->string,
424 			   stream_data_ptr + offset, stream_data_len - offset);
425   /* Global Subrs */
426   offset += cff_pack_index(cffont->gsubr,
427 			   stream_data_ptr + offset, stream_data_len - offset);
428   /* Encoding */
429   /* TODO: don't write Encoding entry if the font is always used
430    * with PDF Encoding information. Applies to type1c.c as well.
431    */
432   cff_dict_set(cffont->topdict, "Encoding", 0, offset);
433   offset += cff_pack_encoding(cffont,
434 			      stream_data_ptr + offset, stream_data_len - offset);
435   /* charset */
436   cff_dict_set(cffont->topdict, "charset", 0, offset);
437   offset += cff_pack_charsets(cffont,
438 			      stream_data_ptr + offset, stream_data_len - offset);
439   /* CharStrings */
440   cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
441   offset += cff_pack_index(cffont->cstrings,
442 			   stream_data_ptr + offset, charstring_len);
443   /* Private */
444   if ((cffont->private)[0] && private_size > 0) {
445     private_size = cff_dict_pack(cffont->private[0],
446 				 stream_data_ptr + offset, private_size);
447     cff_dict_set(cffont->topdict, "Private", 1, offset);
448     cff_dict_set(cffont->topdict, "Private", 0, private_size);
449   }
450   offset += private_size;
451 
452   /* Finally Top DICT */
453   topdict->data = NEW(topdict->offset[1] - 1, card8);
454   cff_dict_pack (cffont->topdict, topdict->data, topdict->offset[1] - 1);
455   cff_pack_index(topdict,
456 		 stream_data_ptr + topdict_offset, cff_index_size(topdict));
457   cff_release_index(topdict);
458 
459   /* Copyright and Trademark Notice ommited. */
460 
461   /* Flush Font File */
462   fontfile    = pdf_new_stream(STREAM_COMPRESS);
463   stream_dict = pdf_stream_dict(fontfile);
464   pdf_add_dict(descriptor,
465 	       pdf_new_name("FontFile3"), pdf_ref_obj (fontfile));
466   pdf_add_dict(stream_dict,
467 	       pdf_new_name("Subtype"),   pdf_new_name("Type1C"));
468   pdf_add_stream (fontfile, (void *) stream_data_ptr,  offset);
469   pdf_release_obj(fontfile);
470 
471   RELEASE(stream_data_ptr);
472 
473   return offset;
474 }
475 
476 
477 int
pdf_font_load_type1(pdf_font * font)478 pdf_font_load_type1 (pdf_font *font)
479 {
480   pdf_obj      *fontdict;
481   int           encoding_id;
482   char         *usedchars, *ident;
483   char         *fontname, *uniqueTag;
484   char         *fullname; /* With pseudo unique tag */
485   cff_font     *cffont;
486   cff_charsets *charset;
487   char        **enc_vec;
488   double        defaultwidth, nominalwidth;
489   double       *widths;
490   card16       *GIDMap, num_glyphs = 0;
491   FILE         *fp;
492   long          offset;
493   int           code, verbose;
494 
495   ASSERT(font);
496 
497   if (!pdf_font_is_in_use(font)) {
498     return 0;
499   }
500 
501   verbose     = pdf_font_get_verbose();
502 
503   encoding_id = pdf_font_get_encoding  (font);
504   fontdict    = pdf_font_get_resource  (font);
505 
506                 pdf_font_get_descriptor(font);
507   usedchars   = pdf_font_get_usedchars (font);
508   ident       = pdf_font_get_ident     (font);
509   fontname    = pdf_font_get_fontname  (font);
510   uniqueTag   = pdf_font_get_uniqueTag (font);
511   if (!usedchars || !ident || !fontname) {
512     ERROR("Type1: Unexpected error.");
513   }
514 
515   fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT);
516   if (!fp) {
517     ERROR("Type1: Could not open Type1 font: %s", ident);
518   }
519 
520   GIDMap     = NULL;
521   num_glyphs = 0;
522 
523   if (encoding_id >= 0) {
524     enc_vec = NULL;
525   } else {
526     enc_vec = NEW(256, char *);
527     for (code = 0; code <= 0xff; code++) {
528       enc_vec[code] = NULL;
529     }
530   }
531 
532   cffont = t1_load_font(enc_vec, 0, fp);
533   if (!cffont) {
534     ERROR("Could not load Type 1 font: %s", ident);
535   }
536   DPXFCLOSE(fp);
537 
538   fullname = NEW(strlen(fontname) + 8, char);
539   sprintf(fullname, "%6s+%s", uniqueTag, fontname);
540 
541   /*
542    * Encoding related things.
543    */
544   if (encoding_id >= 0) {
545     enc_vec = pdf_encoding_get_encoding(encoding_id);
546   } else {
547     pdf_obj *tounicode;
548 
549     /*
550      * Create enc_vec and ToUnicode CMap for built-in encoding.
551      */
552     if (!pdf_lookup_dict(fontdict, "ToUnicode")) {
553     tounicode = pdf_create_ToUnicode_CMap(fullname,
554 					  enc_vec, usedchars);
555     if (tounicode) {
556       pdf_add_dict(fontdict,
557                      pdf_new_name("ToUnicode"),
558                      pdf_ref_obj (tounicode));
559       pdf_release_obj(tounicode);
560       }
561     }
562   }
563 
564   cff_set_name(cffont, fullname);
565   RELEASE(fullname);
566 
567   /* defaultWidthX, CapHeight, etc. */
568   get_font_attr(font, cffont);
569   if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
570     defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
571   } else {
572     defaultwidth = 0.0;
573   }
574   if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
575     nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
576   } else {
577     nominalwidth = 0.0;
578   }
579 
580   /* Create CFF encoding, charset, sort glyphs */
581 #define MAX_GLYPHS 1024
582   GIDMap = NEW(MAX_GLYPHS, card16);
583   {
584     int     prev, duplicate;
585     long    gid;
586     char   *glyph;
587     s_SID   sid;
588 
589     cffont->encoding = NEW(1, cff_encoding);
590     cffont->encoding->format      = 1;
591     cffont->encoding->num_entries = 0;
592     cffont->encoding->data.range1 = NEW(256, cff_range1);
593     cffont->encoding->num_supps   = 0;
594     cffont->encoding->supp        = NEW(256, cff_map);
595 
596     charset = NEW(1, cff_charsets);
597     charset->format      = 0;
598     charset->num_entries = 0;
599     charset->data.glyphs = NEW(MAX_GLYPHS, s_SID);
600 
601     gid = cff_glyph_lookup(cffont, ".notdef");
602     if (gid < 0)
603       ERROR("Type 1 font with no \".notdef\" glyph???");
604     GIDMap[0] = (card16) gid;
605     if (verbose > 2)
606       MESG("[glyphs:/.notdef");
607     num_glyphs =  1;
608     for (prev = -2, code = 0; code <= 0xff; code++) {
609       glyph = enc_vec[code];
610 
611       if (!usedchars[code])
612 	continue;
613       if (glyph && !strcmp(glyph, ".notdef")) {
614 	WARN("Character mapped to .notdef used in font: %s",
615 	     fontname);
616 	usedchars[code] = 0;
617 	continue;
618       }
619 
620       gid = cff_glyph_lookup(cffont, glyph);
621       if (gid < 1 || gid >= cffont->cstrings->count) {
622 	WARN("Glyph \"%s\" missing in font \"%s\".", glyph, fontname);
623 	usedchars[code] = 0;
624 	continue;
625       }
626 
627       for (duplicate = 0; duplicate < code; duplicate++) {
628 	if (usedchars[duplicate] &&
629 	    enc_vec[duplicate]   && !strcmp(enc_vec[duplicate], glyph))
630 	  break;
631       }
632 
633       sid = cff_add_string(cffont, glyph, 1); /* FIXME */
634       if (duplicate < code) { /* found duplicates */
635 	cffont->encoding->supp[cffont->encoding->num_supps].code  = duplicate;
636 	cffont->encoding->supp[cffont->encoding->num_supps].glyph = sid;
637 	cffont->encoding->num_supps += 1;
638       } else {
639 	GIDMap[num_glyphs] = (card16) gid;
640 	charset->data.glyphs[charset->num_entries] = sid;
641 	charset->num_entries += 1;
642 	if (code != prev + 1) {
643 	  cffont->encoding->num_entries += 1;
644 	  cffont->encoding->data.range1[cffont->encoding->num_entries-1].first  = code;
645 	  cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left = 0;
646 	} else {
647 	  cffont->encoding->data.range1[cffont->encoding->num_entries-1].n_left += 1;
648 	}
649 	prev = code;
650 	num_glyphs++;
651 
652 	if (verbose > 2) {
653 	  MESG("/%s", glyph);
654 	}
655 
656       }
657     }
658     if (cffont->encoding->num_supps > 0) {
659       cffont->encoding->format |= 0x80;
660     } else {
661       RELEASE(cffont->encoding->supp); /* FIXME */
662       cffont->encoding->supp = NULL;
663     }
664   }
665 
666   widths = NEW(cffont->cstrings->count, double);
667   /*
668    * No more string will be added.
669    * The Type 1 seac operator may add another glyph but the glyph name of
670    * those glyphs are contained in standard string. The String Index will
671    * not be modified after here.
672    * BUT: We cannot update the String Index yet because then we wouldn't be
673    * able to find the GIDs of the base and accent characters (unless they
674    * have been used already).
675    */
676 
677   {
678     cff_index *cstring;
679     t1_ginfo   gm;
680     card16     gid, gid_orig;
681     long       dstlen_max, srclen;
682     card8     *srcptr, *dstptr;
683 
684     offset  = dstlen_max = 0L;
685     cstring = cff_new_index(cffont->cstrings->count);
686     cstring->data      = NULL;
687     cstring->offset[0] = 1;
688 
689     /* The num_glyphs increases if "seac" operators are used. */
690     for (gid = 0; gid < num_glyphs; gid++) {
691       if (offset + CS_STR_LEN_MAX >= dstlen_max) {
692 	dstlen_max += CS_STR_LEN_MAX * 2;
693 	cstring->data = RENEW(cstring->data, dstlen_max, card8);
694       }
695       gid_orig = GIDMap[gid];
696 
697       dstptr   = cstring->data + cstring->offset[gid] - 1;
698       srcptr   = cffont->cstrings->data + cffont->cstrings->offset[gid_orig] - 1;
699       srclen   = cffont->cstrings->offset[gid_orig + 1] - cffont->cstrings->offset[gid_orig];
700 
701       offset  += t1char_convert_charstring(dstptr, CS_STR_LEN_MAX,
702 					   srcptr, srclen,
703 					   cffont->subrs[0], defaultwidth, nominalwidth, &gm);
704       cstring->offset[gid + 1] = offset + 1;
705       if (gm.use_seac) {
706 	long  bchar_gid, achar_gid, i;
707 	const char *bchar_name, *achar_name;
708 
709 	/*
710 	 * NOTE:
711 	 *  1. seac.achar and seac.bchar must be contained in the CFF standard string.
712 	 *  2. Those characters need not to be encoded.
713 	 *  3. num_glyphs == charsets->num_entries + 1.
714 	 */
715 	achar_name = t1_get_standard_glyph(gm.seac.achar);
716 	achar_gid  = cff_glyph_lookup(cffont, achar_name);
717 	bchar_name = t1_get_standard_glyph(gm.seac.bchar);
718 	bchar_gid  = cff_glyph_lookup(cffont, bchar_name);
719 	if (achar_gid < 0) {
720 	  WARN("Accent char \"%s\" not found. Invalid use of \"seac\" operator.",
721 	       achar_name);
722 	  continue;
723 	}
724 	if (bchar_gid < 0) {
725 	  WARN("Base char \"%s\" not found. Invalid use of \"seac\" operator.",
726 	       bchar_name);
727 	  continue;
728 	}
729 
730 	for (i = 0; i < num_glyphs; i++) {
731 	  if (GIDMap[i] == achar_gid)
732 	    break;
733 	}
734 	if (i == num_glyphs) {
735 	  if (verbose > 2)
736 	    MESG("/%s", achar_name);
737 	  GIDMap[num_glyphs++] = achar_gid;
738 	  charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, achar_name);
739 	  charset->num_entries += 1;
740 	}
741 
742 	for (i = 0; i < num_glyphs; i++) {
743 	  if (GIDMap[i] == bchar_gid)
744 	    break;
745 	}
746 	if (i == num_glyphs) {
747 	  if (verbose > 2)
748 	    MESG("/%s", bchar_name);
749 	  GIDMap[num_glyphs++] = bchar_gid;
750 	  charset->data.glyphs[charset->num_entries] = cff_get_seac_sid(cffont, bchar_name);
751 	  charset->num_entries += 1;
752 	}
753       }
754       widths[gid] = gm.wx;
755     }
756     cstring->count = num_glyphs;
757 
758     cff_release_index(cffont->subrs[0]);
759     cffont->subrs[0] = NULL;
760     RELEASE(cffont->subrs);
761     cffont->subrs    = NULL;
762 
763     cff_release_index(cffont->cstrings);
764     cffont->cstrings = cstring;
765 
766     cff_release_charsets(cffont->charsets);
767     cffont->charsets = charset;
768   }
769   if (verbose > 2)
770     MESG("]");
771 
772   /* Now we can update the String Index */
773   cff_dict_update  (cffont->topdict,    cffont);
774   cff_dict_update  (cffont->private[0], cffont);
775   cff_update_string(cffont);
776 
777   add_metrics(font, cffont, enc_vec, widths, num_glyphs);
778 
779   offset = write_fontfile(font, cffont);
780   if (verbose > 1)
781     MESG("[%u glyphs][%ld bytes]", num_glyphs, offset);
782 
783   cff_close(cffont);
784 
785   /* Cleanup */
786   if (encoding_id < 0 && enc_vec) {
787     for (code = 0; code < 256; code++) {
788       if (enc_vec[code])
789 	RELEASE(enc_vec[code]);
790       enc_vec[code] = NULL;
791     }
792     RELEASE(enc_vec);
793   }
794   if (widths)
795     RELEASE(widths);
796   if (GIDMap)
797     RELEASE(GIDMap);
798 
799   /*
800    * Maybe writing Charset is recommended for subsetted font.
801    */
802 
803   return 0;
804 }
805