Back to index

texmacs  1.0.7.15
cid.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/cid.c,v 1.33 2009/05/06 01:50:55 matthias Exp $
00002     
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012     
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017     
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00021 */
00022 
00023 /*
00024  * CID-keyed font support:
00025  *
00026  *  See also, cidtype0, and cidtype2
00027  */
00028 
00029 #if HAVE_CONFIG_H
00030 #include "config.h"
00031 #endif
00032 
00033 #include <string.h>
00034 
00035 #include "system.h"
00036 #include "mem.h"
00037 #include "error.h"
00038 #include "dpxutil.h"
00039 
00040 #include "pdfobj.h"
00041 
00042 #include "cidtype0.h"
00043 #include "cidtype2.h"
00044 #include "cid_p.h"
00045 #include "cid.h"
00046 
00047 #define CIDFONT_DEBUG     3
00048 #define CIDFONT_DEBUG_STR "CIDFont"
00049 
00050 #define PDF_CID_SUPPORT_MIN 2
00051 #define PDF_CID_SUPPORT_MAX 6
00052 
00053 /*
00054  * Unicode and PDF Standard Character Collections.
00055  *
00056  *  Adobe-Identity is only for TrueType fonts and it means font's
00057  *  internal glyph ordering.
00058  */
00059 static struct {
00060   const char *registry;
00061   const char *ordering;
00062   /* Heighest Supplement values supported by PDF-1.0, 1.1, ...; see
00063    * also http://partners.adobe.com/public/developer/font/index.html#ckf
00064    */
00065   int   supplement[16];
00066 } CIDFont_stdcc_def[] = {
00067   {"Adobe", "UCS",      {-1, -1, 0, 0, 0, 0, 0, 0}}, 
00068   {"Adobe", "GB1",      {-1, -1, 0, 2, 4, 4, 4, 4}}, 
00069   {"Adobe", "CNS1",     {-1, -1, 0, 0, 3, 4, 4, 4}},
00070   {"Adobe", "Japan1",   {-1, -1, 2, 2, 4, 5, 6, 6}},
00071   {"Adobe", "Korea1",   {-1, -1, 1, 1, 2, 2, 2, 2}},
00072   {"Adobe", "Identity", {-1, -1, 0, 0, 0, 0, 0, 0}},
00073   {NULL, NULL, {0,0,0,0,0,0,0,0}}
00074 };
00075 #define UCS_CC    0
00076 #define ACC_START 1
00077 #define ACC_END   4
00078 
00079 CIDSysInfo CSI_IDENTITY = {
00080   (char *) "Adobe",
00081   (char *) "Identity",
00082   0
00083 };
00084 
00085 CIDSysInfo CSI_UNICODE = {
00086   (char *) "Adobe",
00087   (char *) "UCS",
00088   0
00089 };
00090 
00091 /*
00092  * Optional supplement after alias name.
00093  */
00094 static struct {
00095   const char *name;
00096   int   index;
00097 } CIDFont_stdcc_alias[] = {
00098   {"AU",     0}, {"AG1",    1}, {"AC1",    2}, {"AJ1",    3}, {"AK1",    4}, {"AI", 5},
00099   {"UCS",    0}, {"GB1",    1}, {"CNS1",   2}, {"Japan1", 3}, {"Korea1", 4}, {"Identity", 5},
00100   {"U",      0}, {"G",      1}, {"C",      2}, {"J",      3}, {"K",      4}, {"I", 5},
00101   {NULL,     0}
00102 };
00103 
00104 static void release_opt (cid_opt *opt);
00105 static CIDSysInfo *get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt);
00106 
00107 static int   __verbose   = 0;
00108 static long  cidoptflags = 0;
00109 
00110 void
00111 CIDFont_set_verbose (void)
00112 {
00113   CIDFont_type0_set_verbose();
00114   CIDFont_type2_set_verbose();
00115   __verbose++;
00116 }
00117 
00118 #if 0
00119 int
00120 CIDFont_require_version (void)
00121 {
00122   return PDF_CID_SUPPORT_MIN;
00123 }
00124 #endif
00125 
00126 CIDFont *
00127 CIDFont_new (void)
00128 {
00129   CIDFont *font = NULL;
00130 
00131   font = NEW(1, struct CIDFont);
00132 
00133   font->name     = NULL;
00134   font->fontname = NULL;
00135   font->ident    = NULL;
00136 
00137   /*
00138    * CIDFont
00139    */
00140   font->subtype = -1;
00141   font->flags   = FONT_FLAG_NONE;
00142   font->csi     = NULL;
00143   font->options = NULL;
00144   (font->parent)[0] = -1; /* Horizontal */
00145   (font->parent)[1] = -1; /* Vertical   */
00146 
00147   /*
00148    * PDF Font Resource
00149    */
00150   font->indirect = NULL;
00151   font->fontdict = NULL;
00152   font->descriptor = NULL;
00153 
00154   return font;
00155 }
00156 
00157 /* It does write PDF objects. */
00158 void
00159 CIDFont_flush (CIDFont *font)
00160 {
00161   if (font) {
00162     if (font->indirect)   pdf_release_obj(font->indirect);
00163     font->indirect = NULL;
00164     if (font->fontdict)   pdf_release_obj(font->fontdict);
00165     font->fontdict = NULL;
00166     if (font->descriptor) pdf_release_obj(font->descriptor);
00167     font->descriptor = NULL;
00168   }
00169 }
00170 
00171 void
00172 CIDFont_release (CIDFont *font)
00173 {
00174   if (font) {
00175     switch(font->subtype) {
00176     case CIDFONT_TYPE0:
00177       CIDFont_type0_release(font);
00178       break;
00179     case CIDFONT_TYPE2:
00180       CIDFont_type2_release(font);
00181       break;
00182     }
00183     if (font->indirect)
00184       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
00185     if (font->fontdict)
00186       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
00187     if (font->descriptor)
00188       ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR);
00189 
00190     if (font->fontname) RELEASE(font->fontname);
00191     if (font->name)     RELEASE(font->name);
00192     if (font->ident)    RELEASE(font->ident);
00193     if (font->csi) {
00194       if (font->csi->registry)
00195        RELEASE(font->csi->registry);
00196       if (font->csi->ordering)
00197        RELEASE(font->csi->ordering);
00198       RELEASE(font->csi);
00199     }
00200     if (font->options)
00201       release_opt(font->options);
00202   }
00203 }
00204 
00205 char *
00206 CIDFont_get_fontname (CIDFont *font)
00207 {
00208   ASSERT(font);
00209   return font->fontname;
00210 }
00211 
00212 char *
00213 CIDFont_get_ident (CIDFont *font)
00214 {
00215   ASSERT(font);
00216   return font->ident;
00217 }
00218 
00219 int
00220 CIDFont_get_opt_index (CIDFont *font)
00221 {
00222   int  opt_index;
00223 
00224   ASSERT(font);
00225 
00226   if (font->options)
00227     opt_index = font->options->index;
00228   else {
00229     opt_index = 0;
00230   }
00231 
00232   return opt_index;
00233 }
00234 
00235 int
00236 CIDFont_get_subtype (CIDFont *font)
00237 {
00238   ASSERT(font);
00239   return font->subtype;
00240 }
00241 
00242 int
00243 CIDFont_get_embedding (CIDFont *font)
00244 {
00245   ASSERT(font);
00246   return font->options->embed;
00247 }
00248 
00249 CIDSysInfo *
00250 CIDFont_get_CIDSysInfo (CIDFont *font)
00251 {
00252   ASSERT(font);
00253 
00254   return font->csi;
00255 }
00256 
00257 /*
00258  * Returns ID of parent Type0 font
00259  *  wmode: 0 for horizontal, 1 for vertical
00260  */
00261 int
00262 CIDFont_get_parent_id (CIDFont *font, int wmode)
00263 {
00264   ASSERT(font);
00265 
00266   if (wmode < 0 || wmode > 1)
00267     ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR);
00268 
00269   return (font->parent)[wmode];
00270 }
00271 
00272 pdf_obj *
00273 CIDFont_get_resource (CIDFont *font)
00274 {
00275   ASSERT(font);
00276 
00277   if (!font->indirect)
00278     font->indirect = pdf_ref_obj(font->fontdict);
00279 
00280   return pdf_link_obj(font->indirect);
00281 }
00282 
00283 /*
00284  * Set parent Type0 font.
00285  */
00286 void
00287 CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode)
00288 {
00289   ASSERT(font);
00290 
00291   if (wmode < 0 || wmode > 1)
00292     ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR);
00293 
00294   if (font->parent[wmode] >= 0)
00295     WARN("%s: CIDFont already have a parent Type1 font.", CIDFONT_DEBUG_STR);
00296 
00297   font->parent[wmode] = parent_id;
00298 }
00299 
00300 int
00301 CIDFont_is_ACCFont (CIDFont *font)
00302 {
00303   int   i;
00304 
00305   ASSERT(font);
00306 
00307   if (!font->csi)
00308     ERROR("%s: CIDSystemInfo undefined.", CIDFONT_DEBUG_STR);
00309 
00310   for (i = ACC_START; i <= ACC_END ; i++) {
00311     if (!strcmp(font->csi->registry, CIDFont_stdcc_def[i].registry) &&
00312        !strcmp(font->csi->ordering, CIDFont_stdcc_def[i].ordering))
00313       return 1;
00314   }
00315 
00316   return 0;
00317 }
00318 
00319 int
00320 CIDFont_is_UCSFont (CIDFont *font)
00321 {
00322   ASSERT(font);
00323   if (!strcmp(font->csi->ordering, "UCS") ||
00324       !strcmp(font->csi->ordering, "UCS2"))
00325     return 1;
00326   return 0;
00327 }
00328 
00329 /* FIXME */
00330 int
00331 CIDFont_get_flag (CIDFont *font, int mask)
00332 {
00333   ASSERT(font);
00334   return ((font->flags & mask) ? 1 : 0);
00335 }
00336 
00337 static void
00338 CIDFont_dofont (CIDFont *font)
00339 {
00340   if (!font || !font->indirect)
00341     return;
00342 
00343   if (__verbose)
00344     MESG(":%s", font->ident);
00345   if (__verbose > 1) {
00346     if (font->fontname)
00347       MESG("[%s]", font->fontname);
00348   }
00349 
00350   switch (font->subtype) {
00351   case CIDFONT_TYPE0:
00352     if(__verbose)
00353       MESG("[CIDFontType0]");
00354     if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1))
00355       CIDFont_type0_t1dofont(font);
00356     else if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1C))
00357       CIDFont_type0_t1cdofont(font);
00358     else
00359       CIDFont_type0_dofont(font);
00360     break;
00361   case CIDFONT_TYPE2:
00362     if(__verbose)
00363       MESG("[CIDFontType2]");
00364     CIDFont_type2_dofont(font);
00365     break;
00366   default:
00367     ERROR("%s: Unknown CIDFontType %d.", CIDFONT_DEBUG_STR, font->subtype);
00368     break;
00369   }
00370 }
00371 
00372 
00373 /*
00374  *
00375  */
00376 int
00377 CIDFont_is_BaseFont (CIDFont *font)
00378 {
00379   ASSERT(font);
00380   return (font->flags & FONT_FLAG_BASEFONT) ? 1 : 0;
00381 }
00382 
00383 #include "pdfparse.h"
00384 #include "cid_basefont.h"
00385 
00386 static int CIDFont_base_open (CIDFont *font,
00387                               const char *name, CIDSysInfo *cmap_csi, cid_opt *opt);
00388 
00389 static int
00390 CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt)
00391 {
00392   pdf_obj *fontdict, *descriptor;
00393   char    *fontname = NULL;
00394   int      idx;
00395 
00396   ASSERT(font);
00397 
00398   for (idx = 0; cid_basefont[idx].fontname != NULL; idx++) {
00399     if (!strcmp(name, cid_basefont[idx].fontname) ||
00400         (strlen(name) == strlen(cid_basefont[idx].fontname) - strlen("-Acro") &&
00401          !strncmp(name, cid_basefont[idx].fontname,
00402                   strlen(cid_basefont[idx].fontname)-strlen("-Acro")))
00403         )
00404       break;
00405   }
00406 
00407   if (cid_basefont[idx].fontname == NULL)
00408     return -1;
00409 
00410   fontname = NEW(strlen(name)+12, char);
00411   memset(fontname, 0, strlen(name)+12);
00412   strcpy(fontname, name);
00413 
00414   switch (opt->style) {
00415   case FONT_STYLE_BOLD:
00416     strcat(fontname, ",Bold");
00417     break;
00418   case FONT_STYLE_ITALIC:
00419     strcat(fontname, ",Italic");
00420     break;
00421   case FONT_STYLE_BOLDITALIC:
00422     strcat(fontname, ",BoldItalic");
00423     break;
00424   }
00425   {
00426     const char *start;
00427     const char *end;
00428 
00429     start = cid_basefont[idx].fontdict;
00430     end   = start + strlen(start);
00431     fontdict   = parse_pdf_dict((char **)&start, (char *)end, NULL);
00432     start = cid_basefont[idx].descriptor;
00433     end   = start + strlen(start);
00434     descriptor = parse_pdf_dict((char **)&start, (char *)end, NULL);
00435 
00436     ASSERT(fontdict && descriptor);
00437   }
00438 
00439   font->fontname = fontname;
00440   font->flags   |= FONT_FLAG_BASEFONT;
00441   {
00442     char    *registry, *ordering;
00443     int      supplement;
00444     pdf_obj *tmp;
00445 
00446     tmp = pdf_lookup_dict(fontdict, "CIDSystemInfo");
00447 
00448     ASSERT( tmp && pdf_obj_typeof(tmp) == PDF_DICT );
00449 
00450     registry   = pdf_string_value(pdf_lookup_dict(tmp, "Registry"));
00451     ordering   = pdf_string_value(pdf_lookup_dict(tmp, "Ordering"));
00452     supplement = pdf_number_value(pdf_lookup_dict(tmp, "Supplement"));
00453     if (cmap_csi) { /* NULL for accept any */
00454       if (strcmp(registry, cmap_csi->registry) ||
00455           strcmp(ordering, cmap_csi->ordering))
00456         ERROR("Inconsistent CMap used for CID-keyed font %s.",
00457               cid_basefont[idx].fontname);
00458       else if (supplement < cmap_csi->supplement) {
00459         WARN("CMap has higher supplement number than CIDFont: %s", fontname);
00460         WARN("Some chracters may not be displayed or printed.");
00461       }
00462     }
00463     font->csi = NEW(1, CIDSysInfo);
00464     font->csi->registry = NEW(strlen(registry)+1, char);
00465     font->csi->ordering = NEW(strlen(ordering)+1, char);
00466     strcpy(font->csi->registry, registry);
00467     strcpy(font->csi->ordering, ordering);
00468     font->csi->supplement = supplement;
00469   }
00470 
00471   {
00472     pdf_obj *tmp;
00473     char    *type;
00474 
00475     tmp  = pdf_lookup_dict(fontdict, "Subtype");
00476     ASSERT( tmp != NULL && pdf_obj_typeof(tmp) == PDF_NAME );
00477 
00478     type = pdf_name_value(tmp);
00479     if (!strcmp(type, "CIDFontType0"))
00480       font->subtype = CIDFONT_TYPE0;
00481     else if (!strcmp(type, "CIDFontType2"))
00482       font->subtype = CIDFONT_TYPE2;
00483     else {
00484       ERROR("Unknown CIDFontType \"%s\"", type);
00485     }
00486   }
00487 
00488   if (cidoptflags & CIDFONT_FORCE_FIXEDPITCH) {
00489     if (pdf_lookup_dict(fontdict, "W")) {
00490        pdf_remove_dict(fontdict, "W");
00491     }
00492     if (pdf_lookup_dict(fontdict, "W2")) {
00493        pdf_remove_dict(fontdict, "W2");
00494     }
00495   }
00496 
00497   pdf_add_dict(fontdict,   pdf_new_name("Type"),     pdf_new_name("Font"));
00498   pdf_add_dict(fontdict,   pdf_new_name("BaseFont"), pdf_new_name(fontname));
00499   pdf_add_dict(descriptor, pdf_new_name("Type"),     pdf_new_name("FontDescriptor"));
00500   pdf_add_dict(descriptor, pdf_new_name("FontName"), pdf_new_name(fontname));
00501 
00502   font->fontdict   = fontdict;
00503   font->descriptor = descriptor;
00504 
00505   opt->embed = 0;
00506 
00507   return  0;
00508 }
00509 
00510 
00511 
00512 #define CACHE_ALLOC_SIZE  16u
00513 
00514 struct FontCache {
00515   int       num;
00516   int       max;
00517   CIDFont **fonts;
00518 };
00519 
00520 static struct FontCache *__cache   = NULL;
00521 
00522 #define CHECK_ID(n) do {\
00523                         if (! __cache)\
00524                            ERROR("%s: CIDFont cache not initialized.", CIDFONT_DEBUG_STR);\
00525                         if ((n) < 0 || (n) >= __cache->num)\
00526                            ERROR("%s: Invalid ID %d", CIDFONT_DEBUG_STR, (n));\
00527                     } while (0)
00528 
00529 void
00530 CIDFont_cache_init (void)
00531 {
00532   if (__cache)
00533     ERROR("%s: Already initialized.", CIDFONT_DEBUG_STR);
00534 
00535   __cache = NEW(1, struct FontCache);
00536 
00537   __cache->max  = CACHE_ALLOC_SIZE;
00538   __cache->fonts = NEW(__cache->max, struct CIDFont *);
00539   __cache->num  = 0;
00540 }
00541 
00542 CIDFont *
00543 CIDFont_cache_get (int font_id)
00544 {
00545   CHECK_ID(font_id);
00546   return __cache->fonts[font_id];
00547 }
00548 
00549 /*
00550  * cmap_csi is NULL if CMap is Identity.
00551  */
00552 int
00553 CIDFont_cache_find (const char *map_name,
00554                   CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt)
00555 {
00556   int      font_id = -1;
00557   CIDFont *font    = NULL;
00558   cid_opt *opt     = NULL;
00559 
00560   if (!__cache)
00561     CIDFont_cache_init();
00562 
00563   opt  = NEW(1, cid_opt);
00564   opt->style = fmap_opt->style;
00565   opt->index = fmap_opt->index;
00566   opt->embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1;
00567   opt->name  = NULL;
00568   opt->csi   = get_cidsysinfo(map_name, fmap_opt);
00569   opt->stemv = fmap_opt->stemv;
00570 
00571   if (!opt->csi && cmap_csi) {
00572     /*
00573      * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available.
00574      * It is not neccesary for CID-keyed fonts. But TrueType requires them.
00575      */
00576     opt->csi = NEW(1, CIDSysInfo);
00577     opt->csi->registry   = NEW(strlen(cmap_csi->registry)+1, char);
00578     strcpy(opt->csi->registry, cmap_csi->registry);
00579     opt->csi->ordering   = NEW(strlen(cmap_csi->ordering)+1, char);
00580     strcpy(opt->csi->ordering, cmap_csi->ordering);
00581     opt->csi->supplement = cmap_csi->supplement;
00582   }
00583   /*
00584    * Here, we do not compare font->ident and map_name because of
00585    * implicit CIDSystemInfo supplied by CMap for TrueType.
00586    */
00587   for (font_id = 0; font_id < __cache->num; font_id++) {
00588     font = __cache->fonts[font_id];
00589     if (!strcmp(font->name, map_name) &&
00590        font->options->style == opt->style &&
00591        font->options->index == opt->index) {
00592       if (font->options->embed == opt->embed) {
00593        /*
00594         * Case 1: CSI not available (Identity CMap)
00595         *         Font is TrueType --> continue
00596         *         Font is CIDFont  --> break
00597         * Case 2: CSI matched      --> break
00598         */
00599        if (!opt->csi) {
00600          if (font->subtype == CIDFONT_TYPE2)
00601            continue;
00602          else
00603            break;
00604        } else if (!strcmp(font->csi->registry, opt->csi->registry) &&
00605                  !strcmp(font->csi->ordering, opt->csi->ordering)) {
00606          if (font->subtype == CIDFONT_TYPE2)
00607            font->csi->supplement =
00608              MAX(opt->csi->supplement, font->csi->supplement);
00609          break;
00610        }
00611       } else if (CIDFont_is_BaseFont(font)) {
00612        opt->embed = 0;
00613        break;
00614       }
00615     }
00616   }
00617 
00618   if (font_id < __cache->num && cmap_csi) {
00619     if (strcmp(font->csi->registry, cmap_csi->registry) ||
00620        strcmp(font->csi->ordering, cmap_csi->ordering))
00621       ERROR("%s: Incompatible CMap for CIDFont \"%s\"",
00622            CIDFONT_DEBUG_STR, map_name);
00623   }
00624 
00625   if (font_id == __cache->num) {
00626     font = CIDFont_new();
00627     if (CIDFont_type0_open(font, map_name, cmap_csi, opt)    < 0 &&
00628        CIDFont_type2_open(font, map_name, cmap_csi, opt)    < 0 &&
00629        CIDFont_type0_t1open(font, map_name, cmap_csi, opt)  < 0 &&
00630        CIDFont_type0_t1copen(font, map_name, cmap_csi, opt) < 0 &&
00631        CIDFont_base_open (font, map_name, cmap_csi, opt)    < 0
00632        ) {
00633       CIDFont_release(font);
00634       release_opt(opt);
00635       return -1;
00636     } else {
00637       if (__cache->num >= __cache->max) {
00638        __cache->max  += CACHE_ALLOC_SIZE;
00639        __cache->fonts = RENEW(__cache->fonts,
00640                             __cache->max, struct CIDFont *);
00641       }
00642       font->name    = NEW(strlen(map_name)+1, char);
00643       strcpy(font->name,  map_name);
00644       font->ident   = NEW(strlen(map_name)+1, char);
00645       strcpy(font->ident, map_name);
00646       font->options = opt;
00647       __cache->fonts[font_id] = font;
00648       (__cache->num)++;
00649     }
00650   } else if (opt) {
00651     release_opt(opt);
00652   }
00653 
00654   return font_id;
00655 }
00656 
00657 void
00658 CIDFont_cache_close (void)
00659 {
00660   int  font_id;
00661 
00662   if (__cache) {
00663     for (font_id = 0;
00664         font_id < __cache->num; font_id++) {
00665       CIDFont *font;
00666 
00667       font = __cache->fonts[font_id];
00668 
00669       if (__verbose)
00670        MESG("(CID");
00671 
00672       CIDFont_dofont (font);
00673       CIDFont_flush  (font);
00674       CIDFont_release(font);
00675 
00676       RELEASE(font);
00677 
00678       if (__verbose)
00679        MESG(")");
00680     }
00681     RELEASE(__cache->fonts);
00682     RELEASE(__cache);
00683     __cache = NULL;
00684   }
00685 }
00686 
00687 /******************************* OPTIONS *******************************/
00688 
00689 /*
00690  * FORMAT:
00691  *
00692  *   (:int:)?!?string(/string)?(,string)?
00693  */
00694 
00695 static void
00696 release_opt (cid_opt *opt)
00697 {
00698   if (opt->csi) {
00699     if (opt->csi->registry)
00700       RELEASE(opt->csi->registry);
00701     if (opt->csi->ordering)
00702       RELEASE(opt->csi->ordering);
00703     RELEASE(opt->csi);
00704   }
00705   RELEASE(opt);
00706 }
00707 
00708 static CIDSysInfo *
00709 get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt)
00710 {
00711   CIDSysInfo *csi = NULL;
00712   int pdf_ver;
00713   int i, csi_idx = -1, n, m;
00714 
00715   pdf_ver = pdf_get_version();
00716 
00717   if (!fmap_opt || !fmap_opt->charcoll)
00718     return NULL;
00719 
00720   /* First try alias for standard one. */
00721   for (i = 0; CIDFont_stdcc_alias[i].name != NULL; i++) {
00722     n = strlen(CIDFont_stdcc_alias[i].name);
00723     if (!strncmp(fmap_opt->charcoll,
00724                CIDFont_stdcc_alias[i].name, n)) {
00725       csi_idx  = CIDFont_stdcc_alias[i].index;
00726       csi = NEW(1, CIDSysInfo);
00727       csi->registry = NEW(strlen(CIDFont_stdcc_def[csi_idx].registry)+1, char);
00728       strcpy(csi->registry, CIDFont_stdcc_def[csi_idx].registry);
00729       csi->ordering = NEW(strlen(CIDFont_stdcc_def[csi_idx].ordering)+1, char);
00730       strcpy(csi->ordering, CIDFont_stdcc_def[csi_idx].ordering);
00731       if (strlen(fmap_opt->charcoll) > n) {
00732        csi->supplement = (int) strtoul(&(fmap_opt->charcoll[n]), NULL, 10);
00733       } else { /* Use heighest supported value for current output PDF version. */
00734        csi->supplement = CIDFont_stdcc_def[csi_idx].supplement[pdf_ver];
00735       }
00736       break;
00737     }
00738   }
00739   if (csi == NULL) {
00740     char *p, *q;
00741 
00742     p   = (char *) fmap_opt->charcoll;
00743     csi = NEW(1, CIDSysInfo);
00744 
00745     /* Full REGISTRY-ORDERING-SUPPLEMENT */
00746     p = strchr(fmap_opt->charcoll, '-');
00747     if (!p || p[1] == '\0')
00748       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
00749            CIDFONT_DEBUG_STR, fmap_opt->charcoll);
00750     p++;
00751 
00752     q = strchr(p, '-');
00753     if (!q || q[1] == '\0')
00754       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
00755            CIDFONT_DEBUG_STR, fmap_opt->charcoll);
00756     q++;
00757 
00758     if (!isdigit(q[0]))
00759       ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s",
00760            CIDFONT_DEBUG_STR, fmap_opt->charcoll);
00761 
00762     n = strlen(fmap_opt->charcoll) - strlen(p) - 1;
00763     csi->registry = NEW(n+1, char);
00764     memcpy(csi->registry, fmap_opt->charcoll, n);
00765     csi->registry[n] = '\0';
00766 
00767     m = strlen(p) - strlen(q) - 1;
00768     csi->ordering = NEW(m+1, char);
00769     memcpy(csi->ordering, p, m);
00770     csi->ordering[m] = '\0';
00771 
00772     csi->supplement = (int) strtoul(q, NULL, 10);
00773 
00774     /* Check for standart character collections. */
00775     for (i = 0; CIDFont_stdcc_def[i].ordering != NULL; i++) {
00776       if ((CIDFont_stdcc_def[i].registry &&
00777           !strcmp(csi->registry, CIDFont_stdcc_def[i].registry)) &&
00778          !strcmp(csi->ordering, CIDFont_stdcc_def[i].ordering)) {
00779        csi_idx = i;
00780        break;
00781       }
00782     }
00783   }
00784 
00785   if (csi && csi_idx >= 0) {
00786     if (csi->supplement > CIDFont_stdcc_def[csi_idx].supplement[pdf_ver]
00787        && (fmap_opt->flags & FONTMAP_OPT_NOEMBED)) {
00788       WARN("%s: Heighest supplement number supported in PDF-1.%d for %s-%s is %d.",
00789           CIDFONT_DEBUG_STR, pdf_ver, csi->registry, csi->ordering,
00790           CIDFont_stdcc_def[csi_idx].supplement[pdf_ver]);
00791       WARN("%s: Some character may not shown without embedded font (--> %s).",
00792           CIDFONT_DEBUG_STR, map_name);
00793     }
00794   }
00795 
00796   return csi;
00797 }
00798 
00799 void
00800 CIDFont_set_flags (long flags)
00801 {
00802   CIDFont_type0_set_flags(flags);
00803   CIDFont_type2_set_flags(flags);
00804   cidoptflags |= flags;
00805 }