bdfutils.c revision a96d7823
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#include "libxfontint.h"
56
57#include <ctype.h>
58#include <stdio.h>
59#include <stdarg.h>
60
61#include <X11/fonts/fntfilst.h>
62#include <X11/fonts/fontstruct.h>
63/* use bitmap structure */
64#include <X11/fonts/bitmap.h>
65#include <X11/fonts/bdfint.h>
66
67int bdfFileLineNum;
68
69/***====================================================================***/
70
71void
72bdfError(const char* message, ...)
73{
74    va_list args;
75
76    va_start (args, message);
77    fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
78    vfprintf(stderr, message, args);
79    va_end (args);
80}
81
82/***====================================================================***/
83
84void
85bdfWarning(const char *message, ...)
86{
87    va_list args;
88
89    va_start (args, message);
90    fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
91    vfprintf(stderr, message, args);
92    va_end (args);
93}
94
95/*
96 * read the next (non-comment) line and keep a count for error messages.
97 * Returns buf, or NULL if EOF.
98 */
99
100unsigned char *
101bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
102{
103    int         c;
104    unsigned char *b;
105
106    for (;;) {
107	b = buf;
108	while ((c = FontFileGetc(file)) != FontFileEOF) {
109	    if (c == '\r')
110		continue;
111	    if (c == '\n') {
112		bdfFileLineNum++;
113		break;
114	    }
115	    if (b - buf >= (len - 1))
116		break;
117	    *b++ = c;
118	}
119	*b = '\0';
120	if (c == FontFileEOF)
121	    return NULL;
122	if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
123	    break;
124    }
125    return buf;
126}
127
128/***====================================================================***/
129
130Atom
131bdfForceMakeAtom(const char *str, int *size)
132{
133    register int len = strlen(str);
134    Atom the_atom;
135
136    if (size != NULL)
137	*size += len + 1;
138    the_atom = MakeAtom(str, len, TRUE);
139    if (the_atom == None)
140      bdfError("Atom allocation failed\n");
141    return the_atom;
142}
143
144/***====================================================================***/
145
146/*
147 * Handle quoted strings.
148 */
149
150Atom
151bdfGetPropertyValue(char *s)
152{
153    register char *p,
154               *pp;
155    char *orig_s = s;
156    Atom        atom;
157
158    /* strip leading white space */
159    while (*s && (*s == ' ' || *s == '\t'))
160	s++;
161    if (*s == 0) {
162	return bdfForceMakeAtom(s, NULL);
163    }
164    if (*s != '"') {
165	pp = s;
166	/* no white space in value */
167	for (pp = s; *pp; pp++)
168	    if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
169		*pp = 0;
170		break;
171	    }
172	return bdfForceMakeAtom(s, NULL);
173    }
174    /* quoted string: strip outer quotes and undouble inner quotes */
175    s++;
176    pp = p = malloc((unsigned) strlen(s) + 1);
177    if (pp == NULL) {
178	bdfError("Couldn't allocate property value string (%d)\n",
179		 (int) strlen(s) + 1);
180	return None;
181    }
182    while (*s) {
183	if (*s == '"') {
184	    if (*(s + 1) != '"') {
185		*p++ = 0;
186		atom = bdfForceMakeAtom(pp, NULL);
187		free(pp);
188		return atom;
189	    } else {
190		s++;
191	    }
192	}
193	*p++ = *s++;
194    }
195    free (pp);
196    bdfError("unterminated quoted string property: %s\n", orig_s);
197    return None;
198}
199
200/***====================================================================***/
201
202/*
203 * return TRUE if string is a valid integer
204 */
205int
206bdfIsInteger(char *str)
207{
208    char        c;
209
210    c = *str++;
211    if (!(isdigit((unsigned char)c) || c == '-' || c == '+'))
212	return (FALSE);
213
214    while ((c = *str++))
215	if (!isdigit((unsigned char)c))
216	    return (FALSE);
217
218    return (TRUE);
219}
220
221/***====================================================================***/
222
223/*
224 * make a byte from the first two hex characters in glyph picture
225 */
226
227unsigned char
228bdfHexByte(unsigned char *s)
229{
230    unsigned char b = 0;
231    register char c;
232    int         i;
233
234    for (i = 2; i; i--) {
235	c = *s++;
236	if ((c >= '0') && (c <= '9'))
237	    b = (b << 4) + (c - '0');
238	else if ((c >= 'A') && (c <= 'F'))
239	    b = (b << 4) + 10 + (c - 'A');
240	else if ((c >= 'a') && (c <= 'f'))
241	    b = (b << 4) + 10 + (c - 'a');
242	else
243	    bdfError("bad hex char '%c'", c);
244    }
245    return b;
246}
247
248/***====================================================================***/
249
250/*
251 * check for known special property values
252 */
253
254static const char *SpecialAtoms[] = {
255    "FONT_ASCENT",
256#define BDF_FONT_ASCENT	0
257    "FONT_DESCENT",
258#define BDF_FONT_DESCENT 1
259    "DEFAULT_CHAR",
260#define BDF_DEFAULT_CHAR 2
261    "POINT_SIZE",
262#define BDF_POINT_SIZE 3
263    "RESOLUTION",
264#define BDF_RESOLUTION 4
265    "X_HEIGHT",
266#define BDF_X_HEIGHT 5
267    "WEIGHT",
268#define BDF_WEIGHT 6
269    "QUAD_WIDTH",
270#define BDF_QUAD_WIDTH 7
271    "FONT",
272#define BDF_FONT 8
273    "RESOLUTION_X",
274#define BDF_RESOLUTION_X 9
275    "RESOLUTION_Y",
276#define BDF_RESOLUTION_Y 10
277    0,
278};
279
280Bool
281bdfSpecialProperty(FontPtr pFont, FontPropPtr prop,
282		   char isString, bdfFileState *bdfState)
283{
284    const char      **special;
285    const char       *name;
286
287    name = NameForAtom(prop->name);
288    for (special = SpecialAtoms; *special; special++)
289	if (!strcmp(name, *special))
290	    break;
291
292    switch (special - SpecialAtoms) {
293    case BDF_FONT_ASCENT:
294	if (!isString) {
295	    pFont->info.fontAscent = prop->value;
296	    bdfState->haveFontAscent = TRUE;
297	}
298	return TRUE;
299    case BDF_FONT_DESCENT:
300	if (!isString) {
301	    pFont->info.fontDescent = prop->value;
302	    bdfState->haveFontDescent = TRUE;
303	}
304	return TRUE;
305    case BDF_DEFAULT_CHAR:
306	if (!isString) {
307	    pFont->info.defaultCh = prop->value;
308	    bdfState->haveDefaultCh = TRUE;
309	}
310	return TRUE;
311    case BDF_POINT_SIZE:
312	bdfState->pointSizeProp = prop;
313	return FALSE;
314    case BDF_RESOLUTION:
315	bdfState->resolutionProp = prop;
316	return FALSE;
317    case BDF_X_HEIGHT:
318	bdfState->xHeightProp = prop;
319	return FALSE;
320    case BDF_WEIGHT:
321	bdfState->weightProp = prop;
322	return FALSE;
323    case BDF_QUAD_WIDTH:
324	bdfState->quadWidthProp = prop;
325	return FALSE;
326    case BDF_FONT:
327	bdfState->fontProp = prop;
328	return FALSE;
329    case BDF_RESOLUTION_X:
330	bdfState->resolutionXProp = prop;
331	return FALSE;
332    case BDF_RESOLUTION_Y:
333	bdfState->resolutionYProp = prop;
334	return FALSE;
335    default:
336	return FALSE;
337    }
338}
339