2 Copyright (c) 2003 by Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
25 * Permission is hereby granted, free of charge, to any person obtaining a
26 * copy of this software and associated documentation files (the "Software"),
27 * to deal in the Software without restriction, including without limitation
28 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
29 * and/or sell copies of the Software, and to permit persons to whom the
30 * Software is furnished to do so, subject to the following conditions:
32 * The above copyright notice and this permission notice (including the next
33 * paragraph) shall be included in all copies or substantial portions of the
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
42 * DEALINGS IN THE SOFTWARE.
45 /* The function identifyBitmap returns -1 if filename is definitively not
46 a font file, 1 if it is a single-face bitmap font with a XLFD name,
47 and 0 if it should be processed normally. identifyBitmap is
48 much faster than parsing the whole font. */
57 #ifdef X_BZIP2_FONT_COMPRESSION
61 #define PCF_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1)
62 #define PCF_PROPERTIES (1 << 0)
64 typedef struct _Prop {
70 #ifdef X_BZIP2_FONT_COMPRESSION
72 enum { gzFontFile, bz2FontFile } type;
81 fontFileOpen(fontFile *ff, const char *filename) {
82 int n = strlen(filename);
84 if (strcmp(filename + n - 4, ".bz2") == 0) {
85 ff->type = bz2FontFile;
86 ff->f.bz2 = BZ2_bzopen(filename, "rb");
90 ff->type = gzFontFile;
91 ff->f.gz = gzopen(filename, "rb");
97 fontFileRead(fontFile *ff, void *buf, unsigned len)
99 if (ff->type == gzFontFile) {
100 return gzread(ff->f.gz, buf, len);
102 int r = BZ2_bzread(ff->f.bz2, buf, len);
109 fontFileGetc(fontFile *ff)
111 if (ff->type == gzFontFile) {
112 return gzgetc(ff->f.gz);
115 if (BZ2_bzread(ff->f.bz2, &buf, 1) != 1) {
125 fontFileSeek(fontFile *ff, z_off_t offset, int whence)
127 if (ff->type == gzFontFile) {
128 return gzseek(ff->f.gz, offset, whence);
130 /* bzlib has no easy equivalent so we have to fake it,
131 * fortunately, we only have to handle a couple of cases
138 n = offset - ff->pos;
148 if (BZ2_bzread(ff->f.bz2, buf, BUFSIZ) != BUFSIZ)
152 if (BZ2_bzread(ff->f.bz2, buf, n) != n)
161 fontFileClose(fontFile *ff)
163 if (ff->type == gzFontFile) {
164 return gzclose(ff->f.gz);
166 BZ2_bzclose(ff->f.bz2);
171 #else /* no bzip2, only gzip */
172 typedef gzFile fontFile;
173 # define fontFileOpen(ff, filename) (*(ff) = gzopen(filename, "rb"))
174 # define fontFileRead(ff, buf, len) gzread(*(ff), buf, len)
175 # define fontFileGetc(ff) gzgetc(*(ff))
176 # define fontFileSeek(ff, off, whence) gzseek(*(ff), off, whence)
177 # define fontFileClose(ff) gzclose(*(ff))
180 static int pcfIdentify(fontFile *f, char **name);
181 static int bdfIdentify(fontFile *f, char **name);
184 getLSB32(fontFile *f)
189 rc = fontFileRead(f, c, 4);
192 return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
196 getInt8(fontFile *f, int format)
201 rc = fontFileRead(f, &c, 1);
208 getInt32(fontFile *f, int format)
213 rc = fontFileRead(f, c, 4);
217 if(format & (1 << 2)) {
218 return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | (c[3]);
220 return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
225 bitmapIdentify(const char *filename, char **name)
230 if (fontFileOpen(&ff, filename) == NULL)
233 magic = getLSB32(&ff);
234 if(magic == PCF_VERSION)
235 return pcfIdentify(&ff, name);
236 else if(magic == ('S' | ('T' << 8) | ('A' << 16) | ('R') << 24))
237 return bdfIdentify(&ff, name);
244 pcfIdentify(fontFile *f, char **name)
247 PropPtr props = NULL;
248 int format, count, nprops, i, string_size, rc;
249 char *strings = NULL, *s;
256 for(i = 0; i < count; i++) {
261 offset = getLSB32(f);
262 if(type == PCF_PROPERTIES) {
263 prop_position = offset;
267 if(prop_position < 0)
270 rc = fontFileSeek(f, prop_position, SEEK_SET);
274 format = getLSB32(f);
275 if((format & 0xFFFFFF00) != 0)
277 nprops = getInt32(f, format);
278 if(nprops <= 0 || nprops > 1000)
280 props = malloc(nprops * sizeof(PropRec));
284 for(i = 0; i < nprops; i++) {
285 props[i].name = getInt32(f, format);
286 props[i].isString = getInt8(f, format);
287 props[i].value = getInt32(f, format);
290 rc = fontFileSeek(f, 4 - (nprops & 3), SEEK_CUR);
295 string_size = getInt32(f, format);
296 if(string_size < 0 || string_size > 100000)
298 strings = malloc(string_size);
302 rc = fontFileRead(f, strings, string_size);
303 if(rc != string_size)
306 for(i = 0; i < nprops; i++) {
307 if(!props[i].isString ||
308 props[i].name >= string_size - 4 ||
309 props[i].value >= string_size)
311 if(strcmp(strings + props[i].name, "FONT") == 0)
318 s = malloc(strlen(strings + props[i].value) + 1);
321 strcpy(s, strings + props[i].value);
329 if(strings) free(strings);
330 if(props) free(props);
338 getKeyword(fontFile *f, int *eol)
340 static char keyword[NKEY + 1];
345 if(c == ' ' || c == '\n') {
353 if(c < 'A' || c > 'Z')
366 } while(c >= 0 && c != '\n');
385 if(c < 0 || (c == '\n' && i == 0)) {
388 if(bufsize < i + 1) {
392 newbuf = malloc(bufsize);
394 bufsize = 2 * bufsize;
395 newbuf = realloc(buf, bufsize);
416 bdfIdentify(fontFile *f, char **name)
421 /* bitmapIdentify already read "STAR", so we need to check for
423 k = getKeyword(f, &eol);
426 if(strcmp(k, "TFONT") != 0)
434 k = getKeyword(f, &eol);
437 else if(strcmp(k, "FONT") == 0) {
446 } else if(strcmp(k, "CHARS") == 0)