modified makefile to allow easier adjustment of build options for different targets...
[AROS-Contrib.git] / arospdf / fofi / FoFiType1.cc
blob17feb5c0555631b5eef836cecc3675e1f892b2a8
1 //========================================================================
2 //
3 // FoFiType1.cc
4 //
5 // Copyright 1999-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
9 #include <aconf.h>
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
15 #include <stdlib.h>
16 #include <string.h>
17 #include "gmem.h"
18 #include "FoFiEncodings.h"
19 #include "FoFiType1.h"
21 //------------------------------------------------------------------------
22 // FoFiType1
23 //------------------------------------------------------------------------
25 FoFiType1 *FoFiType1::make(char *fileA, int lenA) {
26 return new FoFiType1(fileA, lenA, gFalse);
29 FoFiType1 *FoFiType1::load(char *fileName) {
30 char *fileA;
31 int lenA;
33 if (!(fileA = FoFiBase::readFile(fileName, &lenA))) {
34 return NULL;
36 return new FoFiType1(fileA, lenA, gTrue);
39 FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA):
40 FoFiBase(fileA, lenA, freeFileDataA)
42 name = NULL;
43 encoding = NULL;
44 parsed = gFalse;
47 FoFiType1::~FoFiType1() {
48 int i;
50 if (name) {
51 gfree(name);
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() {
62 if (!parsed) {
63 parse();
65 return name;
68 char **FoFiType1::getEncoding() {
69 if (!parsed) {
70 parse();
72 return (char**)encoding;
75 void FoFiType1::writeEncoded(char **newEncoding,
76 FoFiOutputFunc outputFunc, void *outputStream) {
77 char buf[512];
78 char *line, *line2, *p;
79 int i;
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;
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) {
97 if (newEncoding[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);
108 } else {
109 // skip "/Encoding" + one whitespace char,
110 // then look for 'def' preceded by PostScript whitespace
111 p = line + 10;
112 line = NULL;
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)) {
118 line = p + 4;
119 break;
124 // some fonts have two /Encoding entries in their dictionary, so we
125 // check for a second one here
126 if (line) {
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);
134 } else {
135 // skip "/Encoding" + one whitespace char,
136 // then look for 'def' preceded by PostScript whitespace
137 p = line2 + 10;
138 line = NULL;
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)) {
144 line = p + 4;
145 break;
151 // copy everything after the encoding
152 if (line) {
153 (*outputFunc)(outputStream, line, ((char *)file + len) - line);
158 char *FoFiType1::getNextLine(char *line) {
159 while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') {
160 ++line;
162 if (line < (char *)file + len && *line == '\x0d') {
163 ++line;
165 if (line < (char *)file + len && *line == '\x0a') {
166 ++line;
168 if (line >= (char *)file + len) {
169 return NULL;
171 return line;
174 void FoFiType1::parse() {
175 char *line, *line1, *p, *p2;
176 char buf[256];
177 char c;
178 int n, code, i, j;
180 for (i = 1, line = (char *)file;
181 i <= 100 && line && (!name || !encoding);
182 ++i) {
184 // get font name
185 if (!name && !strncmp(line, "/FontName", 9)) {
186 strncpy(buf, line, 255);
187 buf[255] = '\0';
188 if ((p = strchr(buf+9, '/')) &&
189 (p = strtok(p+1, " \t\n\r"))) {
190 name = copyString(p);
192 line = getNextLine(line);
194 // get encoding
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) {
202 encoding[j] = NULL;
204 for (j = 0, line = getNextLine(line);
205 j < 300 && line && (line1 = getNextLine(line));
206 ++j, line = line1) {
207 if ((n = line1 - line) > 255) {
208 n = 255;
210 strncpy(buf, line, n);
211 buf[n] = '\0';
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) ;
216 if (*p2) {
217 c = *p2;
218 *p2 = '\0';
219 code = atoi(p);
220 *p2 = c;
221 if (code == 8 && *p2 == '#') {
222 code = 0;
223 for (++p2; *p2 >= '0' && *p2 <= '7'; ++p2) {
224 code = code * 8 + (*p2 - '0');
227 if (code < 256) {
228 for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
229 if (*p == '/') {
230 ++p;
231 for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ;
232 *p2 = '\0';
233 encoding[code] = copyString(p);
237 } else {
238 if (strtok(buf, " \t") &&
239 (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
240 break;
244 //~ check for getinterval/putinterval junk
246 } else {
247 line = getNextLine(line);
251 parsed = gTrue;