]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | //======================================================================== |
2 | // | |
3 | // FoFiType1.cc | |
4 | // | |
5 | // Copyright 1999-2003 Glyph & Cog, LLC | |
6 | // | |
7 | //======================================================================== | |
8 | ||
9 | #include <config.h> | |
10 | ||
11 | #ifdef USE_GCC_PRAGMAS | |
12 | #pragma implementation | |
13 | #endif | |
14 | ||
15 | #include <stdlib.h> | |
16 | #include <string.h> | |
17 | #include "gmem.h" | |
18 | #include "FoFiEncodings.h" | |
19 | #include "FoFiType1.h" | |
20 | ||
21 | //------------------------------------------------------------------------ | |
22 | // FoFiType1 | |
23 | //------------------------------------------------------------------------ | |
24 | ||
25 | FoFiType1 *FoFiType1::make(char *fileA, int lenA) { | |
26 | return new FoFiType1(fileA, lenA, gFalse); | |
27 | } | |
28 | ||
29 | FoFiType1 *FoFiType1::load(char *fileName) { | |
30 | char *fileA; | |
31 | int lenA; | |
32 | ||
33 | if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { | |
34 | return NULL; | |
35 | } | |
36 | return new FoFiType1(fileA, lenA, gTrue); | |
37 | } | |
38 | ||
39 | FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA): | |
40 | FoFiBase(fileA, lenA, freeFileDataA) | |
41 | { | |
42 | name = NULL; | |
43 | encoding = NULL; | |
44 | parsed = gFalse; | |
45 | } | |
46 | ||
47 | FoFiType1::~FoFiType1() { | |
48 | int i; | |
49 | ||
50 | if (name) { | |
51 | gfree(name); | |
52 | } | |
53 | if (encoding && encoding != fofiType1StandardEncoding) { | |
54 | for (i = 0; i < 256; ++i) { | |
55 | gfree(encoding[i]); | |
56 | } | |
57 | gfree(encoding); | |
58 | } | |
59 | } | |
60 | ||
61 | char *FoFiType1::getName() { | |
62 | if (!parsed) { | |
63 | parse(); | |
64 | } | |
65 | return name; | |
66 | } | |
67 | ||
68 | char **FoFiType1::getEncoding() { | |
69 | if (!parsed) { | |
70 | parse(); | |
71 | } | |
72 | return encoding; | |
73 | } | |
74 | ||
75 | void FoFiType1::writeEncoded(char **newEncoding, | |
76 | FoFiOutputFunc outputFunc, void *outputStream) { | |
77 | char buf[512]; | |
78 | char *line; | |
79 | int i; | |
80 | ||
81 | // copy everything up to the encoding | |
82 | for (line = (char *)file; | |
83 | line && strncmp(line, "/Encoding", 9); | |
84 | line = getNextLine(line)) ; | |
85 | if (!line) { | |
86 | // no encoding - just copy the whole font file | |
87 | (*outputFunc)(outputStream, (char *)file, len); | |
88 | return; | |
89 | } | |
90 | (*outputFunc)(outputStream, (char *)file, line - (char *)file); | |
91 | ||
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) { | |
97 | if (newEncoding[i]) { | |
98 | sprintf(buf, "dup %d /%s put\n", i, newEncoding[i]); | |
99 | (*outputFunc)(outputStream, buf, strlen(buf)); | |
100 | } | |
101 | } | |
102 | (*outputFunc)(outputStream, "readonly def\n", 13); | |
103 | ||
104 | // copy everything after the encoding | |
105 | if (!strncmp(line, "/Encoding StandardEncoding def", 30)) { | |
106 | line = getNextLine(line); | |
107 | } else { | |
108 | for (line = getNextLine(line); | |
109 | line && strncmp(line, "readonly def", 12); | |
110 | line = getNextLine(line)) ; | |
111 | if (line) { | |
112 | line = getNextLine(line); | |
113 | } | |
114 | } | |
115 | if (line) { | |
116 | (*outputFunc)(outputStream, line, ((char *)file + len) - line); | |
117 | } | |
118 | } | |
119 | ||
120 | char *FoFiType1::getNextLine(char *line) { | |
121 | while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') { | |
122 | ++line; | |
123 | } | |
124 | if (line < (char *)file + len && *line == '\x0d') { | |
125 | ++line; | |
126 | } | |
127 | if (line < (char *)file + len && *line == '\x0a') { | |
128 | ++line; | |
129 | } | |
130 | if (line >= (char *)file + len) { | |
131 | return NULL; | |
132 | } | |
133 | return line; | |
134 | } | |
135 | ||
136 | void FoFiType1::parse() { | |
137 | char *line, *line1, *p, *p2; | |
138 | char buf[256]; | |
139 | char c; | |
140 | int n, code, i, j; | |
141 | ||
142 | for (i = 1, line = (char *)file; | |
143 | i <= 100 && line && (!name || !encoding); | |
144 | ++i) { | |
145 | ||
146 | // get font name | |
147 | if (!name && !strncmp(line, "/FontName", 9)) { | |
148 | strncpy(buf, line, 255); | |
149 | buf[255] = '\0'; | |
150 | if ((p = strchr(buf+9, '/')) && | |
151 | (p = strtok(p+1, " \t\n\r"))) { | |
152 | name = copyString(p); | |
153 | } | |
154 | line = getNextLine(line); | |
155 | ||
156 | // get encoding | |
157 | } else if (!encoding && | |
158 | !strncmp(line, "/Encoding StandardEncoding def", 30)) { | |
159 | encoding = fofiType1StandardEncoding; | |
160 | } else if (!encoding && | |
161 | !strncmp(line, "/Encoding 256 array", 19)) { | |
162 | encoding = (char **)gmallocn(256, sizeof(char *)); | |
163 | for (j = 0; j < 256; ++j) { | |
164 | encoding[j] = NULL; | |
165 | } | |
166 | for (j = 0, line = getNextLine(line); | |
167 | j < 300 && line && (line1 = getNextLine(line)); | |
168 | ++j, line = line1) { | |
169 | if ((n = line1 - line) > 255) { | |
170 | n = 255; | |
171 | } | |
172 | strncpy(buf, line, n); | |
173 | buf[n] = '\0'; | |
174 | for (p = buf; *p == ' ' || *p == '\t'; ++p) ; | |
175 | if (!strncmp(p, "dup", 3)) { | |
176 | for (p += 3; *p == ' ' || *p == '\t'; ++p) ; | |
177 | for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ; | |
178 | if (*p2) { | |
179 | c = *p2; | |
180 | *p2 = '\0'; | |
181 | if ((code = atoi(p)) < 256) { | |
182 | *p2 = c; | |
183 | for (p = p2; *p == ' ' || *p == '\t'; ++p) ; | |
184 | if (*p == '/') { | |
185 | ++p; | |
186 | for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ; | |
187 | *p2 = '\0'; | |
188 | encoding[code] = copyString(p); | |
189 | } | |
190 | } | |
191 | } | |
192 | } else { | |
193 | if (strtok(buf, " \t") && | |
194 | (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) { | |
195 | break; | |
196 | } | |
197 | } | |
198 | } | |
199 | //~ check for getinterval/putinterval junk | |
200 | ||
201 | } else { | |
202 | line = getNextLine(line); | |
203 | } | |
204 | } | |
205 | ||
206 | parsed = gTrue; | |
207 | } |