~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to texk/dvipdfmx/dvipdfmx-20110311/src/cidtype0.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-05-07 10:47:49 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20120507104749-p00ot5sajjbkp1hp
Tags: 2011.20120507-1
* new upstream checkout: uptex 1.10
* drop patches for config file inclusion in (x)dvipdfmx, included upstream
* add man page for etex
* include pmpost patches and build it
* adapt/unfuzzify patches for current sources
* disable mtx building, we have prepmx package in Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  $Header: /home/cvsroot/dvipdfmx/src/cidtype0.c,v 1.40 2011/03/06 03:14:13 chofchof Exp $
2
 
    
3
 
    This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
4
 
 
5
 
    Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
6
 
    the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
7
 
    
8
 
    This program is free software; you can redistribute it and/or modify
9
 
    it under the terms of the GNU General Public License as published by
10
 
    the Free Software Foundation; either version 2 of the License, or
11
 
    (at your option) any later version.
12
 
    
13
 
    This program is distributed in the hope that it will be useful,
14
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
    GNU General Public License for more details.
17
 
    
18
 
    You should have received a copy of the GNU General Public License
19
 
    along with this program; if not, write to the Free Software
20
 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21
 
*/
22
 
 
23
 
/*
24
 
 * CID-Keyed Font support:
25
 
 *
26
 
 *  Only CFF/OpenType CID-Keyed Font with Type 2 charstrings is supported.
27
 
 *
28
 
 */ 
29
 
 
30
 
#if HAVE_CONFIG_H
31
 
#include "config.h"
32
 
#endif
33
 
 
34
 
#include "system.h"
35
 
#include "numbers.h"
36
 
#include "mem.h"
37
 
#include "error.h"
38
 
 
39
 
#include "dpxfile.h"
40
 
 
41
 
#include "pdfobj.h"
42
 
/* pseudo unique tag */
43
 
#include "pdffont.h"
44
 
 
45
 
/* Font info. from OpenType tables */
46
 
#include "sfnt.h"
47
 
#include "tt_aux.h"
48
 
/* Metrics */
49
 
#include "tt_table.h"
50
 
 
51
 
#include "cff_types.h"
52
 
#include "cff_limits.h"
53
 
#include "cff.h"
54
 
#include "cff_dict.h"
55
 
#include "cs_type2.h"
56
 
 
57
 
/* typedef CID in cmap.h */
58
 
#include "cmap.h"
59
 
#include "type0.h"
60
 
#include "cid.h"
61
 
#include "cid_p.h"
62
 
#include "cidtype0.h"
63
 
 
64
 
static int  verbose   = 0;
65
 
static long opt_flags = 0;
66
 
 
67
 
void
68
 
CIDFont_type0_set_verbose (void)
69
 
{
70
 
  verbose++;
71
 
}
72
 
 
73
 
void
74
 
CIDFont_type0_set_flags (long flags)
75
 
{
76
 
  opt_flags = flags;
77
 
}
78
 
 
79
 
/*
80
 
 * PDF Reference 3rd. ed., p.340, "Glyph Metrics in CID Fonts".
81
 
 */
82
 
#ifndef PDFUNIT
83
 
#define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
84
 
#endif
85
 
 
86
 
static void
87
 
add_CIDHMetrics (sfnt *sfont, pdf_obj *fontdict,
88
 
                 unsigned char *CIDToGIDMap, unsigned short last_cid,
89
 
                 struct tt_maxp_table *maxp,
90
 
                 struct tt_head_table *head, struct tt_longMetrics *hmtx)
91
 
{
92
 
  pdf_obj *w_array, *an_array = NULL;
93
 
  long   cid, start = 0, prev = 0;
94
 
  double defaultAdvanceWidth;
95
 
  int    empty = 1;
96
 
 
97
 
  defaultAdvanceWidth = PDFUNIT(hmtx[0].advance);
98
 
  /*
99
 
   * We alway use format:
100
 
   *  c [w_1 w_2 ... w_n]
101
 
   */
102
 
  w_array = pdf_new_array();
103
 
  for (cid = 0; cid <= last_cid; cid++) {
104
 
    USHORT gid;
105
 
    double advanceWidth;
106
 
    gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
107
 
    if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
108
 
      continue;
109
 
    advanceWidth = PDFUNIT(hmtx[gid].advance);
110
 
    if (advanceWidth == defaultAdvanceWidth) {
111
 
      if (an_array) {
112
 
        pdf_add_array(w_array, pdf_new_number(start));
113
 
        pdf_add_array(w_array, an_array);
114
 
        an_array = NULL;
115
 
        empty = 0;
116
 
      }
117
 
    } else {
118
 
      if (cid != prev + 1 &&  an_array) {
119
 
          pdf_add_array(w_array, pdf_new_number(start));
120
 
          pdf_add_array(w_array, an_array);
121
 
          an_array = NULL;
122
 
          empty = 0;
123
 
      }
124
 
      if (an_array == NULL) {
125
 
        an_array = pdf_new_array();
126
 
        start = cid;
127
 
      }
128
 
      pdf_add_array(an_array, pdf_new_number(advanceWidth));
129
 
      prev = cid;
130
 
    }
131
 
  }
132
 
 
133
 
  if (an_array) {
134
 
    pdf_add_array(w_array, pdf_new_number(start));
135
 
    pdf_add_array(w_array, an_array);
136
 
    empty = 0;
137
 
  }
138
 
 
139
 
  /*
140
 
   * We always write DW for older MacOS X's preview app.
141
 
   * PDF Reference 2nd. ed, wrongly described default value of DW as 0, and
142
 
   * MacOS X's (up to 10.2.8) preview app. implements this wrong description.
143
 
   */
144
 
  pdf_add_dict(fontdict,
145
 
               pdf_new_name("DW"),
146
 
               pdf_new_number(defaultAdvanceWidth));
147
 
  if (!empty) {
148
 
    pdf_add_dict(fontdict,
149
 
                 pdf_new_name("W"),
150
 
                 pdf_ref_obj(w_array));
151
 
  }
152
 
  pdf_release_obj(w_array);
153
 
 
154
 
  return;
155
 
}
156
 
 
157
 
static void
158
 
add_CIDVMetrics (sfnt *sfont, pdf_obj *fontdict,
159
 
                 unsigned char *CIDToGIDMap, unsigned short last_cid,
160
 
                 struct tt_maxp_table *maxp,
161
 
                 struct tt_head_table *head, struct tt_longMetrics *hmtx)
162
 
{
163
 
  pdf_obj *w2_array, *an_array = NULL;
164
 
  long cid, prev, start;
165
 
  struct tt_VORG_table *vorg;
166
 
  struct tt_vhea_table *vhea  = NULL;
167
 
  struct tt_longMetrics *vmtx = NULL;
168
 
  double defaultAdvanceHeight, defaultVertOriginY;
169
 
  int    empty = 1;
170
 
 
171
 
  /*
172
 
   * No accurate vertical metrics can be obtained by simple way if the
173
 
   * font does not have VORG table. Only CJK fonts may have VORG.
174
 
   */
175
 
  if (sfnt_find_table_pos(sfont, "VORG") <= 0)
176
 
    return;
177
 
 
178
 
  vorg = tt_read_VORG_table(sfont);
179
 
  defaultVertOriginY = PDFUNIT(vorg->defaultVertOriginY);
180
 
  if (sfnt_find_table_pos(sfont, "vhea") > 0)
181
 
    vhea = tt_read_vhea_table(sfont);
182
 
  if (vhea && sfnt_find_table_pos(sfont, "vmtx") > 0) {
183
 
    sfnt_locate_table(sfont, "vmtx");
184
 
    vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics, vhea->numOfExSideBearings);
185
 
  }
186
 
 
187
 
  if (sfnt_find_table_pos(sfont, "OS/2") <= 0) {
188
 
    struct tt_os2__table *os2;
189
 
    /* OpenType font must have OS/2 table. */
190
 
    os2 = tt_read_os2__table(sfont);
191
 
    defaultVertOriginY   = PDFUNIT(os2->sTypoAscender);
192
 
    defaultAdvanceHeight = PDFUNIT(os2->sTypoAscender - os2->sTypoDescender);
193
 
    RELEASE(os2);
194
 
  } else {
195
 
    /* Some TrueType fonts used in Macintosh does not have OS/2 table. */
196
 
    defaultAdvanceHeight = 1000;
197
 
  }
198
 
 
199
 
  w2_array = pdf_new_array();
200
 
  start = prev = 0;
201
 
  for (cid = 0; cid <= last_cid; cid++) {
202
 
    USHORT i, gid;
203
 
    double advanceHeight, vertOriginX, vertOriginY;
204
 
    gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
205
 
    if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
206
 
      continue;
207
 
    advanceHeight = vmtx ? PDFUNIT(vmtx[gid].advance) : defaultAdvanceHeight;
208
 
    vertOriginX   = PDFUNIT(hmtx[gid].advance*0.5);
209
 
    vertOriginY   = defaultVertOriginY;
210
 
    for (i = 0;
211
 
         i < vorg->numVertOriginYMetrics && gid > vorg->vertOriginYMetrics[i].glyphIndex;
212
 
         i++) {
213
 
      if (gid == vorg->vertOriginYMetrics[i].glyphIndex)
214
 
        vertOriginY = PDFUNIT(vorg->vertOriginYMetrics[i].vertOriginY);
215
 
    }
216
 
#if 0
217
 
    /*
218
 
     * c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...]
219
 
     * Not working... Why?
220
 
     * Acrobat Reader:
221
 
     *  Wrong rendering, interpretation of position vector is wrong.
222
 
     * Xpdf and gs: ignores W2?
223
 
     */
224
 
    if (vertOriginY == defaultVertOriginY &&
225
 
        advanceHeight == defaultAdvanceHeight) {
226
 
      if (an_array) {
227
 
        pdf_add_array(w2_array, pdf_new_number(start));
228
 
        pdf_add_array(w2_array, an_array);
229
 
        an_array = NULL;
230
 
        empty = 0;
231
 
      }
232
 
    } else {
233
 
      if (cid != prev + 1 && an_array) {
234
 
        pdf_add_array(w2_array, pdf_new_number(start));
235
 
        pdf_add_array(w2_array, an_array);
236
 
        an_array = NULL;
237
 
        empty = 0;
238
 
      }
239
 
      if (an_array == NULL) {
240
 
        an_array = pdf_new_array();
241
 
        start = cid;
242
 
      }
243
 
      pdf_add_array(an_array, pdf_new_number(-advanceHeight));
244
 
      pdf_add_array(an_array, pdf_new_number(vertOriginX));
245
 
      pdf_add_array(an_array, pdf_new_number(vertOriginY));
246
 
      prev = cid;
247
 
    }
248
 
#else
249
 
    /*
250
 
     * c_first c_last w1_y v_x v_y
251
 
     * This form may hit Acrobat's implementation limit of array element size, 8192.
252
 
     * AFPL GhostScript 8.11 stops with rangecheck error with this. Maybe GS's bug?
253
 
     */
254
 
    if (vertOriginY != defaultVertOriginY ||
255
 
        advanceHeight != defaultAdvanceHeight) {
256
 
      pdf_add_array(w2_array, pdf_new_number(cid));
257
 
      pdf_add_array(w2_array, pdf_new_number(cid));
258
 
      pdf_add_array(w2_array, pdf_new_number(-advanceHeight));
259
 
      pdf_add_array(w2_array, pdf_new_number(vertOriginX));
260
 
      pdf_add_array(w2_array, pdf_new_number(vertOriginY));
261
 
      empty = 0;
262
 
    }
263
 
#endif
264
 
  }
265
 
 
266
 
#if 0
267
 
  if (an_array) {
268
 
    pdf_add_array(w2_array, pdf_new_number(start));
269
 
    pdf_add_array(w2_array, an_array);
270
 
    empty = 0;
271
 
  }
272
 
#endif
273
 
 
274
 
  if (defaultVertOriginY != 880 || defaultAdvanceHeight != 1000) {
275
 
    an_array = pdf_new_array();
276
 
    pdf_add_array(an_array, pdf_new_number(defaultVertOriginY));
277
 
    pdf_add_array(an_array, pdf_new_number(-defaultAdvanceHeight));
278
 
    pdf_add_dict(fontdict, pdf_new_name ("DW2"), an_array);
279
 
  }
280
 
  if (!empty) {
281
 
    pdf_add_dict(fontdict,
282
 
                 pdf_new_name("W2"), pdf_ref_obj(w2_array));
283
 
  }
284
 
  pdf_release_obj(w2_array);
285
 
 
286
 
  if (vorg->vertOriginYMetrics)
287
 
    RELEASE(vorg->vertOriginYMetrics);
288
 
  RELEASE(vorg);
289
 
 
290
 
  if (vmtx)
291
 
    RELEASE(vmtx);
292
 
  if (vhea)
293
 
    RELEASE(vhea);
294
 
 
295
 
  return;
296
 
}
297
 
 
298
 
static void
299
 
add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict,
300
 
                unsigned char *CIDToGIDMap, unsigned short last_cid, int need_vmetrics)
301
 
{
302
 
  struct tt_longMetrics *hmtx;
303
 
  struct tt_head_table  *head;
304
 
  struct tt_hhea_table  *hhea;
305
 
  struct tt_maxp_table  *maxp;
306
 
 
307
 
  /*
308
 
   * Read head, hhea, maxp:
309
 
   *
310
 
   *   unitsPerEm       --> head
311
 
   *   numHMetrics      --> hhea
312
 
   *   numGlyphs        --> maxp
313
 
   */
314
 
  head = tt_read_head_table(sfont);
315
 
  maxp = tt_read_maxp_table(sfont);
316
 
  hhea = tt_read_hhea_table(sfont);
317
 
 
318
 
  sfnt_locate_table(sfont, "hmtx");
319
 
  hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
320
 
 
321
 
  add_CIDHMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
322
 
  if (need_vmetrics)
323
 
    add_CIDVMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
324
 
 
325
 
  RELEASE(hmtx);
326
 
  RELEASE(hhea);
327
 
  RELEASE(maxp);
328
 
  RELEASE(head);
329
 
 
330
 
  return;
331
 
}
332
 
 
333
 
/*
334
 
 * Create an instance of embeddable font.
335
 
 */
336
 
static long
337
 
write_fontfile (CIDFont *font, cff_font *cffont)
338
 
{
339
 
  cff_index *topdict, *fdarray, *private;
340
 
  unsigned char *dest;
341
 
  long destlen = 0, i, size;
342
 
  long offset, topdict_offset, fdarray_offset;
343
 
 
344
 
  /*  DICT sizes (offset set to long int) */
345
 
  topdict = cff_new_index(1);
346
 
  fdarray = cff_new_index(cffont->num_fds);
347
 
  private = cff_new_index(cffont->num_fds);
348
 
 
349
 
  cff_dict_remove(cffont->topdict, "UniqueID");
350
 
  cff_dict_remove(cffont->topdict, "XUID");
351
 
  cff_dict_remove(cffont->topdict, "Private");  /* some bad font may have */
352
 
  cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */
353
 
 
354
 
  topdict->offset[1] = cff_dict_pack(cffont->topdict,
355
 
                                     (card8 *) work_buffer,
356
 
                                     WORK_BUFFER_SIZE) + 1;
357
 
  for (i = 0;i < cffont->num_fds; i++) {
358
 
    size = 0;
359
 
    if (cffont->private && cffont->private[i]) {
360
 
      size = cff_dict_pack(cffont->private[i],
361
 
                           (card8 *) work_buffer, WORK_BUFFER_SIZE);
362
 
      if (size < 1) { /* Private had contained only Subr */
363
 
        cff_dict_remove(cffont->fdarray[i], "Private");
364
 
      }
365
 
    }
366
 
    (private->offset)[i+1] = (private->offset)[i] + size;
367
 
    (fdarray->offset)[i+1] = (fdarray->offset)[i] +
368
 
      cff_dict_pack(cffont->fdarray[i],
369
 
                    (card8 *) work_buffer, WORK_BUFFER_SIZE);
370
 
  }
371
 
 
372
 
  destlen = 4; /* header size */
373
 
  destlen += cff_set_name(cffont, font->fontname);
374
 
  destlen += cff_index_size(topdict);
375
 
  destlen += cff_index_size(cffont->string);
376
 
  destlen += cff_index_size(cffont->gsubr);
377
 
  destlen += (cffont->charsets->num_entries) * 2 + 1;  /* charset format 0 */
378
 
  destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */
379
 
  destlen += cff_index_size(cffont->cstrings);
380
 
  destlen += cff_index_size(fdarray);
381
 
  destlen += private->offset[private->count] - 1; /* Private is not INDEX */
382
 
 
383
 
  dest = NEW(destlen, card8);
384
 
 
385
 
  offset = 0;
386
 
  /* Header */
387
 
  offset += cff_put_header(cffont, dest + offset, destlen - offset);
388
 
  /* Name */
389
 
  offset += cff_pack_index(cffont->name, dest + offset, destlen - offset);
390
 
  /* Top DICT */
391
 
  topdict_offset = offset;
392
 
  offset += cff_index_size(topdict);
393
 
  /* Strings */
394
 
  offset += cff_pack_index(cffont->string, dest + offset, destlen - offset);
395
 
  /* Global Subrs */
396
 
  offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset);
397
 
 
398
 
  /* charset */
399
 
  cff_dict_set(cffont->topdict, "charset", 0, offset);
400
 
  offset += cff_pack_charsets(cffont, dest + offset, destlen - offset);
401
 
 
402
 
  /* FDSelect */
403
 
  cff_dict_set(cffont->topdict, "FDSelect", 0, offset);
404
 
  offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset);
405
 
 
406
 
  /* CharStrings */
407
 
  cff_dict_set(cffont->topdict, "CharStrings", 0, offset);
408
 
  offset += cff_pack_index(cffont->cstrings,
409
 
                           dest + offset, cff_index_size(cffont->cstrings));
410
 
  cff_release_index(cffont->cstrings);
411
 
  cffont->cstrings = NULL; /* Charstrings cosumes huge memory */
412
 
 
413
 
  /* FDArray and Private */
414
 
  cff_dict_set(cffont->topdict, "FDArray", 0, offset);
415
 
  fdarray_offset = offset;
416
 
  offset += cff_index_size(fdarray);
417
 
 
418
 
  fdarray->data = NEW(fdarray->offset[fdarray->count] - 1, card8);
419
 
  for (i = 0; i < cffont->num_fds; i++) {
420
 
    size = private->offset[i+1] - private->offset[i];
421
 
    if (cffont->private[i] && size > 0) {
422
 
      cff_dict_pack(cffont->private[i], dest + offset, size);
423
 
      cff_dict_set(cffont->fdarray[i], "Private", 0, size);
424
 
      cff_dict_set(cffont->fdarray[i], "Private", 1, offset);
425
 
    }
426
 
    cff_dict_pack(cffont->fdarray[i],
427
 
                  fdarray->data + (fdarray->offset)[i] - 1,
428
 
                  fdarray->offset[fdarray->count] - 1);
429
 
    offset += size;
430
 
  }
431
 
 
432
 
  cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray));
433
 
  cff_release_index(fdarray);
434
 
  cff_release_index(private);
435
 
 
436
 
  /* Finally Top DICT */
437
 
  topdict->data = NEW(topdict->offset[topdict->count] - 1, card8);
438
 
  cff_dict_pack(cffont->topdict,
439
 
                topdict->data, topdict->offset[topdict->count] - 1);
440
 
  cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict));
441
 
  cff_release_index(topdict);
442
 
 
443
 
  /*
444
 
   * FontFile
445
 
   */
446
 
  {
447
 
    pdf_obj *fontfile, *stream_dict;
448
 
 
449
 
    fontfile    = pdf_new_stream(STREAM_COMPRESS);
450
 
    stream_dict = pdf_stream_dict(fontfile);
451
 
    pdf_add_dict(font->descriptor,
452
 
                 pdf_new_name("FontFile3"),
453
 
                 pdf_ref_obj (fontfile));
454
 
    pdf_add_dict(stream_dict,
455
 
                 pdf_new_name("Subtype"),
456
 
                 pdf_new_name("CIDFontType0C"));
457
 
    pdf_add_stream(fontfile, (char *) dest, offset);
458
 
    pdf_release_obj(fontfile);
459
 
    RELEASE(dest);
460
 
  }
461
 
 
462
 
  return destlen;
463
 
}
464
 
 
465
 
void
466
 
CIDFont_type0_dofont (CIDFont *font)
467
 
{
468
 
  sfnt     *sfont;
469
 
  cff_font *cffont;
470
 
  FILE     *fp;
471
 
  cff_index    *charstrings, *idx;
472
 
  cff_charsets *charset = NULL;
473
 
  cff_fdselect *fdselect = NULL;
474
 
  long   charstring_len, max_len;
475
 
  long   destlen = 0;
476
 
  long   size, offset = 0;
477
 
  card8 *data;
478
 
  card16 num_glyphs, gid;
479
 
  long   cid, cid_count;
480
 
  card16 cs_count, last_cid;
481
 
  int    fd, prev_fd, parent_id;
482
 
  char  *used_chars;
483
 
  unsigned char *CIDToGIDMap = NULL;
484
 
 
485
 
  ASSERT(font);
486
 
 
487
 
  if (!font->indirect)
488
 
    return;
489
 
 
490
 
  pdf_add_dict(font->fontdict, 
491
 
               pdf_new_name("FontDescriptor"),
492
 
               pdf_ref_obj (font->descriptor));
493
 
 
494
 
  if (CIDFont_is_BaseFont(font))
495
 
    return;
496
 
  else if (!CIDFont_get_embedding(font) &&
497
 
           (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) {
498
 
    /* No metrics needed. */
499
 
    pdf_add_dict(font->fontdict,
500
 
                 pdf_new_name("DW"), pdf_new_number(1000.0));
501
 
    return;
502
 
  }
503
 
 
504
 
  if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
505
 
      (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
506
 
    ERROR("No parent Type 0 font !");
507
 
 
508
 
  used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
509
 
  if (!used_chars)
510
 
    ERROR("Unexpected error: Font not actually used???");
511
 
 
512
 
  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
513
 
  if (!fp)
514
 
    ERROR("Could not open OpenType font file: %s", font->ident);
515
 
  sfont = sfnt_open(fp);
516
 
  if (!sfont)
517
 
    ERROR("Could not open OpenType font file: %s", font->ident);
518
 
 
519
 
  if (sfnt_read_table_directory(sfont, 0) < 0 ||
520
 
      sfont->type != SFNT_TYPE_POSTSCRIPT)
521
 
    ERROR("Not a CFF/OpenType font ?");
522
 
  offset = sfnt_find_table_pos(sfont, "CFF ");
523
 
  if (offset == 0)
524
 
    ERROR("Not a CFF/OpenType font ?");
525
 
 
526
 
  cffont = cff_open(fp, offset, font->options->index);
527
 
  if (!cffont)
528
 
    ERROR("Could not open CFF font.");
529
 
  if (!(cffont->flag & FONTTYPE_CIDFONT))
530
 
    ERROR("Not a CIDFont.");
531
 
 
532
 
  if (cff_dict_known(cffont->topdict, "CIDCount")) {
533
 
    cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0);
534
 
  } else {
535
 
    cid_count = CID_MAX + 1;
536
 
  }
537
 
 
538
 
  cff_read_charsets(cffont);
539
 
  CIDToGIDMap = NEW(2*cid_count, unsigned char);
540
 
  memset(CIDToGIDMap, 0, 2*cid_count);
541
 
  add_to_used_chars2(used_chars, 0); /* .notdef */
542
 
  cid = 0; last_cid = 0; num_glyphs = 0;
543
 
  for (cid = 0; cid <= CID_MAX; cid++) {
544
 
    if (is_used_char2(used_chars, cid)) {
545
 
      gid = cff_charsets_lookup(cffont, cid);
546
 
      if (cid != 0 && gid == 0) {
547
 
        WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->ident);
548
 
        used_chars[cid/8] &= ~(1 << (7 - (cid % 8)));
549
 
        continue;
550
 
      }
551
 
      CIDToGIDMap[2*cid]   = (gid >> 8) & 0xff;
552
 
      CIDToGIDMap[2*cid+1] = gid & 0xff;
553
 
      last_cid = cid;
554
 
      num_glyphs++;
555
 
    }
556
 
  }
557
 
 
558
 
  /*
559
 
   * DW, W, DW2 and W2:
560
 
   * Those values are obtained from OpenType table (not TFM).
561
 
   */
562
 
  if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
563
 
    pdf_add_dict(font->fontdict,
564
 
                 pdf_new_name("DW"), pdf_new_number(1000.0));
565
 
  } else {
566
 
    add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
567
 
                   ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
568
 
  }
569
 
 
570
 
  if (!CIDFont_get_embedding(font)) {
571
 
    RELEASE(CIDToGIDMap);
572
 
    cff_close(cffont);
573
 
    sfnt_close(sfont);
574
 
    DPXFCLOSE(fp);
575
 
 
576
 
    return;
577
 
  }
578
 
 
579
 
  /*
580
 
   * Embed font subset.
581
 
   */
582
 
  cff_read_fdselect(cffont);
583
 
  cff_read_fdarray(cffont);
584
 
  cff_read_private(cffont);
585
 
 
586
 
  cff_read_subrs(cffont);
587
 
 
588
 
  offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
589
 
  cff_seek_set(cffont, offset);
590
 
  idx = cff_get_index_header(cffont);
591
 
  /* offset is now absolute offset ... bad */
592
 
  offset = ftell(cffont->stream);
593
 
  
594
 
  if ((cs_count = idx->count) < 2) {
595
 
    ERROR("No valid charstring data found.");
596
 
  }
597
 
 
598
 
  /* New Charsets data */
599
 
  charset = NEW(1, cff_charsets);
600
 
  charset->format = 0;
601
 
  charset->num_entries = 0;
602
 
  charset->data.glyphs = NEW(num_glyphs, s_SID);
603
 
 
604
 
  /* New FDSelect data */
605
 
  fdselect = NEW(1, cff_fdselect);
606
 
  fdselect->format = 3;
607
 
  fdselect->num_entries = 0;
608
 
  fdselect->data.ranges = NEW(num_glyphs, cff_range3);
609
 
 
610
 
  /* New CharStrings INDEX */
611
 
  charstrings = cff_new_index(num_glyphs+1);
612
 
  max_len = 2 * CS_STR_LEN_MAX;
613
 
  charstrings->data = NEW(max_len, card8);
614
 
  charstring_len = 0;
615
 
 
616
 
  /*
617
 
   * TODO: Re-assign FD number.
618
 
   */
619
 
  prev_fd = -1; gid = 0;
620
 
  data = NEW(CS_STR_LEN_MAX, card8);
621
 
  for (cid = 0; cid <= last_cid; cid++) {
622
 
    unsigned short gid_org;
623
 
 
624
 
    if (!is_used_char2(used_chars, cid))
625
 
      continue;
626
 
 
627
 
    gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]);
628
 
    if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org])
629
 
        > CS_STR_LEN_MAX)
630
 
      ERROR("Charstring too long: gid=%u", gid_org);
631
 
    if (charstring_len + CS_STR_LEN_MAX >= max_len) {
632
 
      max_len = charstring_len + 2 * CS_STR_LEN_MAX;
633
 
      charstrings->data = RENEW(charstrings->data, max_len, card8);
634
 
    }
635
 
    (charstrings->offset)[gid] = charstring_len + 1;
636
 
    seek_absolute(cffont->stream, offset + (idx->offset)[gid_org] - 1);
637
 
    fread(data, 1, size, cffont->stream);
638
 
    fd = cff_fdselect_lookup(cffont, gid_org);
639
 
    charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
640
 
                                         max_len - charstring_len,
641
 
                                         data, size,
642
 
                                         cffont->gsubr, (cffont->subrs)[fd], 0, 0, NULL);
643
 
    if (cid > 0 && gid_org > 0) {
644
 
      charset->data.glyphs[charset->num_entries] = cid;
645
 
      charset->num_entries += 1;
646
 
    }
647
 
    if (fd != prev_fd) {
648
 
      fdselect->data.ranges[fdselect->num_entries].first = gid;
649
 
      fdselect->data.ranges[fdselect->num_entries].fd    = fd;
650
 
      fdselect->num_entries += 1;
651
 
      prev_fd = fd;
652
 
    }
653
 
    gid++;
654
 
  }
655
 
  if (gid != num_glyphs)
656
 
    ERROR("Unexpeced error: ?????");
657
 
  RELEASE(data);
658
 
  cff_release_index(idx);
659
 
 
660
 
  RELEASE(CIDToGIDMap);
661
 
  
662
 
  (charstrings->offset)[num_glyphs] = charstring_len + 1;
663
 
  charstrings->count = num_glyphs;
664
 
  cffont->num_glyphs    = num_glyphs;
665
 
  cffont->cstrings      = charstrings;
666
 
  
667
 
  /* discard old one, set new data */
668
 
  cff_release_charsets(cffont->charsets);
669
 
  cffont->charsets = charset;
670
 
  cff_release_fdselect(cffont->fdselect);
671
 
  cffont->fdselect = fdselect;
672
 
 
673
 
  /* no Global subr */
674
 
  if (cffont->gsubr)
675
 
    cff_release_index(cffont->gsubr);
676
 
  cffont->gsubr = cff_new_index(0);
677
 
 
678
 
  for (fd = 0; fd < cffont->num_fds; fd++) {
679
 
    if (cffont->subrs && cffont->subrs[fd]) {
680
 
      cff_release_index(cffont->subrs[fd]);
681
 
      cffont->subrs[fd] = NULL;
682
 
    }
683
 
    if (cffont->private && (cffont->private)[fd]) {
684
 
      cff_dict_remove((cffont->private)[fd], "Subrs"); /* no Subrs */
685
 
    }
686
 
  }
687
 
 
688
 
  destlen = write_fontfile(font, cffont);
689
 
 
690
 
  cff_close(cffont);
691
 
  sfnt_close(sfont);
692
 
  DPXFCLOSE(fp);
693
 
 
694
 
  if (verbose > 1)
695
 
    MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen);
696
 
 
697
 
  /*
698
 
   * CIDSet:
699
 
   * Length of CIDSet stream is not clear. Must be 8192 bytes long?
700
 
   */
701
 
  {
702
 
    pdf_obj *cidset;
703
 
 
704
 
    cidset = pdf_new_stream(STREAM_COMPRESS);
705
 
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
706
 
    pdf_add_dict(font->descriptor,
707
 
                 pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
708
 
    pdf_release_obj(cidset);
709
 
  }
710
 
 
711
 
  return;
712
 
}
713
 
 
714
 
int
715
 
CIDFont_type0_open (CIDFont *font, const char *name,
716
 
                    CIDSysInfo *cmap_csi, cid_opt *opt)
717
 
{
718
 
  CIDSysInfo *csi;
719
 
  char       *fontname;
720
 
  sfnt       *sfont;
721
 
  cff_font   *cffont;
722
 
  FILE       *fp;
723
 
  unsigned long offset = 0;
724
 
 
725
 
  ASSERT(font);
726
 
 
727
 
  fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
728
 
  if (!fp)
729
 
    return -1;
730
 
 
731
 
  sfont = sfnt_open(fp);
732
 
  if (!sfont) {
733
 
    ERROR("Not a CFF/OpenType font?");
734
 
  }
735
 
  if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
736
 
      sfnt_read_table_directory(sfont, 0) < 0 ||
737
 
      (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
738
 
    ERROR("Not a CFF/OpenType font?");
739
 
  }
740
 
 
741
 
  cffont = cff_open(sfont->stream, offset, opt->index);
742
 
  if (!cffont) {
743
 
    ERROR("Cannot read CFF font data");
744
 
  }
745
 
 
746
 
  if (!(cffont->flag & FONTTYPE_CIDFONT)) {
747
 
    cff_close(cffont);
748
 
    sfnt_close(sfont);
749
 
    DPXFCLOSE(fp);
750
 
    return -1;
751
 
  }
752
 
 
753
 
  csi = NEW(1, CIDSysInfo);
754
 
  csi->registry =
755
 
    cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0));
756
 
  csi->ordering =
757
 
    cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1));
758
 
  csi->supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2);
759
 
 
760
 
  if (cmap_csi) {
761
 
    if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
762
 
        strcmp(csi->ordering, cmap_csi->ordering) != 0) {
763
 
      MESG("\nCharacter collection mismatched:\n");
764
 
      MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
765
 
      MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
766
 
      ERROR("Inconsistent CMap specified for this font.");
767
 
    }
768
 
    if (csi->supplement < cmap_csi->supplement) {
769
 
      WARN("CMap have higher supplmement number.");
770
 
      WARN("Some characters may not be displayed or printed.");
771
 
    }
772
 
  }
773
 
 
774
 
  {
775
 
    char *shortname;
776
 
 
777
 
    shortname = cff_get_name(cffont);
778
 
    if (!shortname)
779
 
      ERROR("No valid FontName found.");
780
 
    /*
781
 
     * Mangled name requires more 7 bytes.
782
 
     * Style requires more 11 bytes.
783
 
     */
784
 
    fontname = NEW(strlen(shortname)+19, char);
785
 
    memset(fontname, 0, strlen(shortname)+19);
786
 
    strcpy(fontname, shortname);
787
 
    RELEASE(shortname);
788
 
  }
789
 
  cff_close(cffont);
790
 
 
791
 
  if (opt->embed && opt->style != FONT_STYLE_NONE) {
792
 
    WARN("Embedding disabled due to style option for %s.", name);
793
 
    opt->embed = 0;
794
 
  }
795
 
  switch (opt->style) {
796
 
  case FONT_STYLE_BOLD:
797
 
    strcat(fontname, ",Bold");
798
 
    break;
799
 
  case FONT_STYLE_ITALIC:
800
 
    strcat(fontname, ",Italic");
801
 
    break;
802
 
  case FONT_STYLE_BOLDITALIC:
803
 
    strcat(fontname, ",BoldItalic");
804
 
    break;
805
 
  }
806
 
 
807
 
  font->fontname = fontname;
808
 
  font->subtype  = CIDFONT_TYPE0;
809
 
  font->csi      = csi;
810
 
 
811
 
  font->fontdict = pdf_new_dict();
812
 
  pdf_add_dict(font->fontdict,
813
 
               pdf_new_name("Type"),
814
 
               pdf_new_name("Font"));
815
 
  pdf_add_dict(font->fontdict,
816
 
               pdf_new_name("Subtype"),
817
 
               pdf_new_name("CIDFontType0"));
818
 
 
819
 
  /* getting font info. from TrueType tables */
820
 
  if ((font->descriptor
821
 
       = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
822
 
    ERROR("Could not obtain neccesary font info.");
823
 
 
824
 
  if (opt->embed) {
825
 
    memmove(fontname + 7, fontname, strlen(fontname) + 1);
826
 
    pdf_font_make_uniqueTag(fontname); 
827
 
    fontname[6] = '+';
828
 
  }
829
 
 
830
 
  pdf_add_dict(font->descriptor,
831
 
               pdf_new_name("FontName"),
832
 
               pdf_new_name(fontname));
833
 
  pdf_add_dict(font->fontdict, 
834
 
               pdf_new_name("BaseFont"),
835
 
               pdf_new_name(fontname));
836
 
  {
837
 
    pdf_obj *csi_dict = pdf_new_dict();
838
 
    pdf_add_dict(csi_dict,
839
 
                 pdf_new_name("Registry"),
840
 
                 pdf_new_string(csi->registry, strlen(csi->registry)));
841
 
    pdf_add_dict(csi_dict,
842
 
                 pdf_new_name("Ordering"),
843
 
                 pdf_new_string(csi->ordering, strlen(csi->ordering)));
844
 
    pdf_add_dict(csi_dict,
845
 
                 pdf_new_name("Supplement"),
846
 
                 pdf_new_number(csi->supplement));
847
 
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
848
 
  }
849
 
  pdf_add_dict(font->fontdict, 
850
 
               pdf_new_name("DW"),
851
 
               pdf_new_number(1000)); /* not sure */
852
 
 
853
 
  sfnt_close(sfont);
854
 
  DPXFCLOSE(fp);
855
 
 
856
 
  return 0;
857
 
}
858
 
 
859
 
void
860
 
CIDFont_type0_t1cdofont (CIDFont *font)
861
 
{
862
 
  sfnt      *sfont;
863
 
  cff_font  *cffont;
864
 
  cff_index *charstrings, *idx;
865
 
  long   charstring_len, max_len;
866
 
  long   destlen = 0;
867
 
  long   size, offset = 0;
868
 
  card8 *data;
869
 
  card16 num_glyphs, gid, last_cid;
870
 
  long   i, cid;
871
 
  int    parent_id;
872
 
  char  *used_chars;
873
 
  double default_width, nominal_width;
874
 
  FILE  *fp;
875
 
 
876
 
  ASSERT(font);
877
 
 
878
 
  if (!font->indirect)
879
 
    return;
880
 
 
881
 
  pdf_add_dict(font->fontdict, 
882
 
               pdf_new_name("FontDescriptor"),
883
 
               pdf_ref_obj (font->descriptor));
884
 
 
885
 
  if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
886
 
      (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
887
 
    ERROR("No parent Type 0 font !");
888
 
 
889
 
  used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
890
 
  if (!used_chars)
891
 
    ERROR("Unexpected error: Font not actually used???");
892
 
 
893
 
  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
894
 
  if (!fp)
895
 
    ERROR("Could not open OpenType font file: %s", font->ident);
896
 
 
897
 
  sfont = sfnt_open(fp);
898
 
  if (!sfont)
899
 
    ERROR("Could not open OpenType font file: %s", font->ident);
900
 
 
901
 
  if (sfnt_read_table_directory(sfont, 0) < 0 ||
902
 
      sfont->type != SFNT_TYPE_POSTSCRIPT)
903
 
    ERROR("Not a CFF/OpenType font ?");
904
 
  offset = sfnt_find_table_pos(sfont, "CFF ");
905
 
  if (offset == 0)
906
 
    ERROR("Not a CFF/OpenType font ?");
907
 
 
908
 
  cffont = cff_open(fp, offset, font->options->index);
909
 
  if (!cffont)
910
 
    ERROR("Could not open CFF font.");
911
 
  if (cffont->flag & FONTTYPE_CIDFONT)
912
 
    ERROR("This is CIDFont...");
913
 
 
914
 
  cff_read_private(cffont);
915
 
  cff_read_subrs  (cffont);
916
 
 
917
 
  if (cffont->private[0] && cff_dict_known(cffont->private[0], "StdVW")) {
918
 
    double stemv;
919
 
    stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
920
 
    pdf_add_dict(font->descriptor,
921
 
                 pdf_new_name("StemV"), pdf_new_number(stemv));
922
 
  }
923
 
  if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) {
924
 
    default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
925
 
  } else {
926
 
    default_width = CFF_DEFAULTWIDTHX_DEFAULT;
927
 
  }
928
 
  if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) {
929
 
    nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
930
 
  } else {
931
 
    nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
932
 
  }
933
 
 
934
 
  num_glyphs = 0; last_cid = 0;
935
 
  add_to_used_chars2(used_chars, 0); /* .notdef */
936
 
  for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
937
 
    int c, j;
938
 
 
939
 
    c = used_chars[i];
940
 
    for (j = 7; j >= 0; j--) {
941
 
      if (c & (1 << j)) {
942
 
        num_glyphs++;
943
 
        last_cid = (i + 1) * 8 - j - 1;
944
 
      }
945
 
    }
946
 
  }
947
 
 
948
 
  {
949
 
    cff_fdselect *fdselect;
950
 
 
951
 
    fdselect = NEW(1, cff_fdselect);
952
 
    fdselect->format = 3;
953
 
    fdselect->num_entries = 1;
954
 
    fdselect->data.ranges = NEW(1, cff_range3);
955
 
    fdselect->data.ranges[0].first = 0;
956
 
    fdselect->data.ranges[0].fd    = 0;
957
 
    cffont->fdselect = fdselect;
958
 
  }
959
 
 
960
 
  {
961
 
    cff_charsets *charset;
962
 
 
963
 
    charset  = NEW(1, cff_charsets);
964
 
    charset->format = 0;
965
 
    charset->num_entries = num_glyphs-1;
966
 
    charset->data.glyphs = NEW(num_glyphs-1, s_SID);
967
 
 
968
 
    for (gid = 0, cid = 0; cid <= last_cid; cid++) {
969
 
      if (is_used_char2(used_chars, cid)) {
970
 
        if (gid > 0)
971
 
          charset->data.glyphs[gid-1] = cid;
972
 
        gid++;
973
 
      }
974
 
    }
975
 
    /* cff_release_charsets(cffont->charsets); */
976
 
    cffont->charsets = charset;
977
 
  }
978
 
 
979
 
  cff_dict_add(cffont->topdict, "CIDCount", 1);
980
 
  cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
981
 
 
982
 
  cffont->fdarray    = NEW(1, cff_dict *);
983
 
  cffont->fdarray[0] = cff_new_dict();
984
 
  cff_dict_add(cffont->fdarray[0], "FontName", 1);
985
 
  cff_dict_set(cffont->fdarray[0], "FontName", 0,
986
 
               (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
987
 
  cff_dict_add(cffont->fdarray[0], "Private", 2);
988
 
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
989
 
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
990
 
  /* FDArray  - index offset, not known yet */
991
 
  cff_dict_add(cffont->topdict, "FDArray", 1);
992
 
  cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
993
 
  /* FDSelect - offset, not known yet */
994
 
  cff_dict_add(cffont->topdict, "FDSelect", 1);
995
 
  cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
996
 
 
997
 
  cff_dict_remove(cffont->topdict, "UniqueID");
998
 
  cff_dict_remove(cffont->topdict, "XUID");
999
 
  cff_dict_remove(cffont->topdict, "Private");
1000
 
  cff_dict_remove(cffont->topdict, "Encoding");
1001
 
 
1002
 
 
1003
 
  /* */
1004
 
  offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
1005
 
  cff_seek_set(cffont, offset);
1006
 
  idx = cff_get_index_header(cffont);
1007
 
  /* offset is now absolute offset ... bad */
1008
 
  offset = ftell(cffont->stream);
1009
 
 
1010
 
  if (idx->count < 2)
1011
 
    ERROR("No valid charstring data found.");
1012
 
 
1013
 
  /* New CharStrings INDEX */
1014
 
  charstrings = cff_new_index(num_glyphs+1);
1015
 
  max_len = 2 * CS_STR_LEN_MAX;
1016
 
  charstrings->data = NEW(max_len, card8);
1017
 
  charstring_len = 0;
1018
 
 
1019
 
  gid  = 0;
1020
 
  data = NEW(CS_STR_LEN_MAX, card8);
1021
 
  for (cid = 0; cid <= last_cid; cid++) {
1022
 
    if (!is_used_char2(used_chars, cid))
1023
 
      continue;
1024
 
 
1025
 
    if ((size = (idx->offset)[cid+1] - (idx->offset)[cid])
1026
 
        > CS_STR_LEN_MAX)
1027
 
      ERROR("Charstring too long: gid=%u", cid);
1028
 
    if (charstring_len + CS_STR_LEN_MAX >= max_len) {
1029
 
      max_len = charstring_len + 2 * CS_STR_LEN_MAX;
1030
 
      charstrings->data = RENEW(charstrings->data, max_len, card8);
1031
 
    }
1032
 
    (charstrings->offset)[gid] = charstring_len + 1;
1033
 
    seek_absolute(cffont->stream, offset + (idx->offset)[cid] - 1);
1034
 
    fread(data, 1, size, cffont->stream);
1035
 
    charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
1036
 
                                         max_len - charstring_len,
1037
 
                                         data, size,
1038
 
                                         cffont->gsubr, (cffont->subrs)[0],
1039
 
                                         default_width, nominal_width, NULL);
1040
 
    gid++;
1041
 
  }
1042
 
  if (gid != num_glyphs)
1043
 
    ERROR("Unexpeced error: ?????");
1044
 
  RELEASE(data);
1045
 
  cff_release_index(idx);
1046
 
 
1047
 
  (charstrings->offset)[num_glyphs] = charstring_len + 1;
1048
 
  charstrings->count = num_glyphs;
1049
 
  cffont->num_glyphs    = num_glyphs;
1050
 
  cffont->cstrings      = charstrings;
1051
 
  
1052
 
  /* no Global subr */
1053
 
  if (cffont->gsubr)
1054
 
    cff_release_index(cffont->gsubr);
1055
 
  cffont->gsubr = cff_new_index(0);
1056
 
 
1057
 
  if (cffont->subrs && cffont->subrs[0]) {
1058
 
    cff_release_index(cffont->subrs[0]);
1059
 
    cffont->subrs[0] = NULL;
1060
 
  }
1061
 
  if (cffont->private && (cffont->private)[0]) {
1062
 
    cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */
1063
 
  }
1064
 
 
1065
 
  cff_add_string(cffont, "Adobe", 1);
1066
 
  cff_add_string(cffont, "Identity", 1);
1067
 
 
1068
 
  cff_dict_update(cffont->topdict, cffont);
1069
 
  cff_dict_update(cffont->private[0], cffont);
1070
 
  cff_update_string(cffont);
1071
 
 
1072
 
  /* CFF code need to be rewrote... */
1073
 
  cff_dict_add(cffont->topdict, "ROS", 3);
1074
 
  cff_dict_set(cffont->topdict, "ROS", 0,
1075
 
               (double) cff_get_sid(cffont, "Adobe"));
1076
 
  cff_dict_set(cffont->topdict, "ROS", 1,
1077
 
               (double) cff_get_sid(cffont, "Identity"));
1078
 
  cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
1079
 
 
1080
 
  destlen = write_fontfile(font, cffont);
1081
 
 
1082
 
  cff_close(cffont);
1083
 
 
1084
 
  /*
1085
 
   * DW, W, DW2 and W2:
1086
 
   * Those values are obtained from OpenType table (not TFM).
1087
 
   */
1088
 
  {
1089
 
    unsigned char *CIDToGIDMap;
1090
 
 
1091
 
    CIDToGIDMap = NEW(2 * (last_cid+1), unsigned char);
1092
 
    memset(CIDToGIDMap, 0, 2 * (last_cid + 1));
1093
 
    for (cid = 0; cid <= last_cid; cid++) {
1094
 
      if (is_used_char2(used_chars, cid)) {
1095
 
        CIDToGIDMap[2*cid  ] = (cid >> 8) & 0xff;
1096
 
        CIDToGIDMap[2*cid+1] = cid & 0xff;
1097
 
      }
1098
 
    }
1099
 
    add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
1100
 
                   ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
1101
 
    RELEASE(CIDToGIDMap);
1102
 
  }
1103
 
 
1104
 
  sfnt_close(sfont);
1105
 
  DPXFCLOSE(fp);
1106
 
 
1107
 
  if (verbose > 1)
1108
 
    MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen);
1109
 
 
1110
 
  /*
1111
 
   * CIDSet:
1112
 
   * Length of CIDSet stream is not clear. Must be 8192 bytes long?
1113
 
   */
1114
 
  {
1115
 
    pdf_obj *cidset;
1116
 
 
1117
 
    cidset = pdf_new_stream(STREAM_COMPRESS);
1118
 
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
1119
 
    pdf_add_dict(font->descriptor,
1120
 
                 pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
1121
 
    pdf_release_obj(cidset);
1122
 
  }
1123
 
 
1124
 
  return;
1125
 
}
1126
 
 
1127
 
int
1128
 
CIDFont_type0_t1copen (CIDFont *font, const char *name,
1129
 
                       CIDSysInfo *cmap_csi, cid_opt *opt)
1130
 
{
1131
 
  CIDSysInfo *csi;
1132
 
  char       *fontname;
1133
 
  sfnt       *sfont;
1134
 
  cff_font   *cffont;
1135
 
  unsigned long offset = 0;
1136
 
  FILE       *fp;
1137
 
 
1138
 
  ASSERT(font);
1139
 
 
1140
 
  fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
1141
 
  if (!fp)
1142
 
    return -1;
1143
 
 
1144
 
  sfont = sfnt_open(fp);
1145
 
  if (!sfont) {
1146
 
    ERROR("Not a CFF/OpenType font?");
1147
 
  }
1148
 
  if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
1149
 
      sfnt_read_table_directory(sfont, 0) < 0 ||
1150
 
      (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
1151
 
    ERROR("Not a CFF/OpenType font?");
1152
 
  }
1153
 
 
1154
 
  cffont = cff_open(fp, offset, opt->index);
1155
 
  if (!cffont) {
1156
 
    ERROR("Cannot read CFF font data");
1157
 
  }
1158
 
 
1159
 
  if (cffont->flag & FONTTYPE_CIDFONT) {
1160
 
    cff_close(cffont);
1161
 
    sfnt_close(sfont);
1162
 
    DPXFCLOSE(fp);
1163
 
 
1164
 
    return -1;
1165
 
  }
1166
 
 
1167
 
  csi = NEW(1, CIDSysInfo);
1168
 
  csi->registry   = NEW(strlen("Adobe")+1, char);
1169
 
  strcpy(csi->registry, "Adobe");
1170
 
  csi->ordering   = NEW(strlen("Identity")+1, char);
1171
 
  strcpy(csi->ordering, "Identity");
1172
 
  csi->supplement = 0;
1173
 
 
1174
 
  if (cmap_csi) {
1175
 
    if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
1176
 
        strcmp(csi->ordering, cmap_csi->ordering) != 0) {
1177
 
      MESG("\nCharacter collection mismatched:\n");
1178
 
      MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
1179
 
      MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
1180
 
      ERROR("Inconsistent CMap specified for this font.");
1181
 
    }
1182
 
    if (csi->supplement < cmap_csi->supplement) {
1183
 
      WARN("CMap have higher supplmement number.");
1184
 
      WARN("Some characters may not be displayed or printed.");
1185
 
    }
1186
 
  }
1187
 
 
1188
 
  {
1189
 
    char *shortname;
1190
 
 
1191
 
    shortname = cff_get_name(cffont);
1192
 
    if (!shortname)
1193
 
      ERROR("No valid FontName found.");
1194
 
    /* Mangled name requires more 7 bytes. */
1195
 
 
1196
 
    fontname = NEW(strlen(shortname) + 8, char);
1197
 
    memset(fontname, 0, strlen(shortname) + 8);
1198
 
    strcpy(fontname, shortname);
1199
 
    RELEASE(shortname);
1200
 
  }
1201
 
  cff_close(cffont);
1202
 
 
1203
 
  opt->embed = 1;
1204
 
 
1205
 
  font->fontname = fontname;
1206
 
  font->subtype  = CIDFONT_TYPE0;
1207
 
  font->csi      = csi;
1208
 
  font->flags   |= CIDFONT_FLAG_TYPE1C;
1209
 
 
1210
 
  font->fontdict = pdf_new_dict();
1211
 
  pdf_add_dict(font->fontdict,
1212
 
               pdf_new_name("Type"),
1213
 
               pdf_new_name("Font"));
1214
 
  pdf_add_dict(font->fontdict,
1215
 
               pdf_new_name("Subtype"),
1216
 
               pdf_new_name("CIDFontType0"));
1217
 
 
1218
 
  /* getting font info. from TrueType tables */
1219
 
  if ((font->descriptor
1220
 
       = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
1221
 
    ERROR("Could not obtain neccesary font info.");
1222
 
 
1223
 
  if (opt->embed) {
1224
 
    memmove(fontname + 7, fontname, strlen(fontname) + 1);
1225
 
    pdf_font_make_uniqueTag(fontname);
1226
 
    fontname[6] = '+';
1227
 
  }
1228
 
 
1229
 
  pdf_add_dict(font->descriptor,
1230
 
               pdf_new_name("FontName"),
1231
 
               pdf_new_name(fontname));
1232
 
  pdf_add_dict(font->fontdict, 
1233
 
               pdf_new_name("BaseFont"),
1234
 
               pdf_new_name(fontname));
1235
 
  {
1236
 
    pdf_obj *csi_dict = pdf_new_dict();
1237
 
    pdf_add_dict(csi_dict,
1238
 
                 pdf_new_name("Registry"),
1239
 
                 pdf_new_string(csi->registry, strlen(csi->registry)));
1240
 
    pdf_add_dict(csi_dict,
1241
 
                 pdf_new_name("Ordering"),
1242
 
                 pdf_new_string(csi->ordering, strlen(csi->ordering)));
1243
 
    pdf_add_dict(csi_dict,
1244
 
                 pdf_new_name("Supplement"),
1245
 
                 pdf_new_number(csi->supplement));
1246
 
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
1247
 
  }
1248
 
  sfnt_close(sfont);
1249
 
  DPXFCLOSE(fp);
1250
 
 
1251
 
  return 0;
1252
 
}
1253
 
 
1254
 
 
1255
 
/* Type1 --> CFF CIDFont */
1256
 
#include "unicode.h"
1257
 
#include "t1_load.h"
1258
 
#include "t1_char.h"
1259
 
 
1260
 
#include "agl.h"
1261
 
 
1262
 
#include "cmap.h"
1263
 
#include "cmap_write.h"
1264
 
#include "fontmap.h"
1265
 
 
1266
 
static int
1267
 
load_base_CMap (const char *font_name, int wmode, cff_font *cffont)
1268
 
{
1269
 
  int       cmap_id = -1;
1270
 
  CMap     *cmap;
1271
 
  char     *cmap_name;
1272
 
  card16    gid;
1273
 
  unsigned char range_min[4] = {0x00, 0x00, 0x00, 0x00};
1274
 
  unsigned char range_max[4] = {0x7f, 0xff, 0xff, 0xff};
1275
 
 
1276
 
  cmap_name = NEW(strlen(font_name)+strlen("-UCS4-H")+1, char);
1277
 
  if (wmode) {
1278
 
    sprintf(cmap_name, "%s-UCS4-V", font_name);
1279
 
  } else {
1280
 
    sprintf(cmap_name, "%s-UCS4-H", font_name);
1281
 
  }
1282
 
 
1283
 
  cmap_id = CMap_cache_find(cmap_name);
1284
 
  if (cmap_id >= 0) {
1285
 
    RELEASE(cmap_name);
1286
 
    return cmap_id;
1287
 
  }
1288
 
 
1289
 
  cmap = CMap_new();
1290
 
  CMap_set_name (cmap, cmap_name);
1291
 
  CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID);
1292
 
  CMap_set_wmode(cmap, wmode);
1293
 
  CMap_add_codespacerange(cmap, range_min, range_max, 4);
1294
 
  CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY);
1295
 
  RELEASE(cmap_name);
1296
 
 
1297
 
  for (gid = 1; gid < cffont->num_glyphs; gid++) {
1298
 
    long      ucv;
1299
 
    s_SID     sid;
1300
 
    char     *glyph, *name, *suffix;
1301
 
    unsigned char  srcCode[4];
1302
 
 
1303
 
    sid   = cff_charsets_lookup_inverse(cffont, gid);
1304
 
    glyph = cff_get_string (cffont, sid);
1305
 
 
1306
 
    name  = agl_chop_suffix(glyph, &suffix);
1307
 
    if (!name) {
1308
 
      if (suffix)
1309
 
        RELEASE(suffix);
1310
 
      RELEASE(glyph);
1311
 
      continue;
1312
 
    }
1313
 
 
1314
 
    if (suffix) {
1315
 
      RELEASE(name);
1316
 
      RELEASE(suffix);
1317
 
      RELEASE(glyph);
1318
 
      continue;
1319
 
    }
1320
 
 
1321
 
    if (agl_name_is_unicode(name)) {
1322
 
      ucv = agl_name_convert_unicode(name);
1323
 
      srcCode[0] = (ucv >> 24) & 0xff;
1324
 
      srcCode[1] = (ucv >> 16) & 0xff;
1325
 
      srcCode[2] = (ucv >>  8) & 0xff;
1326
 
      srcCode[3] = ucv & 0xff;
1327
 
      CMap_add_cidchar(cmap, srcCode, 4, gid);
1328
 
    } else {
1329
 
      agl_name *agln;
1330
 
 
1331
 
      agln = agl_lookup_list(name);
1332
 
      if (!agln)
1333
 
        WARN("Glyph \"%s\" inaccessible (no Unicode mapping)", glyph);
1334
 
      while (agln) {
1335
 
        if (agln->n_components > 1) {
1336
 
          WARN("Glyph \"%s\" inaccessible (composite character)", glyph);
1337
 
        } else if (agln->n_components == 1) {
1338
 
          ucv = agln->unicodes[0];
1339
 
          srcCode[0] = (ucv >> 24) & 0xff;
1340
 
          srcCode[1] = (ucv >> 16) & 0xff;
1341
 
          srcCode[2] = (ucv >>  8) & 0xff;
1342
 
          srcCode[3] = ucv & 0xff;
1343
 
          CMap_add_cidchar(cmap, srcCode, 4, gid);
1344
 
        }
1345
 
        agln = agln->alternate;
1346
 
      }
1347
 
    }
1348
 
    RELEASE(name);
1349
 
    if (suffix)
1350
 
      RELEASE(suffix);
1351
 
    RELEASE(glyph);
1352
 
  }
1353
 
  cmap_id = CMap_cache_add(cmap);
1354
 
 
1355
 
  return cmap_id;
1356
 
}
1357
 
 
1358
 
int
1359
 
t1_load_UnicodeCMap (const char *font_name,
1360
 
                     const char *otl_tags,  /* not supported yet */
1361
 
                     int wmode)
1362
 
{
1363
 
  int       cmap_id = -1;
1364
 
  cff_font *cffont;
1365
 
  FILE     *fp;
1366
 
 
1367
 
  if (!font_name)
1368
 
    return -1;
1369
 
 
1370
 
  fp = DPXFOPEN(font_name, DPX_RES_TYPE_T1FONT);
1371
 
  if (!fp)
1372
 
    return -1;
1373
 
 
1374
 
  cffont = t1_load_font(NULL, 1, fp);
1375
 
  if (!cffont) {
1376
 
    DPXFCLOSE(fp);
1377
 
    return -1;
1378
 
  }
1379
 
  DPXFCLOSE(fp);
1380
 
 
1381
 
  cmap_id = load_base_CMap(font_name, wmode, cffont);
1382
 
  
1383
 
  cff_close(cffont);
1384
 
 
1385
 
  if (cmap_id < 0) {
1386
 
    ERROR("Failed to create Unicode charmap for font \"%s\".", font_name);
1387
 
    return -1;
1388
 
  }
1389
 
 
1390
 
  if (otl_tags) {
1391
 
    WARN("Glyph substitution not supported for Type1 font yet...");
1392
 
  }
1393
 
 
1394
 
  return cmap_id;
1395
 
}
1396
 
 
1397
 
 
1398
 
/*
1399
 
 * ToUnicode CMap
1400
 
 */
1401
 
 
1402
 
static pdf_obj *
1403
 
create_ToUnicode_stream (cff_font *cffont,
1404
 
                         const char *font_name, const char *used_glyphs)
1405
 
{
1406
 
  pdf_obj *stream = NULL;
1407
 
  CMap    *cmap;
1408
 
  CID      cid;
1409
 
  card16   gid;
1410
 
  long     glyph_count, total_fail_count;
1411
 
  char    *cmap_name;
1412
 
#define WBUF_SIZE 1024
1413
 
  unsigned char  wbuf[WBUF_SIZE];
1414
 
  unsigned char *p, *endptr;
1415
 
  static unsigned char range_min[2] = {0x00, 0x00};
1416
 
  static unsigned char range_max[2] = {0xff, 0xff};
1417
 
 
1418
 
  if (!font_name || !used_glyphs)
1419
 
    return NULL;
1420
 
 
1421
 
  cmap = CMap_new();
1422
 
 
1423
 
  cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+1, char);
1424
 
  strcpy(cmap_name, font_name);
1425
 
  strcat(cmap_name, "-UTF16");
1426
 
  CMap_set_name (cmap, cmap_name);
1427
 
  RELEASE(cmap_name);
1428
 
 
1429
 
  CMap_set_wmode(cmap, 0);
1430
 
  CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
1431
 
  CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
1432
 
 
1433
 
  CMap_add_codespacerange(cmap, range_min, range_max, 2);
1434
 
 
1435
 
  glyph_count = total_fail_count = 0;
1436
 
  p      = wbuf;
1437
 
  endptr = wbuf + WBUF_SIZE;
1438
 
  for (cid = 1; cid < cffont->num_glyphs; cid++) { /* Skip .notdef */
1439
 
    if (is_used_char2(used_glyphs, cid)) {
1440
 
      char *glyph;
1441
 
      long  len;
1442
 
      int   fail_count;
1443
 
 
1444
 
      wbuf[0] = (cid >> 8) & 0xff;
1445
 
      wbuf[1] = (cid & 0xff);
1446
 
 
1447
 
      p = wbuf + 2;
1448
 
      gid = cff_charsets_lookup_inverse(cffont, cid);
1449
 
      if (gid == 0)
1450
 
        continue;
1451
 
      glyph = cff_get_string(cffont, gid);
1452
 
      if (glyph) {
1453
 
        len = agl_sput_UTF16BE(glyph, &p, endptr, &fail_count);
1454
 
        if (len < 1 || fail_count) {
1455
 
          total_fail_count += fail_count;
1456
 
        } else {
1457
 
          CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len);
1458
 
        }
1459
 
        RELEASE(glyph);
1460
 
      }
1461
 
      glyph_count++;
1462
 
    }
1463
 
  }
1464
 
 
1465
 
  if (total_fail_count != 0 &&
1466
 
      total_fail_count >= glyph_count/10) {
1467
 
    WARN("%d glyph names (out of %d) missing Unicode mapping.",
1468
 
         total_fail_count, glyph_count);
1469
 
    WARN("ToUnicode CMap \"%s-UTF16\" removed.", font_name);
1470
 
  } else {
1471
 
    stream = CMap_create_stream(cmap, 0);
1472
 
  }
1473
 
  CMap_release(cmap);
1474
 
 
1475
 
  return stream;
1476
 
}
1477
 
 
1478
 
 
1479
 
int
1480
 
CIDFont_type0_t1open (CIDFont *font, const char *name,
1481
 
                      CIDSysInfo *cmap_csi, cid_opt *opt)
1482
 
{
1483
 
  FILE       *fp;
1484
 
  char       *fontname, *shortname;
1485
 
  cff_font   *cffont;
1486
 
 
1487
 
  ASSERT(font);
1488
 
 
1489
 
  if (cmap_csi &&
1490
 
      (strcmp(cmap_csi->registry, "Adobe")    != 0 ||
1491
 
       strcmp(cmap_csi->ordering, "Identity") != 0)) {
1492
 
    return -1;
1493
 
  }
1494
 
  fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT);
1495
 
  if (!fp)
1496
 
    return -1;
1497
 
 
1498
 
  cffont = t1_load_font(NULL, 1, fp);
1499
 
  if (!cffont) {
1500
 
    DPXFCLOSE(fp);
1501
 
    return -1;
1502
 
  }
1503
 
  DPXFCLOSE(fp);
1504
 
 
1505
 
  shortname = cff_get_name(cffont);
1506
 
  if (!shortname)
1507
 
    ERROR("No valid FontName found.");
1508
 
  fontname = NEW(strlen(shortname) + 8, char);
1509
 
  memset(fontname, 0, strlen(shortname) + 8);
1510
 
  strcpy(fontname, shortname);
1511
 
  RELEASE(shortname);
1512
 
 
1513
 
  cff_close(cffont);
1514
 
 
1515
 
  if (opt->style != FONT_STYLE_NONE) {
1516
 
    WARN(",Bold, ,Italic, ... not supported for this type of font...");
1517
 
    opt->style = FONT_STYLE_NONE;
1518
 
  }
1519
 
 
1520
 
  font->fontname = fontname;
1521
 
  font->subtype  = CIDFONT_TYPE0;
1522
 
  font->csi      = NEW(1, CIDSysInfo);
1523
 
  font->csi->registry = NEW(strlen("Adobe")+1, char);
1524
 
  strcpy(font->csi->registry, "Adobe");
1525
 
  font->csi->ordering = NEW(strlen("Identity")+1, char);
1526
 
  strcpy(font->csi->ordering, "Identity");
1527
 
  font->csi->supplement = 0;
1528
 
  font->flags   |= CIDFONT_FLAG_TYPE1;
1529
 
 
1530
 
  font->fontdict = pdf_new_dict();
1531
 
  pdf_add_dict(font->fontdict,
1532
 
               pdf_new_name("Type"),
1533
 
               pdf_new_name("Font"));
1534
 
  pdf_add_dict(font->fontdict,
1535
 
               pdf_new_name("Subtype"),
1536
 
               pdf_new_name("CIDFontType0"));
1537
 
 
1538
 
  memmove(fontname + 7, fontname, strlen(fontname) + 1);
1539
 
  pdf_font_make_uniqueTag(fontname);
1540
 
  fontname[6] = '+';
1541
 
 
1542
 
  font->descriptor = pdf_new_dict();
1543
 
  pdf_add_dict(font->descriptor,
1544
 
               pdf_new_name("FontName"),
1545
 
               pdf_new_name(fontname));
1546
 
  pdf_add_dict(font->fontdict, 
1547
 
               pdf_new_name("BaseFont"),
1548
 
               pdf_new_name(fontname));
1549
 
  {
1550
 
    pdf_obj *csi_dict;
1551
 
 
1552
 
    csi_dict = pdf_new_dict();
1553
 
    pdf_add_dict(csi_dict,
1554
 
                 pdf_new_name("Registry"),
1555
 
                 pdf_new_string("Adobe", strlen("Adobe")));
1556
 
    pdf_add_dict(csi_dict,
1557
 
                 pdf_new_name("Ordering"),
1558
 
                 pdf_new_string("Identity", strlen("Identity")));
1559
 
    pdf_add_dict(csi_dict,
1560
 
                 pdf_new_name("Supplement"),
1561
 
                 pdf_new_number(0.0));
1562
 
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
1563
 
  }
1564
 
 
1565
 
 
1566
 
  return 0;
1567
 
}
1568
 
 
1569
 
/* Duplicate from type1.c */
1570
 
#define TYPE1_NAME_LEN_MAX   127
1571
 
 
1572
 
#define FONT_FLAG_FIXEDPITCH (1 << 0)  /* Fixed-width font */
1573
 
#define FONT_FLAG_SERIF      (1 << 1)  /* Serif font */
1574
 
#define FONT_FLAG_SYMBOLIC   (1 << 2)  /* Symbolic font */
1575
 
#define FONT_FLAG_SCRIPT     (1 << 3)  /* Script font */
1576
 
#define FONT_FLAG_STANDARD   (1 << 5)  /* Adobe Standard Character Set */
1577
 
#define FONT_FLAG_ITALIC     (1 << 6)  /* Italic */
1578
 
#define FONT_FLAG_ALLCAP     (1 << 16) /* All-cap font */
1579
 
#define FONT_FLAG_SMALLCAP   (1 << 17) /* Small-cap font */
1580
 
#define FONT_FLAG_FORCEBOLD  (1 << 18) /* Force bold at small text sizes */
1581
 
 
1582
 
/* pdf_font --> CIDFont */
1583
 
static void
1584
 
get_font_attr (CIDFont *font, cff_font *cffont)
1585
 
{
1586
 
  double capheight, ascent, descent;
1587
 
  double italicangle, stemv;
1588
 
  double defaultwidth, nominalwidth;
1589
 
  long   flags = 0;
1590
 
  long   gid;
1591
 
  int    i;
1592
 
  static const char *L_c[] = {
1593
 
    "H", "P", "Pi", "Rho", NULL
1594
 
  };
1595
 
  static const char *L_d[] = {
1596
 
    "p", "q", "mu", "eta", NULL
1597
 
  };
1598
 
  static const char *L_a[] = {
1599
 
    "b", "h", "lambda", NULL
1600
 
  };
1601
 
  t1_ginfo gm;
1602
 
 
1603
 
  defaultwidth = 500.0;
1604
 
  nominalwidth = 0.0;
1605
 
 
1606
 
  /*
1607
 
   * CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
1608
 
   * The BlueValues and OtherBlues also have those information.
1609
 
   */
1610
 
  if (cff_dict_known(cffont->topdict, "FontBBox")) {
1611
 
    /* Default values */
1612
 
    capheight = ascent = cff_dict_get(cffont->topdict, "FontBBox", 3);
1613
 
    descent = cff_dict_get(cffont->topdict, "FontBBox", 1);
1614
 
  } else {
1615
 
    capheight =  680.0;
1616
 
    ascent    =  690.0;
1617
 
    descent   = -190.0;
1618
 
  }
1619
 
  if (cff_dict_known(cffont->private[0], "StdVW")) {
1620
 
    stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
1621
 
  } else {
1622
 
    /*
1623
 
     * We may use the following values for StemV:
1624
 
     *  Thin - ExtraLight: <= 50
1625
 
     *  Light: 71
1626
 
     *  Regular(Normal): 88
1627
 
     *  Medium: 109
1628
 
     *  SemiBold(DemiBold): 135
1629
 
     *  Bold - Heavy: >= 166
1630
 
     */
1631
 
    stemv = 88.0;
1632
 
  }
1633
 
  if (cff_dict_known(cffont->topdict, "ItalicAngle")) {
1634
 
    italicangle = cff_dict_get(cffont->topdict, "ItalicAngle", 0);
1635
 
    if (italicangle != 0.0)
1636
 
      flags |= FONT_FLAG_ITALIC;
1637
 
  } else {
1638
 
    italicangle = 0.0;
1639
 
  }
1640
 
 
1641
 
  /*
1642
 
   * Use "space", "H", "p", and "b" for various values.
1643
 
   * Those characters should not "seac". (no accent)
1644
 
   */
1645
 
  gid = cff_glyph_lookup(cffont, "space");
1646
 
  if (gid >= 0 && gid < cffont->cstrings->count) {
1647
 
    t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
1648
 
                       cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
1649
 
                       cffont->subrs[0], &gm);
1650
 
    defaultwidth = gm.wx;
1651
 
  }
1652
 
 
1653
 
  for (i = 0; L_c[i] != NULL; i++) {
1654
 
    gid = cff_glyph_lookup(cffont, L_c[i]);
1655
 
    if (gid >= 0 && gid < cffont->cstrings->count) {
1656
 
      t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
1657
 
                         cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
1658
 
                         cffont->subrs[0], &gm);
1659
 
      capheight = gm.bbox.ury;
1660
 
      break;
1661
 
    }
1662
 
  }
1663
 
 
1664
 
  for (i = 0; L_d[i] != NULL; i++) {
1665
 
    gid = cff_glyph_lookup(cffont, L_d[i]);
1666
 
    if (gid >= 0 && gid < cffont->cstrings->count) {
1667
 
      t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
1668
 
                         cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
1669
 
                         cffont->subrs[0], &gm);
1670
 
      descent = gm.bbox.lly;
1671
 
      break;
1672
 
    }
1673
 
  }
1674
 
 
1675
 
  for (i = 0; L_a[i] != NULL; i++) {
1676
 
    gid = cff_glyph_lookup(cffont, L_a[i]);
1677
 
    if (gid >= 0 && gid < cffont->cstrings->count) {
1678
 
      t1char_get_metrics(cffont->cstrings->data + cffont->cstrings->offset[gid] - 1,
1679
 
                         cffont->cstrings->offset[gid+1] - cffont->cstrings->offset[gid],
1680
 
                         cffont->subrs[0], &gm);
1681
 
      ascent = gm.bbox.ury;
1682
 
      break;
1683
 
    }
1684
 
  }
1685
 
 
1686
 
  if (defaultwidth != 0.0) {
1687
 
    cff_dict_add(cffont->private[0], "defaultWidthX", 1);
1688
 
    cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
1689
 
  }
1690
 
  if (nominalwidth != 0.0) {
1691
 
    cff_dict_add(cffont->private[0], "nominalWidthX", 1);
1692
 
    cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
1693
 
  }
1694
 
  if (cff_dict_known(cffont->private[0], "ForceBold") &&
1695
 
      cff_dict_get(cffont->private[0], "ForceBold", 0)) {
1696
 
    flags |= FONT_FLAG_FORCEBOLD;
1697
 
  }
1698
 
  if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
1699
 
      cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
1700
 
    flags |= FONT_FLAG_FIXEDPITCH;
1701
 
  }
1702
 
  if (font->fontname &&
1703
 
      !strstr(font->fontname, "Sans")) {
1704
 
    flags |= FONT_FLAG_SERIF;
1705
 
  }
1706
 
  flags |= FONT_FLAG_SYMBOLIC;
1707
 
 
1708
 
  pdf_add_dict(font->descriptor,
1709
 
               pdf_new_name("CapHeight"), pdf_new_number(capheight));
1710
 
  pdf_add_dict(font->descriptor,
1711
 
               pdf_new_name("Ascent"), pdf_new_number(ascent));
1712
 
  pdf_add_dict(font->descriptor,
1713
 
               pdf_new_name("Descent"), pdf_new_number(descent));
1714
 
  pdf_add_dict(font->descriptor,
1715
 
               pdf_new_name("ItalicAngle"), pdf_new_number(italicangle));
1716
 
  pdf_add_dict(font->descriptor,
1717
 
               pdf_new_name("StemV"), pdf_new_number(stemv));
1718
 
  pdf_add_dict(font->descriptor,
1719
 
               pdf_new_name("Flags"), pdf_new_number(flags));
1720
 
}
1721
 
 
1722
 
static void
1723
 
add_metrics (CIDFont *font, cff_font *cffont,
1724
 
             unsigned char *CIDToGIDMap,
1725
 
             double *widths, double default_width, CID last_cid)
1726
 
{
1727
 
  pdf_obj *tmp;
1728
 
  double   val;
1729
 
  card16   cid, gid;
1730
 
  char    *used_chars;
1731
 
  int      i, parent_id;
1732
 
 
1733
 
  /*
1734
 
   * The original FontBBox of the font is preserved, instead
1735
 
   * of replacing it with tight bounding box calculated from
1736
 
   * charstrings, to prevent Acrobat 4 from greeking text as
1737
 
   * much as possible.
1738
 
   */
1739
 
  if (!cff_dict_known(cffont->topdict, "FontBBox")) {
1740
 
    ERROR("No FontBBox?");
1741
 
  }
1742
 
  tmp = pdf_new_array();
1743
 
  for (i = 0; i < 4; i++) {
1744
 
    val = cff_dict_get(cffont->topdict, "FontBBox", i);
1745
 
    pdf_add_array(tmp, pdf_new_number(ROUND(val, 1.0)));
1746
 
  }
1747
 
  pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp);
1748
 
 
1749
 
  if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
1750
 
      (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
1751
 
    ERROR("No parent Type 0 font !");
1752
 
 
1753
 
  used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
1754
 
  if (!used_chars) {
1755
 
    ERROR("Unexpected error: Font not actually used???");
1756
 
  }
1757
 
 
1758
 
  /* FIXME:
1759
 
   * This writes "CID CID width".
1760
 
   * I think it's better to handle each 8 char block
1761
 
   * and to use "CID_start [ w0 w1 ...]".
1762
 
   */
1763
 
  tmp = pdf_new_array();
1764
 
  for (cid = 0; cid <= last_cid; cid++) {
1765
 
    if (is_used_char2(used_chars, cid)) {
1766
 
      gid = (CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1];
1767
 
      if (widths[gid] != default_width) {
1768
 
        pdf_add_array(tmp, pdf_new_number(cid));
1769
 
        pdf_add_array(tmp, pdf_new_number(cid));
1770
 
        pdf_add_array(tmp, pdf_new_number(ROUND(widths[gid], 1.0)));
1771
 
      }
1772
 
    }
1773
 
  }
1774
 
  pdf_add_dict(font->fontdict,
1775
 
               pdf_new_name("DW"), pdf_new_number(default_width));
1776
 
  if (pdf_array_length(tmp) > 0) {
1777
 
    pdf_add_dict(font->fontdict, pdf_new_name("W"), pdf_ref_obj(tmp));
1778
 
  }
1779
 
  pdf_release_obj(tmp);
1780
 
}
1781
 
 
1782
 
void
1783
 
CIDFont_type0_t1dofont (CIDFont *font)
1784
 
{
1785
 
  cff_font *cffont;
1786
 
  double    defaultwidth, nominalwidth;
1787
 
  long      num_glyphs = 0;
1788
 
  FILE     *fp;
1789
 
  long      i, offset;
1790
 
  char     *used_chars = NULL;
1791
 
  card16    last_cid, gid, cid;
1792
 
  unsigned char *CIDToGIDMap;
1793
 
 
1794
 
  ASSERT(font);
1795
 
 
1796
 
  if (!font->indirect) {
1797
 
    return;
1798
 
  }
1799
 
 
1800
 
  pdf_add_dict(font->fontdict, 
1801
 
               pdf_new_name("FontDescriptor"),
1802
 
               pdf_ref_obj (font->descriptor));
1803
 
 
1804
 
  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT);
1805
 
  if (!fp) {
1806
 
    ERROR("Type1: Could not open Type1 font.");
1807
 
  }
1808
 
 
1809
 
  cffont = t1_load_font(NULL, 0, fp);
1810
 
  if (!cffont)
1811
 
    ERROR("Could not read Type 1 font...");
1812
 
  DPXFCLOSE(fp);
1813
 
 
1814
 
  if (!font->fontname)
1815
 
    ERROR("Fontname undefined...");
1816
 
 
1817
 
  {
1818
 
    Type0Font *hparent, *vparent;
1819
 
    pdf_obj   *tounicode;
1820
 
    int        vparent_id, hparent_id;
1821
 
 
1822
 
    hparent_id = CIDFont_get_parent_id(font, 0);
1823
 
    vparent_id = CIDFont_get_parent_id(font, 1);
1824
 
    if (hparent_id < 0 && vparent_id < 0)
1825
 
      ERROR("No parent Type 0 font !");
1826
 
 
1827
 
    /* usedchars is same for h and v */
1828
 
    if (hparent_id < 0)
1829
 
      hparent = NULL;
1830
 
    else {
1831
 
      hparent    = Type0Font_cache_get(hparent_id);
1832
 
      used_chars = Type0Font_get_usedchars(hparent);
1833
 
    }
1834
 
    if (vparent_id < 0)
1835
 
      vparent = NULL;
1836
 
    else {
1837
 
      vparent    = Type0Font_cache_get(vparent_id);
1838
 
      used_chars = Type0Font_get_usedchars(vparent);
1839
 
    }
1840
 
    if (!used_chars)
1841
 
      ERROR("Unexpected error: Font not actually used???");
1842
 
 
1843
 
    tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars);
1844
 
 
1845
 
    if (hparent)
1846
 
      Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode));
1847
 
    if (vparent)
1848
 
      Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode));
1849
 
    pdf_release_obj(tounicode);
1850
 
  }
1851
 
 
1852
 
  cff_set_name(cffont, font->fontname);
1853
 
 
1854
 
  /* defaultWidthX, CapHeight, etc. */
1855
 
  get_font_attr(font, cffont);
1856
 
  if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
1857
 
    defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
1858
 
  } else {
1859
 
    defaultwidth = 0.0;
1860
 
  }
1861
 
  if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
1862
 
    nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
1863
 
  } else {
1864
 
    nominalwidth = 0.0;
1865
 
  }
1866
 
 
1867
 
  num_glyphs = 0; last_cid = 0;
1868
 
  add_to_used_chars2(used_chars, 0); /* .notdef */
1869
 
  for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
1870
 
    int c, j;
1871
 
 
1872
 
    c = used_chars[i];
1873
 
    for (j = 7; j >= 0; j--) {
1874
 
      if (c & (1 << j)) {
1875
 
        num_glyphs++;
1876
 
        last_cid = (i + 1) * 8 - j - 1;
1877
 
      }
1878
 
    }
1879
 
  }
1880
 
 
1881
 
  {
1882
 
    cff_fdselect *fdselect;
1883
 
 
1884
 
    fdselect = NEW(1, cff_fdselect);
1885
 
    fdselect->format = 3;
1886
 
    fdselect->num_entries = 1;
1887
 
    fdselect->data.ranges = NEW(1, cff_range3);
1888
 
    fdselect->data.ranges[0].first = 0;
1889
 
    fdselect->data.ranges[0].fd    = 0;
1890
 
    cffont->fdselect = fdselect;
1891
 
  }
1892
 
 
1893
 
  CIDToGIDMap = NEW(2*(last_cid+1), unsigned char);
1894
 
  memset(CIDToGIDMap, 0, 2*(last_cid+1));
1895
 
  {
1896
 
    cff_charsets *charset;
1897
 
 
1898
 
    charset  = NEW(1, cff_charsets);
1899
 
    charset->format = 0;
1900
 
    charset->num_entries = num_glyphs-1;
1901
 
    charset->data.glyphs = NEW(num_glyphs-1, s_SID);
1902
 
 
1903
 
    for (gid = 0, cid = 0; cid <= last_cid; cid++) {
1904
 
      if (is_used_char2(used_chars, cid)) {
1905
 
        if (gid > 0)
1906
 
          charset->data.glyphs[gid-1] = cid;
1907
 
        CIDToGIDMap[2*cid  ] = (gid >> 8) & 0xff;
1908
 
        CIDToGIDMap[2*cid+1] = gid & 0xff;
1909
 
        gid++;
1910
 
      }
1911
 
    }
1912
 
 
1913
 
    cff_release_charsets(cffont->charsets);
1914
 
    cffont->charsets = charset;
1915
 
  }
1916
 
 
1917
 
  cff_dict_add(cffont->topdict, "CIDCount", 1);
1918
 
  cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
1919
 
 
1920
 
  cffont->fdarray    = NEW(1, cff_dict *);
1921
 
  cffont->fdarray[0] = cff_new_dict();
1922
 
  cff_dict_add(cffont->fdarray[0], "FontName", 1);
1923
 
  cff_dict_set(cffont->fdarray[0], "FontName", 0,
1924
 
               (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
1925
 
  cff_dict_add(cffont->fdarray[0], "Private", 2);
1926
 
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
1927
 
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
1928
 
 
1929
 
  /* FDArray  - index offset, not known yet */
1930
 
  cff_dict_add(cffont->topdict, "FDArray", 1);
1931
 
  cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
1932
 
  /* FDSelect - offset, not known yet */
1933
 
  cff_dict_add(cffont->topdict, "FDSelect", 1);
1934
 
  cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);
1935
 
 
1936
 
  cff_dict_add(cffont->topdict, "charset", 1);
1937
 
  cff_dict_set(cffont->topdict, "charset", 0, 0.0);
1938
 
 
1939
 
  cff_dict_add(cffont->topdict, "CharStrings", 1);
1940
 
  cff_dict_set(cffont->topdict, "CharStrings", 0, 0.0);
1941
 
 
1942
 
  {
1943
 
    cff_index *cstring;
1944
 
    t1_ginfo   gm;
1945
 
    long       max = 0;
1946
 
    double    *widths;
1947
 
    int        w_stat[1001], max_count, dw;
1948
 
 
1949
 
    widths = NEW(num_glyphs, double);
1950
 
    memset(w_stat, 0, sizeof(int)*1001);
1951
 
    offset  = 0L;
1952
 
    cstring = cff_new_index(num_glyphs);
1953
 
    cstring->data = NULL;
1954
 
    cstring->offset[0] = 1;
1955
 
    gid = 0;
1956
 
    for (cid = 0; cid <= last_cid; cid++) {
1957
 
      if (!is_used_char2(used_chars, cid))
1958
 
          continue;
1959
 
 
1960
 
      if (offset + CS_STR_LEN_MAX >= max) {
1961
 
        max += CS_STR_LEN_MAX*2;
1962
 
        cstring->data = RENEW(cstring->data, max, card8);
1963
 
      }
1964
 
      offset += t1char_convert_charstring(cstring->data + cstring->offset[gid] - 1, CS_STR_LEN_MAX,
1965
 
                                          cffont->cstrings->data + cffont->cstrings->offset[cid] - 1,
1966
 
                                          cffont->cstrings->offset[cid+1] - cffont->cstrings->offset[cid],
1967
 
                                          cffont->subrs[0], defaultwidth, nominalwidth, &gm);
1968
 
      cstring->offset[gid+1] = offset + 1;
1969
 
      if (gm.use_seac) {
1970
 
        ERROR("This font using the \"seac\" command for accented characters...");
1971
 
      }
1972
 
      widths[gid] = gm.wx;
1973
 
      if (gm.wx >= 0.0 && gm.wx <= 1000.0) {
1974
 
        w_stat[((int) gm.wx)] += 1;
1975
 
      }
1976
 
      gid++;
1977
 
    }
1978
 
 
1979
 
    cff_release_index(cffont->cstrings);
1980
 
    cffont->cstrings = cstring;
1981
 
 
1982
 
    max_count = 0; dw = -1;
1983
 
    for (i = 0; i <= 1000; i++) {
1984
 
      if (w_stat[i] > max_count) {
1985
 
        dw        = i;
1986
 
        max_count = w_stat[i];
1987
 
      }
1988
 
    }
1989
 
    if (dw >= 0) {
1990
 
      add_metrics(font, cffont, CIDToGIDMap, widths, dw, last_cid);
1991
 
    } else {
1992
 
      add_metrics(font, cffont, CIDToGIDMap, widths, defaultwidth, last_cid);
1993
 
    }
1994
 
    RELEASE(widths);
1995
 
  }
1996
 
  cff_release_index(cffont->subrs[0]);
1997
 
  cffont->subrs[0] = NULL;
1998
 
 
1999
 
  RELEASE(CIDToGIDMap);
2000
 
 
2001
 
  cff_add_string(cffont, "Adobe", 1);
2002
 
  cff_add_string(cffont, "Identity", 1);
2003
 
 
2004
 
  cff_dict_update(cffont->topdict, cffont);
2005
 
  cff_dict_update(cffont->private[0], cffont);
2006
 
 
2007
 
  cff_update_string(cffont);
2008
 
 
2009
 
  /* CFF code need to be rewrote... */
2010
 
  cff_dict_add(cffont->topdict, "ROS", 3);
2011
 
  cff_dict_set(cffont->topdict, "ROS", 0,
2012
 
               (double) cff_get_sid(cffont, "Adobe"));
2013
 
  cff_dict_set(cffont->topdict, "ROS", 1,
2014
 
               (double) cff_get_sid(cffont, "Identity"));
2015
 
  cff_dict_set(cffont->topdict, "ROS", 2, 0.0);
2016
 
 
2017
 
  cffont->num_glyphs = num_glyphs;
2018
 
  offset = write_fontfile(font, cffont);
2019
 
 
2020
 
  cff_close(cffont);
2021
 
 
2022
 
  {
2023
 
    pdf_obj *cidset;
2024
 
 
2025
 
    cidset = pdf_new_stream(STREAM_COMPRESS);
2026
 
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
2027
 
    pdf_add_dict(font->descriptor,
2028
 
                 pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
2029
 
    pdf_release_obj(cidset);
2030
 
  }
2031
 
 
2032
 
 
2033
 
  return;
2034
 
}
2035
 
 
2036
 
void
2037
 
CIDFont_type0_release(CIDFont *font)
2038
 
{
2039
 
  return;
2040
 
}