1 //========================================================================
5 // Copyright 1999-2003 Glyph & Cog, LLC
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2005, 2008, 2010 Albert Astals Cid <aacid@kde.org>
17 // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
18 // Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
19 // Copyright (C) 2014 Carlos Garcia Campos <carlosgc@gnome.org>
21 // To see a description of the changes please see the Changelog file that
22 // came with your tarball or type make ChangeLog if you are building from git
24 //========================================================================
28 #ifdef USE_GCC_PRAGMAS
29 #pragma implementation
35 #include "goo/GooLikely.h"
36 #include "FoFiEncodings.h"
37 #include "FoFiType1.h"
38 #include "poppler/Error.h"
40 //------------------------------------------------------------------------
42 //------------------------------------------------------------------------
44 FoFiType1
*FoFiType1::make(char *fileA
, int lenA
) {
45 return new FoFiType1(fileA
, lenA
, gFalse
);
48 FoFiType1
*FoFiType1::load(char *fileName
) {
52 if (!(fileA
= FoFiBase::readFile(fileName
, &lenA
))) {
55 return new FoFiType1(fileA
, lenA
, gTrue
);
58 FoFiType1::FoFiType1(char *fileA
, int lenA
, GBool freeFileDataA
):
59 FoFiBase(fileA
, lenA
, freeFileDataA
)
63 fontMatrix
[0] = 0.001;
66 fontMatrix
[3] = 0.001;
73 FoFiType1::~FoFiType1() {
79 if (encoding
&& encoding
!= fofiType1StandardEncoding
) {
80 for (i
= 0; i
< 256; ++i
) {
87 char *FoFiType1::getName() {
94 char **FoFiType1::getEncoding() {
101 void FoFiType1::getFontMatrix(double *mat
) {
107 for (i
= 0; i
< 6; ++i
) {
108 mat
[i
] = fontMatrix
[i
];
112 void FoFiType1::writeEncoded(const char **newEncoding
,
113 FoFiOutputFunc outputFunc
, void *outputStream
) {
115 char *line
, *line2
, *p
;
118 // copy everything up to the encoding
119 for (line
= (char *)file
;
120 line
&& strncmp(line
, "/Encoding", 9);
121 line
= getNextLine(line
)) ;
123 // no encoding - just copy the whole font file
124 (*outputFunc
)(outputStream
, (char *)file
, len
);
127 (*outputFunc
)(outputStream
, (char *)file
, line
- (char *)file
);
129 // write the new encoding
130 (*outputFunc
)(outputStream
, "/Encoding 256 array\n", 20);
131 (*outputFunc
)(outputStream
,
132 "0 1 255 {1 index exch /.notdef put} for\n", 40);
133 for (i
= 0; i
< 256; ++i
) {
134 if (newEncoding
[i
]) {
135 sprintf(buf
, "dup %d /%s put\n", i
, newEncoding
[i
]);
136 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
139 (*outputFunc
)(outputStream
, "readonly def\n", 13);
141 // find the end of the encoding data
142 //~ this ought to parse PostScript tokens
143 if (!strncmp(line
, "/Encoding StandardEncoding def", 30)) {
144 line
= getNextLine(line
);
146 // skip "/Encoding" + one whitespace char,
147 // then look for 'def' preceded by PostScript whitespace
150 for (; p
< (char *)file
+ len
; ++p
) {
151 if ((*p
== ' ' || *p
== '\t' || *p
== '\x0a' ||
152 *p
== '\x0d' || *p
== '\x0c' || *p
== '\0') &&
153 p
+ 4 <= (char *)file
+ len
&&
154 !strncmp(p
+ 1, "def", 3)) {
161 // some fonts have two /Encoding entries in their dictionary, so we
162 // check for a second one here
164 for (line2
= line
, i
= 0;
165 i
< 20 && line2
&& strncmp(line2
, "/Encoding", 9);
166 line2
= getNextLine(line2
), ++i
) ;
167 if (i
< 20 && line2
) {
168 (*outputFunc
)(outputStream
, line
, line2
- line
);
169 if (!strncmp(line2
, "/Encoding StandardEncoding def", 30)) {
170 line
= getNextLine(line2
);
172 // skip "/Encoding" + one whitespace char,
173 // then look for 'def' preceded by PostScript whitespace
176 for (; p
< (char *)file
+ len
; ++p
) {
177 if ((*p
== ' ' || *p
== '\t' || *p
== '\x0a' ||
178 *p
== '\x0d' || *p
== '\x0c' || *p
== '\0') &&
179 p
+ 4 <= (char *)file
+ len
&&
180 !strncmp(p
+ 1, "def", 3)) {
188 // copy everything after the encoding
190 (*outputFunc
)(outputStream
, line
, ((char *)file
+ len
) - line
);
195 char *FoFiType1::getNextLine(char *line
) {
196 while (line
< (char *)file
+ len
&& *line
!= '\x0a' && *line
!= '\x0d') {
199 if (line
< (char *)file
+ len
&& *line
== '\x0d') {
202 if (line
< (char *)file
+ len
&& *line
== '\x0a') {
205 if (line
>= (char *)file
+ len
) {
211 void FoFiType1::parse() {
212 char *line
, *line1
, *p
, *p2
;
215 int n
, code
, base
, i
, j
;
220 for (i
= 1, line
= (char *)file
;
221 i
<= 100 && line
&& (!name
|| !encoding
);
225 if (!name
&& !strncmp(line
, "/FontName", 9)) {
226 strncpy(buf
, line
, 255);
228 if ((p
= strchr(buf
+9, '/')) &&
229 (p
= strtok_r(p
+1, " \t\n\r", &tokptr
))) {
230 name
= copyString(p
);
232 line
= getNextLine(line
);
235 } else if (!encoding
&&
236 !strncmp(line
, "/Encoding StandardEncoding def", 30)) {
237 encoding
= (char **)fofiType1StandardEncoding
;
238 } else if (!encoding
&&
239 !strncmp(line
, "/Encoding 256 array", 19)) {
240 encoding
= (char **)gmallocn(256, sizeof(char *));
241 for (j
= 0; j
< 256; ++j
) {
244 for (j
= 0, line
= getNextLine(line
);
245 j
< 300 && line
&& (line1
= getNextLine(line
));
247 if ((n
= (int)(line1
- line
)) > 255) {
248 error(errSyntaxWarning
, -1, "FoFiType1::parse a line has more than 255 characters, we don't support this");
251 strncpy(buf
, line
, n
);
253 for (p
= buf
; *p
== ' ' || *p
== '\t'; ++p
) ;
254 if (!strncmp(p
, "dup", 3)) {
257 for (; *p
== ' ' || *p
== '\t'; ++p
) ;
259 if (*p
== '8' && p
[1] == '#') {
262 } else if (*p
>= '0' && *p
<= '9') {
267 for (; *p
>= '0' && *p
< '0' + base
&& code
< INT_MAX
/ (base
+ (*p
- '0')); ++p
) {
268 code
= code
* base
+ (*p
- '0');
270 for (; *p
== ' ' || *p
== '\t'; ++p
) ;
275 for (p2
= p
; *p2
&& *p2
!= ' ' && *p2
!= '\t'; ++p2
) ;
276 if (code
>= 0 && code
< 256) {
279 encoding
[code
] = copyString(p
);
282 for (p
= p2
; *p
== ' ' || *p
== '\t'; ++p
) ;
283 if (strncmp(p
, "put", 3)) {
286 for (p
+= 3; *p
== ' ' || *p
== '\t'; ++p
) ;
287 if (strncmp(p
, "dup", 3)) {
292 if (strtok_r(buf
, " \t", &tokptr
) &&
293 (p
= strtok_r(NULL
, " \t\n\r", &tokptr
)) && !strcmp(p
, "def")) {
298 //~ check for getinterval/putinterval junk
300 } else if (!gotMatrix
&& !strncmp(line
, "/FontMatrix", 11)) {
301 strncpy(buf
, line
+ 11, 255);
303 if ((p
= strchr(buf
, '['))) {
305 if ((p2
= strchr(p
, ']'))) {
307 for (j
= 0; j
< 6; ++j
) {
308 if ((p
= strtok(j
== 0 ? p
: (char *)NULL
, " \t\n\r"))) {
309 fontMatrix
[j
] = atof(p
);
319 line
= getNextLine(line
);
326 // Undo the PFB encoding, i.e., remove the PFB headers.
327 void FoFiType1::undoPFB() {
330 int pos1
, pos2
, type
;
334 if (getU8(0, &ok
) != 0x80 || !ok
) {
337 file2
= (Guchar
*)gmalloc(len
);
339 while (getU8(pos1
, &ok
) == 0x80 && ok
) {
340 type
= getU8(pos1
+ 1, &ok
);
341 if (type
< 1 || type
> 2 || !ok
) {
344 segLen
= getU32LE(pos1
+ 2, &ok
);
346 if (!ok
|| !checkRegion(pos1
, segLen
)) {
349 memcpy(file2
+ pos2
, file
+ pos1
, segLen
);
356 file
= fileData
= file2
;
357 freeFileData
= gTrue
;