OSDN Git Service

c1ccbaf05857a5b18951d8074ebd41e8b3b7e668
[putex/putex.git] / src / dvipdfmx-pu / src / cid.c
1 /*  
2     
3     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
4
5     Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6     the dvipdfmx project team.
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 /*
24  * CID-keyed font support:
25  *
26  *  See also, cidtype0, and cidtype2
27  */
28
29 #if HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34
35 #include "system.h"
36 #include "mem.h"
37 #include "error.h"
38 #include "dpxutil.h"
39
40 #include "pdfobj.h"
41
42 #include "cidtype0.h"
43 #include "cidtype2.h"
44 #include "cid_p.h"
45 #include "cid.h"
46
47 #define CIDFONT_DEBUG     3
48 #define CIDFONT_DEBUG_STR "CIDFont"
49
50 #define PDF_CID_SUPPORT_MIN 2
51 #define PDF_CID_SUPPORT_MAX 6
52
53 /*
54  * Unicode and PDF Standard Character Collections.
55  *
56  *  Adobe-Identity is only for TrueType fonts and it means font's
57  *  internal glyph ordering.
58  */
59 static struct {
60   const char *registry;
61   const char *ordering;
62   /* Heighest Supplement values supported by PDF-1.0, 1.1, ...; see
63    * also http://partners.adobe.com/public/developer/font/index.html#ckf
64    */
65   int   supplement[16];
66 } CIDFont_stdcc_def[] = {
67   {"Adobe", "UCS",      {-1, -1, 0, 0, 0, 0, 0, 0}}, 
68   {"Adobe", "GB1",      {-1, -1, 0, 2, 4, 4, 4, 4}}, 
69   {"Adobe", "CNS1",     {-1, -1, 0, 0, 3, 4, 4, 4}},
70   {"Adobe", "Japan1",   {-1, -1, 2, 2, 4, 5, 6, 6}},
71   {"Adobe", "Korea1",   {-1, -1, 1, 1, 2, 2, 2, 2}},
72   {"Adobe", "Identity", {-1, -1, 0, 0, 0, 0, 0, 0}},
73   {NULL,    NULL,       { 0,  0, 0, 0, 0, 0, 0, 0}}
74 };
75 #define UCS_CC    0
76 #define ACC_START 1
77 #define ACC_END   4
78
79 static char registry_Adobe[] = "Adobe";
80 static char ordering_Identity[] = "Identity";
81 static char ordering_UCS[] = "UCS";
82
83 CIDSysInfo CSI_IDENTITY = {
84   registry_Adobe,
85   ordering_Identity,
86   0
87 };
88
89 CIDSysInfo CSI_UNICODE = {
90   registry_Adobe,
91   ordering_UCS,
92   0
93 };
94
95 /*
96  * Optional supplement after alias name.
97  */
98 static struct {
99   const char *name;
100   int   index;
101 } CIDFont_stdcc_alias[] = {
102   {"AU",     0}, {"AG1",    1}, {"AC1",    2}, {"AJ1",    3}, {"AK1",    4}, {"AI", 5},
103   {"UCS",    0}, {"GB1",    1}, {"CNS1",   2}, {"Japan1", 3}, {"Korea1", 4}, {"Identity", 5},
104   {"U",      0}, {"G",      1}, {"C",      2}, {"J",      3}, {"K",      4}, {"I", 5},
105   {NULL,     0}
106 };
107
108 static void release_opt (cid_opt *opt);
109 static CIDSysInfo *get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt);
110
111 static int   __verbose   = 0;
112 static long  cidoptflags = 0;
113
114 void
115 CIDFont_set_verbose (void)
116 {
117   CIDFont_type0_set_verbose();
118   CIDFont_type2_set_verbose();
119   __verbose++;
120 }
121
122 #if 0
123 int
124 CIDFont_require_version (void)
125 {
126   return PDF_CID_SUPPORT_MIN;
127 }
128 #endif
129
130 CIDFont *
131 CIDFont_new (void)
132 {
133   CIDFont *font = NULL;
134
135   font = NEW(1, struct CIDFont);
136
137   font->name     = NULL;
138   font->fontname = NULL;
139   font->ident    = NULL;
140
141 #ifdef XETEX
142   font->ft_face = NULL;
143   font->ft_to_gid = NULL;
144 #endif
145
146   /*
147    * CIDFont
148    */
149   font->subtype = -1;
150   font->flags   = FONT_FLAG_NONE;
151   font->csi     = NULL;
152   font->options = NULL;
153   (font->parent)[0] = -1; /* Horizontal */
154   (font->parent)[1] = -1; /* Vertical   */
155
156   /*
157    * PDF Font Resource
158    */
159   font->indirect = NULL;
160   font->fontdict = NULL;
161   font->descriptor = NULL;
162
163   return font;
164 }
165
166 /* It does write PDF objects. */
167 void
168 CIDFont_flush (CIDFont *font)
169 {
170   if (font) {
171     if (font->indirect)   pdf_release_obj(font->indirect);
172     font->indirect = NULL;
173     if (font->fontdict)   pdf_release_obj(font->fontdict);
174     font->fontdict = NULL;
175     if (font->descriptor) pdf_release_obj(font->descriptor);
176     font->descriptor = NULL;
177   }
178 }
179
180 void
181 CIDFont_release (CIDFont *font)
182 {
183   if (font) {
184     switch(font->subtype) {
185     case CIDFONT_TYPE0:
186       CIDFont_type0_release(font);
187       break;
188     case CIDFONT_TYPE2:
189       CIDFont_type2_release(font);
190       break;
191     }
192     if (font->indirect)
193       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
194     if (font->fontdict)
195       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
196     if (font->descriptor)
197       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
198
199     if (font->fontname) RELEASE(font->fontname);
200     if (font->name)     RELEASE(font->name);
201     if (font->ident)    RELEASE(font->ident);
202     if (font->csi) {
203       if (font->csi->registry)
204         RELEASE(font->csi->registry);
205       if (font->csi->ordering)
206         RELEASE(font->csi->ordering);
207       RELEASE(font->csi);
208     }
209     if (font->options)
210       release_opt(font->options);
211   }
212 }
213
214 #ifdef XETEX
215 unsigned short *
216 CIDFont_get_ft_to_gid(CIDFont *font)
217 {
218   ASSERT(font);
219   return font->ft_to_gid;
220 }
221 #endif
222
223 char *
224 CIDFont_get_fontname (CIDFont *font)
225 {
226   ASSERT(font);
227   return font->fontname;
228 }
229
230 char *
231 CIDFont_get_ident (CIDFont *font)
232 {
233   ASSERT(font);
234   return font->ident;
235 }
236
237 int
238 CIDFont_get_opt_index (CIDFont *font)
239 {
240   int  opt_index;
241
242   ASSERT(font);
243
244   if (font->options)
245     opt_index = font->options->index;
246   else {
247     opt_index = 0;
248   }
249
250   return opt_index;
251 }
252
253 #ifdef XETEX
254 FT_Face
255 CIDFont_get_ft_face(CIDFont *font)
256 {
257   ASSERT(font);
258   return font->ft_face;
259 }
260 #endif
261
262 int
263 CIDFont_get_subtype (CIDFont *font)
264 {
265   ASSERT(font);
266   return font->subtype;
267 }
268
269 int
270 CIDFont_get_embedding (CIDFont *font)
271 {
272   ASSERT(font);
273   return font->options->embed;
274 }
275
276 CIDSysInfo *
277 CIDFont_get_CIDSysInfo (CIDFont *font)
278 {
279   ASSERT(font);
280
281   return font->csi;
282 }
283
284 /*
285  * Returns ID of parent Type0 font
286  *  wmode: 0 for horizontal, 1 for vertical
287  */
288 int
289 CIDFont_get_parent_id (CIDFont *font, int wmode)
290 {
291   ASSERT(font);
292
293   if (wmode < 0 || wmode > 1)
294     ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR);
295
296   return (font->parent)[wmode];
297 }
298
299 pdf_obj *
300 CIDFont_get_resource (CIDFont *font)
301 {
302   ASSERT(font);
303
304   if (!font->indirect)
305     font->indirect = pdf_ref_obj(font->fontdict);
306
307   return pdf_link_obj(font->indirect);
308 }
309
310 /*
311  * Set parent Type0 font.
312  */
313 void
314 CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode)
315 {
316   ASSERT(font);
317
318   if (wmode < 0 || wmode > 1)
319     ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR);
320
321   if (font->parent[wmode] >= 0)
322     WARN("%s: CIDFont already have a parent Type1 font.", CIDFONT_DEBUG_STR);
323
324   font->parent[wmode] = parent_id;
325 }
326
327 int
328 CIDFont_is_ACCFont (CIDFont *font)
329 {
330   int   i;
331
332   ASSERT(font);
333
334   if (!font->csi)
335     ERROR("%s: CIDSystemInfo undefined.", CIDFONT_DEBUG_STR);
336
337   for (i = ACC_START; i <= ACC_END ; i++) {
338     if (!strcmp(font->csi->registry, CIDFont_stdcc_def[i].registry) &&
339         !strcmp(font->csi->ordering, CIDFont_stdcc_def[i].ordering))
340       return 1;
341   }
342
343   return 0;
344 }
345
346 int
347 CIDFont_is_UCSFont (CIDFont *font)
348 {
349   ASSERT(font);
350   if (!strcmp(font->csi->ordering, "UCS") ||
351       !strcmp(font->csi->ordering, "UCS2"))
352     return 1;
353   return 0;
354 }
355
356 /* FIXME */
357 int
358 CIDFont_get_flag (CIDFont *font, int mask)
359 {
360   ASSERT(font);
361   return ((font->flags & mask) ? 1 : 0);
362 }
363
364 static void
365 CIDFont_dofont (CIDFont *font)
366 {
367   if (!font || !font->indirect)
368     return;
369
370   if (__verbose)
371     MESG(":%s", font->ident);
372   if (__verbose > 1) {
373     if (font->fontname)
374       MESG("[%s]", font->fontname);
375   }
376
377   switch (font->subtype) {
378   case CIDFONT_TYPE0:
379     if(__verbose)
380       MESG("[CIDFontType0]");
381     if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1))
382       CIDFont_type0_t1dofont(font);
383     else if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1C))
384       CIDFont_type0_t1cdofont(font);
385     else
386       CIDFont_type0_dofont(font);
387     break;
388   case CIDFONT_TYPE2:
389     if(__verbose)
390       MESG("[CIDFontType2]");
391     CIDFont_type2_dofont(font);
392     break;
393   default:
394     ERROR("%s: Unknown CIDFontType %d.", CIDFONT_DEBUG_STR, font->subtype);
395     break;
396   }
397 }
398
399
400 /*
401  *
402  */
403 int
404 CIDFont_is_BaseFont (CIDFont *font)
405 {
406   ASSERT(font);
407   return (font->flags & FONT_FLAG_BASEFONT) ? 1 : 0;
408 }
409
410 #include "pdfparse.h"
411 #include "cid_basefont.h"
412
413 static int CIDFont_base_open (CIDFont *font,
414                               const char *name, CIDSysInfo *cmap_csi, cid_opt *opt);
415
416 static int
417 CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt)
418 {
419   pdf_obj *fontdict, *descriptor;
420   char    *fontname = NULL;
421   int      idx;
422
423   ASSERT(font);
424
425   for (idx = 0; cid_basefont[idx].fontname != NULL; idx++) {
426     if (!strcmp(name, cid_basefont[idx].fontname) ||
427         (strlen(name) == strlen(cid_basefont[idx].fontname) - strlen("-Acro") &&
428          !strncmp(name, cid_basefont[idx].fontname,
429                   strlen(cid_basefont[idx].fontname)-strlen("-Acro")))
430         )
431       break;
432   }
433
434   if (cid_basefont[idx].fontname == NULL)
435     return -1;
436
437   fontname = NEW(strlen(name)+12, char);
438   memset(fontname, 0, strlen(name)+12);
439   strcpy(fontname, name);
440
441   switch (opt->style) {
442   case FONT_STYLE_BOLD:
443     strcat(fontname, ",Bold");
444     break;
445   case FONT_STYLE_ITALIC:
446     strcat(fontname, ",Italic");
447     break;
448   case FONT_STYLE_BOLDITALIC:
449     strcat(fontname, ",BoldItalic");
450     break;
451   }
452   {
453     const char *start;
454     const char *end;
455
456     start = cid_basefont[idx].fontdict;
457     end   = start + strlen(start);
458     fontdict   = parse_pdf_dict(&start, end, NULL);
459     start = cid_basefont[idx].descriptor;
460     end   = start + strlen(start);
461     descriptor = parse_pdf_dict(&start, end, NULL);
462
463     ASSERT(fontdict && descriptor);
464   }
465
466   font->fontname = fontname;
467   font->flags   |= FONT_FLAG_BASEFONT;
468   {
469     char    *registry, *ordering;
470     int      supplement;
471     pdf_obj *tmp;
472
473     tmp = pdf_lookup_dict(fontdict, "CIDSystemInfo");
474
475     ASSERT( tmp && pdf_obj_typeof(tmp) == PDF_DICT );
476
477     registry   = pdf_string_value(pdf_lookup_dict(tmp, "Registry"));
478     ordering   = pdf_string_value(pdf_lookup_dict(tmp, "Ordering"));
479     supplement = pdf_number_value(pdf_lookup_dict(tmp, "Supplement"));
480     if (cmap_csi) { /* NULL for accept any */
481       if (strcmp(registry, cmap_csi->registry) ||
482           strcmp(ordering, cmap_csi->ordering))
483         ERROR("Inconsistent CMap used for CID-keyed font %s.",
484               cid_basefont[idx].fontname);
485       else if (supplement < cmap_csi->supplement) {
486         WARN("CMap has higher supplement number than CIDFont: %s", fontname);
487         WARN("Some chracters may not be displayed or printed.");
488       }
489     }
490     font->csi = NEW(1, CIDSysInfo);
491     font->csi->registry = NEW(strlen(registry)+1, char);
492     font->csi->ordering = NEW(strlen(ordering)+1, char);
493     strcpy(font->csi->registry, registry);
494     strcpy(font->csi->ordering, ordering);
495     font->csi->supplement = supplement;
496   }
497
498   {
499     pdf_obj *tmp;
500     char    *type;
501
502     tmp  = pdf_lookup_dict(fontdict, "Subtype");
503     ASSERT( tmp != NULL && pdf_obj_typeof(tmp) == PDF_NAME );
504
505     type = pdf_name_value(tmp);
506     if (!strcmp(type, "CIDFontType0"))
507       font->subtype = CIDFONT_TYPE0;
508     else if (!strcmp(type, "CIDFontType2"))
509       font->subtype = CIDFONT_TYPE2;
510     else {
511       ERROR("Unknown CIDFontType \"%s\"", type);
512     }
513   }
514
515   if (cidoptflags & CIDFONT_FORCE_FIXEDPITCH) {
516     if (pdf_lookup_dict(fontdict, "W")) {
517        pdf_remove_dict(fontdict, "W");
518     }
519     if (pdf_lookup_dict(fontdict, "W2")) {
520        pdf_remove_dict(fontdict, "W2");
521     }
522   }
523
524   pdf_add_dict(fontdict,   pdf_new_name("Type"),     pdf_new_name("Font"));
525   pdf_add_dict(fontdict,   pdf_new_name("BaseFont"), pdf_new_name(fontname));
526   pdf_add_dict(descriptor, pdf_new_name("Type"),     pdf_new_name("FontDescriptor"));
527   pdf_add_dict(descriptor, pdf_new_name("FontName"), pdf_new_name(fontname));
528
529   font->fontdict   = fontdict;
530   font->descriptor = descriptor;
531
532   opt->embed = 0;
533
534   return  0;
535 }
536
537
538
539 #define CACHE_ALLOC_SIZE  16u
540
541 struct FontCache {
542   int       num;
543   int       max;
544   CIDFont **fonts;
545 };
546
547 static struct FontCache *__cache   = NULL;
548
549 #define CHECK_ID(n) do {\
550                         if (! __cache)\
551                            ERROR("%s: CIDFont cache not initialized.", CIDFONT_DEBUG_STR);\
552                         if ((n) < 0 || (n) >= __cache->num)\
553                            ERROR("%s: Invalid ID %d", CIDFONT_DEBUG_STR, (n));\
554                     } while (0)
555
556 void
557 CIDFont_cache_init (void)
558 {
559   if (__cache)
560     ERROR("%s: Already initialized.", CIDFONT_DEBUG_STR);
561
562   __cache = NEW(1, struct FontCache);
563
564   __cache->max  = CACHE_ALLOC_SIZE;
565   __cache->fonts = NEW(__cache->max, struct CIDFont *);
566   __cache->num  = 0;
567 }
568
569 CIDFont *
570 CIDFont_cache_get (int font_id)
571 {
572   CHECK_ID(font_id);
573   return __cache->fonts[font_id];
574 }
575
576 /*
577  * cmap_csi is NULL if CMap is Identity.
578  */
579 int
580 CIDFont_cache_find (const char *map_name,
581                     CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt)
582 {
583   int      font_id = -1;
584   CIDFont *font    = NULL;
585   cid_opt *opt     = NULL;
586
587   if (!__cache)
588     CIDFont_cache_init();
589
590   opt  = NEW(1, cid_opt);
591   opt->style = fmap_opt->style;
592   opt->index = fmap_opt->index;
593   opt->embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1;
594   opt->name  = NULL;
595   opt->csi   = get_cidsysinfo(map_name, fmap_opt);
596   opt->stemv = fmap_opt->stemv;
597
598   if (!opt->csi && cmap_csi) {
599     /*
600      * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available.
601      * It is not neccesary for CID-keyed fonts. But TrueType requires them.
602      */
603     opt->csi = NEW(1, CIDSysInfo);
604     opt->csi->registry   = NEW(strlen(cmap_csi->registry)+1, char);
605     strcpy(opt->csi->registry, cmap_csi->registry);
606     opt->csi->ordering   = NEW(strlen(cmap_csi->ordering)+1, char);
607     strcpy(opt->csi->ordering, cmap_csi->ordering);
608     opt->csi->supplement = cmap_csi->supplement;
609   }
610   /*
611    * Here, we do not compare font->ident and map_name because of
612    * implicit CIDSystemInfo supplied by CMap for TrueType.
613    */
614   for (font_id = 0; font_id < __cache->num; font_id++) {
615     font = __cache->fonts[font_id];
616     if (!strcmp(font->name, map_name) &&
617         font->options->style == opt->style &&
618         font->options->index == opt->index) {
619       if (font->options->embed == opt->embed) {
620         /*
621          * Case 1: CSI not available (Identity CMap)
622          *         Font is TrueType --> continue
623          *         Font is CIDFont  --> break
624          * Case 2: CSI matched      --> break
625          */
626         if (!opt->csi) {
627           if (font->subtype == CIDFONT_TYPE2)
628             continue;
629           else
630             break;
631         } else if (!strcmp(font->csi->registry, opt->csi->registry) &&
632                    !strcmp(font->csi->ordering, opt->csi->ordering)) {
633           if (font->subtype == CIDFONT_TYPE2)
634             font->csi->supplement =
635               MAX(opt->csi->supplement, font->csi->supplement);
636           break;
637         }
638       } else if (CIDFont_is_BaseFont(font)) {
639         opt->embed = 0;
640         break;
641       }
642     }
643   }
644
645   if (font_id < __cache->num && cmap_csi) {
646     if (strcmp(font->csi->registry, cmap_csi->registry) ||
647         strcmp(font->csi->ordering, cmap_csi->ordering))
648       ERROR("%s: Incompatible CMap for CIDFont \"%s\"",
649             CIDFONT_DEBUG_STR, map_name);
650   }
651
652   if (font_id == __cache->num) {
653     font = CIDFont_new();
654 #ifdef XETEX
655     font->ft_face = fmap_opt->ft_face;
656 #endif
657     if (CIDFont_type0_open(font, map_name, cmap_csi, opt)    < 0 &&
658         CIDFont_type2_open(font, map_name, cmap_csi, opt)    < 0 &&
659         CIDFont_type0_t1open(font, map_name, cmap_csi, opt)  < 0 &&
660         CIDFont_type0_t1copen(font, map_name, cmap_csi, opt) < 0 &&
661         CIDFont_base_open (font, map_name, cmap_csi, opt)    < 0
662         ) {
663       CIDFont_release(font);
664       release_opt(opt);
665       return -1;
666     } else {
667       if (__cache->num >= __cache->max) {
668         __cache->max  += CACHE_ALLOC_SIZE;
669         __cache->fonts = RENEW(__cache->fonts,
670                                __cache->max, struct CIDFont *);
671       }
672       font->name    = NEW(strlen(map_name)+1, char);
673       strcpy(font->name,  map_name);
674       font->ident   = NEW(strlen(map_name)+1, char);
675       strcpy(font->ident, map_name);
676       font->options = opt;
677       __cache->fonts[font_id] = font;
678       (__cache->num)++;
679     }
680   } else if (opt) {
681     release_opt(opt);
682   }
683
684   return font_id;
685 }
686
687 void
688 CIDFont_cache_close (void)
689 {
690   int  font_id;
691
692   if (__cache) {
693     for (font_id = 0;
694          font_id < __cache->num; font_id++) {
695       CIDFont *font;
696
697       font = __cache->fonts[font_id];
698
699       if (__verbose)
700         MESG("(CID");
701
702       CIDFont_dofont (font);
703       CIDFont_flush  (font);
704       CIDFont_release(font);
705
706       RELEASE(font);
707
708       if (__verbose)
709         MESG(")");
710     }
711     RELEASE(__cache->fonts);
712     RELEASE(__cache);
713     __cache = NULL;
714   }
715 }
716
717 /******************************* OPTIONS *******************************/
718
719 /*
720  * FORMAT:
721  *
722  *   (:int:)?!?string(/string)?(,string)?
723  */
724
725 static void
726 release_opt (cid_opt *opt)
727 {
728   if (opt->csi) {
729     if (opt->csi->registry)
730       RELEASE(opt->csi->registry);
731     if (opt->csi->ordering)
732       RELEASE(opt->csi->ordering);
733     RELEASE(opt->csi);
734   }
735   RELEASE(opt);
736 }
737
738 static CIDSysInfo *
739 get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt)
740 {
741   CIDSysInfo *csi = NULL;
742   int pdf_ver;
743   int i, csi_idx = -1, n, m;
744
745   pdf_ver = pdf_get_version();
746
747   if (!fmap_opt || !fmap_opt->charcoll)
748     return NULL;
749
750   /* First try alias for standard one. */
751   for (i = 0; CIDFont_stdcc_alias[i].name != NULL; i++) {
752     n = strlen(CIDFont_stdcc_alias[i].name);
753     if (!strncmp(fmap_opt->charcoll,
754                  CIDFont_stdcc_alias[i].name, n)) {
755       csi_idx  = CIDFont_stdcc_alias[i].index;
756       csi = NEW(1, CIDSysInfo);
757       csi->registry = NEW(strlen(CIDFont_stdcc_def[csi_idx].registry)+1, char);
758       strcpy(csi->registry, CIDFont_stdcc_def[csi_idx].registry);
759       csi->ordering = NEW(strlen(CIDFont_stdcc_def[csi_idx].ordering)+1, char);
760       strcpy(csi->ordering, CIDFont_stdcc_def[csi_idx].ordering);
761       if (strlen(fmap_opt->charcoll) > n) {
762         csi->supplement = (int) strtoul(&(fmap_opt->charcoll[n]), NULL, 10);
763       } else { /* Use heighest supported value for current output PDF version. */
764         csi->supplement = CIDFont_stdcc_def[csi_idx].supplement[pdf_ver];
765       }
766       break;
767     }
768   }
769   if (csi == NULL) {
770     char *p, *q;
771
772     p   = (char *) fmap_opt->charcoll;
773     csi = NEW(1, CIDSysInfo);
774
775     /* Full REGISTRY-ORDERING-SUPPLEMENT */
776     p = strchr(fmap_opt->charcoll, '-');
777     if (!p || p[1] == '\0')
778       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
779             CIDFONT_DEBUG_STR, fmap_opt->charcoll);
780     p++;
781
782     q = strchr(p, '-');
783     if (!q || q[1] == '\0')
784       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
785             CIDFONT_DEBUG_STR, fmap_opt->charcoll);
786     q++;
787
788     if (!isdigit(q[0]))
789       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
790             CIDFONT_DEBUG_STR, fmap_opt->charcoll);
791
792     n = strlen(fmap_opt->charcoll) - strlen(p) - 1;
793     csi->registry = NEW(n+1, char);
794     memcpy(csi->registry, fmap_opt->charcoll, n);
795     csi->registry[n] = '\0';
796
797     m = strlen(p) - strlen(q) - 1;
798     csi->ordering = NEW(m+1, char);
799     memcpy(csi->ordering, p, m);
800     csi->ordering[m] = '\0';
801
802     csi->supplement = (int) strtoul(q, NULL, 10);
803
804     /* Check for standart character collections. */
805     for (i = 0; CIDFont_stdcc_def[i].ordering != NULL; i++) {
806       if ((CIDFont_stdcc_def[i].registry &&
807            !strcmp(csi->registry, CIDFont_stdcc_def[i].registry)) &&
808           !strcmp(csi->ordering, CIDFont_stdcc_def[i].ordering)) {
809         csi_idx = i;
810         break;
811       }
812     }
813   }
814
815   if (csi && csi_idx >= 0) {
816     if (csi->supplement > CIDFont_stdcc_def[csi_idx].supplement[pdf_ver]
817         && (fmap_opt->flags & FONTMAP_OPT_NOEMBED)) {
818       WARN("%s: Heighest supplement number supported in PDF-1.%d for %s-%s is %d.",
819            CIDFONT_DEBUG_STR, pdf_ver, csi->registry, csi->ordering,
820            CIDFont_stdcc_def[csi_idx].supplement[pdf_ver]);
821       WARN("%s: Some character may not shown without embedded font (--> %s).",
822            CIDFONT_DEBUG_STR, map_name);
823     }
824   }
825
826   return csi;
827 }
828
829 void
830 CIDFont_set_flags (long flags)
831 {
832   CIDFont_type0_set_flags(flags);
833   CIDFont_type2_set_flags(flags);
834   cidoptflags |= flags;
835 }