bdfutils.c revision 41c30155
1/************************************************************************
2Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3
4                        All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22************************************************************************/
23
24/*
25
26Copyright 1994, 1998  The Open Group
27
28Permission to use, copy, modify, distribute, and sell this software and its
29documentation for any purpose is hereby granted without fee, provided that
30the above copyright notice appear in all copies and that both that
31copyright notice and this permission notice appear in supporting
32documentation.
33
34The above copyright notice and this permission notice shall be included
35in all copies or substantial portions of the Software.
36
37THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
40IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
41OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43OTHER DEALINGS IN THE SOFTWARE.
44
45Except as contained in this notice, the name of The Open Group shall
46not be used in advertising or otherwise to promote the sale, use or
47other dealings in this Software without prior written authorization
48from The Open Group.
49
50*/
51
52#ifdef HAVE_CONFIG_H
53#include <config.h>
54#endif
55
56#include <ctype.h>
57#include <stdio.h>
58#include <stdarg.h>
59
60#include <X11/fonts/fntfilst.h>
61#include <X11/fonts/fontstruct.h>
62/* use bitmap structure */
63#include <X11/fonts/bitmap.h>
64#include <X11/fonts/bdfint.h>
65
66int bdfFileLineNum;
67
68/***====================================================================***/
69
70void
71bdfError(const char* message, ...)
72{
73    va_list args;
74
75    va_start (args, message);
76    fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
77    vfprintf(stderr, message, args);
78    va_end (args);
79}
80
81/***====================================================================***/
82
83void
84bdfWarning(const char *message, ...)
85{
86    va_list args;
87
88    va_start (args, message);
89    fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
90    vfprintf(stderr, message, args);
91    va_end (args);
92}
93
94/*
95 * read the next (non-comment) line and keep a count for error messages.
96 * Returns buf, or NULL if EOF.
97 */
98
99unsigned char *
100bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
101{
102    int         c;
103    unsigned char *b;
104
105    for (;;) {
106	b = buf;
107	while ((c = FontFileGetc(file)) != FontFileEOF) {
108	    if (c == '\r')
109		continue;
110	    if (c == '\n') {
111		bdfFileLineNum++;
112		break;
113	    }
114	    if (b - buf >= (len - 1))
115		break;
116	    *b++ = c;
117	}
118	*b = '\0';
119	if (c == FontFileEOF)
120	    return NULL;
121	if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
122	    break;
123    }
124    return buf;
125}
126
127/***====================================================================***/
128
129Atom
130bdfForceMakeAtom(const char *str, int *size)
131{
132    register int len = strlen(str);
133    Atom the_atom;
134
135    if (size != NULL)
136	*size += len + 1;
137    the_atom = MakeAtom(str, len, TRUE);
138    if (the_atom == None)
139      bdfError("Atom allocation failed\n");
140    return the_atom;
141}
142
143/***====================================================================***/
144
145/*
146 * Handle quoted strings.
147 */
148
149Atom
150bdfGetPropertyValue(char *s)
151{
152    register char *p,
153               *pp;
154    char *orig_s = s;
155    Atom        atom;
156
157    /* strip leading white space */
158    while (*s && (*s == ' ' || *s == '\t'))
159	s++;
160    if (*s == 0) {
161	return bdfForceMakeAtom(s, NULL);
162    }
163    if (*s != '"') {
164	pp = s;
165	/* no white space in value */
166	for (pp = s; *pp; pp++)
167	    if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
168		*pp = 0;
169		break;
170	    }
171	return bdfForceMakeAtom(s, NULL);
172    }
173    /* quoted string: strip outer quotes and undouble inner quotes */
174    s++;
175    pp = p = malloc((unsigned) strlen(s) + 1);
176    if (pp == NULL) {
177	bdfError("Couldn't allocate property value string (%d)\n",
178		 (int) strlen(s) + 1);
179	return None;
180    }
181    while (*s) {
182	if (*s == '"') {
183	    if (*(s + 1) != '"') {
184		*p++ = 0;
185		atom = bdfForceMakeAtom(pp, NULL);
186		free(pp);
187		return atom;
188	    } else {
189		s++;
190	    }
191	}
192	*p++ = *s++;
193    }
194    free (pp);
195    bdfError("unterminated quoted string property: %s\n", orig_s);
196    return None;
197}
198
199/***====================================================================***/
200
201/*
202 * return TRUE if string is a valid integer
203 */
204int
205bdfIsInteger(char *str)
206{
207    char        c;
208
209    c = *str++;
210    if (!(isdigit(c) || c == '-' || c == '+'))
211	return (FALSE);
212
213    while ((c = *str++))
214	if (!isdigit(c))
215	    return (FALSE);
216
217    return (TRUE);
218}
219
220/***====================================================================***/
221
222/*
223 * make a byte from the first two hex characters in glyph picture
224 */
225
226unsigned char
227bdfHexByte(unsigned char *s)
228{
229    unsigned char b = 0;
230    register char c;
231    int         i;
232
233    for (i = 2; i; i--) {
234	c = *s++;
235	if ((c >= '0') && (c <= '9'))
236	    b = (b << 4) + (c - '0');
237	else if ((c >= 'A') && (c <= 'F'))
238	    b = (b << 4) + 10 + (c - 'A');
239	else if ((c >= 'a') && (c <= 'f'))
240	    b = (b << 4) + 10 + (c - 'a');
241	else
242	    bdfError("bad hex char '%c'", c);
243    }
244    return b;
245}
246
247/***====================================================================***/
248
249/*
250 * check for known special property values
251 */
252
253static const char *SpecialAtoms[] = {
254    "FONT_ASCENT",
255#define BDF_FONT_ASCENT	0
256    "FONT_DESCENT",
257#define BDF_FONT_DESCENT 1
258    "DEFAULT_CHAR",
259#define BDF_DEFAULT_CHAR 2
260    "POINT_SIZE",
261#define BDF_POINT_SIZE 3
262    "RESOLUTION",
263#define BDF_RESOLUTION 4
264    "X_HEIGHT",
265#define BDF_X_HEIGHT 5
266    "WEIGHT",
267#define BDF_WEIGHT 6
268    "QUAD_WIDTH",
269#define BDF_QUAD_WIDTH 7
270    "FONT",
271#define BDF_FONT 8
272    "RESOLUTION_X",
273#define BDF_RESOLUTION_X 9
274    "RESOLUTION_Y",
275#define BDF_RESOLUTION_Y 10
276    0,
277};
278
279Bool
280bdfSpecialProperty(FontPtr pFont, FontPropPtr prop,
281		   char isString, bdfFileState *bdfState)
282{
283    const char      **special;
284    const char       *name;
285
286    name = NameForAtom(prop->name);
287    for (special = SpecialAtoms; *special; special++)
288	if (!strcmp(name, *special))
289	    break;
290
291    switch (special - SpecialAtoms) {
292    case BDF_FONT_ASCENT:
293	if (!isString) {
294	    pFont->info.fontAscent = prop->value;
295	    bdfState->haveFontAscent = TRUE;
296	}
297	return TRUE;
298    case BDF_FONT_DESCENT:
299	if (!isString) {
300	    pFont->info.fontDescent = prop->value;
301	    bdfState->haveFontDescent = TRUE;
302	}
303	return TRUE;
304    case BDF_DEFAULT_CHAR:
305	if (!isString) {
306	    pFont->info.defaultCh = prop->value;
307	    bdfState->haveDefaultCh = TRUE;
308	}
309	return TRUE;
310    case BDF_POINT_SIZE:
311	bdfState->pointSizeProp = prop;
312	return FALSE;
313    case BDF_RESOLUTION:
314	bdfState->resolutionProp = prop;
315	return FALSE;
316    case BDF_X_HEIGHT:
317	bdfState->xHeightProp = prop;
318	return FALSE;
319    case BDF_WEIGHT:
320	bdfState->weightProp = prop;
321	return FALSE;
322    case BDF_QUAD_WIDTH:
323	bdfState->quadWidthProp = prop;
324	return FALSE;
325    case BDF_FONT:
326	bdfState->fontProp = prop;
327	return FALSE;
328    case BDF_RESOLUTION_X:
329	bdfState->resolutionXProp = prop;
330	return FALSE;
331    case BDF_RESOLUTION_Y:
332	bdfState->resolutionYProp = prop;
333	return FALSE;
334    default:
335	return FALSE;
336    }
337}
338