1 //========================================================================
5 // Copyright 1999-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
18 #include "FoFiEncodings.h"
19 #include "FoFiType1.h"
21 //------------------------------------------------------------------------
23 //------------------------------------------------------------------------
25 FoFiType1
*FoFiType1::make(char *fileA
, int lenA
) {
26 return new FoFiType1(fileA
, lenA
, gFalse
);
29 FoFiType1
*FoFiType1::load(char *fileName
) {
33 if (!(fileA
= FoFiBase::readFile(fileName
, &lenA
))) {
36 return new FoFiType1(fileA
, lenA
, gTrue
);
39 FoFiType1::FoFiType1(char *fileA
, int lenA
, GBool freeFileDataA
):
40 FoFiBase(fileA
, lenA
, freeFileDataA
)
47 FoFiType1::~FoFiType1() {
53 if (encoding
&& encoding
!= fofiType1StandardEncoding
) {
54 for (i
= 0; i
< 256; ++i
) {
55 gfree((void *)encoding
[i
]);
57 gfree((void *)encoding
);
61 char *FoFiType1::getName() {
68 char **FoFiType1::getEncoding() {
72 return (char**)encoding
;
75 void FoFiType1::writeEncoded(char **newEncoding
,
76 FoFiOutputFunc outputFunc
, void *outputStream
) {
78 char *line
, *line2
, *p
;
81 // copy everything up to the encoding
82 for (line
= (char *)file
;
83 line
&& strncmp(line
, "/Encoding", 9);
84 line
= getNextLine(line
)) ;
86 // no encoding - just copy the whole font file
87 (*outputFunc
)(outputStream
, (char *)file
, len
);
90 (*outputFunc
)(outputStream
, (char *)file
, line
- (char *)file
);
92 // write the new encoding
93 (*outputFunc
)(outputStream
, "/Encoding 256 array\n", 20);
94 (*outputFunc
)(outputStream
,
95 "0 1 255 {1 index exch /.notdef put} for\n", 40);
96 for (i
= 0; i
< 256; ++i
) {
98 sprintf(buf
, "dup %d /%s put\n", i
, newEncoding
[i
]);
99 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
102 (*outputFunc
)(outputStream
, "readonly def\n", 13);
104 // find the end of the encoding data
105 //~ this ought to parse PostScript tokens
106 if (!strncmp(line
, "/Encoding StandardEncoding def", 30)) {
107 line
= getNextLine(line
);
109 // skip "/Encoding" + one whitespace char,
110 // then look for 'def' preceded by PostScript whitespace
113 for (; p
< (char *)file
+ len
; ++p
) {
114 if ((*p
== ' ' || *p
== '\t' || *p
== '\x0a' ||
115 *p
== '\x0d' || *p
== '\x0c' || *p
== '\0') &&
116 p
+ 4 <= (char *)file
+ len
&&
117 !strncmp(p
+ 1, "def", 3)) {
124 // some fonts have two /Encoding entries in their dictionary, so we
125 // check for a second one here
127 for (line2
= line
, i
= 0;
128 i
< 20 && line2
&& strncmp(line2
, "/Encoding", 9);
129 line2
= getNextLine(line2
), ++i
) ;
130 if (i
< 20 && line2
) {
131 (*outputFunc
)(outputStream
, line
, line2
- line
);
132 if (!strncmp(line2
, "/Encoding StandardEncoding def", 30)) {
133 line
= getNextLine(line2
);
135 // skip "/Encoding" + one whitespace char,
136 // then look for 'def' preceded by PostScript whitespace
139 for (; p
< (char *)file
+ len
; ++p
) {
140 if ((*p
== ' ' || *p
== '\t' || *p
== '\x0a' ||
141 *p
== '\x0d' || *p
== '\x0c' || *p
== '\0') &&
142 p
+ 4 <= (char *)file
+ len
&&
143 !strncmp(p
+ 1, "def", 3)) {
151 // copy everything after the encoding
153 (*outputFunc
)(outputStream
, line
, ((char *)file
+ len
) - line
);
158 char *FoFiType1::getNextLine(char *line
) {
159 while (line
< (char *)file
+ len
&& *line
!= '\x0a' && *line
!= '\x0d') {
162 if (line
< (char *)file
+ len
&& *line
== '\x0d') {
165 if (line
< (char *)file
+ len
&& *line
== '\x0a') {
168 if (line
>= (char *)file
+ len
) {
174 void FoFiType1::parse() {
175 char *line
, *line1
, *p
, *p2
;
180 for (i
= 1, line
= (char *)file
;
181 i
<= 100 && line
&& (!name
|| !encoding
);
185 if (!name
&& !strncmp(line
, "/FontName", 9)) {
186 strncpy(buf
, line
, 255);
188 if ((p
= strchr(buf
+9, '/')) &&
189 (p
= strtok(p
+1, " \t\n\r"))) {
190 name
= copyString(p
);
192 line
= getNextLine(line
);
195 } else if (!encoding
&&
196 !strncmp(line
, "/Encoding StandardEncoding def", 30)) {
197 encoding
= fofiType1StandardEncoding
;
198 } else if (!encoding
&&
199 !strncmp(line
, "/Encoding 256 array", 19)) {
200 encoding
= (const char **)gmallocn(256, sizeof(const char *));
201 for (j
= 0; j
< 256; ++j
) {
204 for (j
= 0, line
= getNextLine(line
);
205 j
< 300 && line
&& (line1
= getNextLine(line
));
207 if ((n
= line1
- line
) > 255) {
210 strncpy(buf
, line
, n
);
212 for (p
= buf
; *p
== ' ' || *p
== '\t'; ++p
) ;
213 if (!strncmp(p
, "dup", 3)) {
214 for (p
+= 3; *p
== ' ' || *p
== '\t'; ++p
) ;
215 for (p2
= p
; *p2
>= '0' && *p2
<= '9'; ++p2
) ;
221 if (code
== 8 && *p2
== '#') {
223 for (++p2
; *p2
>= '0' && *p2
<= '7'; ++p2
) {
224 code
= code
* 8 + (*p2
- '0');
228 for (p
= p2
; *p
== ' ' || *p
== '\t'; ++p
) ;
231 for (p2
= p
; *p2
&& *p2
!= ' ' && *p2
!= '\t'; ++p2
) ;
233 encoding
[code
] = copyString(p
);
238 if (strtok(buf
, " \t") &&
239 (p
= strtok(NULL
, " \t\n\r")) && !strcmp(p
, "def")) {
244 //~ check for getinterval/putinterval junk
247 line
= getNextLine(line
);