3 % Copyright
2006-2010 Taco Hoekwater
<taco@@luatex.org
>
5 % This file is part of LuaTeX.
7 % LuaTeX is free software
; you can redistribute it and
/or modify it under
8 % the terms of the GNU General Public License as published by the Free
9 % Software Foundation
; either version
2 of the License
, or
(at your
10 % option
) any later version.
12 % LuaTeX is distributed in the hope that it will be useful
, but WITHOUT
13 % ANY WARRANTY
; without even the implied warranty of MERCHANTABILITY or
14 % FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 % License for more details.
17 % You should have received a copy of the GNU General Public License along
18 % with LuaTeX
; if not
, see
<http
://www.gnu.org
/licenses
/>.
24 #include
"lua/luatex-api.h"
25 #include
"font/writecff.h"
30 #define get_offset
(s
,n
) get_unsigned
(s
, (n
))
31 #define get_card8
(a
) (card8
)(a-
>stream
[a-
>offset
++])
32 #define get_card16
(a
) (card16
)(get_unsigned
(a
,2))
39 #define WORK_BUFFER_SIZE
1024
41 static char work_buffer
[WORK_BUFFER_SIZE
];
43 static unsigned long get_unsigned
(cff_font
* cff
, int n
)
47 v
= v
* 256 + get_card8
(cff
);
53 const char
*const cff_stdstr
[CFF_STDSTR_MAX
] = {
54 ".notdef", "space", "exclam", "quotedbl", "numbersign",
55 "dollar", "percent", "ampersand", "quoteright", "parenleft",
56 "parenright", "asterisk", "plus", "comma", "hyphen",
57 "period", "slash", "zero", "one", "two",
58 "three", "four", "five", "six", "seven",
59 "eight", "nine", "colon", "semicolon", "less",
60 "equal", "greater", "question", "at", "A",
61 "B", "C", "D", "E", "F",
62 "G", "H", "I", "J", "K",
63 "L", "M", "N", "O", "P",
64 "Q", "R", "S", "T", "U",
65 "V", "W", "X", "Y", "Z",
66 "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
67 "quoteleft", "a", "b", "c", "d",
68 "e", "f", "g", "h", "i",
69 "j", "k", "l", "m", "n",
70 "o", "p", "q", "r", "s",
71 "t", "u", "v", "w", "x",
72 "y", "z", "braceleft", "bar", "braceright",
73 "asciitilde", "exclamdown", "cent", "sterling", "fraction",
74 "yen", "florin", "section", "currency", "quotesingle",
75 "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi",
76 "fl", "endash", "dagger", "daggerdbl", "periodcentered",
77 "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
78 "guillemotright", "ellipsis", "perthousand", "questiondown", "grave",
79 "acute", "circumflex", "tilde", "macron", "breve",
80 "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
81 "ogonek", "caron", "emdash", "AE", "ordfeminine",
82 "Lslash", "Oslash", "OE", "ordmasculine", "ae",
83 "dotlessi", "lslash", "oslash", "oe", "germandbls",
84 "onesuperior", "logicalnot", "mu", "trademark", "Eth",
85 "onehalf", "plusminus", "Thorn", "onequarter", "divide",
86 "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
87 "registered", "minus", "eth", "multiply", "threesuperior",
88 "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
89 "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
90 "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
91 "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
92 "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
93 "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
94 "aacute", "acircumflex", "adieresis", "agrave", "aring",
95 "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
96 "egrave", "iacute", "icircumflex", "idieresis", "igrave",
97 "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
98 "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
99 "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
100 "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
102 "parenleftsuperior", "parenrightsuperior", "twodotenleader",
103 "onedotenleader", "zerooldstyle",
104 "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
106 "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
108 "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
110 "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
111 "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
112 "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
113 "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
115 "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
116 "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
117 "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
118 "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
119 "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
120 "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
121 "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
123 "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
124 "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
126 "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
127 "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior",
128 "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
130 "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
132 "seveninferior", "eightinferior", "nineinferior", "centinferior",
134 "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
136 "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
137 "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
139 "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
141 "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
143 "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall",
144 "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
145 "001.000", "001.001", "001.002", "001.003",
146 "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"
150 @ Only read header part but not body
152 cff_index
*cff_get_index_header
(cff_font
* cff
)
157 idx
= xcalloc
(1, sizeof
(cff_index
));
159 idx-
>count
= count
= get_card16
(cff
);
161 idx-
>offsize
= get_card8
(cff
);
162 if
(idx-
>offsize
< 1 || idx-
>offsize
> 4)
163 normal_error
("cff","invalid offsize data");
166 xmalloc
((unsigned
) (((unsigned
) count
+ 1) * sizeof
(l_offset
)));
167 for
(i
= 0; i
<count
+ 1 ; i
++) {
168 (idx-
>offset
)[i
] = get_offset
(cff
, idx-
>offsize
);
173 if
(idx-
>offset
[0] != 1)
174 normal_error
("cff","invalid index data");
189 cff_index
*cff_get_index
(cff_font
* cff
)
195 idx
= xcalloc
(1, sizeof
(cff_index
));
197 idx-
>count
= count
= get_card16
(cff
);
199 idx-
>offsize
= get_card8
(cff
);
200 if
(idx-
>offsize
< 1 || idx-
>offsize
> 4)
201 normal_error
("cff","invalid offsize data");
204 xmalloc
((unsigned
) (((unsigned
) count
+ 1) * sizeof
(l_offset
)));
205 for
(i
= 0; i
< count
+ 1; i
++) {
206 idx-
>offset
[i
] = get_offset
(cff
, idx-
>offsize
);
209 if
(idx-
>offset
[0] != 1)
210 normal_error
("cff","invalid index offset data");
212 length
= (size_t
) (idx-
>offset
[count
] - idx-
>offset
[0]);
214 idx-
>data
= xmalloc
((unsigned
) length
* sizeof
(card8
));
215 memcpy
(idx-
>data
, &cff->stream[cff->offset], length);
216 cff-
>offset
+= length
;
228 long cff_pack_index
(cff_index
* idx
, card8
* dest
, long destlen
)
231 unsigned long datalen
;
234 if
(idx-
>count
< 1) {
236 normal_error
("cff","not enough space available");
241 len
= cff_index_size
(idx
);
242 datalen
= idx-
>offset
[idx-
>count
] - 1;
245 normal_error
("cff","not enough space available");
247 *(dest
++) = (card8
) ((idx-
>count
>> 8) & 0xff);
248 *(dest
++) = (card8
) (idx-
>count
& 0xff);
250 if
(datalen
< 0xffUL
) {
253 for
(i
= 0; i
<= idx-
>count
; i
++) {
254 *(dest
++) = (card8
) (idx-
>offset
[i
] & 0xff);
256 } else if
(datalen
< 0xffffUL
) {
259 for
(i
= 0; i
<= idx-
>count
; i
++) {
260 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 8) & 0xff);
261 *(dest
++) = (card8
) (idx-
>offset
[i
] & 0xff);
263 } else if
(datalen
< 0xffffffUL
) {
266 for
(i
= 0; i
<= idx-
>count
; i
++) {
267 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 16) & 0xff);
268 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 8) & 0xff);
269 *(dest
++) = (card8
) (idx-
>offset
[i
] & 0xff);
274 for
(i
= 0; i
<= idx-
>count
; i
++) {
275 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 24) & 0xff);
276 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 16) & 0xff);
277 *(dest
++) = (card8
) ((idx-
>offset
[i
] >> 8) & 0xff);
278 *(dest
++) = (card8
) (idx-
>offset
[i
] & 0xff);
282 memmove
(dest
, idx-
>data
, idx-
>offset
[idx-
>count
] - 1);
288 long cff_index_size
(cff_index
* idx
)
290 if
(idx-
>count
> 0) {
293 datalen
= idx-
>offset
[idx-
>count
] - 1;
294 if
(datalen
< 0xffUL
) {
296 } else if
(datalen
< 0xffffUL
) {
298 } else if
(datalen
< 0xffffffUL
) {
303 return
(3 + (idx-
>offsize
) * (idx-
>count
+ 1) + (long
) datalen
);
310 cff_index
*cff_new_index
(card16 count
)
314 idx
= xcalloc
(1, sizeof
(cff_index
));
319 idx-
>offset
= xcalloc
((unsigned
) (count
+ 1), sizeof
(l_offset
));
320 (idx-
>offset
)[0] = 1;
331 void cff_release_index
(cff_index
* idx
)
341 void cff_release_dict
(cff_dict
* dict
)
346 for
(i
= 0; i
< dict-
>count
; i
++) {
347 xfree
((dict-
>entries
)[i
].values
);
349 xfree
(dict-
>entries
);
357 void cff_release_encoding
(cff_encoding
* encoding
)
360 switch
(encoding-
>format
& (~0x80)) {
362 xfree
(encoding-
>data.codes
);
365 xfree
(encoding-
>data.range1
);
368 normal_error
("cff","unknown encoding format");
370 if
(encoding-
>format
& 0x80)
371 xfree
(encoding-
>supp
);
377 void cff_release_charsets
(cff_charsets
* charset
)
380 switch
(charset-
>format
) {
382 xfree
(charset-
>data.glyphs
);
385 xfree
(charset-
>data.range1
);
388 xfree
(charset-
>data.range2
);
398 void cff_release_fdselect
(cff_fdselect
* fdselect
)
401 if
(fdselect-
>format
== 0) {
402 xfree
(fdselect-
>data.fds
);
403 } else if
(fdselect-
>format
== 3) {
404 xfree
(fdselect-
>data.ranges
);
412 void cff_close
(cff_font
* cff
)
417 xfree
(cff-
>fontname
);
419 cff_release_index
(cff-
>name
);
421 cff_release_dict
(cff-
>topdict
);
423 cff_release_index
(cff-
>string
);
425 cff_release_index
(cff-
>gsubr
);
427 cff_release_encoding
(cff-
>encoding
);
429 cff_release_charsets
(cff-
>charsets
);
431 cff_release_fdselect
(cff-
>fdselect
);
433 cff_release_index
(cff-
>cstrings
);
435 for
(i
= 0; i
< cff-
>num_fds
; i
++) {
437 cff_release_dict
(cff-
>fdarray
[i
]);
442 for
(i
= 0; i
< cff-
>num_fds
; i
++) {
444 cff_release_dict
(cff-
>private
[i
]);
449 for
(i
= 0; i
< cff-
>num_fds
; i
++) {
451 cff_release_index
(cff-
>subrs
[i
]);
456 cff_release_index
(cff-
>_string
);
464 char
*cff_get_name
(cff_font
* cff
)
471 len
= idx-
>offset
[cff-
>index
+ 1] - idx-
>offset
[cff-
>index
];
472 fontname
= xmalloc
((unsigned
) (len
+ 1) * sizeof
(char
));
473 memcpy
(fontname
, idx-
>data
+ idx-
>offset
[cff-
>index
] - 1, len
);
474 fontname
[len
] = '\
0'
;
481 long cff_set_name
(cff_font
* cff
, char
*name
)
485 if
(strlen
(name
) > 127)
486 normal_error
("cff","FontName string length too large");
489 cff_release_index
(cff-
>name
);
491 cff-
>name
= idx
= xcalloc
(1, sizeof
(cff_index
));
494 idx-
>offset
= xmalloc
(2 * sizeof
(l_offset
));
495 (idx-
>offset
)[0] = 1;
496 (idx-
>offset
)[1] = strlen
(name
) + 1;
497 idx-
>data
= xmalloc
((unsigned
) strlen
(name
) * sizeof
(card8
));
498 memmove
(idx-
>data
, name
, strlen
(name
)); /* no trailing |'\
0'|
*/
500 return
(long
) (5 + strlen
(name
));
503 long cff_put_header
(cff_font
* cff
, card8
* dest
, long destlen
)
506 normal_error
("cff","not enough space available");
508 *(dest
++) = cff-
>header_major
;
509 *(dest
++) = cff-
>header_minor
;
510 *(dest
++) = 4; /* Additional data in between header and
511 * Name
INDEX ignored.
513 /* We will set all offset
(0) to four-byte integer.
*/
515 cff-
>header_offsize
= 4;
521 #define CFF_PARSE_OK
0
522 #define CFF_CFF_ERROR_PARSE_CFF_ERROR
-1
523 #define CFF_CFF_ERROR_STACK_OVERFLOW
-2
524 #define CFF_CFF_ERROR_STACK_UNDERFLOW
-3
525 #define CFF_CFF_ERROR_STACK_RANGECHECK
-4
527 #define DICT_ENTRY_MAX
16
529 cff_dict
*cff_new_dict
(void
)
533 dict
= xcalloc
(1, sizeof
(cff_dict
));
534 dict-
>max
= DICT_ENTRY_MAX
;
536 dict-
>entries
= xcalloc
((unsigned
) dict-
>max
, sizeof
(cff_dict_entry
));
543 only numbers are stored
(as double
)
547 number
: double
(integer or real
)
548 boolean
: stored as a number
549 SID
: stored as a number
550 array
: array of numbers
551 delta
: array of numbers
554 #define CFF_DICT_STACK_LIMIT
64
555 static int stack_top
= 0;
556 static double arg_stack
[CFF_DICT_STACK_LIMIT
];
563 #define CFF_LAST_DICT_OP1
22
564 #define CFF_LAST_DICT_OP2
39
565 #define CFF_LAST_DICT_OP
(CFF_LAST_DICT_OP1
+ CFF_LAST_DICT_OP2
)
570 } dict_operator
[CFF_LAST_DICT_OP
] = {
572 "version", CFF_TYPE_SID
}, {
573 "Notice", CFF_TYPE_SID
}, {
574 "FullName", CFF_TYPE_SID
}, {
575 "FamilyName", CFF_TYPE_SID
}, {
576 "Weight", CFF_TYPE_SID
}, {
577 "FontBBox", CFF_TYPE_ARRAY
}, {
578 "BlueValues", CFF_TYPE_DELTA
}, {
579 "OtherBlues", CFF_TYPE_DELTA
}, {
580 "FamilyBlues", CFF_TYPE_DELTA
}, {
581 "FamilyOtherBlues", CFF_TYPE_DELTA
}, {
582 "StdHW", CFF_TYPE_NUMBER
}, {
583 "StdVW", CFF_TYPE_NUMBER
}, {
584 NULL, -1}, /* first byte of two-byte operator
*/
587 "UniqueID", CFF_TYPE_NUMBER
}, {
588 "XUID", CFF_TYPE_ARRAY
}, {
589 "charset", CFF_TYPE_OFFSET
}, {
590 "Encoding", CFF_TYPE_OFFSET
}, {
591 "CharStrings", CFF_TYPE_OFFSET
}, {
592 "Private", CFF_TYPE_SZOFF
}, /* two numbers
(size and offset
) */
595 "Subrs", CFF_TYPE_OFFSET
}, {
596 "defaultWidthX", CFF_TYPE_NUMBER
}, {
597 "nominalWidthX", CFF_TYPE_NUMBER
},
600 "Copyright", CFF_TYPE_SID
}, {
601 "IsFixedPitch", CFF_TYPE_BOOLEAN
}, {
602 "ItalicAngle", CFF_TYPE_NUMBER
}, {
603 "UnderlinePosition", CFF_TYPE_NUMBER
}, {
604 "UnderlineThickness", CFF_TYPE_NUMBER
}, {
605 "PaintType", CFF_TYPE_NUMBER
}, {
606 "CharstringType", CFF_TYPE_NUMBER
}, {
607 "FontMatrix", CFF_TYPE_ARRAY
}, {
608 "StrokeWidth", CFF_TYPE_NUMBER
}, {
609 "BlueScale", CFF_TYPE_NUMBER
}, {
610 "BlueShift", CFF_TYPE_NUMBER
}, {
611 "BlueFuzz", CFF_TYPE_NUMBER
}, {
612 "StemSnapH", CFF_TYPE_DELTA
}, {
613 "StemSnapV", CFF_TYPE_DELTA
}, {
614 "ForceBold", CFF_TYPE_BOOLEAN
}, {
617 "LanguageGroup", CFF_TYPE_NUMBER
}, {
618 "ExpansionFactor", CFF_TYPE_NUMBER
}, {
619 "InitialRandomSeed", CFF_TYPE_NUMBER
}, {
620 "SyntheticBase", CFF_TYPE_NUMBER
}, {
621 "PostScript", CFF_TYPE_SID
}, {
622 "BaseFontName", CFF_TYPE_SID
}, {
623 "BaseFontBlend", CFF_TYPE_DELTA
}, /* MMaster ?
*/
633 "ROS", CFF_TYPE_ROS
}, /* SID SID number
*/
635 "CIDFontVersion", CFF_TYPE_NUMBER
}, {
636 "CIDFontRevision", CFF_TYPE_NUMBER
}, {
637 "CIDFontType", CFF_TYPE_NUMBER
}, {
638 "CIDCount", CFF_TYPE_NUMBER
}, {
639 "UIDBase", CFF_TYPE_NUMBER
}, {
640 "FDArray", CFF_TYPE_OFFSET
}, {
641 "FDSelect", CFF_TYPE_OFFSET
}, {
642 "FontName", CFF_TYPE_SID
},};
646 static double get_integer
(card8
** data
, card8
* endptr
, int
*status
)
652 if
(b0
== 28 && *data < endptr - 2) { /* shortint */
655 result
= b1
* 256 + b2
;
656 if
(result
> 0x7fffL
)
658 } else if
(b0
== 29 && *data < endptr - 4) { /* longint */
663 for
(i
= 0; i
< 3; i
++) {
664 result
= result
* 256 + (**data
);
667 } else if
(b0
>= 32 && b0 <= 246) { /* int (1) */
669 } else if
(b0
>= 247 && b0 <= 250) { /* int (2) */
671 result
= (b0
- 247) * 256 + b1
+ 108;
672 } else if
(b0
>= 251 && b0 <= 254) {
674 result
= -(b0
- 251) * 256 - b1
- 108;
676 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
679 return
(double
) result
;
684 static double get_real
(card8
** data
, card8
* endptr
, int
*status
)
687 int nibble
= 0, pos
= 0;
688 int len
= 0, fail
= 0;
690 if
(**data
!= 30 ||
*data
>= endptr
- 1) {
691 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
695 *data
+= 1; /* skip first byte
(30) */
698 while
((!fail
) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) {
701 nibble
= **data
& 0x0f;
704 nibble
= (**data
>> 4) & 0x0f;
706 if
(nibble
>= 0x00 && nibble <= 0x09) {
707 work_buffer
[len
++] = (char
) (nibble
+ '
0'
);
708 } else if
(nibble
== 0x0a) { /* .
*/
709 work_buffer
[len
++] = '.'
;
710 } else if
(nibble
== 0x0b || nibble
== 0x0c) { /* E
, E-
*/
711 work_buffer
[len
++] = 'e'
;
713 work_buffer
[len
++] = '
-'
;
714 } else if
(nibble
== 0x0e) { /* `
-'
*/
715 work_buffer
[len
++] = '
-'
;
716 } else if
(nibble
== 0x0d) { /* skip
*/
718 } else if
(nibble
== 0x0f) { /* end
*/
719 work_buffer
[len
++] = '\
0'
;
720 if
(((pos
% 2) == 0) && (**data != 0xff)) {
724 } else
{ /* invalid
*/
730 /* returned values
*/
731 if
(fail || nibble
!= 0x0f) {
732 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
735 /* strtod sets errno for OVERFLOW and _maybe_ UNDERFLOW
*/
736 /* but not for an invalid conversion
(as for example if we try to convert
"foo" in a double
)*/
737 /* At least in glib sets errno also for UNDERFLOW
*/
738 /* We don't save
/restore the prev. errno
*/
740 result
= strtod
(work_buffer
, &s);
741 if
( (result
==0.0 && work_buffer==s) || errno ) {
742 /* conversion is not possible
*/
743 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
751 static void add_dict
(cff_dict
* dict
,
752 card8
** data
, card8
* endptr
, int
*status
)
759 if
(*data
>= endptr ||
760 (id
= **data
+ CFF_LAST_DICT_OP1
) >= CFF_LAST_DICT_OP
) {
761 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
764 } else if
(id
>= CFF_LAST_DICT_OP1
) {
765 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
769 argtype
= dict_operator
[id
].argtype
;
770 if
(dict_operator
[id
].opname
== NULL || argtype
< 0) {
771 *status
= CFF_CFF_ERROR_PARSE_CFF_ERROR
;
775 if
(dict-
>count
>= dict-
>max
) {
776 dict-
>max
+= DICT_ENTRY_MAX
;
779 xrealloc
(dict-
>entries
,
780 (unsigned
) ((unsigned
) dict-
>max
*
781 sizeof
(cff_dict_entry
)));
784 (dict-
>entries
)[dict-
>count
].id
= id
;
785 (dict-
>entries
)[dict-
>count
].key
= dict_operator
[id
].opname
;
786 if
(argtype
== CFF_TYPE_NUMBER ||
787 argtype
== CFF_TYPE_BOOLEAN ||
788 argtype
== CFF_TYPE_SID || argtype
== CFF_TYPE_OFFSET
) {
789 /* check for underflow here
, as exactly one operand is expected
*/
791 *status
= CFF_CFF_ERROR_STACK_UNDERFLOW
;
795 (dict-
>entries
)[dict-
>count
].count
= 1;
796 (dict-
>entries
)[dict-
>count
].values
= xcalloc
(1, sizeof
(double
));
797 (dict-
>entries
)[dict-
>count
].values
[0] = arg_stack
[stack_top
];
800 /* just ignore operator if there were no operands provided
;
801 don't treat this as underflow
(e.g. StemSnapV in TemporaLGCUni-Italic.otf
) */
802 if
((t
= stack_top
) > 0) {
803 (dict-
>entries
)[dict-
>count
].count
= stack_top
;
804 (dict-
>entries
)[dict-
>count
].values
=
805 xmalloc
((unsigned
) ((unsigned
) stack_top
* sizeof
(double
)));
806 while
(stack_top
> 0) {
808 (dict-
>entries
)[dict-
>count
].values
[stack_top
] =
809 arg_stack
[stack_top
];
811 if
(t
> 3 && strcmp(dict_operator[id].opname, "FontMatrix") == 0) {
812 /* reset FontMatrix to
[0.001 * * 0.001 * *],
813 fix mantis bug \#
0000200 (acroread
"feature") */
814 (dict-
>entries
)[dict-
>count
].values
[0] = 0.001;
815 (dict-
>entries
)[dict-
>count
].values
[3] = 0.001;
827 @ All operands are treated as number or array of numbers.
828 Private
: two numbers
, size and offset
829 ROS
: three numbers
, SID
, SID
, and a number
832 cff_dict
*cff_dict_unpack
(card8
* data
, card8
* endptr
)
835 int status
= CFF_PARSE_OK
;
839 dict
= cff_new_dict
();
840 while
(data
< endptr
&& status == CFF_PARSE_OK) {
841 if
(*data
< 22) { /* operator
*/
842 add_dict
(dict
, &data, endptr, &status);
843 } else if
(*data
== 30) { /* real
- First byte of a sequence
(variable
) */
844 if
(stack_top
< CFF_DICT_STACK_LIMIT
) {
845 arg_stack
[stack_top
] = get_real
(&data, endptr, &status);
848 status
= CFF_CFF_ERROR_STACK_OVERFLOW
;
850 } else if
(*data
== 255 ||
(*data
>= 22 && *data <= 27)) { /* reserved */
852 } else
{ /* everything else are integer
*/
853 if
(stack_top
< CFF_DICT_STACK_LIMIT
) {
854 arg_stack
[stack_top
] = get_integer
(&data, endptr, &status);
857 status
= CFF_CFF_ERROR_STACK_OVERFLOW
;
862 if
(status
!= CFF_PARSE_OK
) {
863 formatted_error
("cff","parsing DICT failed (error=%d)", status
);
864 } else if
(stack_top
!= 0) {
865 normal_warning
("cff","garbage in DICT data");
873 int cff_dict_known
(cff_dict
* dict
, const char
*key
)
877 for
(i
= 0; i
< dict-
>count
; i
++) {
878 if
(key
&& strcmp(key, (dict->entries)[i].key) == 0
879 && (dict->entries)[i].count > 0)
887 double cff_dict_get
(cff_dict
* dict
, const char
*key
, int idx
)
894 for
(i
= 0; i
< dict-
>count
; i
++) {
895 if
(strcmp
(key
, (dict-
>entries
)[i
].key
) == 0) {
896 if
((dict-
>entries
)[i
].count
> idx
)
897 value
= (dict-
>entries
)[i
].values
[idx
];
899 normal_error
("cff","invalid index number");
904 if
(i
== dict-
>count
)
905 formatted_error
("cff","DICT entry '%s' not found", key
);
911 card8 cff_fdselect_lookup
(cff_font
* cff
, card16 gid
)
916 if
(cff-
>fdselect
== NULL)
917 normal_error
("cff","FDSelect not available");
919 fdsel
= cff-
>fdselect
;
921 if
(gid
>= cff-
>num_glyphs
)
922 normal_error
("cff","invalid glyph index");
924 switch
(fdsel-
>format
) {
926 fd
= fdsel-
>data.fds
[gid
];
931 fd
= (fdsel-
>data
).ranges
[0].fd
;
934 for
(i
= 1; i
< (fdsel-
>num_entries
); i
++) {
935 if
(gid
< (fdsel-
>data
).ranges
[i
].first
)
938 fd
= (fdsel-
>data
).ranges
[i
- 1].fd
;
943 normal_error
("cff","invalid FDSelect format");
947 if
(fd
>= cff-
>num_fds
)
948 normal_error
("cff","invalid Font DICT index");
954 long cff_read_subrs
(cff_font
* cff
)
961 if
((cff-
>flag
& FONTTYPE_CIDFONT) && cff->fdselect == NULL) {
962 cff_read_fdselect
(cff
);
965 if
((cff-
>flag
& FONTTYPE_CIDFONT) && cff->fdarray == NULL) {
966 cff_read_fdarray
(cff
);
969 if
(cff-
>private
== NULL)
970 cff_read_private
(cff
);
972 if
(cff-
>gsubr
== NULL) {
973 cff-
>offset
= cff-
>gsubr_offset
;
974 cff-
>gsubr
= cff_get_index
(cff
);
977 cff-
>subrs
= xcalloc
(cff-
>num_fds
, sizeof
(cff_index
*));
978 if
(cff-
>flag
& FONTTYPE_CIDFONT) {
979 for
(i
= 0; i
< cff-
>num_fds
; i
++) {
980 if
(cff-
>private
[i
] == NULL ||
981 !cff_dict_known
(cff-
>private
[i
], "Subrs")) {
982 (cff-
>subrs
)[i
] = NULL;
984 offset
= (long
) cff_dict_get
(cff-
>fdarray
[i
], "Private", 1);
985 offset
+= (long
) cff_dict_get
(cff-
>private
[i
], "Subrs", 0);
986 cff-
>offset
= (l_offset
) offset
;
987 (cff-
>subrs
)[i
] = cff_get_index
(cff
);
988 len
+= cff_index_size
((cff-
>subrs
)[i
]);
992 if
(cff-
>private
[0] == NULL ||
993 !cff_dict_known
(cff-
>private
[0], "Subrs")) {
994 (cff-
>subrs
)[0] = NULL;
996 offset
= (long
) cff_dict_get
(cff-
>topdict
, "Private", 1);
997 offset
+= (long
) cff_dict_get
(cff-
>private
[0], "Subrs", 0);
998 cff-
>offset
= (l_offset
) offset
;
999 (cff-
>subrs
)[0] = cff_get_index
(cff
);
1000 len
+= cff_index_size
((cff-
>subrs
)[0]);
1009 long cff_read_fdarray
(cff_font
* cff
)
1016 if
(cff-
>topdict
== NULL)
1017 normal_error
("cff","top DICT not found");
1019 if
(!(cff-
>flag
& FONTTYPE_CIDFONT))
1023 offset
= (long
) cff_dict_get
(cff-
>topdict
, "FDArray", 0);
1024 cff-
>offset
= (l_offset
) offset
;
1025 idx
= cff_get_index
(cff
);
1026 cff-
>num_fds
= (card8
) idx-
>count
;
1027 cff-
>fdarray
= xmalloc
((unsigned
) (idx-
>count
* sizeof
(cff_dict
*)));
1028 for
(i
= 0; i
< idx-
>count
; i
++) {
1029 card8
*data
= idx-
>data
+ (idx-
>offset
)[i
] - 1;
1030 size
= (long
) ((idx-
>offset
)[i
+ 1] - (idx-
>offset
)[i
]);
1032 (cff-
>fdarray
)[i
] = cff_dict_unpack
(data
, data
+ size
);
1034 (cff-
>fdarray
)[i
] = NULL;
1037 len
= cff_index_size
(idx
);
1038 cff_release_index
(idx
);
1045 long cff_read_private
(cff_font
* cff
)
1051 if
(cff-
>flag
& FONTTYPE_CIDFONT) {
1054 if
(cff-
>fdarray
== NULL)
1055 cff_read_fdarray
(cff
);
1057 cff-
>private
= xmalloc
((unsigned
) (cff-
>num_fds
* sizeof
(cff_dict
*)));
1058 for
(i
= 0; i
< cff-
>num_fds
; i
++) {
1059 if
(cff-
>fdarray
[i
] != NULL &&
1060 cff_dict_known
(cff-
>fdarray
[i
], "Private") &&
1061 (size
= (long
) cff_dict_get
(cff-
>fdarray
[i
], "Private", 0))
1063 offset
= (long
) cff_dict_get
(cff-
>fdarray
[i
], "Private", 1);
1064 cff-
>offset
= (l_offset
) offset
;
1065 data
= xmalloc
((unsigned
) size
* sizeof
(card8
));
1066 memcpy
(data
, &cff->stream[cff->offset], (size_t) size);
1067 cff-
>offset
= (l_offset
) size
;
1068 (cff-
>private
)[i
] = cff_dict_unpack
(data
, data
+ size
);
1072 (cff-
>private
)[i
] = NULL;
1077 cff-
>private
= xmalloc
(sizeof
(cff_dict
*));
1078 if
(cff_dict_known
(cff-
>topdict
, "Private") &&
1079 (size
= (long
) cff_dict_get
(cff-
>topdict
, "Private", 0)) > 0) {
1080 offset
= (long
) cff_dict_get
(cff-
>topdict
, "Private", 1);
1081 cff-
>offset
= (l_offset
) offset
;
1082 data
= xmalloc
((unsigned
) size
* sizeof
(card8
));
1083 memcpy
(data
, &cff->stream[cff->offset], (size_t) size);
1084 cff-
>offset
= (l_offset
) size
;
1085 cff-
>private
[0] = cff_dict_unpack
(data
, data
+ size
);
1089 (cff-
>private
)[0] = NULL;
1099 cff_font
*read_cff
(unsigned char
*buf
, long buflength
, int n
)
1106 cff
= xcalloc
(1, sizeof
(cff_font
));
1109 cff-
>stream_size
= (l_offset
) buflength
;
1112 cff-
>header_major
= get_card8
(cff
);
1113 cff-
>header_minor
= get_card8
(cff
);
1114 cff-
>header_hdr_size
= get_card8
(cff
);
1115 cff-
>header_offsize
= get_card8
(cff
);
1116 if
(cff-
>header_offsize
< 1 || cff-
>header_offsize
> 4) {
1117 normal_warning
("cff","invalid offsize data");
1121 if
(cff-
>header_major
> 1) {
1122 formatted_warning
("cff","major version %u not supported", cff-
>header_major
);
1126 cff-
>offset
= cff-
>header_hdr_size
;
1129 idx
= cff_get_index
(cff
);
1130 if
(n
> idx-
>count
- 1) {
1131 normal_warning
("cff","invalid fontset index number");
1138 cff-
>fontname
= cff_get_name
(cff
);
1140 /* Top
DICT INDEX */
1141 idx
= cff_get_index
(cff
);
1142 if
(n
> idx-
>count
- 1) {
1143 normal_warning
("cff","top DICT not exist");
1147 cff-
>topdict
= cff_dict_unpack
(idx-
>data
+ idx-
>offset
[n
] - 1,
1148 idx-
>data
+ idx-
>offset
[n
+ 1] - 1);
1149 if
(!cff-
>topdict
) {
1150 normal_warning
("cff","parsing top DICT data failed");
1154 cff_release_index
(idx
);
1156 if
(cff_dict_known
(cff-
>topdict
, "CharstringType") &&
1157 cff_dict_get
(cff-
>topdict
, "CharstringType", 0) != 2) {
1158 normal_warning
("cff","only type 2 charstrings supported");
1163 if
(cff_dict_known
(cff-
>topdict
, "SyntheticBase")) {
1164 normal_warning
("cff","synthetic font not supported");
1170 cff-
>string
= cff_get_index
(cff
);
1172 /* offset to GSubr
*/
1173 cff-
>gsubr_offset
= cff-
>offset
;
1175 /* Number of glyphs
*/
1176 offset
= (long
) cff_dict_get
(cff-
>topdict
, "CharStrings", 0);
1177 cff-
>offset
= (l_offset
) offset
;
1178 cff-
>num_glyphs
= get_card16
(cff
);
1180 /* Check for font type
*/
1181 if
(cff_dict_known
(cff-
>topdict
, "ROS")) {
1182 cff-
>flag |
= FONTTYPE_CIDFONT
;
1184 cff-
>flag |
= FONTTYPE_FONT
;
1187 /* Check for encoding
*/
1188 if
(cff_dict_known
(cff-
>topdict
, "Encoding")) {
1189 offset
= (long
) cff_dict_get
(cff-
>topdict
, "Encoding", 0);
1190 if
(offset
== 0) { /* predefined
*/
1191 cff-
>flag |
= ENCODING_STANDARD
;
1192 } else if
(offset
== 1) {
1193 cff-
>flag |
= ENCODING_EXPERT
;
1196 cff-
>flag |
= ENCODING_STANDARD
;
1199 cff-
>offset
= cff-
>gsubr_offset
; /* seek back to GSubr
*/
1204 @
* write a cff for opentype.
1208 static long pack_integer
(card8
* dest
, long destlen
, long value
)
1212 if
(value
>= -107 && value <= 107) {
1214 normal_error
("cff","buffer overflow");
1215 dest
[0] = (card8
) ((value
+ 139) & 0xff);
1217 } else if
(value
>= 108 && value <= 1131) {
1219 normal_error
("cff","buffer overflow");
1220 value
= (long
) 0xf700u
+ value
- 108;
1221 dest
[0] = (card8
) ((value
>> 8) & 0xff);
1222 dest
[1] = (card8
) (value
& 0xff);
1224 } else if
(value
>= -1131 && value <= -108) {
1226 normal_error
("cff","buffer overflow");
1227 value
= (long
) 0xfb00u
- value
- 108;
1228 dest
[0] = (card8
) ((value
>> 8) & 0xff);
1229 dest
[1] = (card8
) (value
& 0xff);
1231 } else if
(value
>= -32768 && value <= 32767) { /* shortint */
1233 normal_error
("cff","buffer overflow");
1235 dest
[1] = (card8
) ((value
>> 8) & 0xff);
1236 dest
[2] = (card8
) (value
& 0xff);
1238 } else
{ /* longint
*/
1240 normal_error
("cff","buffer overflow");
1242 dest
[1] = (card8
) ((value
>> 24) & 0xff);
1243 dest
[2] = (card8
) ((value
>> 16) & 0xff);
1244 dest
[3] = (card8
) ((value
>> 8) & 0xff);
1245 dest
[4] = (card8
) (value
& 0xff);
1252 static long pack_real
(card8
* dest
, long destlen
, double value
)
1257 #define CFF_REAL_MAX_LEN
17
1260 normal_error
("cff","buffer overflow");
1276 if
(value
>= 10.0) {
1277 while
(value
>= 10.0) {
1281 } else if
(value
< 1.0) {
1282 while
(value
< 1.0) {
1288 res
=sprintf
(work_buffer
, "%1.14g", value
);
1289 if
(res
<0) normal_error
("cff","invalid conversion");
1290 if
(res
>CFF_REAL_MAX_LEN
) res
=CFF_REAL_MAX_LEN
;
1292 for
(i
= 0; i
< res
; i
++) {
1293 unsigned char ch
= 0;
1295 if
(work_buffer
[i
] == '\
0'
) {
1296 /* res should prevent this.
*/
1297 /* normal_error
("cff","cannot happen"); */
1299 } else if
(work_buffer
[i
] == '.'
) {
1301 } else if
(work_buffer
[i
] >= '
0'
&& work_buffer[i] <= '9') {
1302 ch
= (unsigned char
) (work_buffer
[i
] - '
0'
);
1304 normal_error
("cff","invalid character");
1307 if
(destlen
< pos
/ 2 + 1)
1308 normal_error
("cff","buffer overflow");
1311 dest
[pos
/ 2] = (card8
) (dest
[pos
/ 2] + ch
);
1313 dest
[pos
/ 2] = (card8
) (ch
<< 4);
1320 dest
[pos
/ 2] = (card8
) (dest
[pos
/ 2] + 0x0b);
1322 if
(destlen
< pos
/ 2 + 1)
1323 normal_error
("cff","buffer overflow");
1324 dest
[pos
/ 2] = (card8
) (0xb0);
1329 dest
[pos
/ 2] = (card8
) (dest
[pos
/ 2] + 0x0c);
1331 if
(destlen
< pos
/ 2 + 1)
1332 normal_error
("cff","buffer overflow");
1333 dest
[pos
/ 2] = (card8
) (0xc0);
1340 sprintf
(work_buffer
, "%ld", e
);
1341 for
(i
= 0; i
< CFF_REAL_MAX_LEN
; i
++) {
1342 unsigned char ch
= 0;
1343 if
(work_buffer
[i
] == '\
0'
) {
1345 } else if
(work_buffer
[i
] == '.'
) {
1347 } else if
(work_buffer
[i
] >= '
0'
&& work_buffer[i] <= '9') {
1348 ch
= (unsigned char
) (work_buffer
[i
] - '
0'
);
1350 normal_error
("cff","invalid character");
1353 if
(destlen
< pos
/ 2 + 1)
1354 normal_error
("cff","buffer overflow");
1357 dest
[pos
/ 2] = (card8
) (dest
[pos
/ 2] + ch
);
1359 dest
[pos
/ 2] = (card8
) (ch
<< 4);
1366 dest
[pos
/ 2] = (card8
) (dest
[pos
/ 2] + 0x0f);
1369 if
(destlen
< pos
/ 2 + 1)
1370 normal_error
("cff","buffer overflow");
1371 dest
[pos
/ 2] = (card8
) (0xff);
1379 static long cff_dict_put_number
(double value
,
1380 card8
* dest
, long destlen
, int type
)
1385 nearint
= floor
(value
+ 0.5);
1386 /* set offset to longint
*/
1387 if
(type
== CFF_TYPE_OFFSET
) {
1390 lvalue
= (long
) value
;
1392 normal_error
("cff","buffer overflow");
1394 dest
[1] = (card8
) ((lvalue
>> 24) & 0xff);
1395 dest
[2] = (card8
) ((lvalue
>> 16) & 0xff);
1396 dest
[3] = (card8
) ((lvalue
>> 8) & 0xff);
1397 dest
[4] = (card8
) (lvalue
& 0xff);
1399 } else if
(value
> CFF_INT_MAX || value
< CFF_INT_MIN ||
(fabs
(value
- nearint
) > 1.0e-5)) { /* real
*/
1400 len
= pack_real
(dest
, destlen
, value
);
1401 } else
{ /* integer
*/
1402 len
= pack_integer
(dest
, destlen
, (long
) nearint
);
1409 static long put_dict_entry
(cff_dict_entry
* de
, card8
* dest
, long destlen
)
1414 if
(de-
>count
> 0) {
1416 if
(dict_operator
[id
].argtype
== CFF_TYPE_OFFSET ||
1417 dict_operator
[id
].argtype
== CFF_TYPE_SZOFF
) {
1418 type
= CFF_TYPE_OFFSET
;
1420 type
= CFF_TYPE_NUMBER
;
1422 for
(i
= 0; i
< de-
>count
; i
++) {
1423 len
+= cff_dict_put_number
(de-
>values
[i
],
1424 dest
+ len
, destlen
- len
, type
);
1426 if
(id
>= 0 && id < CFF_LAST_DICT_OP1) {
1427 if
(len
+ 1 > destlen
)
1428 normal_error
("cff","buffer overflow");
1429 dest
[len
++] = (card8
) id
;
1430 } else if
(id
>= 0 && id < CFF_LAST_DICT_OP) {
1431 if
(len
+ 2 > destlen
)
1432 normal_error
("cff","buffer overflow");
1434 dest
[len
++] = (card8
) (id
- CFF_LAST_DICT_OP1
);
1436 normal_error
("cff","invalid DICT operator ID");
1444 long cff_dict_pack
(cff_dict
* dict
, card8
* dest
, long destlen
)
1449 for
(i
= 0; i
< dict-
>count
; i
++) {
1450 if
(!strcmp
(dict-
>entries
[i
].key
, "ROS")) {
1451 len
+= put_dict_entry
(&dict->entries[i], dest, destlen);
1455 for
(i
= 0; i
< dict-
>count
; i
++) {
1456 if
(strcmp
(dict-
>entries
[i
].key
, "ROS")) {
1457 len
+= put_dict_entry
(&dict->entries[i], dest + len, destlen - len);
1466 void cff_dict_add
(cff_dict
* dict
, const char
*key
, int count
)
1470 for
(id
= 0; id
< CFF_LAST_DICT_OP
; id
++) {
1471 if
(key
&& dict_operator[id].opname &&
1472 strcmp
(dict_operator
[id
].opname
, key
) == 0)
1476 if
(id
== CFF_LAST_DICT_OP
)
1477 normal_error
("cff","unknown DICT operator");
1479 for
(i
= 0; i
< dict-
>count
; i
++) {
1480 if
((dict-
>entries
)[i
].id
== id
) {
1481 if
((dict-
>entries
)[i
].count
!= count
)
1482 normal_error
("cff","inconsistent DICT argument number");
1487 if
(dict-
>count
+ 1 >= dict-
>max
) {
1490 xrealloc
(dict-
>entries
,
1491 (unsigned
) ((unsigned
) dict-
>max
*
1492 sizeof
(cff_dict_entry
)));
1495 (dict-
>entries
)[dict-
>count
].id
= id
;
1496 (dict-
>entries
)[dict-
>count
].key
= dict_operator
[id
].opname
;
1497 (dict-
>entries
)[dict-
>count
].count
= count
;
1499 (dict-
>entries
)[dict-
>count
].values
=
1500 xcalloc
((unsigned
) count
, sizeof
(double
));
1502 (dict-
>entries
)[dict-
>count
].values
= NULL;
1511 void cff_dict_remove
(cff_dict
* dict
, const char
*key
)
1514 for
(i
= 0; i
< dict-
>count
; i
++) {
1515 if
(key
&& strcmp(key, (dict->entries)[i].key) == 0) {
1516 (dict-
>entries
)[i
].count
= 0;
1517 xfree
((dict-
>entries
)[i
].values
);
1523 void cff_dict_set
(cff_dict
* dict
, const char
*key
, int idx
, double value
)
1527 assert
(dict
&& key);
1529 for
(i
= 0; i
< dict-
>count
; i
++) {
1530 if
(strcmp
(key
, (dict-
>entries
)[i
].key
) == 0) {
1531 if
((dict-
>entries
)[i
].count
> idx
)
1532 (dict-
>entries
)[i
].values
[idx
] = value
;
1534 normal_error
("cff","invalid index number");
1539 if
(i
== dict-
>count
)
1540 formatted_error
("cff","DICT entry '%s' not found", key
);
1546 char
*cff_get_string
(cff_font
* cff
, s_SID id
)
1548 char
*result
= NULL;
1551 if
(id
< CFF_STDSTR_MAX
) {
1552 len
= strlen
(cff_stdstr
[id
]);
1553 result
= xmalloc
((unsigned
) (len
+ 1) * sizeof
(char
));
1554 memcpy
(result
, cff_stdstr
[id
], len
);
1556 } else if
(cff
&& cff->string) {
1557 cff_index
*strings
= cff-
>string
;
1558 id
= (s_SID
) (id
- CFF_STDSTR_MAX
);
1559 if
(id
< strings-
>count
) {
1560 len
= (strings-
>offset
)[id
+ 1] - (strings-
>offset
)[id
];
1561 result
= xmalloc
((unsigned
) (len
+ 1) * sizeof
(char
));
1562 memmove
(result
, strings-
>data
+ (strings-
>offset
)[id
] - 1, len
);
1571 long cff_get_sid
(cff_font
* cff
, const char
*str
)
1578 /* I search String
INDEX first.
*/
1579 if
(cff
&& cff->string) {
1580 cff_index
*idx
= cff-
>string
;
1581 for
(i
= 0; i
< idx-
>count
; i
++) {
1582 if
(strlen
(str
) == (idx-
>offset
)[i
+ 1] - (idx-
>offset
)[i
] &&
1583 !memcmp
(str
, (idx-
>data
) + (idx-
>offset
)[i
] - 1, strlen
(str
)))
1584 return
(i
+ CFF_STDSTR_MAX
);
1588 for
(i
= 0; i
< CFF_STDSTR_MAX
; i
++) {
1589 if
(!strcmp
(str
, cff_stdstr
[i
]))
1598 void cff_update_string
(cff_font
* cff
)
1601 normal_error
("cff","CFF font not opened");
1604 cff_release_index
(cff-
>string
);
1605 cff-
>string
= cff-
>_string
;
1606 cff-
>_string
= NULL;
1611 s_SID cff_add_string
(cff_font
* cff
, const char
*str
)
1615 l_offset offset
, size
;
1618 normal_error
("cff","CFF font not opened");
1620 if
(cff-
>_string
== NULL)
1621 cff-
>_string
= cff_new_index
(0);
1622 strings
= cff-
>_string
;
1624 for
(idx
= 0; idx
< strings-
>count
; idx
++) {
1625 size
= strings-
>offset
[idx
+ 1] - strings-
>offset
[idx
];
1626 offset
= strings-
>offset
[idx
];
1627 if
(size
== strlen
(str
) &&
1628 !memcmp
(strings-
>data
+ offset
- 1, str
, strlen
(str
)))
1629 return
(s_SID
) (idx
+ CFF_STDSTR_MAX
);
1632 for
(idx
= 0; idx
< CFF_STDSTR_MAX
; idx
++) {
1633 if
(cff_stdstr
[idx
] && !strcmp(cff_stdstr[idx], str))
1636 offset
= (strings-
>count
> 0) ? strings-
>offset
[strings-
>count
] : 1;
1638 xrealloc
(strings-
>offset
,
1639 (unsigned
) (((unsigned
) strings-
>count
+
1640 2) * sizeof
(l_offset
)));
1641 if
(strings-
>count
== 0)
1642 strings-
>offset
[0] = 1;
1643 idx
= strings-
>count
;
1644 strings-
>count
= (card16
) (strings-
>count
+ 1);
1645 strings-
>offset
[strings-
>count
] = offset
+ strlen
(str
);
1647 xrealloc
(strings-
>data
,
1648 (unsigned
) ((offset
+ strlen
(str
) - 1) * sizeof
(card8
)));
1649 memcpy
(strings-
>data
+ offset
- 1, str
, strlen
(str
));
1651 return
(s_SID
) (idx
+ CFF_STDSTR_MAX
);
1656 void cff_dict_update
(cff_dict
* dict
, cff_font
* cff
)
1660 for
(i
= 0; i
< dict-
>count
; i
++) {
1661 if
((dict-
>entries
)[i
].count
> 0) {
1665 id
= (dict-
>entries
)[i
].id
;
1667 if
(dict_operator
[id
].argtype
== CFF_TYPE_SID
) {
1668 str
= cff_get_string
(cff
, (s_SID
) (dict-
>entries
)[i
].values
[0]);
1669 (dict-
>entries
)[i
].values
[0] = cff_add_string
(cff
, str
);
1671 } else if
(dict_operator
[id
].argtype
== CFF_TYPE_ROS
) {
1672 str
= cff_get_string
(cff
, (s_SID
) (dict-
>entries
)[i
].values
[0]);
1673 (dict-
>entries
)[i
].values
[0] = cff_add_string
(cff
, str
);
1675 str
= cff_get_string
(cff
, (s_SID
) (dict-
>entries
)[i
].values
[1]);
1676 (dict-
>entries
)[i
].values
[1] = cff_add_string
(cff
, str
);
1686 long cff_read_charsets
(cff_font
* cff
)
1688 cff_charsets
*charset
;
1689 long offset
, length
;
1692 if
(cff-
>topdict
== NULL)
1693 normal_error
("cff","top DICT not available");
1695 if
(!cff_dict_known
(cff-
>topdict
, "charset")) {
1696 cff-
>flag |
= CHARSETS_ISOADOBE
;
1697 cff-
>charsets
= NULL;
1701 offset
= (long
) cff_dict_get
(cff-
>topdict
, "charset", 0);
1703 if
(offset
== 0) { /* predefined
*/
1704 cff-
>flag |
= CHARSETS_ISOADOBE
;
1705 cff-
>charsets
= NULL;
1707 } else if
(offset
== 1) {
1708 cff-
>flag |
= CHARSETS_EXPERT
;
1709 cff-
>charsets
= NULL;
1711 } else if
(offset
== 2) {
1712 cff-
>flag |
= CHARSETS_EXPSUB
;
1713 cff-
>charsets
= NULL;
1717 cff-
>offset
= (l_offset
) offset
;
1718 cff-
>charsets
= charset
= xcalloc
(1, sizeof
(cff_charsets
));
1719 charset-
>format
= get_card8
(cff
);
1720 charset-
>num_entries
= 0;
1722 count
= (card16
) (cff-
>num_glyphs
- 1);
1725 /* Not sure. Not well documented.
*/
1726 switch
(charset-
>format
) {
1728 charset-
>num_entries
= (card16
) (cff-
>num_glyphs
- 1); /* no .notdef
*/
1729 charset-
>data.glyphs
=
1730 xmalloc
((unsigned
) (charset-
>num_entries
* sizeof
(s_SID
)));
1731 length
+= (charset-
>num_entries
) * 2;
1732 for
(i
= 0; i
< (charset-
>num_entries
); i
++) {
1733 charset-
>data.glyphs
[i
] = get_card16
(cff
);
1739 cff_range1
*ranges
= NULL;
1740 while
(count
> 0 && charset->num_entries < cff->num_glyphs) {
1743 (unsigned
) (((unsigned
) charset-
>num_entries
+
1744 1) * sizeof
(cff_range1
)));
1745 ranges
[charset-
>num_entries
].first
= get_card16
(cff
);
1746 ranges
[charset-
>num_entries
].n_left
= get_card8
(cff
);
1747 count
= (card16
) (count
- ranges
[charset-
>num_entries
].n_left
+ 1); /* no-overrap
*/
1748 charset-
>num_entries
++;
1749 charset-
>data.range1
= ranges
;
1751 length
+= (charset-
>num_entries
) * 3;
1756 cff_range2
*ranges
= NULL;
1757 while
(count
> 0 && charset->num_entries < cff->num_glyphs) {
1760 (unsigned
) (((unsigned
) charset-
>num_entries
+
1761 1) * sizeof
(cff_range2
)));
1762 ranges
[charset-
>num_entries
].first
= get_card16
(cff
);
1763 ranges
[charset-
>num_entries
].n_left
= get_card16
(cff
);
1764 count
= (card16
) (count
- (ranges
[charset-
>num_entries
].n_left
+ 1)); /* non-overrapping
*/
1765 charset-
>num_entries
++;
1767 charset-
>data.range2
= ranges
;
1768 length
+= (charset-
>num_entries
) * 4;
1773 normal_error
("cff","unknown charset format");
1778 /* fprintf
(stdout
, "count=%d\n", count
); */
1779 normal_warning
("cff","charset data possibly broken (too many glyphs)");
1786 long cff_pack_charsets
(cff_font
* cff
, card8
* dest
, long destlen
)
1790 cff_charsets
*charset
;
1792 if
(cff-
>flag
& HAVE_STANDARD_CHARSETS || cff->charsets == NULL)
1796 normal_error
("cff","buffer overflow");
1798 charset
= cff-
>charsets
;
1800 dest
[len
++] = charset-
>format
;
1801 switch
(charset-
>format
) {
1803 if
(destlen
< len
+ (charset-
>num_entries
) * 2)
1804 normal_error
("cff","buffer overflow");
1805 for
(i
= 0; i
< (charset-
>num_entries
); i
++) {
1806 s_SID sid
= (charset-
>data
).glyphs
[i
]; /* or CID
*/
1807 dest
[len
++] = (card8
) ((sid
>> 8) & 0xff);
1808 dest
[len
++] = (card8
) (sid
& 0xff);
1813 if
(destlen
< len
+ (charset-
>num_entries
) * 3)
1814 normal_error
("cff","buffer overflow");
1815 for
(i
= 0; i
< (charset-
>num_entries
); i
++) {
1817 (card8
) (((charset-
>data
).range1
[i
].first
>> 8) & 0xff);
1818 dest
[len
++] = (card8
) ((charset-
>data
).range1
[i
].first
& 0xff);
1819 dest
[len
++] = (card8
) ((charset-
>data
).range1
[i
].n_left
);
1825 if
(destlen
< len
+ (charset-
>num_entries
) * 4)
1826 normal_error
("cff","buffer overflow");
1827 for
(i
= 0; i
< (charset-
>num_entries
); i
++) {
1829 (card8
) (((charset-
>data
).range2
[i
].first
>> 8) & 0xff);
1830 dest
[len
++] = (card8
) ((charset-
>data
).range2
[i
].first
& 0xff);
1832 (card8
) (((charset-
>data
).range2
[i
].n_left
>> 8) & 0xff);
1833 dest
[len
++] = (card8
) ((charset-
>data
).range2
[i
].n_left
& 0xff);
1838 normal_error
("cff","unknown charset format");
1847 @
* Type
2 Charstring support.
1849 Decode and encode Type
2 charstring
1851 All local
/global subroutine calls in a given charstring is replace by the
1852 content of subroutine charstrings. We do this because some PostScript RIP
1853 may have problems with sparse subroutine array. Workaround for this is to
1854 re-order subroutine array so that no gap appears in the subroutine array
,
1855 or put dummy charstrings that contains only `return' in the gap. However
,
1856 re-ordering of subroutine is rather difficult for Type
2 charstrings due
1857 to the bias which depends on the total number of subroutines. Replacing
1858 callgsubr
/callsubr calls with the content of the corresponding subroutine
1859 charstring may be more efficient than putting dummy subroutines in the
1860 case of subsetted font. Adobe distiller seems doing same thing.
1862 And also note that subroutine numbers within subroutines can depend on the
1863 content of operand stack as follows
:
1865 \.
{ ... l m callsubr
<< subr \#
(m
+bias
): n add callsubr
>> ...
}
1867 I've not implemented the `random' operator which generates a pseudo-random
1868 number in the range
(0, 1] and push them into argument stack.
1869 How pseudo-random sequences are generated is not documented in the Type
2
1874 #define CS_TYPE2_DEBUG_STR
"Type2 Charstring Parser"
1875 #define CS_TYPE2_DEBUG
5
1877 /* decoder
/encoder status codes
*/
1878 #define CS_BUFFER_CFF_ERROR
-3
1879 #define CS_STACK_CFF_ERROR
-2
1880 #define CS_PARSE_CFF_ERROR
-1
1881 #define CS_PARSE_OK
0
1882 #define CS_PARSE_END
1
1883 #define CS_SUBR_RETURN
2
1884 #define CS_CHAR_END
3
1886 static int status
= CS_PARSE_CFF_ERROR
;
1888 #define DST_NEED
(a
,b
) {if
((a
) < (b
)) { status
= CS_BUFFER_CFF_ERROR
; return
; }}
1889 #define SRC_NEED
(a
,b
) {if
((a
) < (b
)) { status
= CS_PARSE_CFF_ERROR
; return
; }}
1890 #define NEED
(a
,b
) {if
((a
) < (b
)) { status
= CS_STACK_CFF_ERROR
; return
; }}
1892 /* hintmask and cntrmask need number of stem zones
*/
1893 static int num_stems
= 0;
1894 static int phase
= 0;
1896 /* subroutine nesting
*/
1897 static int cs2_nest
= 0;
1900 static int have_width
= 0;
1901 static double width
= 0.0;
1904 Standard Encoding Accented Characters
:
1905 Optional four arguments for endchar. See
, CFF spec.
, p
.35.
1906 This is obsolete feature and is no longer supported.
1909 /* adx ady bchar achar endchar
*/
1910 static double seac
[4] = { 0.0, 0.0, 0.0, 0.0 };
1913 @ Operand stack and Transient array
1915 static int cs2_stack_top
= 0;
1916 static double cs2_arg_stack
[CS_ARG_STACK_MAX
];
1917 static double trn_array
[CS_TRANS_ARRAY_MAX
];
1919 @ Type
2 CharString encoding
1923 1-byte CharString operaotrs
:
1924 |cs_escape| is first byte of two-byte operator
1931 #define cs_vmoveto
4
1932 #define cs_rlineto
5
1933 #define cs_hlineto
6
1934 #define cs_vlineto
7
1935 #define cs_rrcurveto
8
1936 /* |cs_closepath|
9 : TYPE1
*/
1937 #define cs_callsubr
10
1938 #define cs_return
11
1939 #define cs_escape
12
1940 /* |cs_hsbw|
13 : TYPE1
*/
1941 #define cs_endchar
14
1945 #define cs_hstemhm
18
1946 #define cs_hintmask
19
1947 #define cs_cntrmask
20
1948 #define cs_rmoveto
21
1949 #define cs_hmoveto
22
1950 #define cs_vstemhm
23
1951 #define cs_rcurveline
24
1952 #define cs_rlinecurve
25
1953 #define cs_vvcurveto
26
1954 #define cs_hhcurveto
27
1955 /* SHORTINT
28 : first byte of shortint
*/
1956 #define cs_callgsubr
29
1957 #define cs_vhcurveto
30
1958 #define cs_hvcurveto
31
1961 2-byte CharString operaotrs
:
1962 "dotsection" is obsoleted in Type
2 charstring.
1965 #define cs_dotsection
0
1966 /* |cs_vstem3|
1 : TYPE1
*/
1967 /* |cs_hstem3|
2 : TYPE1
*/
1971 /* |cs_seac|
6 : TYPE1
*/
1972 /* |cs_sbw|
7 : TYPE1
*/
1981 /* |cs_callothersubr|
16 : TYPE1
*/
1982 /* |cs_pop|
17 : TYPE1
*/
1987 #define cs_ifelse
22
1988 #define cs_random
23
1996 /* |cs_setcurrentpoint|
31 : TYPE1
*/
2001 #define cs_hflex1
36
2005 |clear_stack
()| put all operands sotred in operand stack to dest.
2007 static void clear_stack
(card8
** dest
, card8
* limit
)
2011 for
(i
= 0; i
< cs2_stack_top
; i
++) {
2014 value
= cs2_arg_stack
[i
];
2015 /* Nearest integer value
*/
2016 ivalue
= (long
) floor
(value
+ 0.5);
2017 if
(value
>= 0x8000L || value
<= (-0x8000L
- 1)) {
2019 This number cannot be represented as a single operand.
2020 We must use `a b mul ...' or `a c div' to represent large values.
2022 normal_error
("cff","argument value too large (this is bug)");
2023 } else if
(fabs
(value
- (double
) ivalue
) > 3.0e-5) {
2024 /* 16.16-bit signed fixed value
*/
2025 DST_NEED
(limit
, *dest
+ 5);
2027 ivalue
= (long
) floor
(value
); /* mantissa
*/
2028 *(*dest
)++ = (card8
) ((ivalue
>> 8) & 0xff);
2029 *(*dest
)++ = (card8
) (ivalue
& 0xff);
2030 ivalue
= (long
) ((value
- (double
) ivalue
) * 0x10000l
); /* fraction
*/
2031 *(*dest
)++ = (card8
) ((ivalue
>> 8) & 0xff);
2032 *(*dest
)++ = (card8
) (ivalue
& 0xff);
2033 /* Everything else are integers.
*/
2034 } else if
(ivalue
>= -107 && ivalue <= 107) {
2035 DST_NEED
(limit
, *dest
+ 1);
2036 *(*dest
)++ = (card8
) (ivalue
+ 139);
2037 } else if
(ivalue
>= 108 && ivalue <= 1131) {
2038 DST_NEED
(limit
, *dest
+ 2);
2039 ivalue
= (long
) 0xf700u
+ ivalue
- 108;
2040 *(*dest
)++ = (card8
) ((ivalue
>> 8) & 0xff);
2041 *(*dest
)++ = (card8
) (ivalue
& 0xff);
2042 } else if
(ivalue
>= -1131 && ivalue <= -108) {
2043 DST_NEED
(limit
, *dest
+ 2);
2044 ivalue
= (long
) 0xfb00u
- ivalue
- 108;
2045 *(*dest
)++ = (card8
) ((ivalue
>> 8) & 0xff);
2046 *(*dest
)++ = (card8
) (ivalue
& 0xff);
2047 } else if
(ivalue
>= -32768 && ivalue <= 32767) { /* shortint */
2048 DST_NEED
(limit
, *dest
+ 3);
2050 *(*dest
)++ = (card8
) ((ivalue
>> 8) & 0xff);
2051 *(*dest
)++ = (card8
) ((ivalue
) & 0xff);
2052 } else
{ /* Shouldn't come here
*/
2053 normal_error
("cff","unexpected error");
2057 cs2_stack_top
= 0; /* clear stack
*/
2063 Single byte operators
:
2064 Path construction
, Operator for finishing a path
, Hint operators.
2067 \item
0: inital state
2068 \item
1: hint declaration
, first stack-clearing operator appeared
2069 \item
2: in path construction
2073 do_operator1
(card8
** dest
, card8
* limit
, card8
** data
, card8
* endptr
)
2082 /* charstring may have hintmask if above operator have seen
*/
2085 if
(phase
== 0 && (cs2_stack_top % 2)) {
2087 width
= cs2_arg_stack
[0];
2089 num_stems
+= cs2_stack_top
/ 2;
2090 clear_stack
(dest
, limit
);
2091 DST_NEED
(limit
, *dest
+ 1);
2098 if
(phase
== 0 && (cs2_stack_top % 2)) {
2100 width
= cs2_arg_stack
[0];
2102 num_stems
+= cs2_stack_top
/ 2;
2104 clear_stack
(dest
, limit
);
2105 DST_NEED
(limit
, *dest
+ 1);
2107 if
(num_stems
> 0) {
2108 int masklen
= (num_stems
+ 7) / 8;
2109 DST_NEED
(limit
, *dest
+ masklen
);
2110 SRC_NEED
(endptr
, *data
+ masklen
);
2111 memmove
(*dest
, *data
, (size_t
) masklen
);
2118 if
(phase
== 0 && (cs2_stack_top % 2)) {
2120 width
= cs2_arg_stack
[0];
2122 clear_stack
(dest
, limit
);
2123 DST_NEED
(limit
, *dest
+ 1);
2129 if
(phase
== 0 && (cs2_stack_top % 2) == 0) {
2131 width
= cs2_arg_stack
[0];
2133 clear_stack
(dest
, limit
);
2134 DST_NEED
(limit
, *dest
+ 1);
2139 if
(cs2_stack_top
== 1) {
2141 width
= cs2_arg_stack
[0];
2142 clear_stack
(dest
, limit
);
2143 } else if
(cs2_stack_top
== 4 || cs2_stack_top
== 5) {
2144 normal_warning
("cff","'seac' character deprecated in type 2 charstring");
2145 status
= CS_PARSE_CFF_ERROR
;
2147 } else if
(cs2_stack_top
> 0) {
2148 normal_warning
("cff","operand stack not empty");
2150 DST_NEED
(limit
, *dest
+ 1);
2152 status
= CS_CHAR_END
;
2154 /* above oprators are candidate for first stack-clearing operator
*/
2166 normal_warning
("cff","broken type 2 charstring");
2167 status
= CS_PARSE_CFF_ERROR
;
2170 clear_stack
(dest
, limit
);
2171 DST_NEED
(limit
, *dest
+ 1);
2174 /* all operotors above are stack-clearing operator
*/
2179 normal_error
("cff","unexpected call(g)subr/return");
2183 formatted_warning
("cff","%s: unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR
, op
);
2184 status
= CS_PARSE_CFF_ERROR
;
2192 Double byte operators
:
2193 Flex
, arithmetic
, conditional
, and storage operators.
2195 Following operators are not supported
:
2196 random
: How random ?
2200 do_operator2
(card8
** dest
, card8
* limit
, card8
** data
, card8
* endptr
)
2206 SRC_NEED
(endptr
, *data
+ 1);
2212 case cs_dotsection
: /* deprecated
*/
2213 normal_warning
("cff","Operator 'dotsection' deprecated in type 2 charstring");
2214 status
= CS_PARSE_CFF_ERROR
;
2222 formatted_warning
("cff","%s: broken type 2 charstring", CS_TYPE2_DEBUG_STR
);
2223 status
= CS_PARSE_CFF_ERROR
;
2226 clear_stack
(dest
, limit
);
2227 DST_NEED
(limit
, *dest
+ 2);
2228 *(*dest
)++ = cs_escape
;
2231 /* all operator above are stack-clearing
*/
2234 NEED
(cs2_stack_top
, 2);
2236 if
(cs2_arg_stack
[cs2_stack_top
] && cs2_arg_stack[cs2_stack_top - 1]) {
2237 cs2_arg_stack
[cs2_stack_top
- 1] = 1.0;
2239 cs2_arg_stack
[cs2_stack_top
- 1] = 0.0;
2243 NEED
(cs2_stack_top
, 2);
2245 if
(cs2_arg_stack
[cs2_stack_top
] || cs2_arg_stack
[cs2_stack_top
- 1]) {
2246 cs2_arg_stack
[cs2_stack_top
- 1] = 1.0;
2248 cs2_arg_stack
[cs2_stack_top
- 1] = 0.0;
2252 NEED
(cs2_stack_top
, 1);
2253 if
(cs2_arg_stack
[cs2_stack_top
- 1]) {
2254 cs2_arg_stack
[cs2_stack_top
- 1] = 0.0;
2256 cs2_arg_stack
[cs2_stack_top
- 1] = 1.0;
2260 NEED
(cs2_stack_top
, 1);
2261 cs2_arg_stack
[cs2_stack_top
- 1] =
2262 fabs
(cs2_arg_stack
[cs2_stack_top
- 1]);
2265 NEED
(cs2_stack_top
, 2);
2266 cs2_arg_stack
[cs2_stack_top
- 2] += cs2_arg_stack
[cs2_stack_top
- 1];
2270 NEED
(cs2_stack_top
, 2);
2271 cs2_arg_stack
[cs2_stack_top
- 2] -= cs2_arg_stack
[cs2_stack_top
- 1];
2274 case cs_div
: /* doesn't check overflow
*/
2275 NEED
(cs2_stack_top
, 2);
2276 cs2_arg_stack
[cs2_stack_top
- 2] /= cs2_arg_stack
[cs2_stack_top
- 1];
2280 NEED
(cs2_stack_top
, 1);
2281 cs2_arg_stack
[cs2_stack_top
- 1] *= -1.0;
2284 NEED
(cs2_stack_top
, 2);
2286 if
(cs2_arg_stack
[cs2_stack_top
] == cs2_arg_stack
[cs2_stack_top
- 1]) {
2287 cs2_arg_stack
[cs2_stack_top
- 1] = 1.0;
2289 cs2_arg_stack
[cs2_stack_top
- 1] = 0.0;
2293 NEED
(cs2_stack_top
, 1);
2297 NEED
(cs2_stack_top
, 2);
2299 int idx
= (int
) cs2_arg_stack
[--cs2_stack_top
];
2300 NEED
(CS_TRANS_ARRAY_MAX
, idx
);
2301 trn_array
[idx
] = cs2_arg_stack
[--cs2_stack_top
];
2305 NEED
(cs2_stack_top
, 1);
2307 int idx
= (int
) cs2_arg_stack
[cs2_stack_top
- 1];
2308 NEED
(CS_TRANS_ARRAY_MAX
, idx
);
2309 cs2_arg_stack
[cs2_stack_top
- 1] = trn_array
[idx
];
2313 NEED
(cs2_stack_top
, 4);
2315 if
(cs2_arg_stack
[cs2_stack_top
+ 1] > cs2_arg_stack
[cs2_stack_top
+ 2]) {
2316 cs2_arg_stack
[cs2_stack_top
- 1] = cs2_arg_stack
[cs2_stack_top
];
2320 NEED
(cs2_stack_top
, 2);
2321 cs2_arg_stack
[cs2_stack_top
- 2] =
2322 cs2_arg_stack
[cs2_stack_top
- 2] * cs2_arg_stack
[cs2_stack_top
- 1];
2326 NEED
(cs2_stack_top
, 1);
2327 cs2_arg_stack
[cs2_stack_top
- 1] =
2328 sqrt
(cs2_arg_stack
[cs2_stack_top
- 1]);
2331 NEED
(cs2_stack_top
, 1);
2332 NEED
(CS_ARG_STACK_MAX
, cs2_stack_top
+ 1);
2333 cs2_arg_stack
[cs2_stack_top
] = cs2_arg_stack
[cs2_stack_top
- 1];
2337 NEED
(cs2_stack_top
, 2);
2339 double save
= cs2_arg_stack
[cs2_stack_top
- 2];
2340 cs2_arg_stack
[cs2_stack_top
- 2] = cs2_arg_stack
[cs2_stack_top
- 1];
2341 cs2_arg_stack
[cs2_stack_top
- 1] = save
;
2345 NEED
(cs2_stack_top
, 2); /* need two arguments at least
*/
2347 int idx
= (int
) cs2_arg_stack
[cs2_stack_top
- 1];
2349 cs2_arg_stack
[cs2_stack_top
- 1] =
2350 cs2_arg_stack
[cs2_stack_top
- 2];
2352 NEED
(cs2_stack_top
, idx
+ 2);
2353 cs2_arg_stack
[cs2_stack_top
- 1] =
2354 cs2_arg_stack
[cs2_stack_top
- idx
- 2];
2359 NEED
(cs2_stack_top
, 2);
2362 J
= (int
) cs2_arg_stack
[--cs2_stack_top
];
2363 N
= (int
) cs2_arg_stack
[--cs2_stack_top
];
2364 NEED
(cs2_stack_top
, N
);
2368 double save
= cs2_arg_stack
[cs2_stack_top
- 1];
2369 int i
= cs2_stack_top
- 1;
2370 while
(i
> cs2_stack_top
- N
) {
2371 cs2_arg_stack
[i
] = cs2_arg_stack
[i
- 1];
2374 cs2_arg_stack
[i
] = save
;
2379 double save
= cs2_arg_stack
[cs2_stack_top
- N
];
2380 int i
= cs2_stack_top
- N
;
2381 while
(i
< cs2_stack_top
- 1) {
2382 cs2_arg_stack
[i
] = cs2_arg_stack
[i
+ 1];
2385 cs2_arg_stack
[i
] = save
;
2391 formatted_warning
("cff","%s: Charstring operator 'random' found.", CS_TYPE2_DEBUG_STR
);
2392 NEED
(CS_ARG_STACK_MAX
, cs2_stack_top
+ 1);
2393 cs2_arg_stack
[cs2_stack_top
++] = 1.0;
2397 formatted_warning
("cff","%s: unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR
, op
);
2398 status
= CS_PARSE_CFF_ERROR
;
2407 exactly the same as the
DICT encoding
(except
29)
2409 static void cs2_get_integer
(card8
** data
, card8
* endptr
)
2412 card8 b0
= **data
, b1
, b2
;
2416 if
(b0
== 28) { /* shortint
*/
2417 SRC_NEED
(endptr
, *data
+ 2);
2420 result
= b1
* 256 + b2
;
2421 if
(result
> 0x7fff)
2424 } else if
(b0
>= 32 && b0 <= 246) { /* int (1) */
2426 } else if
(b0
>= 247 && b0 <= 250) { /* int (2) */
2427 SRC_NEED
(endptr
, *data
+ 1);
2429 result
= (b0
- 247) * 256 + b1
+ 108;
2431 } else if
(b0
>= 251 && b0 <= 254) {
2432 SRC_NEED
(endptr
, *data
+ 1);
2434 result
= -(b0
- 251) * 256 - b1
- 108;
2437 status
= CS_PARSE_CFF_ERROR
;
2441 NEED
(CS_ARG_STACK_MAX
, cs2_stack_top
+ 1);
2442 cs2_arg_stack
[cs2_stack_top
++] = (double
) result
;
2448 Signed
16.16-bits fixed number for Type
2 charstring encoding
2450 static void get_fixed
(card8
** data
, card8
* endptr
)
2457 SRC_NEED
(endptr
, *data
+ 4);
2459 ivalue
= *(*data
) * 0x100 + *(*data
+ 1);
2460 rvalue
= (double
) ((ivalue
> 0x7fffL
) ?
(ivalue
- 0x10000L
) : ivalue
);
2461 ivalue
= *(*data
+ 2) * 0x100 + *(*data
+ 3);
2462 rvalue
+= ((double
) ivalue
) / 0x10000L
;
2464 NEED
(CS_ARG_STACK_MAX
, cs2_stack_top
+ 1);
2465 cs2_arg_stack
[cs2_stack_top
++] = rvalue
;
2473 The bias for subroutine number is introduced in type
2 charstrings.
2475 subr
: set to a pointer to the subroutine charstring.
2476 len
: set to the length of subroutine charstring.
2477 |subr_idx|
: CFF
INDEX data that contains subroutines.
2478 id
: biased subroutine number.
2481 static void get_subr
(card8
** subr
, long
*len
, cff_index
* subr_idx
, long id
)
2485 if
(subr_idx
== NULL)
2486 formatted_error
("cff","%s: subroutine called but no subroutine found",CS_TYPE2_DEBUG_STR
);
2488 count
= subr_idx-
>count
;
2490 /* Adding bias number
*/
2493 } else if
(count
< 33900) {
2500 formatted_error
("cff","%s: invalid subroutine index: %ld (max=%u)", CS_TYPE2_DEBUG_STR
, id
, count
);
2502 *len
= (long
) ((subr_idx-
>offset
)[id
+ 1] - (subr_idx-
>offset
)[id
]);
2503 *subr
= subr_idx-
>data
+ (subr_idx-
>offset
)[id
] - 1;
2510 The Type
2 interpretation of a number encoded in five-bytes
(those with
2511 an initial byte value of
255) differs from how it is interpreted in the
2516 do_charstring
(card8
** dest
, card8
* limit
,
2517 card8
** data
, card8
* endptr
,
2518 cff_index
* gsubr_idx
, cff_index
* subr_idx
)
2520 card8 b0
= 0, *subr
;
2523 if
(cs2_nest
> CS_SUBR_NEST_MAX
)
2524 formatted_error
("cff","%s: subroutine nested too deeply", CS_TYPE2_DEBUG_STR
);
2528 while
(*data
< endptr
&& status == CS_PARSE_OK) {
2530 if
(b0
== 255) { /* 16-bit
.16-bit fixed signed number
*/
2531 get_fixed
(data
, endptr
);
2532 } else if
(b0
== cs_return
) {
2533 status
= CS_SUBR_RETURN
;
2534 } else if
(b0
== cs_callgsubr
) {
2535 if
(cs2_stack_top
< 1) {
2536 status
= CS_STACK_CFF_ERROR
;
2539 get_subr
(&subr, &len, gsubr_idx,
2540 (long
) cs2_arg_stack
[cs2_stack_top
]);
2541 if
(*dest
+ len
> limit
)
2542 formatted_error
("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR
);
2543 do_charstring
(dest
, limit
, &subr, subr + len, gsubr_idx, subr_idx);
2546 } else if
(b0
== cs_callsubr
) {
2547 if
(cs2_stack_top
< 1) {
2548 status
= CS_STACK_CFF_ERROR
;
2551 get_subr
(&subr, &len, subr_idx,
2552 (long
) cs2_arg_stack
[cs2_stack_top
]);
2553 if
(limit
< *dest
+ len
)
2554 formatted_error
("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR
);
2555 do_charstring
(dest
, limit
, &subr, subr + len, gsubr_idx, subr_idx);
2558 } else if
(b0
== cs_escape
) {
2559 do_operator2
(dest
, limit
, data
, endptr
);
2560 } else if
(b0
< 32 && b0 != 28) { /* 19, 20 need mask */
2561 do_operator1
(dest
, limit
, data
, endptr
);
2562 } else if
((b0
<= 22 && b0 >= 27) || b0 == 31) { /* reserved */
2563 status
= CS_PARSE_CFF_ERROR
; /* not an error ?
*/
2564 } else
{ /* integer
*/
2565 cs2_get_integer
(data
, endptr
);
2569 if
(status
== CS_SUBR_RETURN
) {
2570 status
= CS_PARSE_OK
;
2571 } else if
(status
== CS_CHAR_END
&& *data < endptr) {
2572 formatted_warning
("cff","%s: garbage after endchar", CS_TYPE2_DEBUG_STR
);
2573 } else if
(status
< CS_PARSE_OK
) { /* error
*/
2574 formatted_error
("cff","%s: parsing charstring failed: (status=%d, stack=%d)", CS_TYPE2_DEBUG_STR
, status
, cs2_stack_top
);
2583 static void cs_parse_init
(void
)
2585 status
= CS_PARSE_OK
;
2593 @ Not just copying...
2596 cs_copy_charstring
(card8
* dst
, long dstlen
,
2597 card8
* src
, long srclen
,
2598 cff_index
* gsubr
, cff_index
* subr
,
2599 double default_width
, double nominal_width
, cs_ginfo
* ginfo
)
2608 /* expand call
(g
)subrs
*/
2609 do_charstring
(&dst, dst + dstlen, &src, src + srclen, gsubr, subr);
2612 ginfo-
>flags
= 0; /* not used
*/
2614 ginfo-
>wx
= nominal_width
+ width
;
2616 ginfo-
>wx
= default_width
;
2620 return
(long
) (dst
- save
);
2625 @ Encoding and Charset
2627 Encoding and Charset arrays always begin with GID
= 1.
2630 long cff_read_encoding
(cff_font
* cff
)
2632 cff_encoding
*encoding
;
2633 long offset
, length
;
2636 if
(cff-
>topdict
== NULL) {
2637 normal_error
("cff","top DICT data not found");
2640 if
(!cff_dict_known
(cff-
>topdict
, "Encoding")) {
2641 cff-
>flag |
= ENCODING_STANDARD
;
2642 cff-
>encoding
= NULL;
2646 offset
= (long
) cff_dict_get
(cff-
>topdict
, "Encoding", 0);
2647 if
(offset
== 0) { /* predefined
*/
2648 cff-
>flag |
= ENCODING_STANDARD
;
2649 cff-
>encoding
= NULL;
2651 } else if
(offset
== 1) {
2652 cff-
>flag |
= ENCODING_EXPERT
;
2653 cff-
>encoding
= NULL;
2657 cff-
>offset
= (l_offset
) offset
;
2658 cff-
>encoding
= encoding
= xcalloc
(1, sizeof
(cff_encoding
));
2659 encoding-
>format
= get_card8
(cff
);
2662 switch
(encoding-
>format
& (~0x80)) {
2664 encoding-
>num_entries
= get_card8
(cff
);
2665 (encoding-
>data
).codes
= xmalloc
(encoding-
>num_entries
* sizeof
(card8
));
2666 for
(i
= 0; i
< (encoding-
>num_entries
); i
++) {
2667 (encoding-
>data
).codes
[i
] = get_card8
(cff
);
2669 length
+= encoding-
>num_entries
+ 1;
2674 encoding-
>num_entries
= get_card8
(cff
);
2675 encoding-
>data.range1
= ranges
2676 = xcalloc
(encoding-
>num_entries
, sizeof
(cff_range1
));
2677 for
(i
= 0; i
< (encoding-
>num_entries
); i
++) {
2678 ranges
[i
].first
= get_card8
(cff
);
2679 ranges
[i
].n_left
= get_card8
(cff
);
2681 length
+= (encoding-
>num_entries
) * 2 + 1;
2686 normal_error
("cff","unknown encoding format");
2690 /* Supplementary data
*/
2691 if
((encoding-
>format
) & 0x80) {
2693 encoding-
>num_supps
= get_card8
(cff
);
2694 encoding-
>supp
= map
= xcalloc
(encoding-
>num_supps
, sizeof
(cff_map
));
2695 for
(i
= 0; i
< (encoding-
>num_supps
); i
++) {
2696 map
[i
].code
= get_card8
(cff
);
2697 map
[i
].glyph
= get_card16
(cff
); /* SID
*/
2699 length
+= (encoding-
>num_supps
) * 3 + 1;
2701 encoding-
>num_supps
= 0;
2702 encoding-
>supp
= NULL;
2709 long cff_pack_encoding
(cff_font
* cff
, card8
* dest
, long destlen
)
2712 cff_encoding
*encoding
;
2715 if
(cff-
>flag
& HAVE_STANDARD_ENCODING || cff->encoding == NULL)
2719 normal_error
("cff","buffer overflow");
2721 encoding
= cff-
>encoding
;
2723 dest
[len
++] = encoding-
>format
;
2724 dest
[len
++] = encoding-
>num_entries
;
2725 switch
(encoding-
>format
& (~0x80)) {
2727 if
(destlen
< len
+ encoding-
>num_entries
)
2728 normal_error
("cff","buffer overflow");
2729 for
(i
= 0; i
< (encoding-
>num_entries
); i
++) {
2730 dest
[len
++] = (encoding-
>data
).codes
[i
];
2735 if
(destlen
< len
+ (encoding-
>num_entries
) * 2)
2736 normal_error
("cff","buffer overflow");
2737 for
(i
= 0; i
< (encoding-
>num_entries
); i
++) {
2738 dest
[len
++] = (card8
) ((encoding-
>data
).range1
[i
].first
& 0xff);
2739 dest
[len
++] = (card8
) ((encoding-
>data
).range1
[i
].n_left
);
2744 normal_error
("cff","unknown encoding format");
2748 if
((encoding-
>format
) & 0x80) {
2749 if
(destlen
< len
+ (encoding-
>num_supps
) * 3 + 1)
2750 normal_error
("cff","buffer overflow");
2751 dest
[len
++] = encoding-
>num_supps
;
2752 for
(i
= 0; i
< (encoding-
>num_supps
); i
++) {
2753 dest
[len
++] = (card8
) ((encoding-
>supp
)[i
].code
);
2754 dest
[len
++] = (card8
) (((encoding-
>supp
)[i
].glyph
>> 8) & 0xff);
2755 dest
[len
++] = (card8
) ((encoding-
>supp
)[i
].glyph
& 0xff);
2762 @ CID-Keyed font specific
2764 long cff_read_fdselect
(cff_font
* cff
)
2766 cff_fdselect
*fdsel
;
2767 long offset
, length
;
2770 if
(cff-
>topdict
== NULL)
2771 normal_error
("cff","top DICT not available");
2773 if
(!(cff-
>flag
& FONTTYPE_CIDFONT))
2776 offset
= (long
) cff_dict_get
(cff-
>topdict
, "FDSelect", 0);
2777 cff-
>offset
= (l_offset
) offset
;
2778 cff-
>fdselect
= fdsel
= xcalloc
(1, sizeof
(cff_fdselect
));
2779 fdsel-
>format
= get_card8
(cff
);
2783 switch
(fdsel-
>format
) {
2785 fdsel-
>num_entries
= cff-
>num_glyphs
;
2786 (fdsel-
>data
).fds
= xmalloc
(fdsel-
>num_entries
* sizeof
(card8
));
2787 for
(i
= 0; i
< (fdsel-
>num_entries
); i
++) {
2788 (fdsel-
>data
).fds
[i
] = get_card8
(cff
);
2790 length
+= fdsel-
>num_entries
;
2795 fdsel-
>num_entries
= get_card16
(cff
);
2796 fdsel-
>data.ranges
= ranges
=
2797 xcalloc
(fdsel-
>num_entries
, sizeof
(cff_range3
));
2798 for
(i
= 0; i
< (fdsel-
>num_entries
); i
++) {
2799 ranges
[i
].first
= get_card16
(cff
);
2800 ranges
[i
].fd
= get_card8
(cff
);
2802 if
(ranges
[0].first
!= 0)
2803 normal_error
("cff","range not starting with 0");
2804 if
(cff-
>num_glyphs
!= get_card16
(cff
))
2805 normal_error
("cff","sentinel value mismatched with number of glyphs");
2806 length
+= (fdsel-
>num_entries
) * 3 + 4;
2811 normal_error
("cff","unknown FDSelect format");
2820 long cff_pack_fdselect
(cff_font
* cff
, card8
* dest
, long destlen
)
2822 cff_fdselect
*fdsel
;
2826 if
(cff-
>fdselect
== NULL)
2830 normal_error
("cff","buffer overflow");
2832 fdsel
= cff-
>fdselect
;
2834 dest
[len
++] = fdsel-
>format
;
2835 switch
(fdsel-
>format
) {
2837 if
(fdsel-
>num_entries
!= cff-
>num_glyphs
)
2838 normal_error
("cff","invalid data");
2839 if
(destlen
< len
+ fdsel-
>num_entries
)
2840 normal_error
("cff","buffer overflow");
2841 for
(i
= 0; i
< fdsel-
>num_entries
; i
++) {
2842 dest
[len
++] = (fdsel-
>data
).fds
[i
];
2847 if
(destlen
< len
+ 2)
2848 normal_error
("cff","buffer overflow");
2850 for
(i
= 0; i
< (fdsel-
>num_entries
); i
++) {
2851 if
(destlen
< len
+ 3)
2852 normal_error
("cff","buffer overflow");
2854 (card8
) (((fdsel-
>data
).ranges
[i
].first
>> 8) & 0xff);
2855 dest
[len
++] = (card8
) ((fdsel-
>data
).ranges
[i
].first
& 0xff);
2856 dest
[len
++] = (card8
) ((fdsel-
>data
).ranges
[i
].fd
);
2858 if
(destlen
< len
+ 2)
2859 normal_error
("cff","buffer overflow");
2860 dest
[len
++] = (card8
) ((cff-
>num_glyphs
>> 8) & 0xff);
2861 dest
[len
++] = (card8
) (cff-
>num_glyphs
& 0xff);
2862 dest
[1] = (card8
) (((len
/ 3 - 1) >> 8) & 0xff);
2863 dest
[2] = (card8
) ((len
/ 3 - 1) & 0xff);
2867 normal_error
("cff","unknown FDSelect format");
2876 @ Create an instance of embeddable font.
2879 static void write_fontfile
(PDF pdf
, cff_font
* cffont
, char
*fullname
)
2881 cff_index
*topdict
, *fdarray
, *private
;
2882 unsigned char
*dest
;
2883 long destlen
= 0, i
, size
;
2884 long offset
, topdict_offset
, fdarray_offset
;
2886 /* DICT sizes
(offset set to long int
) */
2887 topdict
= cff_new_index
(1);
2888 fdarray
= cff_new_index
(cffont-
>num_fds
);
2889 private
= cff_new_index
(cffont-
>num_fds
);
2891 cff_dict_remove
(cffont-
>topdict
, "UniqueID");
2892 cff_dict_remove
(cffont-
>topdict
, "XUID");
2893 cff_dict_remove
(cffont-
>topdict
, "Private"); /* some bad font may have
*/
2894 cff_dict_remove
(cffont-
>topdict
, "Encoding"); /* some bad font may have
*/
2896 topdict-
>offset
[1] = (l_offset
) cff_dict_pack
(cffont-
>topdict
,
2897 (card8
*) work_buffer
,
2898 WORK_BUFFER_SIZE
) + 1;
2899 for
(i
= 0; i
< cffont-
>num_fds
; i
++) {
2901 if
(cffont-
>private
&& cffont->private[i]) {
2902 size
= cff_dict_pack
(cffont-
>private
[i
],
2903 (card8
*) work_buffer
, WORK_BUFFER_SIZE
);
2904 if
(size
< 1) { /* Private had contained only Subr
*/
2905 cff_dict_remove
(cffont-
>fdarray
[i
], "Private");
2908 (private-
>offset
)[i
+ 1] =
2909 (unsigned long
) ((private-
>offset
)[i
] + (unsigned
) size
);
2910 (fdarray-
>offset
)[i
+ 1] =
2911 (unsigned long
) ((fdarray-
>offset
)[i
] + (unsigned
)
2912 cff_dict_pack
(cffont-
>fdarray
[i
],
2913 (card8
*) work_buffer
,
2917 destlen
= 4; /* header size
*/
2918 destlen
+= cff_set_name
(cffont
, fullname
);
2919 destlen
+= cff_index_size
(topdict
);
2920 destlen
+= cff_index_size
(cffont-
>string
);
2921 destlen
+= cff_index_size
(cffont-
>gsubr
);
2922 destlen
+= (cffont-
>charsets-
>num_entries
) * 2 + 1; /* charset format
0 */
2923 destlen
+= (cffont-
>fdselect-
>num_entries
) * 3 + 5; /* fdselect format
3 */
2924 destlen
+= cff_index_size
(cffont-
>cstrings
);
2925 destlen
+= cff_index_size
(fdarray
);
2926 destlen
= (long
) (destlen
+ (long
) private-
>offset
[private-
>count
] - 1); /* Private is not
INDEX */
2928 dest
= xcalloc
((unsigned
) destlen
, sizeof
(card8
));
2932 offset
+= cff_put_header
(cffont
, dest
+ offset
, destlen
- offset
);
2934 offset
+= cff_pack_index
(cffont-
>name
, dest
+ offset
, destlen
- offset
);
2936 topdict_offset
= offset
;
2937 offset
+= cff_index_size
(topdict
);
2939 offset
+= cff_pack_index
(cffont-
>string
, dest
+ offset
, destlen
- offset
);
2941 offset
+= cff_pack_index
(cffont-
>gsubr
, dest
+ offset
, destlen
- offset
);
2944 cff_dict_set
(cffont-
>topdict
, "charset", 0, (double
) offset
);
2945 offset
+= cff_pack_charsets
(cffont
, dest
+ offset
, destlen
- offset
);
2948 cff_dict_set
(cffont-
>topdict
, "FDSelect", 0, (double
) offset
);
2949 offset
+= cff_pack_fdselect
(cffont
, dest
+ offset
, destlen
- offset
);
2952 cff_dict_set
(cffont-
>topdict
, "CharStrings", 0, (double
) offset
);
2953 offset
+= cff_pack_index
(cffont-
>cstrings
,
2954 dest
+ offset
, cff_index_size
(cffont-
>cstrings
));
2955 cff_release_index
(cffont-
>cstrings
);
2956 cffont-
>cstrings
= NULL; /* Charstrings cosumes huge memory
*/
2958 /* FDArray and Private
*/
2959 cff_dict_set
(cffont-
>topdict
, "FDArray", 0, (double
) offset
);
2960 fdarray_offset
= offset
;
2961 offset
+= cff_index_size
(fdarray
);
2964 xcalloc
((unsigned
) (fdarray-
>offset
[fdarray-
>count
] - 1),
2966 for
(i
= 0; i
< cffont-
>num_fds
; i
++) {
2967 size
= (long
) (private-
>offset
[i
+ 1] - private-
>offset
[i
]);
2968 if
(cffont-
>private
[i
] && size > 0) {
2969 cff_dict_pack
(cffont-
>private
[i
], dest
+ offset
, size
);
2970 cff_dict_set
(cffont-
>fdarray
[i
], "Private", 0, (double
) size
);
2971 cff_dict_set
(cffont-
>fdarray
[i
], "Private", 1, (double
) offset
);
2973 cff_dict_pack
(cffont-
>fdarray
[i
],
2974 fdarray-
>data
+ (fdarray-
>offset
)[i
] - 1,
2975 (long
) (fdarray-
>offset
[fdarray-
>count
] - 1));
2979 cff_pack_index
(fdarray
, dest
+ fdarray_offset
, cff_index_size
(fdarray
));
2980 cff_release_index
(fdarray
);
2981 cff_release_index
(private
);
2983 /* Finally Top
DICT */
2985 xcalloc
((unsigned
) (topdict-
>offset
[topdict-
>count
] - 1),
2987 cff_dict_pack
(cffont-
>topdict
, topdict-
>data
,
2988 (long
) (topdict-
>offset
[topdict-
>count
] - 1));
2989 cff_pack_index
(topdict
, dest
+ topdict_offset
, cff_index_size
(topdict
));
2990 cff_release_index
(topdict
);
2992 for
(i
= 0; i
< offset
; i
++)
2993 strbuf_putchar
(pdf-
>fb
, dest
[i
]);
3000 @ this block is used a few times
3002 #define DO_COPY_CHARSTRING
() \
3003 if
((avl_find
(fd-
>gl_tree
,glyph
) != NULL)) { \
3004 size
= (long
)(cs_idx-
>offset
[code
+1] - cs_idx-
>offset
[code
]); \
3005 if
(size
> CS_STR_LEN_MAX
) { \
3006 formatted_error
("cff","charstring too long: gid=%u, %ld bytes", code
, size
); \
3008 if
(charstring_len
+ CS_STR_LEN_MAX
>= max_len
) { \
3009 max_len
= (long
)(charstring_len
+ 2 * CS_STR_LEN_MAX
); \
3010 charstrings-
>data
= xrealloc
(charstrings-
>data
, (unsigned
)((unsigned
)max_len
*sizeof
(card8
))); \
3012 (charstrings-
>offset
)[gid
] = (unsigned
)(charstring_len
+ 1); \
3013 cffont-
>offset
= (l_offset
)((unsigned
)offset
+ (cs_idx-
>offset
)[code
] - 1); \
3014 memcpy
(data
,&cffont->stream[cffont->offset],(size_t)size); \
3015 charstring_len
+= cs_copy_charstring
(charstrings-
>data
+ charstring_len
, \
3016 max_len
- charstring_len
, \
3018 cffont-
>gsubr
, (cffont-
>subrs
)[0], \
3019 default_width
, nominal_width
, NULL); \
3024 void write_cff
(PDF pdf
, cff_font
* cffont
, fd_entry
* fd
)
3026 cff_index
*charstrings
, *cs_idx
;
3028 long charstring_len
, max_len
;
3029 long size
, offset
= 0;
3032 card16 num_glyphs
, cs_count1
, code
, gid
, last_cid
;
3034 double nominal_width
, default_width
;
3038 glw_entry
*glyph
, *found
;
3039 struct avl_traverser t
;
3041 fullname
= xcalloc
((unsigned
) (8 + strlen
(fd-
>fontname
)), 1);
3042 sprintf
(fullname
, "%s+%s", fd-
>subset_tag
, fd-
>fontname
);
3044 /* finish parsing the CFF
*/
3045 cff_read_private
(cffont
);
3046 cff_read_subrs
(cffont
);
3051 if
(cffont-
>private
[0] &&
3052 cff_dict_known
(cffont-
>private
[0], "defaultWidthX")) {
3054 (double
) cff_dict_get
(cffont-
>private
[0], "defaultWidthX", 0);
3056 default_width
= CFF_DEFAULTWIDTHX_DEFAULT
;
3058 if
(cffont-
>private
[0] &&
3059 cff_dict_known
(cffont-
>private
[0], "nominalWidthX")) {
3061 (double
) cff_dict_get
(cffont-
>private
[0], "nominalWidthX", 0);
3063 nominal_width
= CFF_NOMINALWIDTHX_DEFAULT
;
3068 glyph
= xtalloc
(1, glw_entry
);
3072 if
(avl_find
(fd-
>gl_tree
, glyph
) == NULL) {
3073 avl_insert
(fd-
>gl_tree
, glyph
);
3074 glyph
= xtalloc
(1, glw_entry
);
3077 avl_t_init
(&t, fd->gl_tree);
3078 for
(found
= (glw_entry
*) avl_t_first
(&t, fd->gl_tree);
3079 found
!= NULL; found
= (glw_entry
*) avl_t_next
(&t)) {
3080 if
(found-
>id
> last_cid
)
3081 last_cid
= (card16
) found-
>id
;
3086 cff_fdselect
*fdselect
;
3088 fdselect
= xcalloc
(1, sizeof
(cff_fdselect
));
3089 fdselect-
>format
= 3;
3090 fdselect-
>num_entries
= 1;
3091 fdselect-
>data.ranges
= xcalloc
(1, sizeof
(cff_range3
));
3092 fdselect-
>data.ranges
[0].first
= 0;
3093 fdselect-
>data.ranges
[0].fd
= 0;
3094 cffont-
>fdselect
= fdselect
;
3098 cff_charsets
*charset
;
3100 charset
= xcalloc
(1, sizeof
(cff_charsets
));
3101 charset-
>format
= 0;
3102 charset-
>num_entries
= (card16
) (num_glyphs
- 1);
3103 charset-
>data.glyphs
= xcalloc
(num_glyphs
, sizeof
(s_SID
));
3107 avl_t_init
(&t, fd->gl_tree);
3108 for
(found
= (glw_entry
*) avl_t_first
(&t, fd->gl_tree);
3109 found
!= NULL; found
= (glw_entry
*) avl_t_next
(&t)) {
3110 if
(found-
>id
!= 0) {
3111 charset-
>data.glyphs
[gid
] = (s_SID
) found-
>id
;
3115 cffont-
>charsets
= charset
;
3118 cff_dict_add
(cffont-
>topdict
, "CIDCount", 1);
3119 cff_dict_set
(cffont-
>topdict
, "CIDCount", 0, last_cid
+ 1);
3121 cffont-
>fdarray
= xcalloc
(1, sizeof
(cff_dict
*));
3122 cffont-
>fdarray
[0] = cff_new_dict
();
3123 cff_dict_add
(cffont-
>fdarray
[0], "FontName", 1);
3124 cff_dict_set
(cffont-
>fdarray
[0], "FontName", 0, (double
) cff_add_string
(cffont
, fullname
)); /* FIXME
: Skip XXXXXX
+ */
3125 cff_dict_add
(cffont-
>fdarray
[0], "Private", 2);
3126 cff_dict_set
(cffont-
>fdarray
[0], "Private", 0, 0.0);
3127 cff_dict_set
(cffont-
>fdarray
[0], "Private", 0, 0.0);
3128 /* FDArray
- index offset
, not known yet
*/
3129 cff_dict_add
(cffont-
>topdict
, "FDArray", 1);
3130 cff_dict_set
(cffont-
>topdict
, "FDArray", 0, 0.0);
3131 /* FDSelect
- offset
, not known yet
*/
3132 cff_dict_add
(cffont-
>topdict
, "FDSelect", 1);
3133 cff_dict_set
(cffont-
>topdict
, "FDSelect", 0, 0.0);
3135 cff_dict_remove
(cffont-
>topdict
, "UniqueID");
3136 cff_dict_remove
(cffont-
>topdict
, "XUID");
3137 cff_dict_remove
(cffont-
>topdict
, "Private");
3138 cff_dict_remove
(cffont-
>topdict
, "Encoding");
3140 cffont-
>offset
= (l_offset
) cff_dict_get
(cffont-
>topdict
, "CharStrings", 0);
3141 cs_idx
= cff_get_index_header
(cffont
);
3143 offset
= (long
) cffont-
>offset
;
3144 cs_count1
= cs_idx-
>count
;
3145 if
(cs_count1
< 2) {
3146 normal_error
("cff","no valid charstring data found");
3149 /* build the new charstrings entry
*/
3150 charstrings
= cff_new_index
((card16
) (cs_count1
==USHRT_MAX?cs_count1
: cs_count1
+ 1));
3151 max_len
= 2 * CS_STR_LEN_MAX
;
3152 charstrings-
>data
= xcalloc
((unsigned
) max_len
, sizeof
(card8
));
3156 data
= xcalloc
(CS_STR_LEN_MAX
, sizeof
(card8
));
3160 for
(i
= 0; i
< cs_count1
; i
++) {
3163 DO_COPY_CHARSTRING
();
3167 /* CIDSet
: a table of bits indexed by cid
, bytes with high order bit first
,
3168 each
(set
) bit is a
(present
) CID.
*/
3171 cidset
= pdf_create_obj
(pdf
, obj_type_others
, 0);
3173 size_t l
= (last_cid
/8)+1;
3174 char
*stream
= xmalloc
(l
);
3175 memset
(stream
, 0, l
);
3176 for
(cid
= 1; cid
<= (long
) last_cid
; cid
++) {
3178 if
(avl_find
(fd-
>gl_tree
,glyph
) != NULL) {
3179 stream
[(cid
/ 8)] |
= (1 << (7 - (cid
% 8)));
3182 pdf_begin_obj
(pdf
, cidset
, OBJSTM_NEVER
);
3183 pdf_begin_dict
(pdf
);
3184 pdf_dict_add_streaminfo
(pdf
);
3186 pdf_begin_stream
(pdf
);
3187 pdf_out_block
(pdf
, stream
, l
);
3188 pdf_end_stream
(pdf
);
3193 /* this happens if the internal metrics do not agree with the actual disk font
*/
3194 if
(gid
< num_glyphs
) {
3195 formatted_warning
("cff","embedded subset is smaller than expected: %d instead of %d glyphs", gid
, num_glyphs
);
3200 cff_release_index
(cs_idx
);
3202 (charstrings-
>offset
)[num_glyphs
] = (l_offset
) (charstring_len
+ 1);
3203 charstrings-
>count
= num_glyphs
;
3204 cffont-
>num_glyphs
= num_glyphs
;
3205 cffont-
>cstrings
= charstrings
;
3208 We don't use subroutines at all.
3211 cff_release_index
(cffont-
>gsubr
);
3212 cffont-
>gsubr
= cff_new_index
(0);
3214 if
(cffont-
>subrs
&& cffont->subrs[0])
3215 cff_release_index
(cffont-
>subrs
[0]);
3216 cffont-
>subrs
[0] = NULL;
3218 if
(cffont-
>private
&& (cffont->private)[0]) {
3219 cff_dict_remove
((cffont-
>private
)[0], "Subrs"); /* no Subrs
*/
3222 cff_add_string
(cffont
, "Adobe");
3223 cff_add_string
(cffont
, "Identity");
3225 cff_dict_update
(cffont-
>topdict
, cffont
);
3226 cff_dict_update
(cffont-
>private
[0], cffont
);
3227 cff_update_string
(cffont
);
3229 /* CFF code need to be rewrote...
*/
3230 cff_dict_add
(cffont-
>topdict
, "ROS", 3);
3231 cff_dict_set
(cffont-
>topdict
, "ROS", 0,
3232 (double
) cff_get_sid
(cffont
, "Adobe"));
3233 cff_dict_set
(cffont-
>topdict
, "ROS", 1,
3234 (double
) cff_get_sid
(cffont
, "Identity"));
3235 cff_dict_set
(cffont-
>topdict
, "ROS", 2, 0.0);
3237 write_fontfile
(pdf
, cffont
, fullname
);
3244 #undef
ERROR /* for mingw
*/
3245 #define
ERROR(a
) { perror
(a
); return
0; }
3247 @ Input
: SID or CID
(16-bit unsigned int
)
3251 card16 cff_charsets_lookup
(cff_font
* cff
, card16 cid
)
3254 cff_charsets
*charset
;
3257 if
(cff-
>flag
& (CHARSETS_ISOADOBE | CHARSETS_EXPERT | CHARSETS_EXPSUB)) {
3258 ERROR("Predefined CFF charsets not supported yet");
3259 } else if
(cff-
>charsets
== NULL) {
3260 normal_error
("cff","charsets data not available");
3264 return
0; /* GID
0 (.notdef
) */
3267 charset
= cff-
>charsets
;
3270 switch
(charset-
>format
) {
3272 for
(i
= 0; i
< charset-
>num_entries
; i
++) {
3273 if
(cid
== charset-
>data.glyphs
[i
]) {
3274 gid
= (card16
) (i
+ 1);
3280 for
(i
= 0; i
< charset-
>num_entries
; i
++) {
3281 if
(cid
>= charset-
>data.range1
[i
].first
&&
3283 charset-
>data.range1
[i
].first
+
3284 charset-
>data.range1
[i
].n_left
) {
3285 gid
= (card16
) (gid
+ cid
- charset-
>data.range1
[i
].first
+ 1);
3288 gid
= (card16
) (gid
+ charset-
>data.range1
[i
].n_left
+ 1);
3292 for
(i
= 0; i
< charset-
>num_entries
; i
++) {
3293 if
(cid
>= charset-
>data.range2
[i
].first
&&
3295 charset-
>data.range2
[i
].first
+
3296 charset-
>data.range2
[i
].n_left
) {
3297 gid
= (card16
) (gid
+ cid
- charset-
>data.range2
[i
].first
+ 1);
3300 gid
= (card16
) (gid
+ charset-
>data.range2
[i
].n_left
+ 1);
3304 normal_error
("cff","unknown charset format");
3307 return
0; /* not found
*/
3312 #define is_cidfont
(a
) ((a
)->flag
& FONTTYPE_CIDFONT)
3313 #define CID_MAX
65535
3314 void write_cid_cff
(PDF pdf
, cff_font
* cffont
, fd_entry
* fd
)
3316 cff_index
*charstrings
, *cs_idx
;
3318 long charstring_len
, max_len
;
3319 long size
, offset
= 0;
3322 card16 num_glyphs
, cs_count1
, gid
, last_cid
;
3325 int fdsel
, prev_fd
, cid_count
, cid
;
3330 unsigned char
*CIDToGIDMap
= NULL;
3332 cff_fdselect
*fdselect
= NULL;
3333 cff_charsets
*charset
= NULL;
3336 if
(!is_cidfont
(cffont
)) {
3337 perror
("Not a CIDfont.");
3341 fullname
= xcalloc
((unsigned
) (8 + strlen
(fd-
>fontname
)), 1);
3342 sprintf
(fullname
, "%s+%s", fd-
>subset_tag
, fd-
>fontname
);
3344 /* finish parsing the CFF
*/
3346 if
(cff_dict_known
(cffont-
>topdict
, "CIDCount")) {
3347 cid_count
= (card16
) cff_dict_get
(cffont-
>topdict
, "CIDCount", 0);
3349 cid_count
= CFF_CIDCOUNT_DEFAULT
;
3351 cff_read_charsets
(cffont
);
3352 CIDToGIDMap
= xmalloc
((unsigned
)
3353 ((2 * (unsigned
) cid_count
) * sizeof
(unsigned char
)));
3354 memset
(CIDToGIDMap
, 0, (size_t
) (2 * cid_count
));
3357 glyph
= xtalloc
(1, glw_entry
);
3360 if
(avl_find
(fd-
>gl_tree
, glyph
) == NULL) {
3361 avl_insert
(fd-
>gl_tree
, glyph
);
3362 glyph
= xtalloc
(1, glw_entry
);
3367 for
(cid
= 0; cid
<= CID_MAX
; cid
++) {
3368 glyph-
>id
= (unsigned
) cid
;
3369 if
(avl_find
(fd-
>gl_tree
, glyph
) != NULL) {
3370 gid
= (card16
) cff_charsets_lookup
(cffont
, (card16
) cid
);
3371 CIDToGIDMap
[2 * cid
] = (unsigned char
) ((gid
>> 8) & 0xff);
3372 CIDToGIDMap
[2 * cid
+ 1] = (unsigned char
) (gid
& 0xff);
3373 last_cid
= (card16
) cid
;
3377 if
(last_cid
>= cffont-
>num_glyphs
) {
3378 formatted_error
("cff font","bad glyph index %i",last_cid
);
3381 /* CIDSet
: a table of bits indexed by cid
, bytes with high order bit first
,
3382 each
(set
) bit is a
(present
) CID.
*/
3384 cidset
= pdf_create_obj
(pdf
, obj_type_others
, 0);
3386 size_t l
= (last_cid
/ 8) + 1;
3387 char
*stream
= xmalloc
(l
);
3388 memset
(stream
, 0, l
);
3389 for
(cid
= 1; cid
<= (long
) last_cid
; cid
++) {
3390 if
(CIDToGIDMap
[2 * cid
] || CIDToGIDMap
[2 * cid
+ 1]) {
3391 stream
[(cid
/ 8)] |
= (1 << (7 - (cid
% 8)));
3394 pdf_begin_obj
(pdf
, cidset
, OBJSTM_NEVER
);
3395 pdf_begin_dict
(pdf
);
3396 pdf_dict_add_streaminfo
(pdf
);
3398 pdf_begin_stream
(pdf
);
3399 pdf_out_block
(pdf
, stream
, l
);
3400 pdf_end_stream
(pdf
);
3407 cff_read_fdselect
(cffont
);
3408 cff_read_fdarray
(cffont
);
3409 cff_read_private
(cffont
);
3411 cff_read_subrs
(cffont
);
3414 cffont-
>offset
= (l_offset
) cff_dict_get
(cffont-
>topdict
, "CharStrings", 0);
3415 cs_idx
= cff_get_index_header
(cffont
);
3417 offset
= (long
) cffont-
>offset
;
3418 cs_count1
= cs_idx-
>count
;
3419 if
(cs_count1
< 2) {
3420 normal_error
("cff","no valid charstring data found");
3423 charset
= xcalloc
(1, sizeof
(cff_charsets
));
3424 charset-
>format
= 0;
3425 charset-
>num_entries
= 0;
3426 charset-
>data.glyphs
= xcalloc
(num_glyphs
, sizeof
(s_SID
));
3428 fdselect
= xcalloc
(1, sizeof
(cff_fdselect
));
3429 fdselect-
>format
= 3;
3430 fdselect-
>num_entries
= 0;
3431 fdselect-
>data.ranges
= xcalloc
(num_glyphs
, sizeof
(cff_range3
));
3433 charstrings
= cff_new_index
((card16
) (cs_count1
==USHRT_MAX?cs_count1
: cs_count1
+ 1));
3434 max_len
= 2 * CS_STR_LEN_MAX
;
3435 charstrings-
>data
= xcalloc
((unsigned
) max_len
, sizeof
(card8
));
3440 data
= xcalloc
(CS_STR_LEN_MAX
, sizeof
(card8
));
3441 for
(cid
= 0; cid
<= last_cid
; cid
++) {
3442 unsigned short gid_org
;
3444 glyph-
>id
= (unsigned
) cid
;
3445 if
(avl_find
(fd-
>gl_tree
, glyph
) == NULL)
3449 (short unsigned
) ((CIDToGIDMap
[2 * cid
] << 8) |
3450 (CIDToGIDMap
[2 * cid
+ 1]));
3451 size
= (long
) (cs_idx-
>offset
[gid_org
+ 1] - cs_idx-
>offset
[gid_org
]);
3452 if
(size
> CS_STR_LEN_MAX
) {
3453 formatted_error
("cff","charstring too long: gid=%u, %ld bytes", cid
, size
);
3455 if
(charstring_len
+ CS_STR_LEN_MAX
>= max_len
) {
3456 max_len
= charstring_len
+ 2 * CS_STR_LEN_MAX
;
3458 xrealloc
(charstrings-
>data
,
3459 (unsigned
) ((unsigned
) max_len
* sizeof
(card8
)));
3461 (charstrings-
>offset
)[gid
] = (l_offset
) (charstring_len
+ 1);
3463 (l_offset
) ((unsigned
) offset
+ (cs_idx-
>offset
)[gid_org
] - 1);
3464 memcpy
(data
, &cffont->stream[cffont->offset], (size_t) size);
3465 fdsel
= cff_fdselect_lookup
(cffont
, gid_org
);
3466 charstring_len
+= cs_copy_charstring
(charstrings-
>data
+ charstring_len
,
3467 max_len
- charstring_len
,
3470 (cffont-
>subrs
)[fdsel
], 0, 0,
3473 if
(cid
> 0 && gid_org > 0) {
3474 charset-
>data.glyphs
[charset-
>num_entries
] = (s_SID
) cid
;
3475 charset-
>num_entries
++;
3477 if
(fdsel
!= prev_fd
) {
3478 fdselect-
>data.ranges
[fdselect-
>num_entries
].first
= gid
;
3479 fdselect-
>data.ranges
[fdselect-
>num_entries
].fd
= (card8
) fdsel
;
3480 fdselect-
>num_entries
++;
3486 if
(gid
!= num_glyphs
)
3487 formatted_error
("cff","unexpected error: %i != %i", gid
, num_glyphs
);
3489 cff_release_index
(cs_idx
);
3493 (charstrings-
>offset
)[num_glyphs
] = (l_offset
) (charstring_len
+ 1);
3494 charstrings-
>count
= num_glyphs
;
3495 cffont-
>num_glyphs
= num_glyphs
;
3496 cffont-
>cstrings
= charstrings
;
3498 cff_release_charsets
(cffont-
>charsets
);
3499 cffont-
>charsets
= charset
;
3500 cff_release_fdselect
(cffont-
>fdselect
);
3501 cffont-
>fdselect
= fdselect
;
3504 * We don't use subroutines at all.
3507 cff_release_index
(cffont-
>gsubr
);
3508 cffont-
>gsubr
= cff_new_index
(0);
3510 for
(fdsel
= 0; fdsel
< cffont-
>num_fds
; fdsel
++) {
3511 if
(cffont-
>subrs
&& cffont->subrs[fdsel]) {
3512 cff_release_index
(cffont-
>subrs
[fdsel
]);
3513 cffont-
>subrs
[fdsel
] = NULL;
3515 if
(cffont-
>private
&& (cffont->private)[fdsel]) {
3516 cff_dict_remove
((cffont-
>private
)[fdsel
], "Subrs"); /* no Subrs
*/
3520 write_fontfile
(pdf
, cffont
, fullname
);
3526 @ here is a sneaky trick
: fontforge knows how to convert Type1 to CFF
, so
3527 I have defined a utility function in luafflib.c that does exactly that.
3528 If it works out ok
, I will clean up this code.
3531 void writetype1w
(PDF pdf
, fd_entry
* fd
)
3537 unsigned char
*tfm_buffer
= NULL;
3540 ff
= check_ff_exist
(fd-
>fm-
>ff_name
, 0);
3542 fp
= fopen
(ff-
>ff_path
, "rb");
3543 cur_file_name
= ff-
>ff_path
;
3546 fprintf
(stderr
, "Type1: Could not open Type1 font: %s", cur_file_name
);
3551 if
(is_subsetted
(fd-
>fm
)) {
3552 report_start_file
(filetype_subset
,cur_file_name
);
3554 report_start_file
(filetype_font
,cur_file_name
);
3556 (void
) ff_createcff
(ff-
>ff_path
, &tfm_buffer, &tfm_size);
3559 cff
= read_cff
(tfm_buffer
, tfm_size
, 0);
3561 write_cff
(pdf
, cff
, fd
);
3563 for
(i
= 0; i
< tfm_size
; i
++)
3564 strbuf_putchar
(pdf-
>fb
, tfm_buffer
[i
]);
3568 fprintf
(stderr
, "Type1: Could not understand Type1 font: %s",
3572 if
(is_subsetted
(fd-
>fm
)) {
3573 report_stop_file
(filetype_subset
);
3575 report_stop_file
(filetype_font
);
3577 cur_file_name
= NULL;