1
/* $Header: /home/cvsroot/dvipdfmx/src/cidtype0.c,v 1.40 2011/03/06 03:14:13 chofchof Exp $
3
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5
Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
6
the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
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.
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.
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.
24
* CID-Keyed Font support:
26
* Only CFF/OpenType CID-Keyed Font with Type 2 charstrings is supported.
42
/* pseudo unique tag */
45
/* Font info. from OpenType tables */
51
#include "cff_types.h"
52
#include "cff_limits.h"
57
/* typedef CID in cmap.h */
64
static int verbose = 0;
65
static long opt_flags = 0;
68
CIDFont_type0_set_verbose (void)
74
CIDFont_type0_set_flags (long flags)
80
* PDF Reference 3rd. ed., p.340, "Glyph Metrics in CID Fonts".
83
#define PDFUNIT(v) (ROUND((1000.0*(v))/(head->unitsPerEm),1))
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)
92
pdf_obj *w_array, *an_array = NULL;
93
long cid, start = 0, prev = 0;
94
double defaultAdvanceWidth;
97
defaultAdvanceWidth = PDFUNIT(hmtx[0].advance);
99
* We alway use format:
100
* c [w_1 w_2 ... w_n]
102
w_array = pdf_new_array();
103
for (cid = 0; cid <= last_cid; cid++) {
106
gid = CIDToGIDMap ? ((CIDToGIDMap[2*cid] << 8)|CIDToGIDMap[2*cid+1]) : cid;
107
if (gid >= maxp->numGlyphs || (cid != 0 && gid == 0))
109
advanceWidth = PDFUNIT(hmtx[gid].advance);
110
if (advanceWidth == defaultAdvanceWidth) {
112
pdf_add_array(w_array, pdf_new_number(start));
113
pdf_add_array(w_array, an_array);
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);
124
if (an_array == NULL) {
125
an_array = pdf_new_array();
128
pdf_add_array(an_array, pdf_new_number(advanceWidth));
134
pdf_add_array(w_array, pdf_new_number(start));
135
pdf_add_array(w_array, an_array);
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.
144
pdf_add_dict(fontdict,
146
pdf_new_number(defaultAdvanceWidth));
148
pdf_add_dict(fontdict,
150
pdf_ref_obj(w_array));
152
pdf_release_obj(w_array);
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)
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;
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.
175
if (sfnt_find_table_pos(sfont, "VORG") <= 0)
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);
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);
195
/* Some TrueType fonts used in Macintosh does not have OS/2 table. */
196
defaultAdvanceHeight = 1000;
199
w2_array = pdf_new_array();
201
for (cid = 0; cid <= last_cid; cid++) {
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))
207
advanceHeight = vmtx ? PDFUNIT(vmtx[gid].advance) : defaultAdvanceHeight;
208
vertOriginX = PDFUNIT(hmtx[gid].advance*0.5);
209
vertOriginY = defaultVertOriginY;
211
i < vorg->numVertOriginYMetrics && gid > vorg->vertOriginYMetrics[i].glyphIndex;
213
if (gid == vorg->vertOriginYMetrics[i].glyphIndex)
214
vertOriginY = PDFUNIT(vorg->vertOriginYMetrics[i].vertOriginY);
218
* c [w1_1y v_1x v_1y w1_2y v_2x v_2y ...]
219
* Not working... Why?
221
* Wrong rendering, interpretation of position vector is wrong.
222
* Xpdf and gs: ignores W2?
224
if (vertOriginY == defaultVertOriginY &&
225
advanceHeight == defaultAdvanceHeight) {
227
pdf_add_array(w2_array, pdf_new_number(start));
228
pdf_add_array(w2_array, an_array);
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);
239
if (an_array == NULL) {
240
an_array = pdf_new_array();
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));
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?
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));
268
pdf_add_array(w2_array, pdf_new_number(start));
269
pdf_add_array(w2_array, an_array);
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);
281
pdf_add_dict(fontdict,
282
pdf_new_name("W2"), pdf_ref_obj(w2_array));
284
pdf_release_obj(w2_array);
286
if (vorg->vertOriginYMetrics)
287
RELEASE(vorg->vertOriginYMetrics);
299
add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict,
300
unsigned char *CIDToGIDMap, unsigned short last_cid, int need_vmetrics)
302
struct tt_longMetrics *hmtx;
303
struct tt_head_table *head;
304
struct tt_hhea_table *hhea;
305
struct tt_maxp_table *maxp;
308
* Read head, hhea, maxp:
310
* unitsPerEm --> head
311
* numHMetrics --> hhea
314
head = tt_read_head_table(sfont);
315
maxp = tt_read_maxp_table(sfont);
316
hhea = tt_read_hhea_table(sfont);
318
sfnt_locate_table(sfont, "hmtx");
319
hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings);
321
add_CIDHMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
323
add_CIDVMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx);
334
* Create an instance of embeddable font.
337
write_fontfile (CIDFont *font, cff_font *cffont)
339
cff_index *topdict, *fdarray, *private;
341
long destlen = 0, i, size;
342
long offset, topdict_offset, fdarray_offset;
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);
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 */
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++) {
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");
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);
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 */
383
dest = NEW(destlen, card8);
387
offset += cff_put_header(cffont, dest + offset, destlen - offset);
389
offset += cff_pack_index(cffont->name, dest + offset, destlen - offset);
391
topdict_offset = offset;
392
offset += cff_index_size(topdict);
394
offset += cff_pack_index(cffont->string, dest + offset, destlen - offset);
396
offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset);
399
cff_dict_set(cffont->topdict, "charset", 0, offset);
400
offset += cff_pack_charsets(cffont, dest + offset, destlen - offset);
403
cff_dict_set(cffont->topdict, "FDSelect", 0, offset);
404
offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset);
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 */
413
/* FDArray and Private */
414
cff_dict_set(cffont->topdict, "FDArray", 0, offset);
415
fdarray_offset = offset;
416
offset += cff_index_size(fdarray);
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);
426
cff_dict_pack(cffont->fdarray[i],
427
fdarray->data + (fdarray->offset)[i] - 1,
428
fdarray->offset[fdarray->count] - 1);
432
cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray));
433
cff_release_index(fdarray);
434
cff_release_index(private);
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);
447
pdf_obj *fontfile, *stream_dict;
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);
466
CIDFont_type0_dofont (CIDFont *font)
471
cff_index *charstrings, *idx;
472
cff_charsets *charset = NULL;
473
cff_fdselect *fdselect = NULL;
474
long charstring_len, max_len;
476
long size, offset = 0;
478
card16 num_glyphs, gid;
480
card16 cs_count, last_cid;
481
int fd, prev_fd, parent_id;
483
unsigned char *CIDToGIDMap = NULL;
490
pdf_add_dict(font->fontdict,
491
pdf_new_name("FontDescriptor"),
492
pdf_ref_obj (font->descriptor));
494
if (CIDFont_is_BaseFont(font))
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));
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 !");
508
used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
510
ERROR("Unexpected error: Font not actually used???");
512
fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
514
ERROR("Could not open OpenType font file: %s", font->ident);
515
sfont = sfnt_open(fp);
517
ERROR("Could not open OpenType font file: %s", font->ident);
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 ");
524
ERROR("Not a CFF/OpenType font ?");
526
cffont = cff_open(fp, offset, font->options->index);
528
ERROR("Could not open CFF font.");
529
if (!(cffont->flag & FONTTYPE_CIDFONT))
530
ERROR("Not a CIDFont.");
532
if (cff_dict_known(cffont->topdict, "CIDCount")) {
533
cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0);
535
cid_count = CID_MAX + 1;
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)));
551
CIDToGIDMap[2*cid] = (gid >> 8) & 0xff;
552
CIDToGIDMap[2*cid+1] = gid & 0xff;
560
* Those values are obtained from OpenType table (not TFM).
562
if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
563
pdf_add_dict(font->fontdict,
564
pdf_new_name("DW"), pdf_new_number(1000.0));
566
add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
567
((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
570
if (!CIDFont_get_embedding(font)) {
571
RELEASE(CIDToGIDMap);
582
cff_read_fdselect(cffont);
583
cff_read_fdarray(cffont);
584
cff_read_private(cffont);
586
cff_read_subrs(cffont);
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);
594
if ((cs_count = idx->count) < 2) {
595
ERROR("No valid charstring data found.");
598
/* New Charsets data */
599
charset = NEW(1, cff_charsets);
601
charset->num_entries = 0;
602
charset->data.glyphs = NEW(num_glyphs, s_SID);
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);
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);
617
* TODO: Re-assign FD number.
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;
624
if (!is_used_char2(used_chars, cid))
627
gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]);
628
if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org])
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);
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,
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;
648
fdselect->data.ranges[fdselect->num_entries].first = gid;
649
fdselect->data.ranges[fdselect->num_entries].fd = fd;
650
fdselect->num_entries += 1;
655
if (gid != num_glyphs)
656
ERROR("Unexpeced error: ?????");
658
cff_release_index(idx);
660
RELEASE(CIDToGIDMap);
662
(charstrings->offset)[num_glyphs] = charstring_len + 1;
663
charstrings->count = num_glyphs;
664
cffont->num_glyphs = num_glyphs;
665
cffont->cstrings = charstrings;
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;
675
cff_release_index(cffont->gsubr);
676
cffont->gsubr = cff_new_index(0);
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;
683
if (cffont->private && (cffont->private)[fd]) {
684
cff_dict_remove((cffont->private)[fd], "Subrs"); /* no Subrs */
688
destlen = write_fontfile(font, cffont);
695
MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen);
699
* Length of CIDSet stream is not clear. Must be 8192 bytes long?
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);
715
CIDFont_type0_open (CIDFont *font, const char *name,
716
CIDSysInfo *cmap_csi, cid_opt *opt)
723
unsigned long offset = 0;
727
fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
731
sfont = sfnt_open(fp);
733
ERROR("Not a CFF/OpenType font?");
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?");
741
cffont = cff_open(sfont->stream, offset, opt->index);
743
ERROR("Cannot read CFF font data");
746
if (!(cffont->flag & FONTTYPE_CIDFONT)) {
753
csi = NEW(1, CIDSysInfo);
755
cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0));
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);
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.");
768
if (csi->supplement < cmap_csi->supplement) {
769
WARN("CMap have higher supplmement number.");
770
WARN("Some characters may not be displayed or printed.");
777
shortname = cff_get_name(cffont);
779
ERROR("No valid FontName found.");
781
* Mangled name requires more 7 bytes.
782
* Style requires more 11 bytes.
784
fontname = NEW(strlen(shortname)+19, char);
785
memset(fontname, 0, strlen(shortname)+19);
786
strcpy(fontname, shortname);
791
if (opt->embed && opt->style != FONT_STYLE_NONE) {
792
WARN("Embedding disabled due to style option for %s.", name);
795
switch (opt->style) {
796
case FONT_STYLE_BOLD:
797
strcat(fontname, ",Bold");
799
case FONT_STYLE_ITALIC:
800
strcat(fontname, ",Italic");
802
case FONT_STYLE_BOLDITALIC:
803
strcat(fontname, ",BoldItalic");
807
font->fontname = fontname;
808
font->subtype = CIDFONT_TYPE0;
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"));
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.");
825
memmove(fontname + 7, fontname, strlen(fontname) + 1);
826
pdf_font_make_uniqueTag(fontname);
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));
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);
849
pdf_add_dict(font->fontdict,
851
pdf_new_number(1000)); /* not sure */
860
CIDFont_type0_t1cdofont (CIDFont *font)
864
cff_index *charstrings, *idx;
865
long charstring_len, max_len;
867
long size, offset = 0;
869
card16 num_glyphs, gid, last_cid;
873
double default_width, nominal_width;
881
pdf_add_dict(font->fontdict,
882
pdf_new_name("FontDescriptor"),
883
pdf_ref_obj (font->descriptor));
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 !");
889
used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
891
ERROR("Unexpected error: Font not actually used???");
893
fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
895
ERROR("Could not open OpenType font file: %s", font->ident);
897
sfont = sfnt_open(fp);
899
ERROR("Could not open OpenType font file: %s", font->ident);
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 ");
906
ERROR("Not a CFF/OpenType font ?");
908
cffont = cff_open(fp, offset, font->options->index);
910
ERROR("Could not open CFF font.");
911
if (cffont->flag & FONTTYPE_CIDFONT)
912
ERROR("This is CIDFont...");
914
cff_read_private(cffont);
915
cff_read_subrs (cffont);
917
if (cffont->private[0] && cff_dict_known(cffont->private[0], "StdVW")) {
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));
923
if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) {
924
default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
926
default_width = CFF_DEFAULTWIDTHX_DEFAULT;
928
if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) {
929
nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
931
nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
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++) {
940
for (j = 7; j >= 0; j--) {
943
last_cid = (i + 1) * 8 - j - 1;
949
cff_fdselect *fdselect;
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;
961
cff_charsets *charset;
963
charset = NEW(1, cff_charsets);
965
charset->num_entries = num_glyphs-1;
966
charset->data.glyphs = NEW(num_glyphs-1, s_SID);
968
for (gid = 0, cid = 0; cid <= last_cid; cid++) {
969
if (is_used_char2(used_chars, cid)) {
971
charset->data.glyphs[gid-1] = cid;
975
/* cff_release_charsets(cffont->charsets); */
976
cffont->charsets = charset;
979
cff_dict_add(cffont->topdict, "CIDCount", 1);
980
cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
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);
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");
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);
1011
ERROR("No valid charstring data found.");
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);
1020
data = NEW(CS_STR_LEN_MAX, card8);
1021
for (cid = 0; cid <= last_cid; cid++) {
1022
if (!is_used_char2(used_chars, cid))
1025
if ((size = (idx->offset)[cid+1] - (idx->offset)[cid])
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);
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,
1038
cffont->gsubr, (cffont->subrs)[0],
1039
default_width, nominal_width, NULL);
1042
if (gid != num_glyphs)
1043
ERROR("Unexpeced error: ?????");
1045
cff_release_index(idx);
1047
(charstrings->offset)[num_glyphs] = charstring_len + 1;
1048
charstrings->count = num_glyphs;
1049
cffont->num_glyphs = num_glyphs;
1050
cffont->cstrings = charstrings;
1052
/* no Global subr */
1054
cff_release_index(cffont->gsubr);
1055
cffont->gsubr = cff_new_index(0);
1057
if (cffont->subrs && cffont->subrs[0]) {
1058
cff_release_index(cffont->subrs[0]);
1059
cffont->subrs[0] = NULL;
1061
if (cffont->private && (cffont->private)[0]) {
1062
cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */
1065
cff_add_string(cffont, "Adobe", 1);
1066
cff_add_string(cffont, "Identity", 1);
1068
cff_dict_update(cffont->topdict, cffont);
1069
cff_dict_update(cffont->private[0], cffont);
1070
cff_update_string(cffont);
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);
1080
destlen = write_fontfile(font, cffont);
1085
* DW, W, DW2 and W2:
1086
* Those values are obtained from OpenType table (not TFM).
1089
unsigned char *CIDToGIDMap;
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;
1099
add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
1100
((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
1101
RELEASE(CIDToGIDMap);
1108
MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen);
1112
* Length of CIDSet stream is not clear. Must be 8192 bytes long?
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);
1128
CIDFont_type0_t1copen (CIDFont *font, const char *name,
1129
CIDSysInfo *cmap_csi, cid_opt *opt)
1135
unsigned long offset = 0;
1140
fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
1144
sfont = sfnt_open(fp);
1146
ERROR("Not a CFF/OpenType font?");
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?");
1154
cffont = cff_open(fp, offset, opt->index);
1156
ERROR("Cannot read CFF font data");
1159
if (cffont->flag & FONTTYPE_CIDFONT) {
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;
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.");
1182
if (csi->supplement < cmap_csi->supplement) {
1183
WARN("CMap have higher supplmement number.");
1184
WARN("Some characters may not be displayed or printed.");
1191
shortname = cff_get_name(cffont);
1193
ERROR("No valid FontName found.");
1194
/* Mangled name requires more 7 bytes. */
1196
fontname = NEW(strlen(shortname) + 8, char);
1197
memset(fontname, 0, strlen(shortname) + 8);
1198
strcpy(fontname, shortname);
1205
font->fontname = fontname;
1206
font->subtype = CIDFONT_TYPE0;
1208
font->flags |= CIDFONT_FLAG_TYPE1C;
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"));
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.");
1224
memmove(fontname + 7, fontname, strlen(fontname) + 1);
1225
pdf_font_make_uniqueTag(fontname);
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));
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);
1255
/* Type1 --> CFF CIDFont */
1256
#include "unicode.h"
1257
#include "t1_load.h"
1258
#include "t1_char.h"
1263
#include "cmap_write.h"
1264
#include "fontmap.h"
1267
load_base_CMap (const char *font_name, int wmode, cff_font *cffont)
1273
unsigned char range_min[4] = {0x00, 0x00, 0x00, 0x00};
1274
unsigned char range_max[4] = {0x7f, 0xff, 0xff, 0xff};
1276
cmap_name = NEW(strlen(font_name)+strlen("-UCS4-H")+1, char);
1278
sprintf(cmap_name, "%s-UCS4-V", font_name);
1280
sprintf(cmap_name, "%s-UCS4-H", font_name);
1283
cmap_id = CMap_cache_find(cmap_name);
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);
1297
for (gid = 1; gid < cffont->num_glyphs; gid++) {
1300
char *glyph, *name, *suffix;
1301
unsigned char srcCode[4];
1303
sid = cff_charsets_lookup_inverse(cffont, gid);
1304
glyph = cff_get_string (cffont, sid);
1306
name = agl_chop_suffix(glyph, &suffix);
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);
1331
agln = agl_lookup_list(name);
1333
WARN("Glyph \"%s\" inaccessible (no Unicode mapping)", glyph);
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);
1345
agln = agln->alternate;
1353
cmap_id = CMap_cache_add(cmap);
1359
t1_load_UnicodeCMap (const char *font_name,
1360
const char *otl_tags, /* not supported yet */
1370
fp = DPXFOPEN(font_name, DPX_RES_TYPE_T1FONT);
1374
cffont = t1_load_font(NULL, 1, fp);
1381
cmap_id = load_base_CMap(font_name, wmode, cffont);
1386
ERROR("Failed to create Unicode charmap for font \"%s\".", font_name);
1391
WARN("Glyph substitution not supported for Type1 font yet...");
1403
create_ToUnicode_stream (cff_font *cffont,
1404
const char *font_name, const char *used_glyphs)
1406
pdf_obj *stream = NULL;
1410
long glyph_count, total_fail_count;
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};
1418
if (!font_name || !used_glyphs)
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);
1429
CMap_set_wmode(cmap, 0);
1430
CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE);
1431
CMap_set_CIDSysInfo(cmap, &CSI_UNICODE);
1433
CMap_add_codespacerange(cmap, range_min, range_max, 2);
1435
glyph_count = total_fail_count = 0;
1437
endptr = wbuf + WBUF_SIZE;
1438
for (cid = 1; cid < cffont->num_glyphs; cid++) { /* Skip .notdef */
1439
if (is_used_char2(used_glyphs, cid)) {
1444
wbuf[0] = (cid >> 8) & 0xff;
1445
wbuf[1] = (cid & 0xff);
1448
gid = cff_charsets_lookup_inverse(cffont, cid);
1451
glyph = cff_get_string(cffont, gid);
1453
len = agl_sput_UTF16BE(glyph, &p, endptr, &fail_count);
1454
if (len < 1 || fail_count) {
1455
total_fail_count += fail_count;
1457
CMap_add_bfchar(cmap, wbuf, 2, wbuf+2, len);
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);
1471
stream = CMap_create_stream(cmap, 0);
1480
CIDFont_type0_t1open (CIDFont *font, const char *name,
1481
CIDSysInfo *cmap_csi, cid_opt *opt)
1484
char *fontname, *shortname;
1490
(strcmp(cmap_csi->registry, "Adobe") != 0 ||
1491
strcmp(cmap_csi->ordering, "Identity") != 0)) {
1494
fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT);
1498
cffont = t1_load_font(NULL, 1, fp);
1505
shortname = cff_get_name(cffont);
1507
ERROR("No valid FontName found.");
1508
fontname = NEW(strlen(shortname) + 8, char);
1509
memset(fontname, 0, strlen(shortname) + 8);
1510
strcpy(fontname, shortname);
1515
if (opt->style != FONT_STYLE_NONE) {
1516
WARN(",Bold, ,Italic, ... not supported for this type of font...");
1517
opt->style = FONT_STYLE_NONE;
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;
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"));
1538
memmove(fontname + 7, fontname, strlen(fontname) + 1);
1539
pdf_font_make_uniqueTag(fontname);
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));
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);
1569
/* Duplicate from type1.c */
1570
#define TYPE1_NAME_LEN_MAX 127
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 */
1582
/* pdf_font --> CIDFont */
1584
get_font_attr (CIDFont *font, cff_font *cffont)
1586
double capheight, ascent, descent;
1587
double italicangle, stemv;
1588
double defaultwidth, nominalwidth;
1592
static const char *L_c[] = {
1593
"H", "P", "Pi", "Rho", NULL
1595
static const char *L_d[] = {
1596
"p", "q", "mu", "eta", NULL
1598
static const char *L_a[] = {
1599
"b", "h", "lambda", NULL
1603
defaultwidth = 500.0;
1607
* CapHeight, Ascent, and Descent is meaningfull only for Latin/Greek/Cyrillic.
1608
* The BlueValues and OtherBlues also have those information.
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);
1619
if (cff_dict_known(cffont->private[0], "StdVW")) {
1620
stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
1623
* We may use the following values for StemV:
1624
* Thin - ExtraLight: <= 50
1626
* Regular(Normal): 88
1628
* SemiBold(DemiBold): 135
1629
* Bold - Heavy: >= 166
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;
1642
* Use "space", "H", "p", and "b" for various values.
1643
* Those characters should not "seac". (no accent)
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;
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;
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;
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;
1686
if (defaultwidth != 0.0) {
1687
cff_dict_add(cffont->private[0], "defaultWidthX", 1);
1688
cff_dict_set(cffont->private[0], "defaultWidthX", 0, defaultwidth);
1690
if (nominalwidth != 0.0) {
1691
cff_dict_add(cffont->private[0], "nominalWidthX", 1);
1692
cff_dict_set(cffont->private[0], "nominalWidthX", 0, nominalwidth);
1694
if (cff_dict_known(cffont->private[0], "ForceBold") &&
1695
cff_dict_get(cffont->private[0], "ForceBold", 0)) {
1696
flags |= FONT_FLAG_FORCEBOLD;
1698
if (cff_dict_known(cffont->private[0], "IsFixedPitch") &&
1699
cff_dict_get(cffont->private[0], "IsFixedPitch", 0)) {
1700
flags |= FONT_FLAG_FIXEDPITCH;
1702
if (font->fontname &&
1703
!strstr(font->fontname, "Sans")) {
1704
flags |= FONT_FLAG_SERIF;
1706
flags |= FONT_FLAG_SYMBOLIC;
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));
1723
add_metrics (CIDFont *font, cff_font *cffont,
1724
unsigned char *CIDToGIDMap,
1725
double *widths, double default_width, CID last_cid)
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
1739
if (!cff_dict_known(cffont->topdict, "FontBBox")) {
1740
ERROR("No FontBBox?");
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)));
1747
pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp);
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 !");
1753
used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
1755
ERROR("Unexpected error: Font not actually used???");
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 ...]".
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)));
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));
1779
pdf_release_obj(tmp);
1783
CIDFont_type0_t1dofont (CIDFont *font)
1786
double defaultwidth, nominalwidth;
1787
long num_glyphs = 0;
1790
char *used_chars = NULL;
1791
card16 last_cid, gid, cid;
1792
unsigned char *CIDToGIDMap;
1796
if (!font->indirect) {
1800
pdf_add_dict(font->fontdict,
1801
pdf_new_name("FontDescriptor"),
1802
pdf_ref_obj (font->descriptor));
1804
fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT);
1806
ERROR("Type1: Could not open Type1 font.");
1809
cffont = t1_load_font(NULL, 0, fp);
1811
ERROR("Could not read Type 1 font...");
1814
if (!font->fontname)
1815
ERROR("Fontname undefined...");
1818
Type0Font *hparent, *vparent;
1820
int vparent_id, hparent_id;
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 !");
1827
/* usedchars is same for h and v */
1831
hparent = Type0Font_cache_get(hparent_id);
1832
used_chars = Type0Font_get_usedchars(hparent);
1837
vparent = Type0Font_cache_get(vparent_id);
1838
used_chars = Type0Font_get_usedchars(vparent);
1841
ERROR("Unexpected error: Font not actually used???");
1843
tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars);
1846
Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode));
1848
Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode));
1849
pdf_release_obj(tounicode);
1852
cff_set_name(cffont, font->fontname);
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);
1861
if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
1862
nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
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++) {
1873
for (j = 7; j >= 0; j--) {
1876
last_cid = (i + 1) * 8 - j - 1;
1882
cff_fdselect *fdselect;
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;
1893
CIDToGIDMap = NEW(2*(last_cid+1), unsigned char);
1894
memset(CIDToGIDMap, 0, 2*(last_cid+1));
1896
cff_charsets *charset;
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);
1903
for (gid = 0, cid = 0; cid <= last_cid; cid++) {
1904
if (is_used_char2(used_chars, cid)) {
1906
charset->data.glyphs[gid-1] = cid;
1907
CIDToGIDMap[2*cid ] = (gid >> 8) & 0xff;
1908
CIDToGIDMap[2*cid+1] = gid & 0xff;
1913
cff_release_charsets(cffont->charsets);
1914
cffont->charsets = charset;
1917
cff_dict_add(cffont->topdict, "CIDCount", 1);
1918
cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);
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);
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);
1936
cff_dict_add(cffont->topdict, "charset", 1);
1937
cff_dict_set(cffont->topdict, "charset", 0, 0.0);
1939
cff_dict_add(cffont->topdict, "CharStrings", 1);
1940
cff_dict_set(cffont->topdict, "CharStrings", 0, 0.0);
1947
int w_stat[1001], max_count, dw;
1949
widths = NEW(num_glyphs, double);
1950
memset(w_stat, 0, sizeof(int)*1001);
1952
cstring = cff_new_index(num_glyphs);
1953
cstring->data = NULL;
1954
cstring->offset[0] = 1;
1956
for (cid = 0; cid <= last_cid; cid++) {
1957
if (!is_used_char2(used_chars, cid))
1960
if (offset + CS_STR_LEN_MAX >= max) {
1961
max += CS_STR_LEN_MAX*2;
1962
cstring->data = RENEW(cstring->data, max, card8);
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;
1970
ERROR("This font using the \"seac\" command for accented characters...");
1972
widths[gid] = gm.wx;
1973
if (gm.wx >= 0.0 && gm.wx <= 1000.0) {
1974
w_stat[((int) gm.wx)] += 1;
1979
cff_release_index(cffont->cstrings);
1980
cffont->cstrings = cstring;
1982
max_count = 0; dw = -1;
1983
for (i = 0; i <= 1000; i++) {
1984
if (w_stat[i] > max_count) {
1986
max_count = w_stat[i];
1990
add_metrics(font, cffont, CIDToGIDMap, widths, dw, last_cid);
1992
add_metrics(font, cffont, CIDToGIDMap, widths, defaultwidth, last_cid);
1996
cff_release_index(cffont->subrs[0]);
1997
cffont->subrs[0] = NULL;
1999
RELEASE(CIDToGIDMap);
2001
cff_add_string(cffont, "Adobe", 1);
2002
cff_add_string(cffont, "Identity", 1);
2004
cff_dict_update(cffont->topdict, cffont);
2005
cff_dict_update(cffont->private[0], cffont);
2007
cff_update_string(cffont);
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);
2017
cffont->num_glyphs = num_glyphs;
2018
offset = write_fontfile(font, cffont);
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);
2037
CIDFont_type0_release(CIDFont *font)