Back to index

texmacs  1.0.7.15
cidtype0.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/cidtype0.c,v 1.39 2008/10/13 19:42:48 matthias Exp $
00002     
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2007 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  *  Only CFF/OpenType CID-Keyed Font with Type 2 charstrings is supported.
00027  *
00028  */ 
00029 
00030 #if HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include "system.h"
00035 #include "numbers.h"
00036 #include "mem.h"
00037 #include "error.h"
00038 
00039 #include "dpxfile.h"
00040 
00041 #include "pdfobj.h"
00042 /* pseudo unique tag */
00043 #include "pdffont.h"
00044 
00045 /* Font info. from OpenType tables */
00046 #include "sfnt.h"
00047 #include "tt_aux.h"
00048 /* Metrics */
00049 #include "tt_table.h"
00050 
00051 #include "cff_types.h"
00052 #include "cff_limits.h"
00053 #include "cff.h"
00054 #include "cff_dict.h"
00055 #include "cs_type2.h"
00056 
00057 /* typedef CID in cmap.h */
00058 #include "cmap.h"
00059 #include "type0.h"
00060 #include "cid.h"
00061 #include "cid_p.h"
00062 #include "cidtype0.h"
00063 
00064 static int  verbose   = 0;
00065 static long opt_flags = 0;
00066 
00067 void
00068 CIDFont_type0_set_verbose (void)
00069 {
00070   verbose++;
00071 }
00072 
00073 void
00074 CIDFont_type0_set_flags (long flags)
00075 {
00076   opt_flags = flags;
00077 }
00078 
00079 /*
00080  * PDF Reference 3rd. ed., p.340, "Glyph Metrics in CID Fonts".
00081  */
00082 #ifndef PDFUNIT
00083 #define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
00084 #endif
00085 
00086 static void
00087 add_CIDHMetrics (sfnt *sfont, pdf_obj *fontdict,
00088                unsigned char *CIDToGIDMap, unsigned short last_cid,
00089                struct tt_maxp_table *maxp,
00090                struct tt_head_table *head, struct tt_longMetrics *hmtx)
00091 {
00092   pdf_obj *w_array, *an_array = NULL;
00093   long   cid, start = 0, prev = 0;
00094   double defaultAdvanceWidth;
00095   int    empty = 1;
00096 
00097   defaultAdvanceWidth = PDFUNIT(hmtx[0].advance);
00098   /*
00099    * We alway use format:
00100    *  c [w_1 w_2 ... w_n]
00101    */
00102   w_array = pdf_new_array();
00103   for (cid = 0; cid <= last_cid; cid++) {
00104     USHORT gid;
00105     double advanceWidth;
00106     gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
00107     if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
00108       continue;
00109     advanceWidth = PDFUNIT(hmtx[gid].advance);
00110     if (advanceWidth == defaultAdvanceWidth) {
00111       if (an_array) {
00112        pdf_add_array(w_array, pdf_new_number(start));
00113        pdf_add_array(w_array, an_array);
00114        an_array = NULL;
00115        empty = 0;
00116       }
00117     } else {
00118       if (cid != prev + 1 &&  an_array) {
00119          pdf_add_array(w_array, pdf_new_number(start));
00120          pdf_add_array(w_array, an_array);
00121          an_array = NULL;
00122          empty = 0;
00123       }
00124       if (an_array == NULL) {
00125        an_array = pdf_new_array();
00126        start = cid;
00127       }
00128       pdf_add_array(an_array, pdf_new_number(advanceWidth));
00129       prev = cid;
00130     }
00131   }
00132 
00133   if (an_array) {
00134     pdf_add_array(w_array, pdf_new_number(start));
00135     pdf_add_array(w_array, an_array);
00136     empty = 0;
00137   }
00138 
00139   /*
00140    * We always write DW for older MacOS X's preview app.
00141    * PDF Reference 2nd. ed, wrongly described default value of DW as 0, and
00142    * MacOS X's (up to 10.2.8) preview app. implements this wrong description.
00143    */
00144   pdf_add_dict(fontdict,
00145               pdf_new_name("DW"),
00146               pdf_new_number(defaultAdvanceWidth));
00147   if (!empty) {
00148     pdf_add_dict(fontdict,
00149                pdf_new_name("W"),
00150                pdf_ref_obj(w_array));
00151   }
00152   pdf_release_obj(w_array);
00153 
00154   return;
00155 }
00156 
00157 static void
00158 add_CIDVMetrics (sfnt *sfont, pdf_obj *fontdict,
00159                unsigned char *CIDToGIDMap, unsigned short last_cid,
00160                struct tt_maxp_table *maxp,
00161                struct tt_head_table *head, struct tt_longMetrics *hmtx)
00162 {
00163   pdf_obj *w2_array, *an_array = NULL;
00164   long cid, prev, start;
00165   struct tt_VORG_table *vorg;
00166   struct tt_vhea_table *vhea  = NULL;
00167   struct tt_longMetrics *vmtx = NULL;
00168   double defaultAdvanceHeight, defaultVertOriginY;
00169   int    empty = 1;
00170 
00171   /*
00172    * No accurate vertical metrics can be obtained by simple way if the
00173    * font does not have VORG table. Only CJK fonts may have VORG.
00174    */
00175   if (sfnt_find_table_pos(sfont, "VORG") <= 0)
00176     return;
00177 
00178   vorg = tt_read_VORG_table(sfont);
00179   defaultVertOriginY = PDFUNIT(vorg->defaultVertOriginY);
00180   if (sfnt_find_table_pos(sfont, "vhea") > 0)
00181     vhea = tt_read_vhea_table(sfont);
00182   if (vhea && sfnt_find_table_pos(sfont, "vmtx") > 0) {
00183     sfnt_locate_table(sfont, "vmtx");
00184     vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
00185   }
00186 
00187   if (sfnt_find_table_pos(sfont, "OS/2") <= 0) {
00188     struct tt_os2__table *os2;
00189     /* OpenType font must have OS/2 table. */
00190     os2 = tt_read_os2__table(sfont);
00191     defaultVertOriginY   = PDFUNIT(os2->sTypoAscender);
00192     defaultAdvanceHeight = PDFUNIT(os2->sTypoAscender - os2->sTypoDescender);
00193     RELEASE(os2);
00194   } else {
00195     /* Some TrueType fonts used in Macintosh does not have OS/2 table. */
00196     defaultAdvanceHeight = 1000;
00197   }
00198 
00199   w2_array = pdf_new_array();
00200   start = prev = 0;
00201   for (cid = 0; cid <= last_cid; cid++) {
00202     USHORT i, gid;
00203     double advanceHeight, vertOriginX, vertOriginY;
00204     gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
00205     if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
00206       continue;
00207     advanceHeight = vmtx ? PDFUNIT(vmtx[gid].advance) : defaultAdvanceHeight;
00208     vertOriginX   = PDFUNIT(hmtx[gid].advance*0.5);
00209     vertOriginY   = defaultVertOriginY;
00210     for (i = 0;
00211         i < vorg->numVertOriginYMetrics && gid > vorg->vertOriginYMetrics[i].glyphIndex;
00212         i++) {
00213       if (gid == vorg->vertOriginYMetrics[i].glyphIndex)
00214        vertOriginY = PDFUNIT(vorg->vertOriginYMetrics[i].vertOriginY);
00215     }
00216 #if 0
00217     /*
00218      * c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...]
00219      * Not working... Why?
00220      * Acrobat Reader:
00221      *  Wrong rendering, interpretation of position vector is wrong.
00222      * Xpdf and gs: ignores W2?
00223      */
00224     if (vertOriginY == defaultVertOriginY &&
00225        advanceHeight == defaultAdvanceHeight) {
00226       if (an_array) {
00227        pdf_add_array(w2_array, pdf_new_number(start));
00228        pdf_add_array(w2_array, an_array);
00229        an_array = NULL;
00230        empty = 0;
00231       }
00232     } else {
00233       if (cid != prev + 1 && an_array) {
00234        pdf_add_array(w2_array, pdf_new_number(start));
00235        pdf_add_array(w2_array, an_array);
00236        an_array = NULL;
00237        empty = 0;
00238       }
00239       if (an_array == NULL) {
00240        an_array = pdf_new_array();
00241        start = cid;
00242       }
00243       pdf_add_array(an_array, pdf_new_number(-advanceHeight));
00244       pdf_add_array(an_array, pdf_new_number(vertOriginX));
00245       pdf_add_array(an_array, pdf_new_number(vertOriginY));
00246       prev = cid;
00247     }
00248 #else
00249     /*
00250      * c_first c_last w1_y v_x v_y
00251      * This form may hit Acrobat's implementation limit of array element size, 8192.
00252      * AFPL GhostScript 8.11 stops with rangecheck error with this. Maybe GS's bug?
00253      */
00254     if (vertOriginY != defaultVertOriginY ||
00255        advanceHeight != defaultAdvanceHeight) {
00256       pdf_add_array(w2_array, pdf_new_number(cid));
00257       pdf_add_array(w2_array, pdf_new_number(cid));
00258       pdf_add_array(w2_array, pdf_new_number(-advanceHeight));
00259       pdf_add_array(w2_array, pdf_new_number(vertOriginX));
00260       pdf_add_array(w2_array, pdf_new_number(vertOriginY));
00261       empty = 0;
00262     }
00263 #endif
00264   }
00265 
00266 #if 0
00267   if (an_array) {
00268     pdf_add_array(w2_array, pdf_new_number(start));
00269     pdf_add_array(w2_array, an_array);
00270     empty = 0;
00271   }
00272 #endif
00273 
00274   if (defaultVertOriginY != 880 || defaultAdvanceHeight != 1000) {
00275     an_array = pdf_new_array();
00276     pdf_add_array(an_array, pdf_new_number(defaultVertOriginY));
00277     pdf_add_array(an_array, pdf_new_number(-defaultAdvanceHeight));
00278     pdf_add_dict(fontdict, pdf_new_name ("DW2"), an_array);
00279   }
00280   if (!empty) {
00281     pdf_add_dict(fontdict,
00282                pdf_new_name("W2"), pdf_ref_obj(w2_array));
00283   }
00284   pdf_release_obj(w2_array);
00285 
00286   if (vorg->vertOriginYMetrics)
00287     RELEASE(vorg->vertOriginYMetrics);
00288   RELEASE(vorg);
00289 
00290   if (vmtx)
00291     RELEASE(vmtx);
00292   if (vhea)
00293     RELEASE(vhea);
00294 
00295   return;
00296 }
00297 
00298 static void
00299 add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict,
00300               unsigned char *CIDToGIDMap, unsigned short last_cid, int need_vmetrics)
00301 {
00302   struct tt_longMetrics *hmtx;
00303   struct tt_head_table  *head;
00304   struct tt_hhea_table  *hhea;
00305   struct tt_maxp_table  *maxp;
00306 
00307   /*
00308    * Read head, hhea, maxp:
00309    *
00310    *   unitsPerEm       --> head
00311    *   numHMetrics      --> hhea
00312    *   numGlyphs        --> maxp
00313    */
00314   head = tt_read_head_table(sfont);
00315   maxp = tt_read_maxp_table(sfont);
00316   hhea = tt_read_hhea_table(sfont);
00317 
00318   sfnt_locate_table(sfont, "hmtx");
00319   hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
00320 
00321   add_CIDHMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
00322   if (need_vmetrics)
00323     add_CIDVMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
00324 
00325   RELEASE(hmtx);
00326   RELEASE(hhea);
00327   RELEASE(maxp);
00328   RELEASE(head);
00329 
00330   return;
00331 }
00332 
00333 /*
00334  * Create an instance of embeddable font.
00335  */
00336 static long
00337 write_fontfile (CIDFont *font, cff_font *cffont)
00338 {
00339   cff_index *topdict, *fdarray, *private;
00340   unsigned char *dest;
00341   long destlen = 0, i, size;
00342   long offset, topdict_offset, fdarray_offset;
00343 
00344   /*  DICT sizes (offset set to long int) */
00345   topdict = cff_new_index(1);
00346   fdarray = cff_new_index(cffont->num_fds);
00347   private = cff_new_index(cffont->num_fds);
00348 
00349   cff_dict_remove(cffont->topdict, "UniqueID");
00350   cff_dict_remove(cffont->topdict, "XUID");
00351   cff_dict_remove(cffont->topdict, "Private");  /* some bad font may have */
00352   cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */
00353 
00354   topdict->offset[1] = cff_dict_pack(cffont->topdict,
00355                                  (card8 *) work_buffer,
00356                                  WORK_BUFFER_SIZE) + 1;
00357   for (i = 0;i < cffont->num_fds; i++) {
00358     size = 0;
00359     if (cffont->private && cffont->private[i]) {
00360       size = cff_dict_pack(cffont->private[i],
00361                         (card8 *) work_buffer, WORK_BUFFER_SIZE);
00362       if (size < 1) { /* Private had contained only Subr */
00363        cff_dict_remove(cffont->fdarray[i], "Private");
00364       }
00365     }
00366     (private->offset)[i+1] = (private->offset)[i] + size;
00367     (fdarray->offset)[i+1] = (fdarray->offset)[i] +
00368       cff_dict_pack(cffont->fdarray[i],
00369                   (card8 *) work_buffer, WORK_BUFFER_SIZE);
00370   }
00371 
00372   destlen = 4; /* header size */
00373   destlen += cff_set_name(cffont, font->fontname);
00374   destlen += cff_index_size(topdict);
00375   destlen += cff_index_size(cffont->string);
00376   destlen += cff_index_size(cffont->gsubr);
00377   destlen += (cffont->charsets->num_entries) * 2 + 1;  /* charset format 0 */
00378   destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */
00379   destlen += cff_index_size(cffont->cstrings);
00380   destlen += cff_index_size(fdarray);
00381   destlen += private->offset[private->count] - 1; /* Private is not INDEX */
00382 
00383   dest = NEW(destlen, card8);
00384 
00385   offset = 0;
00386   /* Header */
00387   offset += cff_put_header(cffont, dest + offset, destlen - offset);
00388   /* Name */
00389   offset += cff_pack_index(cffont->name, dest + offset, destlen - offset);
00390   /* Top DICT */
00391   topdict_offset = offset;
00392   offset += cff_index_size(topdict);
00393   /* Strings */
00394   offset += cff_pack_index(cffont->string, dest + offset, destlen - offset);
00395   /* Global Subrs */
00396   offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset);
00397 
00398   /* charset */
00399   cff_dict_set(cffont->topdict, "charset", 0, offset);
00400   offset += cff_pack_charsets(cffont, dest + offset, destlen - offset);
00401 
00402   /* FDSelect */
00403   cff_dict_set(cffont->topdict, "FDSelect", 0, offset);
00404   offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset);
00405 
00406   /* CharStrings */
00407   cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
00408   offset += cff_pack_index(cffont->cstrings,
00409                         dest + offset, cff_index_size(cffont->cstrings));
00410   cff_release_index(cffont->cstrings);
00411   cffont->cstrings = NULL; /* Charstrings cosumes huge memory */
00412 
00413   /* FDArray and Private */
00414   cff_dict_set(cffont->topdict, "FDArray", 0, offset);
00415   fdarray_offset = offset;
00416   offset += cff_index_size(fdarray);
00417 
00418   fdarray->data = NEW(fdarray->offset[fdarray->count] - 1, card8);
00419   for (i = 0; i < cffont->num_fds; i++) {
00420     size = private->offset[i+1] - private->offset[i];
00421     if (cffont->private[i] && size > 0) {
00422       cff_dict_pack(cffont->private[i], dest + offset, size);
00423       cff_dict_set(cffont->fdarray[i], "Private", 0, size);
00424       cff_dict_set(cffont->fdarray[i], "Private", 1, offset);
00425     }
00426     cff_dict_pack(cffont->fdarray[i],
00427                 fdarray->data + (fdarray->offset)[i] - 1,
00428                 fdarray->offset[fdarray->count] - 1);
00429     offset += size;
00430   }
00431 
00432   cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray));
00433   cff_release_index(fdarray);
00434   cff_release_index(private);
00435 
00436   /* Finally Top DICT */
00437   topdict->data = NEW(topdict->offset[topdict->count] - 1, card8);
00438   cff_dict_pack(cffont->topdict,
00439               topdict->data, topdict->offset[topdict->count] - 1);
00440   cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict));
00441   cff_release_index(topdict);
00442 
00443   /*
00444    * FontFile
00445    */
00446   {
00447     pdf_obj *fontfile, *stream_dict;
00448 
00449     fontfile    = pdf_new_stream(STREAM_COMPRESS);
00450     stream_dict = pdf_stream_dict(fontfile);
00451     pdf_add_dict(font->descriptor,
00452                pdf_new_name("FontFile3"),
00453                pdf_ref_obj (fontfile));
00454     pdf_add_dict(stream_dict,
00455                pdf_new_name("Subtype"),
00456                pdf_new_name("CIDFontType0C"));
00457     pdf_add_stream(fontfile, (char *) dest, offset);
00458     pdf_release_obj(fontfile);
00459     RELEASE(dest);
00460   }
00461 
00462   return destlen;
00463 }
00464 
00465 void
00466 CIDFont_type0_dofont (CIDFont *font)
00467 {
00468   sfnt     *sfont;
00469   cff_font *cffont;
00470   FILE     *fp;
00471   cff_index    *charstrings, *idx;
00472   cff_charsets *charset = NULL;
00473   cff_fdselect *fdselect = NULL;
00474   long   charstring_len, max_len;
00475   long   destlen = 0;
00476   long   size, offset = 0;
00477   card8 *data;
00478   card16 num_glyphs, gid;
00479   long   cid, cid_count;
00480   card16 cs_count, last_cid;
00481   int    fd, prev_fd, parent_id;
00482   char  *used_chars;
00483   unsigned char *CIDToGIDMap = NULL;
00484 
00485   ASSERT(font);
00486 
00487   if (!font->indirect)
00488     return;
00489 
00490   pdf_add_dict(font->fontdict, 
00491               pdf_new_name("FontDescriptor"),
00492               pdf_ref_obj (font->descriptor));
00493 
00494   if (CIDFont_is_BaseFont(font))
00495     return;
00496   else if (!CIDFont_get_embedding(font) &&
00497           (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) {
00498     /* No metrics needed. */
00499     pdf_add_dict(font->fontdict,
00500                pdf_new_name("DW"), pdf_new_number(1000.0));
00501     return;
00502   }
00503 
00504   if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
00505       (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
00506     ERROR("No parent Type 0 font !");
00507 
00508   used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
00509   if (!used_chars)
00510     ERROR("Unexpected error: Font not actually used???");
00511 
00512   fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
00513   if (!fp)
00514     ERROR("Could not open OpenType font file: %s", font->ident);
00515   sfont = sfnt_open(fp);
00516   if (!sfont)
00517     ERROR("Could not open OpenType font file: %s", font->ident);
00518 
00519   if (sfnt_read_table_directory(sfont, 0) < 0 ||
00520       sfont->type != SFNT_TYPE_POSTSCRIPT)
00521     ERROR("Not a CFF/OpenType font ?");
00522   offset = sfnt_find_table_pos(sfont, "CFF ");
00523   if (offset == 0)
00524     ERROR("Not a CFF/OpenType font ?");
00525 
00526   cffont = cff_open(fp, offset, font->options->index);
00527   if (!cffont)
00528     ERROR("Could not open CFF font.");
00529   if (!(cffont->flag & FONTTYPE_CIDFONT))
00530     ERROR("Not a CIDFont.");
00531 
00532   if (cff_dict_known(cffont->topdict, "CIDCount")) {
00533     cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0);
00534   } else {
00535     cid_count = CID_MAX + 1;
00536   }
00537 
00538   cff_read_charsets(cffont);
00539   CIDToGIDMap = NEW(2*cid_count, unsigned char);
00540   memset(CIDToGIDMap, 0, 2*cid_count);
00541   add_to_used_chars2(used_chars, 0); /* .notdef */
00542   cid = 0; last_cid = 0; num_glyphs = 0;
00543   for (cid = 0; cid <= CID_MAX; cid++) {
00544     if (is_used_char2(used_chars, cid)) {
00545       gid = cff_charsets_lookup(cffont, cid);
00546       if (cid != 0 && gid == 0) {
00547        WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->ident);
00548        used_chars[cid/8] &= ~(1 << (7 - (cid % 8)));
00549        continue;
00550       }
00551       CIDToGIDMap[2*cid]   = (gid >> 8) & 0xff;
00552       CIDToGIDMap[2*cid+1] = gid & 0xff;
00553       last_cid = cid;
00554       num_glyphs++;
00555     }
00556   }
00557 
00558   /*
00559    * DW, W, DW2 and W2:
00560    * Those values are obtained from OpenType table (not TFM).
00561    */
00562   if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
00563     pdf_add_dict(font->fontdict,
00564                pdf_new_name("DW"), pdf_new_number(1000.0));
00565   } else {
00566     add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
00567                  ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
00568   }
00569 
00570   if (!CIDFont_get_embedding(font)) {
00571     RELEASE(CIDToGIDMap);
00572     cff_close(cffont);
00573     sfnt_close(sfont);
00574     DPXFCLOSE(fp);
00575 
00576     return;
00577   }
00578 
00579   /*
00580    * Embed font subset.
00581    */
00582   cff_read_fdselect(cffont);
00583   cff_read_fdarray(cffont);
00584   cff_read_private(cffont);
00585 
00586   cff_read_subrs(cffont);
00587 
00588   offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
00589   cff_seek_set(cffont, offset);
00590   idx = cff_get_index_header(cffont);
00591   /* offset is now absolute offset ... bad */
00592   offset = ftell(cffont->stream);
00593   
00594   if ((cs_count = idx->count) < 2) {
00595     ERROR("No valid charstring data found.");
00596   }
00597 
00598   /* New Charsets data */
00599   charset = NEW(1, cff_charsets);
00600   charset->format = 0;
00601   charset->num_entries = 0;
00602   charset->data.glyphs = NEW(num_glyphs, s_SID);
00603 
00604   /* New FDSelect data */
00605   fdselect = NEW(1, cff_fdselect);
00606   fdselect->format = 3;
00607   fdselect->num_entries = 0;
00608   fdselect->data.ranges = NEW(num_glyphs, cff_range3);
00609 
00610   /* New CharStrings INDEX */
00611   charstrings = cff_new_index(num_glyphs+1);
00612   max_len = 2 * CS_STR_LEN_MAX;
00613   charstrings->data = NEW(max_len, card8);
00614   charstring_len = 0;
00615 
00616   /*
00617    * TODO: Re-assign FD number.
00618    */
00619   prev_fd = -1; gid = 0;
00620   data = NEW(CS_STR_LEN_MAX, card8);
00621   for (cid = 0; cid <= last_cid; cid++) {
00622     unsigned short gid_org;
00623 
00624     if (!is_used_char2(used_chars, cid))
00625       continue;
00626 
00627     gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]);
00628     if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org])
00629        > CS_STR_LEN_MAX)
00630       ERROR("Charstring too long: gid=%u", gid_org);
00631     if (charstring_len + CS_STR_LEN_MAX >= max_len) {
00632       max_len = charstring_len + 2 * CS_STR_LEN_MAX;
00633       charstrings->data = RENEW(charstrings->data, max_len, card8);
00634     }
00635     (charstrings->offset)[gid] = charstring_len + 1;
00636     seek_absolute(cffont->stream, offset + (idx->offset)[gid_org] - 1);
00637     fread(data, 1, size, cffont->stream);
00638     fd = cff_fdselect_lookup(cffont, gid_org);
00639     charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
00640                                     max_len - charstring_len,
00641                                     data, size,
00642                                     cffont->gsubr, (cffont->subrs)[fd], 0, 0, NULL);
00643     if (cid > 0 && gid_org > 0) {
00644       charset->data.glyphs[charset->num_entries] = cid;
00645       charset->num_entries += 1;
00646     }
00647     if (fd != prev_fd) {
00648       fdselect->data.ranges[fdselect->num_entries].first = gid;
00649       fdselect->data.ranges[fdselect->num_entries].fd    = fd;
00650       fdselect->num_entries += 1;
00651       prev_fd = fd;
00652     }
00653     gid++;
00654   }
00655   if (gid != num_glyphs)
00656     ERROR("Unexpeced error: ?????");
00657   RELEASE(data);
00658   cff_release_index(idx);
00659 
00660   RELEASE(CIDToGIDMap);
00661   
00662   (charstrings->offset)[num_glyphs] = charstring_len + 1;
00663   charstrings->count = num_glyphs;
00664   cffont->num_glyphs    = num_glyphs;
00665   cffont->cstrings      = charstrings;
00666   
00667   /* discard old one, set new data */
00668   cff_release_charsets(cffont->charsets);
00669   cffont->charsets = charset;
00670   cff_release_fdselect(cffont->fdselect);
00671   cffont->fdselect = fdselect;
00672 
00673   /* no Global subr */
00674   if (cffont->gsubr)
00675     cff_release_index(cffont->gsubr);
00676   cffont->gsubr = cff_new_index(0);
00677 
00678   for (fd = 0; fd < cffont->num_fds; fd++) {
00679     if (cffont->subrs && cffont->subrs[fd]) {
00680       cff_release_index(cffont->subrs[fd]);
00681       cffont->subrs[fd] = NULL;
00682     }
00683     if (cffont->private && (cffont->private)[fd]) {
00684       cff_dict_remove((cffont->private)[fd], "Subrs"); /* no Subrs */
00685     }
00686   }
00687 
00688   destlen = write_fontfile(font, cffont);
00689 
00690   cff_close(cffont);
00691   sfnt_close(sfont);
00692   DPXFCLOSE(fp);
00693 
00694   if (verbose > 1)
00695     MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen);
00696 
00697   /*
00698    * CIDSet:
00699    * Length of CIDSet stream is not clear. Must be 8192 bytes long?
00700    */
00701   {
00702     pdf_obj *cidset;
00703 
00704     cidset = pdf_new_stream(STREAM_COMPRESS);
00705     pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
00706     pdf_add_dict(font->descriptor,
00707                pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
00708     pdf_release_obj(cidset);
00709   }
00710 
00711   return;
00712 }
00713 
00714 int
00715 CIDFont_type0_open (CIDFont *font, const char *name,
00716                   CIDSysInfo *cmap_csi, cid_opt *opt)
00717 {
00718   CIDSysInfo *csi;
00719   char       *fontname;
00720   sfnt       *sfont;
00721   cff_font   *cffont;
00722   FILE       *fp;
00723   unsigned long offset = 0;
00724 
00725   ASSERT(font);
00726 
00727   fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
00728   if (!fp)
00729     return -1;
00730 
00731   sfont = sfnt_open(fp);
00732   if (!sfont) {
00733     ERROR("Not a CFF/OpenType font?");
00734   }
00735   if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
00736       sfnt_read_table_directory(sfont, 0) < 0 ||
00737       (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
00738     ERROR("Not a CFF/OpenType font?");
00739   }
00740 
00741   cffont = cff_open(sfont->stream, offset, opt->index);
00742   if (!cffont) {
00743     ERROR("Cannot read CFF font data");
00744   }
00745 
00746   if (!(cffont->flag & FONTTYPE_CIDFONT)) {
00747     cff_close(cffont);
00748     sfnt_close(sfont);
00749     DPXFCLOSE(fp);
00750     return -1;
00751   }
00752 
00753   csi = NEW(1, CIDSysInfo);
00754   csi->registry =
00755     cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0));
00756   csi->ordering =
00757     cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1));
00758   csi->supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2);
00759 
00760   if (cmap_csi) {
00761     if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
00762        strcmp(csi->ordering, cmap_csi->ordering) != 0) {
00763       MESG("\nCharacter collection mismatched:\n");
00764       MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
00765       MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
00766       ERROR("Inconsistent CMap specified for this font.");
00767     }
00768     if (csi->supplement < cmap_csi->supplement) {
00769       WARN("CMap have higher supplmement number.");
00770       WARN("Some characters may not be displayed or printed.");
00771     }
00772   }
00773 
00774   {
00775     char *shortname;
00776 
00777     shortname = cff_get_name(cffont);
00778     if (!shortname)
00779       ERROR("No valid FontName found.");
00780     /*
00781      * Mangled name requires more 7 bytes.
00782      * Style requires more 11 bytes.
00783      */
00784     fontname = NEW(strlen(shortname)+19, char);
00785     memset(fontname, 0, strlen(shortname)+19);
00786     strcpy(fontname, shortname);
00787     RELEASE(shortname);
00788   }
00789   cff_close(cffont);
00790 
00791   if (opt->embed && opt->style != FONT_STYLE_NONE) {
00792     WARN("Embedding disabled due to style option for %s.", name);
00793     opt->embed = 0;
00794   }
00795   switch (opt->style) {
00796   case FONT_STYLE_BOLD:
00797     strcat(fontname, ",Bold");
00798     break;
00799   case FONT_STYLE_ITALIC:
00800     strcat(fontname, ",Italic");
00801     break;
00802   case FONT_STYLE_BOLDITALIC:
00803     strcat(fontname, ",BoldItalic");
00804     break;
00805   }
00806 
00807   font->fontname = fontname;
00808   font->subtype  = CIDFONT_TYPE0;
00809   font->csi      = csi;
00810 
00811   font->fontdict = pdf_new_dict();
00812   pdf_add_dict(font->fontdict,
00813               pdf_new_name("Type"),
00814               pdf_new_name("Font"));
00815   pdf_add_dict(font->fontdict,
00816               pdf_new_name("Subtype"),
00817               pdf_new_name("CIDFontType0"));
00818 
00819   /* getting font info. from TrueType tables */
00820   if ((font->descriptor
00821        = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
00822     ERROR("Could not obtain neccesary font info.");
00823 
00824   if (opt->embed) {
00825     memmove(fontname + 7, fontname, strlen(fontname) + 1);
00826     pdf_font_make_uniqueTag(fontname); 
00827     fontname[6] = '+';
00828   }
00829 
00830   pdf_add_dict(font->descriptor,
00831               pdf_new_name("FontName"),
00832               pdf_new_name(fontname));
00833   pdf_add_dict(font->fontdict, 
00834               pdf_new_name("BaseFont"),
00835               pdf_new_name(fontname));
00836   {
00837     pdf_obj *csi_dict = pdf_new_dict();
00838     pdf_add_dict(csi_dict,
00839                pdf_new_name("Registry"),
00840                pdf_new_string(csi->registry, strlen(csi->registry)));
00841     pdf_add_dict(csi_dict,
00842                pdf_new_name("Ordering"),
00843                pdf_new_string(csi->ordering, strlen(csi->ordering)));
00844     pdf_add_dict(csi_dict,
00845                pdf_new_name("Supplement"),
00846                pdf_new_number(csi->supplement));
00847     pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
00848   }
00849   pdf_add_dict(font->fontdict, 
00850               pdf_new_name("DW"),
00851               pdf_new_number(1000)); /* not sure */
00852 
00853   sfnt_close(sfont);
00854   DPXFCLOSE(fp);
00855 
00856   return 0;
00857 }
00858 
00859 void
00860 CIDFont_type0_t1cdofont (CIDFont *font)
00861 {
00862   sfnt      *sfont;
00863   cff_font  *cffont;
00864   cff_index *charstrings, *idx;
00865   long   charstring_len, max_len;
00866   long   destlen = 0;
00867   long   size, offset = 0;
00868   card8 *data;
00869   card16 num_glyphs, gid, last_cid;
00870   long   i, cid;
00871   int    parent_id;
00872   char  *used_chars;
00873   double default_width, nominal_width;
00874   FILE  *fp;
00875 
00876   ASSERT(font);
00877 
00878   if (!font->indirect)
00879     return;
00880 
00881   pdf_add_dict(font->fontdict, 
00882               pdf_new_name("FontDescriptor"),
00883               pdf_ref_obj (font->descriptor));
00884 
00885   if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
00886       (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
00887     ERROR("No parent Type 0 font !");
00888 
00889   used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
00890   if (!used_chars)
00891     ERROR("Unexpected error: Font not actually used???");
00892 
00893   fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
00894   if (!fp)
00895     ERROR("Could not open OpenType font file: %s", font->ident);
00896 
00897   sfont = sfnt_open(fp);
00898   if (!sfont)
00899     ERROR("Could not open OpenType font file: %s", font->ident);
00900 
00901   if (sfnt_read_table_directory(sfont, 0) < 0 ||
00902       sfont->type != SFNT_TYPE_POSTSCRIPT)
00903     ERROR("Not a CFF/OpenType font ?");
00904   offset = sfnt_find_table_pos(sfont, "CFF ");
00905   if (offset == 0)
00906     ERROR("Not a CFF/OpenType font ?");
00907 
00908   cffont = cff_open(fp, offset, font->options->index);
00909   if (!cffont)
00910     ERROR("Could not open CFF font.");
00911   if (cffont->flag & FONTTYPE_CIDFONT)
00912     ERROR("This is CIDFont...");
00913 
00914   cff_read_private(cffont);
00915   cff_read_subrs  (cffont);
00916 
00917   if (cffont->private[0] && cff_dict_known(cffont->private[0], "StdVW")) {
00918     double stemv;
00919     stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
00920     pdf_add_dict(font->descriptor,
00921                pdf_new_name("StemV"), pdf_new_number(stemv));
00922   }
00923   if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) {
00924     default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
00925   } else {
00926     default_width = CFF_DEFAULTWIDTHX_DEFAULT;
00927   }
00928   if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) {
00929     nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
00930   } else {
00931     nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
00932   }
00933 
00934   num_glyphs = 0; last_cid = 0;
00935   add_to_used_chars2(used_chars, 0); /* .notdef */
00936   for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
00937     int c, j;
00938 
00939     c = used_chars[i];
00940     for (j = 7; j >= 0; j--) {
00941       if (c & (1 << j)) {
00942        num_glyphs++;
00943        last_cid = (i + 1) * 8 - j - 1;
00944       }
00945     }
00946   }
00947 
00948   {
00949     cff_fdselect *fdselect;
00950 
00951     fdselect = NEW(1, cff_fdselect);
00952     fdselect->format = 3;
00953     fdselect->num_entries = 1;
00954     fdselect->data.ranges = NEW(1, cff_range3);
00955     fdselect->data.ranges[0].first = 0;
00956     fdselect->data.ranges[0].fd    = 0;
00957     cffont->fdselect = fdselect;
00958   }
00959 
00960   {
00961     cff_charsets *charset;
00962 
00963     charset  = NEW(1, cff_charsets);
00964     charset->format = 0;
00965     charset->num_entries = num_glyphs-1;
00966     charset->data.glyphs = NEW(num_glyphs-1, s_SID);
00967 
00968     for (gid = 0, cid = 0; cid <= last_cid; cid++) {
00969       if (is_used_char2(used_chars, cid)) {
00970        if (gid > 0)
00971          charset->data.glyphs[gid-1] = cid;
00972        gid++;
00973       }
00974     }
00975     /* cff_release_charsets(cffont->charsets); */
00976     cffont->charsets = charset;
00977   }
00978 
00979   cff_dict_add(cffont->topdict, "CIDCount", 1);
00980   cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
00981 
00982   cffont->fdarray    = NEW(1, cff_dict *);
00983   cffont->fdarray[0] = cff_new_dict();
00984   cff_dict_add(cffont->fdarray[0], "FontName", 1);
00985   cff_dict_set(cffont->fdarray[0], "FontName", 0,
00986               (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
00987   cff_dict_add(cffont->fdarray[0], "Private", 2);
00988   cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
00989   cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
00990   /* FDArray  - index offset, not known yet */
00991   cff_dict_add(cffont->topdict, "FDArray", 1);
00992   cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
00993   /* FDSelect - offset, not known yet */
00994   cff_dict_add(cffont->topdict, "FDSelect", 1);
00995   cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
00996 
00997   cff_dict_remove(cffont->topdict, "UniqueID");
00998   cff_dict_remove(cffont->topdict, "XUID");
00999   cff_dict_remove(cffont->topdict, "Private");
01000   cff_dict_remove(cffont->topdict, "Encoding");
01001 
01002 
01003   /* */
01004   offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
01005   cff_seek_set(cffont, offset);
01006   idx = cff_get_index_header(cffont);
01007   /* offset is now absolute offset ... bad */
01008   offset = ftell(cffont->stream);
01009 
01010   if (idx->count < 2)
01011     ERROR("No valid charstring data found.");
01012 
01013   /* New CharStrings INDEX */
01014   charstrings = cff_new_index(num_glyphs+1);
01015   max_len = 2 * CS_STR_LEN_MAX;
01016   charstrings->data = NEW(max_len, card8);
01017   charstring_len = 0;
01018 
01019   gid  = 0;
01020   data = NEW(CS_STR_LEN_MAX, card8);
01021   for (cid = 0; cid <= last_cid; cid++) {
01022     if (!is_used_char2(used_chars, cid))
01023       continue;
01024 
01025     if ((size = (idx->offset)[cid+1] - (idx->offset)[cid])
01026        > CS_STR_LEN_MAX)
01027       ERROR("Charstring too long: gid=%u", cid);
01028     if (charstring_len + CS_STR_LEN_MAX >= max_len) {
01029       max_len = charstring_len + 2 * CS_STR_LEN_MAX;
01030       charstrings->data = RENEW(charstrings->data, max_len, card8);
01031     }
01032     (charstrings->offset)[gid] = charstring_len + 1;
01033     seek_absolute(cffont->stream, offset + (idx->offset)[cid] - 1);
01034     fread(data, 1, size, cffont->stream);
01035     charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
01036                                     max_len - charstring_len,
01037                                     data, size,
01038                                     cffont->gsubr, (cffont->subrs)[0],
01039                                     default_width, nominal_width, NULL);
01040     gid++;
01041   }
01042   if (gid != num_glyphs)
01043     ERROR("Unexpeced error: ?????");
01044   RELEASE(data);
01045   cff_release_index(idx);
01046 
01047   (charstrings->offset)[num_glyphs] = charstring_len + 1;
01048   charstrings->count = num_glyphs;
01049   cffont->num_glyphs    = num_glyphs;
01050   cffont->cstrings      = charstrings;
01051   
01052   /* no Global subr */
01053   if (cffont->gsubr)
01054     cff_release_index(cffont->gsubr);
01055   cffont->gsubr = cff_new_index(0);
01056 
01057   if (cffont->subrs && cffont->subrs[0]) {
01058     cff_release_index(cffont->subrs[0]);
01059     cffont->subrs[0] = NULL;
01060   }
01061   if (cffont->private && (cffont->private)[0]) {
01062     cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */
01063   }
01064 
01065   cff_add_string(cffont, "Adobe", 1);
01066   cff_add_string(cffont, "Identity", 1);
01067 
01068   cff_dict_update(cffont->topdict, cffont);
01069   cff_dict_update(cffont->private[0], cffont);
01070   cff_update_string(cffont);
01071 
01072   /* CFF code need to be rewrote... */
01073   cff_dict_add(cffont->topdict, "ROS", 3);
01074   cff_dict_set(cffont->topdict, "ROS", 0,
01075               (double) cff_get_sid(cffont, (char *)"Adobe"));
01076   cff_dict_set(cffont->topdict, "ROS", 1,
01077               (double) cff_get_sid(cffont, (char *)"Identity"));
01078   cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
01079 
01080   destlen = write_fontfile(font, cffont);
01081 
01082   cff_close(cffont);
01083 
01084   /*
01085    * DW, W, DW2 and W2:
01086    * Those values are obtained from OpenType table (not TFM).
01087    */
01088   {
01089     unsigned char *CIDToGIDMap;
01090 
01091     CIDToGIDMap = NEW(2 * (last_cid+1), unsigned char);
01092     memset(CIDToGIDMap, 0, 2 * (last_cid + 1));
01093     for (cid = 0; cid <= last_cid; cid++) {
01094       if (is_used_char2(used_chars, cid)) {
01095        CIDToGIDMap[2*cid  ] = (cid >> 8) & 0xff;
01096        CIDToGIDMap[2*cid+1] = cid & 0xff;
01097       }
01098     }
01099     add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
01100                  ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
01101     RELEASE(CIDToGIDMap);
01102   }
01103 
01104   sfnt_close(sfont);
01105   DPXFCLOSE(fp);
01106 
01107   if (verbose > 1)
01108     MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen);
01109 
01110   /*
01111    * CIDSet:
01112    * Length of CIDSet stream is not clear. Must be 8192 bytes long?
01113    */
01114   {
01115     pdf_obj *cidset;
01116 
01117     cidset = pdf_new_stream(STREAM_COMPRESS);
01118     pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
01119     pdf_add_dict(font->descriptor,
01120                pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
01121     pdf_release_obj(cidset);
01122   }
01123 
01124   return;
01125 }
01126 
01127 int
01128 CIDFont_type0_t1copen (CIDFont *font, const char *name,
01129                      CIDSysInfo *cmap_csi, cid_opt *opt)
01130 {
01131   CIDSysInfo *csi;
01132   char       *fontname;
01133   sfnt       *sfont;
01134   cff_font   *cffont;
01135   unsigned long offset = 0;
01136   FILE       *fp;
01137 
01138   ASSERT(font);
01139 
01140   fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
01141   if (!fp)
01142     return -1;
01143 
01144   sfont = sfnt_open(fp);
01145   if (!sfont) {
01146     ERROR("Not a CFF/OpenType font?");
01147   }
01148   if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
01149       sfnt_read_table_directory(sfont, 0) < 0 ||
01150       (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
01151     ERROR("Not a CFF/OpenType font?");
01152   }
01153 
01154   cffont = cff_open(fp, offset, opt->index);
01155   if (!cffont) {
01156     ERROR("Cannot read CFF font data");
01157   }
01158 
01159   if (cffont->flag & FONTTYPE_CIDFONT) {
01160     cff_close(cffont);
01161     sfnt_close(sfont);
01162     DPXFCLOSE(fp);
01163 
01164     return -1;
01165   }
01166 
01167   csi = NEW(1, CIDSysInfo);
01168   csi->registry   = NEW(strlen("Adobe")+1, char);
01169   strcpy(csi->registry, "Adobe");
01170   csi->ordering   = NEW(strlen("Identity")+1, char);
01171   strcpy(csi->ordering, "Identity");
01172   csi->supplement = 0;
01173 
01174   if (cmap_csi) {
01175     if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
01176        strcmp(csi->ordering, cmap_csi->ordering) != 0) {
01177       MESG("\nCharacter collection mismatched:\n");
01178       MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
01179       MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
01180       ERROR("Inconsistent CMap specified for this font.");
01181     }
01182     if (csi->supplement < cmap_csi->supplement) {
01183       WARN("CMap have higher supplmement number.");
01184       WARN("Some characters may not be displayed or printed.");
01185     }
01186   }
01187 
01188   {
01189     char *shortname;
01190 
01191     shortname = cff_get_name(cffont);
01192     if (!shortname)
01193       ERROR("No valid FontName found.");
01194     /* Mangled name requires more 7 bytes. */
01195 
01196     fontname = NEW(strlen(shortname) + 8, char);
01197     memset(fontname, 0, strlen(shortname) + 8);
01198     strcpy(fontname, shortname);
01199     RELEASE(shortname);
01200   }
01201   cff_close(cffont);
01202 
01203   opt->embed = 1;
01204 
01205   font->fontname = fontname;
01206   font->subtype  = CIDFONT_TYPE0;
01207   font->csi      = csi;
01208   font->flags   |= CIDFONT_FLAG_TYPE1C;
01209 
01210   font->fontdict = pdf_new_dict();
01211   pdf_add_dict(font->fontdict,
01212               pdf_new_name("Type"),
01213               pdf_new_name("Font"));
01214   pdf_add_dict(font->fontdict,
01215               pdf_new_name("Subtype"),
01216               pdf_new_name("CIDFontType0"));
01217 
01218   /* getting font info. from TrueType tables */
01219   if ((font->descriptor
01220        = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
01221     ERROR("Could not obtain neccesary font info.");
01222 
01223   if (opt->embed) {
01224     memmove(fontname + 7, fontname, strlen(fontname) + 1);
01225     pdf_font_make_uniqueTag(fontname);
01226     fontname[6] = '+';
01227   }
01228 
01229   pdf_add_dict(font->descriptor,
01230               pdf_new_name("FontName"),
01231               pdf_new_name(fontname));
01232   pdf_add_dict(font->fontdict, 
01233               pdf_new_name("BaseFont"),
01234               pdf_new_name(fontname));
01235   {
01236     pdf_obj *csi_dict = pdf_new_dict();
01237     pdf_add_dict(csi_dict,
01238                pdf_new_name("Registry"),
01239                pdf_new_string(csi->registry, strlen(csi->registry)));
01240     pdf_add_dict(csi_dict,
01241                pdf_new_name("Ordering"),
01242                pdf_new_string(csi->ordering, strlen(csi->ordering)));
01243     pdf_add_dict(csi_dict,
01244                pdf_new_name("Supplement"),
01245                pdf_new_number(csi->supplement));
01246     pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
01247   }
01248   sfnt_close(sfont);
01249   DPXFCLOSE(fp);
01250 
01251   return 0;
01252 }
01253 
01254 
01255 /* Type1 --> CFF CIDFont */
01256 #include "unicode.h"
01257 #include "t1_load.h"
01258 #include "t1_char.h"
01259 
01260 #include "agl.h"
01261 
01262 #include "cmap.h"
01263 #include "cmap_write.h"
01264 #include "fontmap.h"
01265 
01266 static int
01267 load_base_CMap (const char *font_name, int wmode, cff_font *cffont)
01268 {
01269   int       cmap_id = -1;
01270   CMap     *cmap;
01271   char     *cmap_name;
01272   card16    gid;
01273   unsigned char range_min[4] = {0x00, 0x00, 0x00, 0x00};
01274   unsigned char range_max[4] = {0x7f, 0xff, 0xff, 0xff};
01275 
01276   cmap_name = NEW(strlen(font_name)+strlen("-UCS4-H")+1, char);
01277   if (wmode) {
01278     sprintf(cmap_name, "%s-UCS4-V", font_name);
01279   } else {
01280     sprintf(cmap_name, "%s-UCS4-H", font_name);
01281   }
01282 
01283   cmap_id = CMap_cache_find(cmap_name);
01284   if (cmap_id >= 0) {
01285     RELEASE(cmap_name);
01286     return cmap_id;
01287   }
01288 
01289   cmap = CMap_new();
01290   CMap_set_name (cmap, cmap_name);
01291   CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID);
01292   CMap_set_wmode(cmap, wmode);
01293   CMap_add_codespacerange(cmap, range_min, range_max, 4);
01294   CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY);
01295   RELEASE(cmap_name);
01296 
01297   for (gid = 1; gid < cffont->num_glyphs; gid++) {
01298     long      ucv;
01299     s_SID     sid;
01300     char     *glyph, *name, *suffix;
01301     unsigned char  srcCode[4];
01302 
01303     sid   = cff_charsets_lookup_inverse(cffont, gid);
01304     glyph = cff_get_string (cffont, sid);
01305 
01306     name  = agl_chop_suffix(glyph, &suffix);
01307     if (!name) {
01308       if (suffix)
01309        RELEASE(suffix);
01310       RELEASE(glyph);
01311       continue;
01312     }
01313 
01314     if (suffix) {
01315       RELEASE(name);
01316       RELEASE(suffix);
01317       RELEASE(glyph);
01318       continue;
01319     }
01320 
01321     if (agl_name_is_unicode(name)) {
01322       ucv = agl_name_convert_unicode(name);
01323       srcCode[0] = (ucv >> 24) & 0xff;
01324       srcCode[1] = (ucv >> 16) & 0xff;
01325       srcCode[2] = (ucv >>  8) & 0xff;
01326       srcCode[3] = ucv & 0xff;
01327       CMap_add_cidchar(cmap, srcCode, 4, gid);
01328     } else {
01329       agl_name *agln;
01330 
01331       agln = agl_lookup_list(name);
01332       if (!agln)
01333        WARN("Glyph \"%s\" inaccessible (no Unicode mapping)", glyph);
01334       while (agln) {
01335        if (agln->n_components > 1) {
01336          WARN("Glyph \"%s\" inaccessible (composite character)", glyph);
01337        } else if (agln->n_components == 1) {
01338          ucv = agln->unicodes[0];
01339          srcCode[0] = (ucv >> 24) & 0xff;
01340          srcCode[1] = (ucv >> 16) & 0xff;
01341          srcCode[2] = (ucv >>  8) & 0xff;
01342          srcCode[3] = ucv & 0xff;
01343          CMap_add_cidchar(cmap, srcCode, 4, gid);
01344        }
01345        agln = agln->alternate;
01346       }
01347     }
01348     RELEASE(name);
01349     if (suffix)
01350       RELEASE(suffix);
01351     RELEASE(glyph);
01352   }
01353   cmap_id = CMap_cache_add(cmap);
01354 
01355   return cmap_id;
01356 }
01357 
01358 int
01359 t1_load_UnicodeCMap (const char *font_name,
01360                    const char *otl_tags,  /* not supported yet */
01361                    int wmode)
01362 {
01363   int       cmap_id = -1;
01364   cff_font *cffont;
01365   FILE     *fp;
01366 
01367   if (!font_name)
01368     return -1;
01369 
01370   fp = DPXFOPEN(font_name, DPX_RES_TYPE_T1FONT);
01371   if (!fp)
01372     return -1;
01373 
01374   cffont = t1_load_font(NULL, 1, fp);
01375   if (!cffont) {
01376     DPXFCLOSE(fp);
01377     return -1;
01378   }
01379   DPXFCLOSE(fp);
01380 
01381   cmap_id = load_base_CMap(font_name, wmode, cffont);
01382   
01383   cff_close(cffont);
01384 
01385   if (cmap_id < 0) {
01386     ERROR("Failed to create Unicode charmap for font \"%s\".", font_name);
01387     return -1;
01388   }
01389 
01390   if (otl_tags) {
01391     WARN("Glyph substitution not supported for Type1 font yet...");
01392   }
01393 
01394   return cmap_id;
01395 }
01396 
01397 
01398 /*
01399  * ToUnicode CMap
01400  */
01401 
01402 static pdf_obj *
01403 create_ToUnicode_stream (cff_font *cffont,
01404                       const char *font_name, const char *used_glyphs)
01405 {
01406   pdf_obj *stream = NULL;
01407   CMap    *cmap;
01408   CID      cid;
01409   card16   gid;
01410   long     glyph_count, total_fail_count;
01411   char    *cmap_name;
01412 #define WBUF_SIZE 1024
01413   unsigned char  wbuf[WBUF_SIZE];
01414   unsigned char *p, *endptr;
01415   static unsigned char range_min[2] = {0x00, 0x00};
01416   static unsigned char range_max[2] = {0xff, 0xff};
01417 
01418   if (!font_name || !used_glyphs)
01419     return NULL;
01420 
01421   cmap = CMap_new();
01422 
01423   cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+1, char);
01424   strcpy(cmap_name, font_name);
01425   strcat(cmap_name, "-UTF16");
01426   CMap_set_name (cmap, cmap_name);
01427   RELEASE(cmap_name);
01428 
01429   CMap_set_wmode(cmap, 0);
01430   CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
01431   CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
01432 
01433   CMap_add_codespacerange(cmap, range_min, range_max, 2);
01434 
01435   glyph_count = total_fail_count = 0;
01436   p      = wbuf;
01437   endptr = wbuf + WBUF_SIZE;
01438   for (cid = 1; cid < cffont->num_glyphs; cid++) { /* Skip .notdef */
01439     if (is_used_char2(used_glyphs, cid)) {
01440       char *glyph;
01441       long  len;
01442       int   fail_count;
01443 
01444       wbuf[0] = (cid >> 8) & 0xff;
01445       wbuf[1] = (cid & 0xff);
01446 
01447       p = wbuf + 2;
01448       gid = cff_charsets_lookup_inverse(cffont, cid);
01449       if (gid == 0)
01450        continue;
01451       glyph = cff_get_string(cffont, gid);
01452       if (glyph) {
01453        len = agl_sput_UTF16BE(glyph, &p, endptr, &fail_count);
01454        if (len < 1 || fail_count) {
01455          total_fail_count += fail_count;
01456        } else {
01457          CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len);
01458        }
01459        RELEASE(glyph);
01460       }
01461       glyph_count++;
01462     }
01463   }
01464 
01465   if (total_fail_count != 0 &&
01466       total_fail_count >= glyph_count/10) {
01467     WARN("%d glyph names (out of %d) missing Unicode mapping.",
01468         total_fail_count, glyph_count);
01469     WARN("ToUnicode CMap \"%s-UTF16\" removed.", font_name);
01470   } else {
01471     stream = CMap_create_stream(cmap, 0);
01472   }
01473   CMap_release(cmap);
01474 
01475   return stream;
01476 }
01477 
01478 
01479 int
01480 CIDFont_type0_t1open (CIDFont *font, const char *name,
01481                     CIDSysInfo *cmap_csi, cid_opt *opt)
01482 {
01483   FILE       *fp;
01484   char       *fontname, *shortname;
01485   cff_font   *cffont;
01486 
01487   ASSERT(font);
01488 
01489   if (cmap_csi &&
01490       (strcmp(cmap_csi->registry, "Adobe")    != 0 ||
01491        strcmp(cmap_csi->ordering, "Identity") != 0)) {
01492     return -1;
01493   }
01494   fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT);
01495   if (!fp)
01496     return -1;
01497 
01498   cffont = t1_load_font(NULL, 1, fp);
01499   if (!cffont) {
01500     DPXFCLOSE(fp);
01501     return -1;
01502   }
01503   DPXFCLOSE(fp);
01504 
01505   shortname = cff_get_name(cffont);
01506   if (!shortname)
01507     ERROR("No valid FontName found.");
01508   fontname = NEW(strlen(shortname) + 8, char);
01509   memset(fontname, 0, strlen(shortname) + 8);
01510   strcpy(fontname, shortname);
01511   RELEASE(shortname);
01512 
01513   cff_close(cffont);
01514 
01515   if (opt->style != FONT_STYLE_NONE) {
01516     WARN(",Bold, ,Italic, ... not supported for this type of font...");
01517     opt->style = FONT_STYLE_NONE;
01518   }
01519 
01520   font->fontname = fontname;
01521   font->subtype  = CIDFONT_TYPE0;
01522   font->csi      = NEW(1, CIDSysInfo);
01523   font->csi->registry = NEW(strlen("Adobe")+1, char);
01524   strcpy(font->csi->registry, "Adobe");
01525   font->csi->ordering = NEW(strlen("Identity")+1, char);
01526   strcpy(font->csi->ordering, "Identity");
01527   font->csi->supplement = 0;
01528   font->flags   |= CIDFONT_FLAG_TYPE1;
01529 
01530   font->fontdict = pdf_new_dict();
01531   pdf_add_dict(font->fontdict,
01532               pdf_new_name("Type"),
01533               pdf_new_name("Font"));
01534   pdf_add_dict(font->fontdict,
01535               pdf_new_name("Subtype"),
01536               pdf_new_name("CIDFontType0"));
01537 
01538   memmove(fontname + 7, fontname, strlen(fontname) + 1);
01539   pdf_font_make_uniqueTag(fontname);
01540   fontname[6] = '+';
01541 
01542   font->descriptor = pdf_new_dict();
01543   pdf_add_dict(font->descriptor,
01544               pdf_new_name("FontName"),
01545               pdf_new_name(fontname));
01546   pdf_add_dict(font->fontdict, 
01547               pdf_new_name("BaseFont"),
01548               pdf_new_name(fontname));
01549   {
01550     pdf_obj *csi_dict;
01551 
01552     csi_dict = pdf_new_dict();
01553     pdf_add_dict(csi_dict,
01554                pdf_new_name("Registry"),
01555                pdf_new_string("Adobe", strlen("Adobe")));
01556     pdf_add_dict(csi_dict,
01557                pdf_new_name("Ordering"),
01558                pdf_new_string("Identity", strlen("Identity")));
01559     pdf_add_dict(csi_dict,
01560                pdf_new_name("Supplement"),
01561                pdf_new_number(0.0));
01562     pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
01563   }
01564 
01565 
01566   return 0;
01567 }
01568 
01569 /* Duplicate from type1.c */
01570 #define TYPE1_NAME_LEN_MAX   127
01571 
01572 #define FONT_FLAG_FIXEDPITCH (1 << 0)  /* Fixed-width font */
01573 #define FONT_FLAG_SERIF      (1 << 1)  /* Serif font */
01574 #define FONT_FLAG_SYMBOLIC   (1 << 2)  /* Symbolic font */
01575 #define FONT_FLAG_SCRIPT     (1 << 3)  /* Script font */
01576 #define FONT_FLAG_STANDARD   (1 << 5)  /* Adobe Standard Character Set */
01577 #define FONT_FLAG_ITALIC     (1 << 6)  /* Italic */
01578 #define FONT_FLAG_ALLCAP     (1 << 16) /* All-cap font */
01579 #define FONT_FLAG_SMALLCAP   (1 << 17) /* Small-cap font */
01580 #define FONT_FLAG_FORCEBOLD  (1 << 18) /* Force bold at small text sizes */
01581 
01582 /* pdf_font --> CIDFont */
01583 static void
01584 get_font_attr (CIDFont *font, cff_font *cffont)
01585 {
01586   double capheight, ascent, descent;
01587   double italicangle, stemv;
01588   double defaultwidth, nominalwidth;
01589   long   flags = 0;
01590   long   gid;
01591   int    i;
01592   static const char *L_c[] = {
01593     "H", "P", "Pi", "Rho", NULL
01594   };
01595   static const char *L_d[] = {
01596     "p", "q", "mu", "eta", NULL
01597   };
01598   static const char *L_a[] = {
01599     "b", "h", "lambda", NULL
01600   };
01601   t1_ginfo gm;
01602 
01603   defaultwidth = 500.0;
01604   nominalwidth = 0.0;
01605 
01606   /*
01607    * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
01608    * The BlueValues and OtherBlues also have those information.
01609    */
01610   if (cff_dict_known(cffont->topdict, "FontBBox")) {
01611     /* Default values */
01612     capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
01613     descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
01614   } else {
01615     capheight =  680.0;
01616     ascent    =  690.0;
01617     descent   = -190.0;
01618   }
01619   if (cff_dict_known(cffont->private[0], "StdVW")) {
01620     stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
01621   } else {
01622     /*
01623      * We may use the following values for StemV:
01624      *  Thin - ExtraLight: <= 50
01625      *  Light: 71
01626      *  Regular(Normal): 88
01627      *  Medium: 109
01628      *  SemiBold(DemiBold): 135
01629      *  Bold - Heavy: >= 166
01630      */
01631     stemv = 88.0;
01632   }
01633   if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
01634     italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
01635     if (italicangle != 0.0)
01636       flags |= FONT_FLAG_ITALIC;
01637   } else {
01638     italicangle = 0.0;
01639   }
01640 
01641   /*
01642    * Use "space", "H", "p", and "b" for various values.
01643    * Those characters should not "seac". (no accent)
01644    */
01645   gid = cff_glyph_lookup(cffont, "space");
01646   if (gid >= 0 && gid < cffont->cstrings->count) {
01647     t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
01648                      cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
01649                      cffont->subrs[0], &gm);
01650     defaultwidth = gm.wx;
01651   }
01652 
01653   for (i = 0; L_c[i] != NULL; i++) {
01654     gid = cff_glyph_lookup(cffont, L_c[i]);
01655     if (gid >= 0 && gid < cffont->cstrings->count) {
01656       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
01657                       cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
01658                       cffont->subrs[0], &gm);
01659       capheight = gm.bbox.ury;
01660       break;
01661     }
01662   }
01663 
01664   for (i = 0; L_d[i] != NULL; i++) {
01665     gid = cff_glyph_lookup(cffont, L_d[i]);
01666     if (gid >= 0 && gid < cffont->cstrings->count) {
01667       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
01668                       cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
01669                       cffont->subrs[0], &gm);
01670       descent = gm.bbox.lly;
01671       break;
01672     }
01673   }
01674 
01675   for (i = 0; L_a[i] != NULL; i++) {
01676     gid = cff_glyph_lookup(cffont, L_a[i]);
01677     if (gid >= 0 && gid < cffont->cstrings->count) {
01678       t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
01679                       cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
01680                       cffont->subrs[0], &gm);
01681       ascent = gm.bbox.ury;
01682       break;
01683     }
01684   }
01685 
01686   if (defaultwidth != 0.0) {
01687     cff_dict_add(cffont->private[0], "defaultWidthX", 1);
01688     cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
01689   }
01690   if (nominalwidth != 0.0) {
01691     cff_dict_add(cffont->private[0], "nominalWidthX", 1);
01692     cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
01693   }
01694   if (cff_dict_known(cffont->private[0], "ForceBold") &&
01695       cff_dict_get(cffont->private[0], "ForceBold", 0)) {
01696     flags |= FONT_FLAG_FORCEBOLD;
01697   }
01698   if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
01699       cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
01700     flags |= FONT_FLAG_FIXEDPITCH;
01701   }
01702   if (font->fontname &&
01703       !strstr(font->fontname, "Sans")) {
01704     flags |= FONT_FLAG_SERIF;
01705   }
01706   flags |= FONT_FLAG_SYMBOLIC;
01707 
01708   pdf_add_dict(font->descriptor,
01709               pdf_new_name("CapHeight"), pdf_new_number(capheight));
01710   pdf_add_dict(font->descriptor,
01711               pdf_new_name("Ascent"), pdf_new_number(ascent));
01712   pdf_add_dict(font->descriptor,
01713               pdf_new_name("Descent"), pdf_new_number(descent));
01714   pdf_add_dict(font->descriptor,
01715               pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
01716   pdf_add_dict(font->descriptor,
01717               pdf_new_name("StemV"), pdf_new_number(stemv));
01718   pdf_add_dict(font->descriptor,
01719               pdf_new_name("Flags"), pdf_new_number(flags));
01720 }
01721 
01722 static void
01723 add_metrics (CIDFont *font, cff_font *cffont,
01724             unsigned char *CIDToGIDMap,
01725             double *widths, double default_width, CID last_cid)
01726 {
01727   pdf_obj *tmp;
01728   double   val;
01729   card16   cid, gid;
01730   char    *used_chars;
01731   int      i, parent_id;
01732 
01733   /*
01734    * The original FontBBox of the font is preserved, instead
01735    * of replacing it with tight bounding box calculated from
01736    * charstrings, to prevent Acrobat 4 from greeking text as
01737    * much as possible.
01738    */
01739   if (!cff_dict_known(cffont->topdict, "FontBBox")) {
01740     ERROR("No FontBBox?");
01741   }
01742   tmp = pdf_new_array();
01743   for (i = 0; i < 4; i++) {
01744     val = cff_dict_get(cffont->topdict, "FontBBox", i);
01745     pdf_add_array(tmp, pdf_new_number(ROUND(val, 1.0)));
01746   }
01747   pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp);
01748 
01749   if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
01750       (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
01751     ERROR("No parent Type 0 font !");
01752 
01753   used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
01754   if (!used_chars) {
01755     ERROR("Unexpected error: Font not actually used???");
01756   }
01757 
01758   /* FIXME:
01759    * This writes "CID CID width".
01760    * I think it's better to handle each 8 char block
01761    * and to use "CID_start [ w0 w1 ...]".
01762    */
01763   tmp = pdf_new_array();
01764   for (cid = 0; cid <= last_cid; cid++) {
01765     if (is_used_char2(used_chars, cid)) {
01766       gid = (CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1];
01767       if (widths[gid] != default_width) {
01768        pdf_add_array(tmp, pdf_new_number(cid));
01769        pdf_add_array(tmp, pdf_new_number(cid));
01770        pdf_add_array(tmp, pdf_new_number(ROUND(widths[gid], 1.0)));
01771       }
01772     }
01773   }
01774   pdf_add_dict(font->fontdict,
01775               pdf_new_name("DW"), pdf_new_number(default_width));
01776   if (pdf_array_length(tmp) > 0) {
01777     pdf_add_dict(font->fontdict, pdf_new_name("W"), pdf_ref_obj(tmp));
01778   }
01779   pdf_release_obj(tmp);
01780 }
01781 
01782 void
01783 CIDFont_type0_t1dofont (CIDFont *font)
01784 {
01785   cff_font *cffont;
01786   double    defaultwidth, nominalwidth;
01787   long      num_glyphs = 0;
01788   FILE     *fp;
01789   long      i, offset;
01790   char     *used_chars = NULL;
01791   card16    last_cid, gid, cid;
01792   unsigned char *CIDToGIDMap;
01793 
01794   ASSERT(font);
01795 
01796   if (!font->indirect) {
01797     return;
01798   }
01799 
01800   pdf_add_dict(font->fontdict, 
01801               pdf_new_name("FontDescriptor"),
01802               pdf_ref_obj (font->descriptor));
01803 
01804   fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT);
01805   if (!fp) {
01806     ERROR("Type1: Could not open Type1 font.");
01807   }
01808 
01809   cffont = t1_load_font(NULL, 0, fp);
01810   if (!cffont)
01811     ERROR("Could not read Type 1 font...");
01812   DPXFCLOSE(fp);
01813 
01814   if (!font->fontname)
01815     ERROR("Fontname undefined...");
01816 
01817   {
01818     Type0Font *hparent, *vparent;
01819     pdf_obj   *tounicode;
01820     int        vparent_id, hparent_id;
01821 
01822     hparent_id = CIDFont_get_parent_id(font, 0);
01823     vparent_id = CIDFont_get_parent_id(font, 1);
01824     if (hparent_id < 0 && vparent_id < 0)
01825       ERROR("No parent Type 0 font !");
01826 
01827     /* usedchars is same for h and v */
01828     if (hparent_id < 0)
01829       hparent = NULL;
01830     else {
01831       hparent    = Type0Font_cache_get(hparent_id);
01832       used_chars = Type0Font_get_usedchars(hparent);
01833     }
01834     if (vparent_id < 0)
01835       vparent = NULL;
01836     else {
01837       vparent    = Type0Font_cache_get(vparent_id);
01838       used_chars = Type0Font_get_usedchars(vparent);
01839     }
01840     if (!used_chars)
01841       ERROR("Unexpected error: Font not actually used???");
01842 
01843     tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars);
01844 
01845     if (hparent)
01846       Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode));
01847     if (vparent)
01848       Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode));
01849     pdf_release_obj(tounicode);
01850   }
01851 
01852   cff_set_name(cffont, font->fontname);
01853 
01854   /* defaultWidthX, CapHeight, etc. */
01855   get_font_attr(font, cffont);
01856   if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
01857     defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
01858   } else {
01859     defaultwidth = 0.0;
01860   }
01861   if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
01862     nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
01863   } else {
01864     nominalwidth = 0.0;
01865   }
01866 
01867   num_glyphs = 0; last_cid = 0;
01868   add_to_used_chars2(used_chars, 0); /* .notdef */
01869   for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
01870     int c, j;
01871 
01872     c = used_chars[i];
01873     for (j = 7; j >= 0; j--) {
01874       if (c & (1 << j)) {
01875        num_glyphs++;
01876        last_cid = (i + 1) * 8 - j - 1;
01877       }
01878     }
01879   }
01880 
01881   {
01882     cff_fdselect *fdselect;
01883 
01884     fdselect = NEW(1, cff_fdselect);
01885     fdselect->format = 3;
01886     fdselect->num_entries = 1;
01887     fdselect->data.ranges = NEW(1, cff_range3);
01888     fdselect->data.ranges[0].first = 0;
01889     fdselect->data.ranges[0].fd    = 0;
01890     cffont->fdselect = fdselect;
01891   }
01892 
01893   CIDToGIDMap = NEW(2*(last_cid+1), unsigned char);
01894   memset(CIDToGIDMap, 0, 2*(last_cid+1));
01895   {
01896     cff_charsets *charset;
01897 
01898     charset  = NEW(1, cff_charsets);
01899     charset->format = 0;
01900     charset->num_entries = num_glyphs-1;
01901     charset->data.glyphs = NEW(num_glyphs-1, s_SID);
01902 
01903     for (gid = 0, cid = 0; cid <= last_cid; cid++) {
01904       if (is_used_char2(used_chars, cid)) {
01905        if (gid > 0)
01906          charset->data.glyphs[gid-1] = cid;
01907        CIDToGIDMap[2*cid  ] = (gid >> 8) & 0xff;
01908        CIDToGIDMap[2*cid+1] = gid & 0xff;
01909        gid++;
01910       }
01911     }
01912 
01913     cff_release_charsets(cffont->charsets);
01914     cffont->charsets = charset;
01915   }
01916 
01917   cff_dict_add(cffont->topdict, "CIDCount", 1);
01918   cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
01919 
01920   cffont->fdarray    = NEW(1, cff_dict *);
01921   cffont->fdarray[0] = cff_new_dict();
01922   cff_dict_add(cffont->fdarray[0], "FontName", 1);
01923   cff_dict_set(cffont->fdarray[0], "FontName", 0,
01924               (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
01925   cff_dict_add(cffont->fdarray[0], "Private", 2);
01926   cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
01927   cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
01928 
01929   /* FDArray  - index offset, not known yet */
01930   cff_dict_add(cffont->topdict, "FDArray", 1);
01931   cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
01932   /* FDSelect - offset, not known yet */
01933   cff_dict_add(cffont->topdict, "FDSelect", 1);
01934   cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
01935 
01936   cff_dict_add(cffont->topdict, "charset", 1);
01937   cff_dict_set(cffont->topdict, "charset", 0, 0.0);
01938 
01939   cff_dict_add(cffont->topdict, "CharStrings", 1);
01940   cff_dict_set(cffont->topdict, "CharStrings", 0, 0.0);
01941 
01942   {
01943     cff_index *cstring;
01944     t1_ginfo   gm;
01945     long       max = 0;
01946     double    *widths;
01947     int        w_stat[1001], max_count, dw;
01948 
01949     widths = NEW(num_glyphs, double);
01950     memset(w_stat, 0, sizeof(int)*1001);
01951     offset  = 0L;
01952     cstring = cff_new_index(num_glyphs);
01953     cstring->data = NULL;
01954     cstring->offset[0] = 1;
01955     gid = 0;
01956     for (cid = 0; cid <= last_cid; cid++) {
01957       if (!is_used_char2(used_chars, cid))
01958          continue;
01959 
01960       if (offset + CS_STR_LEN_MAX >= max) {
01961        max += CS_STR_LEN_MAX*2;
01962        cstring->data = RENEW(cstring->data, max, card8);
01963       }
01964       offset += t1char_convert_charstring(cstring->data + cstring->offset[gid] - 1, CS_STR_LEN_MAX,
01965                                      cffont->cstrings->data + cffont->cstrings->offset[cid] - 1,
01966                                      cffont->cstrings->offset[cid+1] - cffont->cstrings->offset[cid],
01967                                      cffont->subrs[0], defaultwidth, nominalwidth, &gm);
01968       cstring->offset[gid+1] = offset + 1;
01969       if (gm.use_seac) {
01970        ERROR("This font using the \"seac\" command for accented characters...");
01971       }
01972       widths[gid] = gm.wx;
01973       if (gm.wx >= 0.0 && gm.wx <= 1000.0) {
01974        w_stat[((int) gm.wx)] += 1;
01975       }
01976       gid++;
01977     }
01978 
01979     cff_release_index(cffont->cstrings);
01980     cffont->cstrings = cstring;
01981 
01982     max_count = 0; dw = -1;
01983     for (i = 0; i <= 1000; i++) {
01984       if (w_stat[i] > max_count) {
01985        dw        = i;
01986        max_count = w_stat[i];
01987       }
01988     }
01989     if (dw >= 0) {
01990       add_metrics(font, cffont, CIDToGIDMap, widths, dw, last_cid);
01991     } else {
01992       add_metrics(font, cffont, CIDToGIDMap, widths, defaultwidth, last_cid);
01993     }
01994     RELEASE(widths);
01995   }
01996   cff_release_index(cffont->subrs[0]);
01997   cffont->subrs[0] = NULL;
01998 
01999   RELEASE(CIDToGIDMap);
02000 
02001   cff_add_string(cffont, "Adobe", 1);
02002   cff_add_string(cffont, "Identity", 1);
02003 
02004   cff_dict_update(cffont->topdict, cffont);
02005   cff_dict_update(cffont->private[0], cffont);
02006 
02007   cff_update_string(cffont);
02008 
02009   /* CFF code need to be rewrote... */
02010   cff_dict_add(cffont->topdict, "ROS", 3);
02011   cff_dict_set(cffont->topdict, "ROS", 0,
02012               (double) cff_get_sid(cffont, (char *)"Adobe"));
02013   cff_dict_set(cffont->topdict, "ROS", 1,
02014               (double) cff_get_sid(cffont, (char *)"Identity"));
02015   cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
02016 
02017   cffont->num_glyphs = num_glyphs;
02018   offset = write_fontfile(font, cffont);
02019 
02020   cff_close(cffont);
02021 
02022   {
02023     pdf_obj *cidset;
02024 
02025     cidset = pdf_new_stream(STREAM_COMPRESS);
02026     pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
02027     pdf_add_dict(font->descriptor,
02028                pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
02029     pdf_release_obj(cidset);
02030   }
02031 
02032 
02033   return;
02034 }
02035 
02036 void
02037 CIDFont_type0_release(CIDFont *font)
02038 {
02039   return;
02040 }