Bug Summary

File:bitmap/bdfread.c
Location:line 143, column 6
Description:Array access (from variable 'picture') results in a null pointer dereference

Annotated Source Code

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_H1
53#include <config.h>
54#endif
55
56#include <ctype.h>
57#include <X11/fonts/fntfilst.h>
58#include <X11/fonts/fontutil.h>
59/* use bitmap structure */
60#include <X11/fonts/bitmap.h>
61#include <X11/fonts/bdfint.h>
62
63#if HAVE_STDINT_H1
64#include <stdint.h>
65#elif !defined(INT32_MAX(2147483647))
66#define INT32_MAX(2147483647) 0x7fffffff
67#endif
68
69#define INDICES256 256
70#define MAXENCODING0xFFFF 0xFFFF
71#define BDFLINELEN1024 1024
72
73static Bool bdfPadToTerminal(FontPtr pFont);
74extern int bdfFileLineNum;
75
76/***====================================================================***/
77
78static Bool
79bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
80 int glyph, int scan, CARD32 *sizes)
81{
82 int widthBits,
83 widthBytes,
84 widthHexChars;
85 int height,
86 row;
87 int i,
88 inLineLen,
89 nextByte;
90 unsigned char *pInBits,
91 *picture,
92 *line = NULL((void*)0);
93 unsigned char lineBuf[BDFLINELEN1024];
94
95 widthBits = GLYPHWIDTHPIXELS(pCI)((pCI)->metrics.rightSideBearing - (pCI)->metrics.leftSideBearing
)
;
96 height = GLYPHHEIGHTPIXELS(pCI)((pCI)->metrics.ascent + (pCI)->metrics.descent);
97
98 widthBytes = BYTES_PER_ROW(widthBits, glyph)((glyph) == 1 ? (((widthBits)+7)>>3) :(glyph) == 2 ? ((
((widthBits)+15)>>3)&~1) :(glyph) == 4 ? ((((widthBits
)+31)>>3)&~3) :(glyph) == 8 ? ((((widthBits)+63)>>
3)&~7) : 0)
;
1
Within the expansion of the macro 'BYTES_PER_ROW':
a
Assuming 'glyph' is not equal to 1
b
Assuming 'glyph' is not equal to 2
c
Assuming 'glyph' is not equal to 4
d
Assuming 'glyph' is not equal to 8
99 if (widthBytes * height > 0) {
2
Taking false branch
100 picture = malloc(widthBytes * height);
101 if (!picture) {
102 bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
103 goto BAILOUT;
104 }
105 } else
106 picture = NULL((void*)0);
107 pCI->bits = (char *) picture;
108
109 if (sizes) {
3
Assuming 'sizes' is null
4
Taking false branch
110 for (i = 0; i < GLYPHPADOPTIONS4; i++)
111 sizes[i] += BYTES_PER_ROW(widthBits, (1 << i))(((1 << i)) == 1 ? (((widthBits)+7)>>3) :((1 <<
i)) == 2 ? ((((widthBits)+15)>>3)&~1) :((1 <<
i)) == 4 ? ((((widthBits)+31)>>3)&~3) :((1 <<
i)) == 8 ? ((((widthBits)+63)>>3)&~7) : 0)
* height;
112 }
113 nextByte = 0;
114 widthHexChars = BYTES_PER_ROW(widthBits, 1)((1) == 1 ? (((widthBits)+7)>>3) :(1) == 2 ? ((((widthBits
)+15)>>3)&~1) :(1) == 4 ? ((((widthBits)+31)>>
3)&~3) :(1) == 8 ? ((((widthBits)+63)>>3)&~7) :
0)
;
115
116/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
117/* 0 width characters? */
118
119 for (row = 0; row < height; row++) {
5
Assuming 'row' is < 'height'
6
Loop condition is true. Entering loop body
120 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
121 if (!line)
7
Assuming 'line' is non-null
8
Taking false branch
122 break;
123
124 if (widthBits == 0) {
9
Assuming 'widthBits' is not equal to 0
10
Taking false branch
125 if ((!line) || (bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR")))))
126 break;
127 else
128 continue;
129 }
130 pInBits = line;
131 inLineLen = strlen((char *) pInBits);
132
133 if (inLineLen & 1) {
11
Taking false branch
134 bdfError("odd number of characters in hex encoding\n");
135 line[inLineLen++] = '0';
136 line[inLineLen] = '\0';
137 }
138 inLineLen >>= 1;
139 i = inLineLen;
140 if (i > widthHexChars)
12
Taking false branch
141 i = widthHexChars;
142 for (; i > 0; i--, pInBits += 2)
13
Assuming 'i' is > 0
14
Loop condition is true. Entering loop body
143 picture[nextByte++] = bdfHexByte(pInBits);
15
Array access (from variable 'picture') results in a null pointer dereference
144
145 /* pad if line is too short */
146 if (inLineLen < widthHexChars) {
147 for (i = widthHexChars - inLineLen; i > 0; i--)
148 picture[nextByte++] = 0;
149 } else {
150 unsigned char mask;
151
152 mask = 0xff << (8 - (widthBits & 0x7));
153 if (mask && picture[nextByte - 1] & ~mask) {
154 picture[nextByte - 1] &= mask;
155 }
156 }
157
158 if (widthBytes > widthHexChars) {
159 i = widthBytes - widthHexChars;
160 while (i-- > 0)
161 picture[nextByte++] = 0;
162 }
163 }
164
165 if ((line && (!bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))))) || (height == 0))
166 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
167
168 if ((!line) || (!bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))))) {
169 bdfError("missing 'ENDCHAR'\n");
170 goto BAILOUT;
171 }
172 if (nextByte != height * widthBytes) {
173 bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
174 nextByte, height, widthBytes);
175 goto BAILOUT;
176 }
177 if (picture != NULL((void*)0)) {
178 if (bit == LSBFirst0)
179 BitOrderInvert(picture, nextByte);
180 if (bit != byte) {
181 if (scan == 2)
182 TwoByteSwap(picture, nextByte);
183 else if (scan == 4)
184 FourByteSwap(picture, nextByte);
185 }
186 }
187 return (TRUE1);
188BAILOUT:
189 if (picture)
190 free(picture);
191 pCI->bits = NULL((void*)0);
192 return (FALSE0);
193}
194
195/***====================================================================***/
196
197static Bool
198bdfSkipBitmap(FontFilePtr file, int height)
199{
200 unsigned char *line;
201 int i = 0;
202 unsigned char lineBuf[BDFLINELEN1024];
203
204 do {
205 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
206 i++;
207 } while (line && !bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR"))) && i <= height);
208
209 if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")(!strncmp((char *)line,"ENDCHAR",strlen("ENDCHAR")))) {
210 bdfError("Error in bitmap, missing 'ENDCHAR'\n");
211 return (FALSE0);
212 }
213 return (TRUE1);
214}
215
216/***====================================================================***/
217
218static void
219bdfFreeFontBits(FontPtr pFont)
220{
221 BitmapFontPtr bitmapFont;
222 BitmapExtraPtr bitmapExtra;
223 int i, nencoding;
224
225 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
226 bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
227 free(bitmapFont->ink_metrics);
228 if(bitmapFont->encoding) {
229 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
230 (pFont->info.lastRow - pFont->info.firstRow + 1);
231 for(i=0; i<NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128); i++)
232 free(bitmapFont->encoding[i]);
233 }
234 free(bitmapFont->encoding);
235 for (i = 0; i < bitmapFont->num_chars; i++)
236 free(bitmapFont->metrics[i].bits);
237 free(bitmapFont->metrics);
238 if (bitmapExtra)
239 {
240 free (bitmapExtra->glyphNames);
241 free (bitmapExtra->sWidths);
242 free (bitmapExtra);
243 }
244 free(pFont->info.props);
245 free(bitmapFont);
246}
247
248
249static Bool
250bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
251 int bit, int byte, int glyph, int scan)
252{
253 unsigned char *line;
254 register CharInfoPtr ci;
255 int i,
256 ndx,
257 nchars,
258 nignored;
259 unsigned int char_row, char_col;
260 int numEncodedGlyphs = 0;
261 CharInfoPtr *bdfEncoding[256];
262 BitmapFontPtr bitmapFont;
263 BitmapExtraPtr bitmapExtra;
264 CARD32 *bitmapsSizes;
265 unsigned char lineBuf[BDFLINELEN1024];
266 int nencoding;
267
268 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
269 bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
270
271 if (bitmapExtra) {
272 bitmapsSizes = bitmapExtra->bitmapsSizes;
273 for (i = 0; i < GLYPHPADOPTIONS4; i++)
274 bitmapsSizes[i] = 0;
275 } else
276 bitmapsSizes = NULL((void*)0);
277
278 bzero(bdfEncoding, sizeof(bdfEncoding))memset(bdfEncoding,0,sizeof(bdfEncoding));
279 bitmapFont->metrics = NULL((void*)0);
280 ndx = 0;
281
282 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
283
284 if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
285 bdfError("bad 'CHARS' in bdf file\n");
286 return (FALSE0);
287 }
288 if (nchars < 1) {
289 bdfError("invalid number of CHARS in BDF file\n");
290 return (FALSE0);
291 }
292 if (nchars > INT32_MAX(2147483647) / sizeof(CharInfoRec)) {
293 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
294 (int) sizeof(CharInfoRec));
295 goto BAILOUT;
296 }
297 ci = calloc(nchars, sizeof(CharInfoRec));
298 if (!ci) {
299 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
300 (int) sizeof(CharInfoRec));
301 goto BAILOUT;
302 }
303 bitmapFont->metrics = ci;
304
305 if (bitmapExtra) {
306 bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
307 if (!bitmapExtra->glyphNames) {
308 bdfError("Couldn't allocate glyphNames (%d*%d)\n",
309 nchars, (int) sizeof(Atom));
310 goto BAILOUT;
311 }
312 }
313 if (bitmapExtra) {
314 bitmapExtra->sWidths = malloc(nchars * sizeof(int));
315 if (!bitmapExtra->sWidths) {
316 bdfError("Couldn't allocate sWidth (%d *%d)\n",
317 nchars, (int) sizeof(int));
318 return FALSE0;
319 }
320 }
321 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
322 pFont->info.firstRow = 256;
323 pFont->info.lastRow = 0;
324 pFont->info.firstCol = 256;
325 pFont->info.lastCol = 0;
326 nignored = 0;
327 for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR")(!strncmp((char *)line,"STARTCHAR",strlen("STARTCHAR"))));) {
328 int t;
329 int wx; /* x component of width */
330 int wy; /* y component of width */
331 int bw; /* bounding-box width */
332 int bh; /* bounding-box height */
333 int bl; /* bounding-box left */
334 int bb; /* bounding-box bottom */
335 int enc,
336 enc2; /* encoding */
337 unsigned char *p; /* temp pointer into line */
338 char charName[100];
339 int ignore;
340
341 if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
342 bdfError("bad character name in BDF file\n");
343 goto BAILOUT; /* bottom of function, free and return error */
344 }
345 if (bitmapExtra)
346 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL((void*)0));
347
348 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
349 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
350 bdfError("bad 'ENCODING' in BDF file\n");
351 goto BAILOUT;
352 }
353 if (enc < -1 || (t == 2 && enc2 < -1)) {
354 bdfError("bad ENCODING value");
355 goto BAILOUT;
356 }
357 if (t == 2 && enc == -1)
358 enc = enc2;
359 ignore = 0;
360 if (enc == -1) {
361 if (!bitmapExtra) {
362 nignored++;
363 ignore = 1;
364 }
365 } else if (enc > MAXENCODING0xFFFF) {
366 bdfError("char '%s' has encoding too large (%d)\n",
367 charName, enc);
368 } else {
369 char_row = (enc >> 8) & 0xFF;
370 char_col = enc & 0xFF;
371 if (char_row < pFont->info.firstRow)
372 pFont->info.firstRow = char_row;
373 if (char_row > pFont->info.lastRow)
374 pFont->info.lastRow = char_row;
375 if (char_col < pFont->info.firstCol)
376 pFont->info.firstCol = char_col;
377 if (char_col > pFont->info.lastCol)
378 pFont->info.lastCol = char_col;
379 if (bdfEncoding[char_row] == (CharInfoPtr *) NULL((void*)0)) {
380 bdfEncoding[char_row] = malloc(256 * sizeof(CharInfoPtr));
381 if (!bdfEncoding[char_row]) {
382 bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
383 char_row, INDICES256, (int) sizeof(CharInfoPtr));
384 goto BAILOUT;
385 }
386 for (i = 0; i < 256; i++)
387 bdfEncoding[char_row][i] = (CharInfoPtr) NULL((void*)0);
388 }
389 if (bdfEncoding[char_row] != NULL((void*)0)) {
390 bdfEncoding[char_row][char_col] = ci;
391 numEncodedGlyphs++;
392 }
393 }
394
395 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
396 if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
397 bdfError("bad 'SWIDTH'\n");
398 goto BAILOUT;
399 }
400 if (wy != 0) {
401 bdfError("SWIDTH y value must be zero\n");
402 goto BAILOUT;
403 }
404 if (bitmapExtra)
405 bitmapExtra->sWidths[ndx] = wx;
406
407/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
408/* from all of these. */
409
410 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
411 if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
412 bdfError("bad 'DWIDTH'\n");
413 goto BAILOUT;
414 }
415 if (wy != 0) {
416 bdfError("DWIDTH y value must be zero\n");
417 goto BAILOUT;
418 }
419 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
420 if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
421 bdfError("bad 'BBX'\n");
422 goto BAILOUT;
423 }
424 if ((bh < 0) || (bw < 0)) {
425 bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
426 charName, bw, bh);
427 goto BAILOUT;
428 }
429 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
430 if ((line) && (bdfIsPrefix(line, "ATTRIBUTES")(!strncmp((char *)line,"ATTRIBUTES",strlen("ATTRIBUTES"))))) {
431 for (p = line + strlen("ATTRIBUTES ");
432 (*p == ' ') || (*p == '\t');
433 p++)
434 /* empty for loop */ ;
435 ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
436 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
437 } else
438 ci->metrics.attributes = 0;
439
440 if (!line || !bdfIsPrefix(line, "BITMAP")(!strncmp((char *)line,"BITMAP",strlen("BITMAP")))) {
441 bdfError("missing 'BITMAP'\n");
442 goto BAILOUT;
443 }
444 /* collect data for generated properties */
445 if ((strlen(charName) == 1)) {
446 if ((charName[0] >= '0') && (charName[0] <= '9')) {
447 pState->digitWidths += wx;
448 pState->digitCount++;
449 } else if (charName[0] == 'x') {
450 pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
451 }
452 }
453 if (!ignore) {
454 ci->metrics.leftSideBearing = bl;
455 ci->metrics.rightSideBearing = bl + bw;
456 ci->metrics.ascent = bh + bb;
457 ci->metrics.descent = -bb;
458 ci->metrics.characterWidth = wx;
459 ci->bits = NULL((void*)0);
460 bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
461 ci++;
462 ndx++;
463 } else
464 bdfSkipBitmap(file, bh);
465
466 line = bdfGetLine(file, lineBuf, BDFLINELEN1024); /* get STARTCHAR or
467 * ENDFONT */
468 }
469
470 if (ndx + nignored != nchars) {
471 bdfError("%d too few characters\n", nchars - (ndx + nignored));
472 goto BAILOUT;
473 }
474 nchars = ndx;
475 bitmapFont->num_chars = nchars;
476 if ((line) && (bdfIsPrefix(line, "STARTCHAR")(!strncmp((char *)line,"STARTCHAR",strlen("STARTCHAR"))))) {
477 bdfError("more characters than specified\n");
478 goto BAILOUT;
479 }
480 if ((!line) || (!bdfIsPrefix(line, "ENDFONT")(!strncmp((char *)line,"ENDFONT",strlen("ENDFONT"))))) {
481 bdfError("missing 'ENDFONT'\n");
482 goto BAILOUT;
483 }
484 if (numEncodedGlyphs == 0)
485 bdfWarning("No characters with valid encodings\n");
486
487 nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
488 (pFont->info.lastCol - pFont->info.firstCol + 1);
489 bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128),sizeof(CharInfoPtr*));
490 if (!bitmapFont->encoding) {
491 bdfError("Couldn't allocate ppCI (%d,%d)\n",
492 NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128),
493 (int) sizeof(CharInfoPtr*));
494 goto BAILOUT;
495 }
496 pFont->info.allExist = TRUE1;
497 i = 0;
498 for (char_row = pFont->info.firstRow;
499 char_row <= pFont->info.lastRow;
500 char_row++) {
501 if (bdfEncoding[char_row] == (CharInfoPtr *) NULL((void*)0)) {
502 pFont->info.allExist = FALSE0;
503 i += pFont->info.lastCol - pFont->info.firstCol + 1;
504 } else {
505 for (char_col = pFont->info.firstCol;
506 char_col <= pFont->info.lastCol;
507 char_col++) {
508 if (!bdfEncoding[char_row][char_col])
509 pFont->info.allExist = FALSE0;
510 else {
511 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]) {
512 bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]=
513 calloc(BITMAP_FONT_SEGMENT_SIZE128,
514 sizeof(CharInfoPtr));
515 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)])
516 goto BAILOUT;
517 }
518 ACCESSENCODINGL(bitmapFont->encoding,i)(bitmapFont->encoding[(i)/128][(i)%128]) =
519 bdfEncoding[char_row][char_col];
520 }
521 i++;
522 }
523 }
524 }
525 for (i = 0; i < 256; i++)
526 if (bdfEncoding[i])
527 free(bdfEncoding[i]);
528 return (TRUE1);
529BAILOUT:
530 for (i = 0; i < 256; i++)
531 if (bdfEncoding[i])
532 free(bdfEncoding[i]);
533 /* bdfFreeFontBits will clean up the rest */
534 return (FALSE0);
535}
536
537/***====================================================================***/
538
539static Bool
540bdfReadHeader(FontFilePtr file, bdfFileState *pState)
541{
542 unsigned char *line;
543 char namebuf[BDFLINELEN1024];
544 unsigned char lineBuf[BDFLINELEN1024];
545
546 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
547 if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
548 !bdfStrEqual(namebuf, "2.1")(!strcmp(namebuf,"2.1"))) {
549 bdfError("bad 'STARTFONT'\n");
550 return (FALSE0);
551 }
552 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
553 if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
554 bdfError("bad 'FONT'\n");
555 return (FALSE0);
556 }
557 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
558 if (!line || !bdfIsPrefix(line, "SIZE")(!strncmp((char *)line,"SIZE",strlen("SIZE")))) {
559 bdfError("missing 'SIZE'\n");
560 return (FALSE0);
561 }
562 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
563 &pState->resolution_x, &pState->resolution_y) != 3) {
564 bdfError("bad 'SIZE'\n");
565 return (FALSE0);
566 }
567 if (pState->pointSize < 1 ||
568 pState->resolution_x < 1 || pState->resolution_y < 1) {
569 bdfError("SIZE values must be > 0\n");
570 return (FALSE0);
571 }
572 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
573 if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")(!strncmp((char *)line,"FONTBOUNDINGBOX",strlen("FONTBOUNDINGBOX"
)))
) {
574 bdfError("missing 'FONTBOUNDINGBOX'\n");
575 return (FALSE0);
576 }
577 return (TRUE1);
578}
579
580/***====================================================================***/
581
582static Bool
583bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
584{
585 int nProps, props_left,
586 nextProp;
587 char *stringProps;
588 FontPropPtr props;
589 char namebuf[BDFLINELEN1024],
590 secondbuf[BDFLINELEN1024],
591 thirdbuf[BDFLINELEN1024];
592 unsigned char *line;
593 unsigned char lineBuf[BDFLINELEN1024];
594 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
595
596 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
597 if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")(!strncmp((char *)line,"STARTPROPERTIES",strlen("STARTPROPERTIES"
)))
) {
598 bdfError("missing 'STARTPROPERTIES'\n");
599 return (FALSE0);
600 }
601 if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
602 bdfError("bad 'STARTPROPERTIES'\n");
603 return (FALSE0);
604 }
605 pFont->info.isStringProp = NULL((void*)0);
606 pFont->info.props = NULL((void*)0);
607 pFont->info.nprops = 0;
608
609 stringProps = malloc((nProps + BDF_GENPROPS6) * sizeof(char));
610 pFont->info.isStringProp = stringProps;
611 if (stringProps == NULL((void*)0)) {
612 bdfError("Couldn't allocate stringProps (%d*%d)\n",
613 (nProps + BDF_GENPROPS6), (int) sizeof(Bool));
614 goto BAILOUT;
615 }
616 pFont->info.props = props = calloc(nProps + BDF_GENPROPS6,
617 sizeof(FontPropRec));
618 if (props == NULL((void*)0)) {
619 bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS6,
620 (int) sizeof(FontPropRec));
621 goto BAILOUT;
622 }
623
624 nextProp = 0;
625 props_left = nProps;
626 while (props_left-- > 0) {
627 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
628 if (line == NULL((void*)0) || bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
) {
629 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
630 nProps, nProps - props_left - 1);
631 goto BAILOUT;
632 }
633 while (*line && isspace(*line)((*__ctype_b_loc ())[(int) ((*line))] & (unsigned short int
) _ISspace)
)
634 line++;
635
636 switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
637 default:
638 bdfError("missing '%s' parameter value\n", namebuf);
639 goto BAILOUT;
640
641 case 2:
642 /*
643 * Possibilites include: valid quoted string with no white space
644 * valid integer value invalid value
645 */
646 if (secondbuf[0] == '"') {
647 stringProps[nextProp] = TRUE1;
648 props[nextProp].value =
649 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
650 if (!props[nextProp].value)
651 goto BAILOUT;
652 break;
653 } else if (bdfIsInteger(secondbuf)) {
654 stringProps[nextProp] = FALSE0;
655 props[nextProp].value = atoi(secondbuf);
656 break;
657 } else {
658 bdfError("invalid '%s' parameter value\n", namebuf);
659 goto BAILOUT;
660 }
661
662 case 3:
663 /*
664 * Possibilites include: valid quoted string with some white space
665 * invalid value (reject even if second string is integer)
666 */
667 if (secondbuf[0] == '"') {
668 stringProps[nextProp] = TRUE1;
669 props[nextProp].value =
670 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
671 if (!props[nextProp].value)
672 goto BAILOUT;
673 break;
674 } else {
675 bdfError("invalid '%s' parameter value\n", namebuf);
676 goto BAILOUT;
677 }
678 }
679 props[nextProp].name = bdfForceMakeAtom(namebuf, NULL((void*)0));
680 if (props[nextProp].name == None0l) {
681 bdfError("Empty property name.\n");
682 goto BAILOUT;
683 }
684 if (!bdfSpecialProperty(pFont, &props[nextProp],
685 stringProps[nextProp], pState))
686 nextProp++;
687 }
688
689 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
690 if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
) {
691 bdfError("missing 'ENDPROPERTIES'\n");
692 goto BAILOUT;
693 }
694 if (!pState->haveFontAscent || !pState->haveFontDescent) {
695 bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
696 goto BAILOUT;
697 }
698 if (bitmapFont->bitmapExtra) {
699 bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
700 bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
701 }
702 if (!pState->pointSizeProp) {
703 props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL((void*)0));
704 props[nextProp].value = (INT32) (pState->pointSize * 10.0);
705 stringProps[nextProp] = FALSE0;
706 pState->pointSizeProp = &props[nextProp];
707 nextProp++;
708 }
709 if (!pState->fontProp) {
710 props[nextProp].name = bdfForceMakeAtom("FONT", NULL((void*)0));
711 props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL((void*)0));
712 stringProps[nextProp] = TRUE1;
713 pState->fontProp = &props[nextProp];
714 nextProp++;
715 }
716 if (!pState->weightProp) {
717 props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL((void*)0));
718 props[nextProp].value = -1; /* computed later */
719 stringProps[nextProp] = FALSE0;
720 pState->weightProp = &props[nextProp];
721 nextProp++;
722 }
723 if (!pState->resolutionProp &&
724 pState->resolution_x == pState->resolution_y) {
725 props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL((void*)0));
726 props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
727 stringProps[nextProp] = FALSE0;
728 pState->resolutionProp = &props[nextProp];
729 nextProp++;
730 }
731 if (!pState->resolutionXProp) {
732 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL((void*)0));
733 props[nextProp].value = (INT32) pState->resolution_x;
734 stringProps[nextProp] = FALSE0;
735 pState->resolutionProp = &props[nextProp];
736 nextProp++;
737 }
738 if (!pState->resolutionYProp) {
739 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL((void*)0));
740 props[nextProp].value = (INT32) pState->resolution_y;
741 stringProps[nextProp] = FALSE0;
742 pState->resolutionProp = &props[nextProp];
743 nextProp++;
744 }
745 if (!pState->xHeightProp) {
746 props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL((void*)0));
747 props[nextProp].value = -1; /* computed later */
748 stringProps[nextProp] = FALSE0;
749 pState->xHeightProp = &props[nextProp];
750 nextProp++;
751 }
752 if (!pState->quadWidthProp) {
753 props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL((void*)0));
754 props[nextProp].value = -1; /* computed later */
755 stringProps[nextProp] = FALSE0;
756 pState->quadWidthProp = &props[nextProp];
757 nextProp++;
758 }
759 pFont->info.nprops = nextProp;
760 return (TRUE1);
761BAILOUT:
762 if (pFont->info.isStringProp) {
763 free(pFont->info.isStringProp);
764 pFont->info.isStringProp = NULL((void*)0);
765 }
766 if (pFont->info.props) {
767 free(pFont->info.props);
768 pFont->info.props = NULL((void*)0);
769 }
770 while (line && bdfIsPrefix(line, "ENDPROPERTIES")(!strncmp((char *)line,"ENDPROPERTIES",strlen("ENDPROPERTIES"
)))
)
771 line = bdfGetLine(file, lineBuf, BDFLINELEN1024);
772 return (FALSE0);
773}
774
775/***====================================================================***/
776
777static void
778bdfUnloadFont(FontPtr pFont)
779{
780 bdfFreeFontBits (pFont);
781 DestroyFontRec(pFont);
782}
783
784int
785bdfReadFont(FontPtr pFont, FontFilePtr file,
786 int bit, int byte, int glyph, int scan)
787{
788 bdfFileState state;
789 xCharInfo *min,
790 *max;
791 BitmapFontPtr bitmapFont;
792
793 pFont->fontPrivate = 0;
794
795 bzero(&state, sizeof(bdfFileState))memset(&state,0,sizeof(bdfFileState));
796 bdfFileLineNum = 0;
797
798 if (!bdfReadHeader(file, &state))
799 goto BAILOUT;
800
801 bitmapFont = calloc(1, sizeof(BitmapFontRec));
802 if (!bitmapFont) {
803 bdfError("Couldn't allocate bitmapFontRec (%d)\n",
804 (int) sizeof(BitmapFontRec));
805 goto BAILOUT;
806 }
807
808 pFont->fontPrivate = (pointer) bitmapFont;
809 bitmapFont->metrics = 0;
810 bitmapFont->ink_metrics = 0;
811 bitmapFont->bitmaps = 0;
812 bitmapFont->encoding = 0;
813 bitmapFont->pDefault = NULL((void*)0);
814
815 bitmapFont->bitmapExtra = calloc(1, sizeof(BitmapExtraRec));
816 if (!bitmapFont->bitmapExtra) {
817 bdfError("Couldn't allocate bitmapExtra (%d)\n",
818 (int) sizeof(BitmapExtraRec));
819 goto BAILOUT;
820 }
821
822 bitmapFont->bitmapExtra->glyphNames = 0;
823 bitmapFont->bitmapExtra->sWidths = 0;
824
825 if (!bdfReadProperties(file, pFont, &state))
826 goto BAILOUT;
827
828 if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
829 goto BAILOUT;
830
831 if (state.haveDefaultCh) {
832 unsigned int r, c, cols;
833
834 r = pFont->info.defaultCh >> 8;
835 c = pFont->info.defaultCh & 0xFF;
836 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
837 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
838 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
839 r = r - pFont->info.firstRow;
840 c = c - pFont->info.firstCol;
841 bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,(bitmapFont->encoding[(r * cols + c)/128]?(bitmapFont->
encoding[(r * cols + c)/128][(r * cols + c)%128]):0)
842 r * cols + c)(bitmapFont->encoding[(r * cols + c)/128]?(bitmapFont->
encoding[(r * cols + c)/128][(r * cols + c)%128]):0)
;
843 }
844 }
845 pFont->bit = bit;
846 pFont->byte = byte;
847 pFont->glyph = glyph;
848 pFont->scan = scan;
849 pFont->info.anamorphic = FALSE0;
850 pFont->info.cachable = TRUE1;
851 bitmapComputeFontBounds(pFont);
852 if (FontCouldBeTerminal(&pFont->info)) {
853 bdfPadToTerminal(pFont);
854 bitmapComputeFontBounds(pFont);
855 }
856 FontComputeInfoAccelerators(&pFont->info);
857 if (bitmapFont->bitmapExtra)
858 FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
859 if (pFont->info.constantMetrics) {
860 if (!bitmapAddInkMetrics(pFont)) {
861 bdfError("Failed to add bitmap ink metrics\n");
862 goto BAILOUT;
863 }
864 }
865 if (bitmapFont->bitmapExtra)
866 bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
867
868 bitmapComputeFontInkBounds(pFont);
869/* ComputeFontAccelerators (pFont); */
870
871 /* generate properties */
872 min = &pFont->info.ink_minbounds;
873 max = &pFont->info.ink_maxbounds;
874 if (state.xHeightProp && (state.xHeightProp->value == -1))
875 state.xHeightProp->value = state.exHeight ?
876 state.exHeight : min->ascent;
877
878 if (state.quadWidthProp && (state.quadWidthProp->value == -1))
879 state.quadWidthProp->value = state.digitCount ?
880 (INT32) (state.digitWidths / state.digitCount) :
881 (min->characterWidth + max->characterWidth) / 2;
882
883 if (state.weightProp && (state.weightProp->value == -1))
884 state.weightProp->value = bitmapComputeWeight(pFont);
885
886 pFont->get_glyphs = bitmapGetGlyphs;
887 pFont->get_metrics = bitmapGetMetrics;
888 pFont->unload_font = bdfUnloadFont;
889 pFont->unload_glyphs = NULL((void*)0);
890 return Successful85;
891BAILOUT:
892 if (pFont->fontPrivate)
893 bdfFreeFontBits (pFont);
894 return AllocError80;
895}
896
897int
898bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
899{
900 FontRec font;
901 int ret;
902
903 bzero(&font, sizeof (FontRec))memset(&font,0,sizeof (FontRec));
904
905 ret = bdfReadFont(&font, file, MSBFirst1, LSBFirst0, 1, 1);
906 if (ret == Successful85) {
907 *pFontInfo = font.info;
908 font.info.props = 0;
909 font.info.isStringProp = 0;
910 font.info.nprops = 0;
911 bdfFreeFontBits (&font);
912 }
913 return ret;
914}
915
916static Bool
917bdfPadToTerminal(FontPtr pFont)
918{
919 BitmapFontPtr bitmapFont;
920 BitmapExtraPtr bitmapExtra;
921 int i;
922 int new_size;
923 CharInfoRec new;
924 int w,
925 h;
926
927 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
928
929 bzero(&new, sizeof(CharInfoRec))memset(&new,0,sizeof(CharInfoRec));
930 new.metrics.ascent = pFont->info.fontAscent;
931 new.metrics.descent = pFont->info.fontDescent;
932 new.metrics.leftSideBearing = 0;
933 new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
934 new.metrics.characterWidth = new.metrics.rightSideBearing;
935 new_size = BYTES_FOR_GLYPH(&new, pFont->glyph)(((&new)->metrics.ascent + (&new)->metrics.descent
) * ((pFont->glyph) == 1 ? (((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+7)>>3) :(pFont
->glyph) == 2 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+15)>>3)&
~1) :(pFont->glyph) == 4 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+31)>>3)&
~3) :(pFont->glyph) == 8 ? ((((((&new)->metrics.rightSideBearing
- (&new)->metrics.leftSideBearing))+63)>>3)&
~7) : 0))
;
936
937 for (i = 0; i < bitmapFont->num_chars; i++) {
938 new.bits = malloc(new_size);
939 if (!new.bits) {
940 bdfError("Couldn't allocate bits (%d)\n", new_size);
941 return FALSE0;
942 }
943 FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
944 new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
945 free(bitmapFont->metrics[i].bits);
946 bitmapFont->metrics[i] = new;
947 }
948 bitmapExtra = bitmapFont->bitmapExtra;
949 if (bitmapExtra) {
950 w = GLYPHWIDTHPIXELS(&new)((&new)->metrics.rightSideBearing - (&new)->metrics
.leftSideBearing)
;
951 h = GLYPHHEIGHTPIXELS(&new)((&new)->metrics.ascent + (&new)->metrics.descent
)
;
952 for (i = 0; i < GLYPHPADOPTIONS4; i++)
953 bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
954 (BYTES_PER_ROW(w, 1 << i)((1 << i) == 1 ? (((w)+7)>>3) :(1 << i) == 2
? ((((w)+15)>>3)&~1) :(1 << i) == 4 ? ((((w)
+31)>>3)&~3) :(1 << i) == 8 ? ((((w)+63)>>
3)&~7) : 0)
* h);
955 }
956 return TRUE1;
957}