1 /*
2 * Here's some code to handle font libraries. Not needed unless you are
3 * running on a system that can't handle files well. Not endorsed by
4 * Tomas Rokicki or Radical Eye Software; use at your own risk.
5 */
6 #ifdef FONTLIB
7 #include "dvips.h" /* The copyright notice in that file is included too! */
8 #include "paths.h"
9 /*
10 * The external declarations:
11 */
12 #include "protos_add.h"
13
14 /*
15 * font library structures
16 */
17 struct fli_entry {
18 unsigned long offset;
19 char *name;
20 };
21
22 struct fli_size {
23 unsigned long size;
24 halfword entries;
25 struct fli_entry *entry;
26 };
27
28 struct fli_lib {
29 char *name;
30 halfword sizes;
31 struct fli_size *size;
32 struct fli_lib *next;
33 };
34
35 struct fli_lib *firstlib = NULL;
36
37 struct fli_centry {
38 struct fli_lib *lib;
39 FILE *fp;
40 };
41
42 #define FLICSIZE 4
43 struct fli_centry *fli_cache[FLICSIZE];
44
45 Boolean flib = 0; /* non zero if reading a font library */
46
47 halfword
pkdouble(void)48 pkdouble(void)
49 {
50 register halfword i;
51 i = pkbyte();
52 i = i * 256 + pkbyte();
53 return(i);
54 }
55 /*
56 * fliload opens each font library, then reads in its
57 * directory for later use.
58 * fli_cache is initialized.
59 */
60 void
fliload(void)61 fliload(void)
62 {
63 int i;
64 halfword version1, version2;
65 Boolean needext;
66 char fontname[50];
67 char name[50];
68 char *fli;
69 unsigned long dpi;
70 halfword len, numsizes, numfonts;
71 halfword numflib = 0;
72 struct fli_lib *lib=NULL, *next_lib=NULL;
73 struct fli_size *size;
74 struct fli_entry *entry;
75
76 /* initialise fli cache */
77 for (i=0; i<FLICSIZE; i++) {
78 fli_cache[i] = (struct fli_centry *)
79 mymalloc((integer)sizeof(struct fli_centry));
80 fli_cache[i]->lib = (struct fli_lib *)NULL;
81 fli_cache[i]->fp = (FILE *)NULL;
82 }
83
84 fli = fliname;
85
86 while (*fli) {
87 /* get next font library name from fliname */
88 needext=1;
89 for (i=0; *fli && *fli!=PATHSEP; i++)
90 if ( (name[i] = *fli++) == '.')
91 needext=0;
92 name[i] = '\0';
93 if (*fli)
94 fli++; /* skip PATHSEP */
95 if (*name) {
96 /* got fli name, now search for it */
97 if (needext)
98 strcat(name,".fli");
99
100 if ( (pkfile=search(flipath,name,READBIN)) != (FILE *)NULL ) {
101 /* for each font library */
102 for (i=0; i<4; i++) {
103 fontname[i] = pkbyte(); /* read header */
104 }
105 version1 = pkbyte();
106 version2 = pkbyte();
107 if (strncmp(fontname,"FLIB",4)!=0 || version1 != 2 || version2 != 0)
108 badpk("incorrect font library format");
109
110 (void) pkdouble(); /* ignore directory length */
111 numsizes = pkdouble(); /* number of sizes */
112 numfonts = pkdouble(); /* number of fonts */
113 len = pkdouble(); /* length of comment */
114 for (i=0; i<len; i++)
115 pkbyte(); /* skip comment */
116 #ifdef DEBUG
117 if (dd(D_FONTS))
118 fprintf(stderr,"Font library %s has %d font size%s, %d font%s\n",
119 name, numsizes , numsizes !=1 ? "s" : "",
120 numfonts, numfonts!=1 ? "s" : "");
121 #endif /* DEBUG */
122
123 next_lib = (struct fli_lib *)
124 mymalloc((integer)sizeof(struct fli_lib));
125 if (firstlib == (struct fli_lib *)NULL)
126 firstlib = next_lib;
127 else
128 lib->next = next_lib;
129 lib = next_lib;
130 size = (struct fli_size *)
131 mymalloc((integer)numsizes * sizeof(struct fli_size));
132 entry = (struct fli_entry *)
133 mymalloc((integer)numfonts * sizeof(struct fli_entry));
134 lib->name = newstring(name);
135 lib->sizes = numsizes;
136 lib->size = size;
137 lib->next = (struct fli_lib *)NULL;
138
139 for (;numsizes>0; numsizes--, size++) {
140 /* for each font size in this library */
141 pkdouble(); /* length of size entry - ignore */
142 numfonts = pkdouble(); /* number of fonts */
143 dpi = pkquad(); /* DPI (fixed point 16.16) */
144
145 #ifdef DEBUG
146 if (dd(D_FONTS))
147 fprintf(stderr,"Font library %s size %.5gdpi has %d font%s\n",
148 name, dpi/65536.0, numfonts, numfonts!=1 ? "s" : "");
149 #endif /* DEBUG */
150 size->size = dpi;
151 size->entries = numfonts;
152 size->entry = entry;
153 for (;numfonts > 0; numfonts--, entry++) {
154 /* read each entry */
155 pkquad(); /* ignore length of font */
156 entry->offset = pkquad(); /* offset to font */
157 len = pkbyte(); /* length of name */
158 for (i=0; i<len; i++)
159 fontname[i] = pkbyte();
160 fontname[len] = '\0';
161 entry->name = newstring(fontname);
162 } /* end for numfonts>0 */
163 } /* end for numsizes>0 */
164 if (numflib < FLICSIZE) { /* leave first few open */
165 fli_cache[numflib]->lib = lib;
166 fli_cache[numflib]->fp = pkfile;
167 }
168 else
169 fclose(pkfile);
170 numflib++;
171 } /* end if opened library */
172 } /* end if (*name) */
173 }
174 }
175
176
177 /*
178 * flisearch searches all the font libraries for a PK font.
179 * returns FILE pointer positioned to PK font in font library
180 * flisearch caches file pointers for 4 font libraries.
181 */
182 FILE *
flisearch(char * n,halfword dpi)183 flisearch(char *n, halfword dpi)
184 {
185 halfword dpi1, numsizes, numfonts;
186 struct fli_lib *lib=NULL;
187 struct fli_size *size;
188 struct fli_entry *entry;
189 struct fli_centry *centry;
190 int i;
191 Boolean found;
192
193 if (firstlib == (struct fli_lib *)NULL)
194 return((FILE *)NULL); /* return if no font libraries */
195
196 #ifdef DEBUG
197 if (dd(D_FONTS)) {
198 fprintf(stderr,"Trying %s at %ddpi\nfli open:", n, dpi);
199 for (i=0; i<FLICSIZE; i++) /* dump cache contents */
200 if (fli_cache[i]->lib != (struct fli_lib *)NULL)
201 fprintf(stderr, " %s",(fli_cache[i]->lib)->name);
202 fprintf(stderr,"\n");
203 }
204 #endif /* DEBUG */
205 for (lib = firstlib; lib != (struct fli_lib *)NULL; lib = lib->next ) {
206 /* for each font library */
207 numsizes = lib->sizes;
208 size = lib->size;
209 #ifdef DEBUG
210 if (dd(D_FONTS))
211 fprintf(stderr," Searching %s\n", lib->name);
212 #endif /* DEBUG */
213 for (; numsizes>0; numsizes--, size++) {
214 /* for each font size in this library */
215 dpi1 = (halfword)((size->size+32768L)/65536);
216 if ( dpi1 == dpi ) {
217 /* if correct size then search for font */
218 #ifdef DEBUG
219 if (dd(D_FONTS))
220 fprintf(stderr, " Checking size %ddpi\n",dpi1);
221 #endif /* DEBUG */
222 entry = size->entry;
223 for (numfonts=size->entries;numfonts > 0; numfonts--, entry++) {
224 if (strcmp(entry->name,n)==0) {
225 /* if correct font name then look for it in cache */
226 found = 0;
227 for (i=0; i<FLICSIZE && !found; i++) { /* check if fli in cache */
228 if ( fli_cache[i]->lib == lib ) {
229 /* found it, so move to front */
230 centry = fli_cache[i];
231 for (; i>0; i--)
232 fli_cache[i] = fli_cache[i-1];
233 found=1;
234 fli_cache[0] = centry;
235 pkfile = fli_cache[0]->fp; /* font libary already open */
236 }
237 }
238 if (!found) { /* if not in cache then re-open it */
239 /* make space at front */
240 fclose(fli_cache[FLICSIZE-1]->fp);
241 centry = fli_cache[FLICSIZE-1];
242 for (i=FLICSIZE-1; i>0; i--)
243 fli_cache[i] = fli_cache[i-1];
244 /* put this font library at front */
245 if ( (pkfile=search(flipath,lib->name,READBIN)) == (FILE *)NULL ) {
246 sprintf(errbuf,"Can't reopen font library %s", lib->name);
247 error(errbuf);
248 return((FILE *)NULL);
249 }
250 fli_cache[0] = centry;
251 fli_cache[0]->lib = lib;
252 fli_cache[0]->fp = pkfile;
253 }
254 flib = 1; /* tell loadfont() not to close it */
255 /* then seek font within library */
256 sprintf(name,"%s %s %ddpi",lib->name, n, dpi1);
257 if (fseek(pkfile,entry->offset,0) )
258 badpk("couldn't seek font");
259 /* make sure it is a PK font */
260 if (pkbyte()==247) /* pre byte */
261 if (pkbyte()==89) { /* id byte */
262 if ( fseek(pkfile,entry->offset,0) )
263 badpk("couldn't seek font");
264 return(pkfile); /* found it */
265 }
266 sprintf(errbuf,"%s %s %ddpi isn't PK format, ignoring",
267 lib->name, n, dpi1);
268 error(errbuf);
269 } /* end if name correct */
270 } /* end for numfonts>0 */
271 }
272 else {
273 /* if not correct size then skip */
274 #ifdef DEBUG
275 if (dd(D_FONTS))
276 fprintf(stderr, " Skipping size %ddpi\n", dpi1);
277 #endif /* DEBUG */
278 }
279 } /* end for numsizes>0 */
280 }
281 return((FILE *)NULL);
282 }
283
284 /* parse the font library path, putting all directory names in path,
285 * and all font library names in name.
286 * Directory names have a trailing DIRSEP.
287 */
288 char *
fliparse(char * path,char * name)289 fliparse(char *path, char *name)
290 {
291 char *p, *prevp; /* pointers to path */
292 char *n, *prevn; /* pointers to name */
293 char *s;
294
295 p = path;
296 n = name;
297 s = path;
298
299 while (*s) {
300 prevp = p;
301 prevn = n;
302 while (*s && *s != PATHSEP) {
303 /* copy till PATHSEP */
304 *p++ = *s;
305 *n++ = *s;
306 s++;
307 }
308 *n = '\0';
309 if (*s)
310 s++; /* skip PATHSEP */
311
312 if ( *prevn=='\0' || prevn[strlen(prevn)-1] == DIRSEP ) {
313 n = prevn; /* ignore name if it is dir */
314 if (*prevn)
315 p--; /* backup over DIRSEP */
316 *p++ = PATHSEP;
317 prevp = p;
318 }
319 else {
320 p = prevp; /* ignore path if it is library name */
321 *n++ = PATHSEP;
322 prevn = n;
323 }
324
325 }
326 *p = '\0';
327 *n = '\0';
328 if (n!=name && *--n==PATHSEP)
329 *n = '\0'; /* remove trailing PATHSEP from name */
330 if (p!=path && *--p==PATHSEP)
331 *p = '\0'; /* remove trailing PATHSEP from path */
332 return(path);
333 } /* end fliparse */
334 #else
335 /*
336 * Some systems don't like .o files that compile to nothing, so we
337 * provide a stub routine.
338 */
fliload()339 void fliload() {}
340 #endif
341
342