1 /************************************************************************/
2 /* */
3 /* Implements a mapping between font names as implemented by the */
4 /* GhostScript 'Fontmap' file. */
5 /* */
6 /************************************************************************/
7
8 # include "appUtilConfig.h"
9
10 # include <stdio.h>
11 # include <stddef.h>
12 # include <stdlib.h>
13 # include <string.h>
14 # include <ctype.h>
15
16 # include "appSystem.h"
17 # include "utilFontmap.h"
18
19 # include <appDebugon.h>
20
21 typedef struct FontmapEntry
22 {
23 char * feFrom;
24 char * feTo;
25 int feIsAlias;
26 } FontmapEntry;
27
28 static FontmapEntry * UTIL_FontmapEntries;
29 static int UTIL_FontmapEntryCount;
30
31 /************************************************************************/
32 /* */
33 /* Get a name resulting from one of the mappings. */
34 /* */
35 /************************************************************************/
36
utilFontmapGet(const char * from,const FontmapEntry * entries,int entryCount)37 static const char * utilFontmapGet( const char * from,
38 const FontmapEntry * entries,
39 int entryCount )
40 {
41 int turn;
42
43 for ( turn= 0; turn < 20; turn++ )
44 {
45 const FontmapEntry * fe;
46 int i;
47
48 fe= entries;
49 for ( i= 0; i < entryCount; fe++, i++ )
50 {
51 if ( ! strcmp( fe->feFrom, from ) )
52 { break; }
53 }
54
55 if ( i >= entryCount )
56 { return (const char *)0; }
57
58 if ( fe->feIsAlias )
59 { from= fe->feTo; continue; }
60
61 return fe->feTo;
62 }
63
64 LSDEB(turn,from);
65 return (const char *)0;
66 }
67
utilFontmapGetEntry(const char * from)68 const char * utilFontmapGetEntry( const char * from )
69 {
70 return utilFontmapGet( from,
71 UTIL_FontmapEntries, UTIL_FontmapEntryCount );
72 }
73
74 /************************************************************************/
75 /* */
76 /* Read the GhostScript font map. */
77 /* */
78 /* 1) Syntax error in the Cyrillic fonts section. */
79 /* As usual, people do not follow their own file format. */
80 /* 2) The standard GhostScript distribution comes with a reference */
81 /* to Fontmap.greek in Fontmap. As this file does not exist and */
82 /* GhostScript seems to enjoy this kind of a mess, only include */
83 /* existing files. (This is an aspect of Macho culture.. tidiness */
84 /* seems to be for girls and weaklings.) */
85 /* */
86 /************************************************************************/
87
utilFontmapNextItem(FILE * f)88 static int utilFontmapNextItem( FILE * f )
89 {
90 int c;
91
92 c= getc( f );
93 for (;;)
94 {
95 if ( c == '%' )
96 {
97 c= getc( f );
98 while( c != EOF && c != '\n' )
99 { c= getc( f ); }
100
101 if ( c == '\n' )
102 { c= getc( f ); }
103
104 continue;
105 }
106
107 if ( isspace( c ) )
108 { c= getc( f ); continue; }
109
110 break;
111 }
112
113 return c;
114 }
115
utilFontmapReadMap(const char * filename)116 int utilFontmapReadMap( const char * filename )
117 {
118 int rval= 0;
119 FILE * f= (FILE *)0;
120 int c;
121
122 static int recursive= 0;
123
124 static const char runlibfile[]= ".runlibfile";
125
126 MemoryBuffer fileBuf;
127 MemoryBuffer runfile;
128 MemoryBuffer local;
129
130 utilInitMemoryBuffer( &fileBuf );
131 utilInitMemoryBuffer( &runfile );
132 utilInitMemoryBuffer( &local );
133
134 recursive++;
135
136 if ( recursive == 1 && UTIL_FontmapEntryCount > 0 )
137 { /* LDEB(UTIL_FontmapEntryCount); rval= -1; */ goto ready; }
138
139 if ( recursive > 20 )
140 { LDEB(recursive); rval= -1; goto ready; }
141
142 if ( utilMemoryBufferSetString( &fileBuf, filename ) )
143 { LDEB(1); rval= -1; goto ready; }
144
145 f= fopen( filename, "r" );
146 if ( ! f )
147 { SXDEB(filename,f); rval= -1; goto ready; }
148
149 c= utilFontmapNextItem( f );
150 while( c != EOF )
151 {
152 FontmapEntry * fe;
153
154 char scratch[200+ 1];
155 int l;
156
157 switch( c )
158 {
159 case ';':
160 /* 1 */
161 c= utilFontmapNextItem( f );
162 continue;
163
164 case '(':
165 for ( l= 0; l < 200; l++ )
166 {
167 c= getc( f );
168 if ( c == EOF )
169 { LDEB(c); rval= -1; goto ready; }
170 if ( c == ')' )
171 { break; }
172
173 scratch[l]= c;
174 }
175 if ( l >= 200 )
176 { LDEB(l); rval= -1; goto ready; }
177 scratch[l]= '\0';
178
179 c= getc( f );
180 if ( c == EOF )
181 { LDEB(c); rval= -1; goto ready; }
182
183 while( isspace( c ) )
184 {
185 c= getc( f );
186 if ( c == EOF )
187 { LDEB(c); rval= -1; goto ready; }
188 }
189
190 for ( l= 0; l < sizeof(runlibfile)- 1; l++ )
191 {
192 if ( c != runlibfile[l] )
193 { SCDEB(runlibfile+l,c); rval= -1; goto ready; }
194 c= getc( f );
195 }
196
197 while( isspace( c ) && c != '\n' )
198 {
199 c= getc( f );
200 if ( c == EOF )
201 { LDEB(c); rval= -1; goto ready; }
202 }
203
204 if ( c != '\n' )
205 { CDEB(c); rval= -1; goto ready; }
206
207 if ( utilMemoryBufferSetString( &local, scratch ) )
208 { LDEB(l); rval= -1; goto ready; }
209
210 if ( appAbsoluteName( &runfile, &local, 1, &fileBuf ) < 0 )
211 { SSDEB(filename,scratch); rval= -1; goto ready; }
212
213 /* 2 */
214 if ( ! appTestFileExists( &runfile ) &&
215 utilFontmapReadMap( utilMemoryBufferGetString( &runfile ) ) )
216 { LDEB(1); rval= -1; goto ready; }
217
218 c= utilFontmapNextItem( f );
219 continue;
220
221 case '/':
222 break;
223
224 default:
225 CDEB(c);
226 rval= -1; goto ready;
227 }
228
229 fe= (FontmapEntry *)realloc( UTIL_FontmapEntries,
230 ( UTIL_FontmapEntryCount+ 1)* sizeof(FontmapEntry) );
231 if ( ! fe )
232 { LXDEB(UTIL_FontmapEntryCount,fe); rval= -1; goto ready; }
233 UTIL_FontmapEntries= fe;
234 fe += UTIL_FontmapEntryCount;
235
236 for ( l= 0; l < 200; l++ )
237 {
238 c= getc( f );
239 if ( c == EOF )
240 { LDEB(c); rval= -1; goto ready; }
241 if ( isspace( c ) )
242 { break; }
243
244 scratch[l]= c;
245 }
246 if ( l >= 200 )
247 { LDEB(l); rval= -1; goto ready; }
248 scratch[l]= '\0';
249
250 fe->feFrom= strdup( scratch );
251 if ( ! fe->feFrom )
252 { XDEB(fe->feFrom); rval= -1; goto ready; }
253
254 while( isspace( c ) )
255 {
256 c= getc( f );
257 if ( c == EOF )
258 { LDEB(c); rval= -1; goto ready; }
259 }
260
261 switch( c )
262 {
263 case '/':
264 fe->feIsAlias= 1;
265 break;
266 case '(':
267 fe->feIsAlias= 0;
268 break;
269 default:
270 CDEB(c); rval= -1; goto ready;
271 }
272
273 for ( l= 0; l < 200; l++ )
274 {
275 c= getc( f );
276 if ( c == EOF )
277 { LDEB(c); rval= -1; goto ready; }
278 if ( isspace( c ) )
279 { break; }
280
281 scratch[l]= c;
282 }
283 if ( l >= 200 )
284 { LDEB(l); rval= -1; goto ready; }
285 scratch[l]= '\0';
286
287 if ( ! fe->feIsAlias )
288 {
289 if ( l < 1 || scratch[l-1] != ')' )
290 { SDEB(scratch); rval= -1; goto ready; }
291
292 scratch[l-1]= '\0';
293 }
294
295 fe->feTo= strdup( scratch );
296 if ( ! fe->feTo )
297 { XDEB(fe->feTo); rval= -1; goto ready; }
298
299 while( isspace( c ) )
300 {
301 c= getc( f );
302 if ( c == EOF )
303 { LDEB(c); rval= -1; goto ready; }
304 }
305
306 if ( c != ';' )
307 { CDEB(c); rval= -1; goto ready; }
308
309 UTIL_FontmapEntryCount++;
310 c= utilFontmapNextItem( f );
311 }
312
313 ready:
314
315 recursive--;
316
317 if ( f )
318 { fclose( f ); }
319
320 utilCleanMemoryBuffer( &fileBuf );
321 utilCleanMemoryBuffer( &runfile );
322 utilCleanMemoryBuffer( &local );
323
324 return rval;
325 }
326
327