Bug Summary

File:bitmap/pcfread.c
Location:line 476, column 15
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2
3Copyright 1990, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * Author: Keith Packard, MIT X Consortium
31 */
32
33#ifdef HAVE_CONFIG_H1
34#include <config.h>
35#endif
36
37#include <X11/fonts/fntfilst.h>
38#include <X11/fonts/bitmap.h>
39#include <X11/fonts/pcf.h>
40
41#ifndef MAX
42#define MAX(a,b)(((a)>(b)) ? a : b) (((a)>(b)) ? a : b)
43#endif
44
45#include <stdarg.h>
46#include <stdint.h>
47
48void
49pcfError(const char* message, ...)
50{
51 va_list args;
52
53 va_start(args, message)__builtin_va_start(args, message);
54
55 fprintf(stderrstderr, "PCF Error: ");
56 vfprintf(stderrstderr, message, args);
57 va_end(args)__builtin_va_end(args);
58}
59
60/* Read PCF font files */
61
62static void pcfUnloadFont ( FontPtr pFont );
63static int position;
64
65
66#define IS_EOF(file)((file)->eof == -1) ((file)->eof == BUFFILEEOF-1)
67
68#define FONT_FILE_GETC_ERR(f)(tmp = ((f)->left-- ? *(f)->bufp++ : ((f)->eof = (*(
f)->input) (f))), BAIL_ON_EOF)
(tmp = FontFileGetc(f)((f)->left-- ? *(f)->bufp++ : ((f)->eof = (*(f)->
input) (f)))
, BAIL_ON_EOF)
69
70static int
71pcfGetLSB32(FontFilePtr file)
72{
73 int c;
74
75 c = FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
;
76 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 8;
77 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 16;
78 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 24;
79 position += 4;
80 return c;
81}
82
83static int
84pcfGetINT32(FontFilePtr file, CARD32 format)
85{
86 int c;
87
88 if (PCF_BYTE_ORDER(format)(((format) & (1<<2))?1:0) == MSBFirst1) {
89 c = FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 24;
90 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 16;
91 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 8;
92 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
;
93 } else {
94 c = FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
;
95 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 8;
96 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 16;
97 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 24;
98 }
99 position += 4;
100 return c;
101}
102
103static int
104pcfGetINT16(FontFilePtr file, CARD32 format)
105{
106 int c;
107
108 if (PCF_BYTE_ORDER(format)(((format) & (1<<2))?1:0) == MSBFirst1) {
109 c = FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 8;
110 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
;
111 } else {
112 c = FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
;
113 c |= FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
<< 8;
114 }
115 position += 2;
116 return c;
117}
118
119#define pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
(position++, FontFileGetc(file)((file)->left-- ? *(file)->bufp++ : ((file)->eof = (
*(file)->input) (file)))
)
120
121static PCFTablePtr
122pcfReadTOC(FontFilePtr file, int *countp)
123{
124 CARD32 version;
125 PCFTablePtr tables;
126 int count;
127 int i;
128
129 position = 0;
130 version = pcfGetLSB32(file);
131 if (version != PCF_FILE_VERSION(('p'<<24)|('c'<<16)|('f'<<8)|1))
132 return (PCFTablePtr) NULL((void*)0);
133 count = pcfGetLSB32(file);
134 if (IS_EOF(file)((file)->eof == -1)) return (PCFTablePtr) NULL((void*)0);
135 if (count < 0 || count > INT32_MAX(2147483647) / sizeof(PCFTableRec)) {
136 pcfError("pcfReadTOC(): invalid file format\n");
137 return NULL((void*)0);
138 }
139 tables = malloc(count * sizeof(PCFTableRec));
140 if (!tables) {
141 pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n",
142 count, (int) sizeof(PCFTableRec));
143 return (PCFTablePtr) NULL((void*)0);
144 }
145 for (i = 0; i < count; i++) {
146 tables[i].type = pcfGetLSB32(file);
147 tables[i].format = pcfGetLSB32(file);
148 tables[i].size = pcfGetLSB32(file);
149 tables[i].offset = pcfGetLSB32(file);
150 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
151 }
152
153 *countp = count;
154 return tables;
155
156 Bail:
157 free(tables);
158 return (PCFTablePtr) NULL((void*)0);
159}
160
161/*
162 * PCF supports two formats for metrics, both the regular
163 * jumbo size, and 'lite' metrics, which are useful
164 * for most fonts which have even vaguely reasonable
165 * metrics
166 */
167
168static Bool
169pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
170{
171 metric->leftSideBearing = pcfGetINT16(file, format);
172 metric->rightSideBearing = pcfGetINT16(file, format);
173 metric->characterWidth = pcfGetINT16(file, format);
174 metric->ascent = pcfGetINT16(file, format);
175 metric->descent = pcfGetINT16(file, format);
176 metric->attributes = pcfGetINT16(file, format);
177 if (IS_EOF(file)((file)->eof == -1)) return FALSE0;
178
179 return TRUE1;
180}
181
182static Bool
183pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
184{
185 metric->leftSideBearing = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
- 0x80;
186 metric->rightSideBearing = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
- 0x80;
187 metric->characterWidth = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
- 0x80;
188 metric->ascent = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
- 0x80;
189 metric->descent = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
- 0x80;
190 metric->attributes = 0;
191 if (IS_EOF(file)((file)->eof == -1)) return FALSE0;
192
193 return TRUE1;
194}
195
196/*
197 * Position the file to the begining of the specified table
198 * in the font file
199 */
200static Bool
201pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables,
202 CARD32 type, CARD32 *formatp, CARD32 *sizep)
203{
204 int i;
205
206 for (i = 0; i < ntables; i++)
207 if (tables[i].type == type) {
208 if (position > tables[i].offset)
209 return FALSE0;
210 if (!FontFileSkip(file, tables[i].offset - position)(((file)->eof = (*(file)->skip) (file, tables[i].offset
- position)) != -1)
)
211 return FALSE0;
212 position = tables[i].offset;
213 *sizep = tables[i].size;
214 *formatp = tables[i].format;
215 return TRUE1;
216 }
217 return FALSE0;
218}
219
220static Bool
221pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
222{
223 int i;
224
225 for (i = 0; i < ntables; i++)
226 if (tables[i].type == type)
227 return TRUE1;
228 return FALSE0;
229}
230
231/*
232 * pcfGetProperties
233 *
234 * Reads the font properties from the font file, filling in the FontInfo rec
235 * supplied. Used by by both ReadFont and ReadFontInfo routines.
236 */
237
238static Bool
239pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file,
240 PCFTablePtr tables, int ntables)
241{
242 FontPropPtr props = 0;
243 int nprops;
244 char *isStringProp = 0;
245 CARD32 format;
246 int i;
247 CARD32 size;
248 int string_size;
249 char *strings;
250
251 /* font properties */
252
253 if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES(1<<0), &format, &size))
254 goto Bail;
255 format = pcfGetLSB32(file);
256 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
257 goto Bail;
258 nprops = pcfGetINT32(file, format);
259 if (nprops <= 0 || nprops > INT32_MAX(2147483647) / sizeof(FontPropRec)) {
260 pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
261 goto Bail;
262 }
263 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
264 props = malloc(nprops * sizeof(FontPropRec));
265 if (!props) {
266 pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n",
267 nprops, (int) sizeof(FontPropRec));
268 goto Bail;
269 }
270 isStringProp = malloc(nprops * sizeof(char));
271 if (!isStringProp) {
272 pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n",
273 nprops, (int) sizeof(char));
274 goto Bail;
275 }
276 for (i = 0; i < nprops; i++) {
277 props[i].name = pcfGetINT32(file, format);
278 isStringProp[i] = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
279 props[i].value = pcfGetINT32(file, format);
280 if (props[i].name < 0
281 || (isStringProp[i] != 0 && isStringProp[i] != 1)
282 || (isStringProp[i] && props[i].value < 0)) {
283 pcfError("pcfGetProperties(): invalid file format %ld %d %ld\n",
284 props[i].name, isStringProp[i], props[i].value);
285 goto Bail;
286 }
287 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
288 }
289 /* pad the property array */
290 /*
291 * clever here - nprops is the same as the number of odd-units read, as
292 * only isStringProp are odd length
293 */
294 if (nprops & 3)
295 {
296 i = 4 - (nprops & 3);
297 (void)FontFileSkip(file, i)(((file)->eof = (*(file)->skip) (file, i)) != -1);
298 position += i;
299 }
300 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
301 string_size = pcfGetINT32(file, format);
302 if (string_size < 0) goto Bail;
303 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
304 strings = malloc(string_size);
305 if (!strings) {
306 pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
307 goto Bail;
308 }
309 FontFileRead(file, strings, string_size)BufFileRead(file,strings,string_size);
310 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
311 position += string_size;
312 for (i = 0; i < nprops; i++) {
313 props[i].name = MakeAtom(strings + props[i].name,
314 strlen(strings + props[i].name), TRUE1);
315 if (isStringProp[i]) {
316 props[i].value = MakeAtom(strings + props[i].value,
317 strlen(strings + props[i].value), TRUE1);
318 }
319 }
320 free(strings);
321 pFontInfo->isStringProp = isStringProp;
322 pFontInfo->props = props;
323 pFontInfo->nprops = nprops;
324 return TRUE1;
325Bail:
326 free(isStringProp);
327 free(props);
328 return FALSE0;
329}
330
331
332/*
333 * pcfReadAccel
334 *
335 * Fill in the accelerator information from the font file; used
336 * to read both BDF_ACCELERATORS and old style ACCELERATORS
337 */
338
339static Bool
340pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file,
341 PCFTablePtr tables, int ntables, CARD32 type)
342{
343 CARD32 format;
344 CARD32 size;
345
346 if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
347 IS_EOF(file)((file)->eof == -1))
348 goto Bail;
349 format = pcfGetLSB32(file);
350 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)) &&
351 !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)(((format)&0xffffff00) == ((0x00000100)&0xffffff00)))
352 {
353 goto Bail;
354 }
355 pFontInfo->noOverlap = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
356 pFontInfo->constantMetrics = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
357 pFontInfo->terminalFont = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
358 pFontInfo->constantWidth = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
359 pFontInfo->inkInside = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
360 pFontInfo->inkMetrics = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
361 pFontInfo->drawDirection = pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
362 pFontInfo->anamorphic = FALSE0;
363 pFontInfo->cachable = TRUE1;
364 /* natural alignment */ pcfGetINT8(file, format)(position++, ((file)->left-- ? *(file)->bufp++ : ((file
)->eof = (*(file)->input) (file))))
;
365 pFontInfo->fontAscent = pcfGetINT32(file, format);
366 pFontInfo->fontDescent = pcfGetINT32(file, format);
367 pFontInfo->maxOverlap = pcfGetINT32(file, format);
368 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
369 if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
370 goto Bail;
371 if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
372 goto Bail;
373 if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)(((format)&0xffffff00) == ((0x00000100)&0xffffff00))) {
374 if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
375 goto Bail;
376 if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
377 goto Bail;
378 } else {
379 pFontInfo->ink_minbounds = pFontInfo->minbounds;
380 pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
381 }
382 return TRUE1;
383Bail:
384 return FALSE0;
385}
386
387int
388pcfReadFont(FontPtr pFont, FontFilePtr file,
389 int bit, int byte, int glyph, int scan)
390{
391 CARD32 format;
392 CARD32 size;
393 BitmapFontPtr bitmapFont = 0;
394 int i;
395 PCFTablePtr tables = 0;
396 int ntables;
397 int nmetrics;
398 int nbitmaps;
399 int sizebitmaps;
400 int nink_metrics;
401 CharInfoPtr metrics = 0;
402 xCharInfo *ink_metrics = 0;
403 char *bitmaps = 0;
404 CharInfoPtr **encoding = 0;
405 int nencoding = 0;
406 int encodingOffset;
407 CARD32 bitmapSizes[GLYPHPADOPTIONS4];
408 CARD32 *offsets = 0;
409 Bool hasBDFAccelerators;
410
411 pFont->info.nprops = 0;
412 pFont->info.props = 0;
413 pFont->info.isStringProp=0;
414
415 if (!(tables = pcfReadTOC(file, &ntables)))
1
Assuming 'tables' is not null
2
Taking false branch
416 goto Bail;
417
418 /* properties */
419
420 if (!pcfGetProperties(&pFont->info, file, tables, ntables))
3
Taking false branch
421 goto Bail;
422
423 /* Use the old accelerators if no BDF accelerators are in the file */
424
425 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS(1<<8));
426 if (!hasBDFAccelerators)
4
Assuming 'hasBDFAccelerators' is not equal to 0
5
Taking false branch
427 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS(1<<1)))
428 goto Bail;
429
430 /* metrics */
431
432 if (!pcfSeekToType(file, tables, ntables, PCF_METRICS(1<<2), &format, &size)) {
6
Taking false branch
433 goto Bail;
434 }
435 format = pcfGetLSB32(file);
436 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)) &&
7
Taking false branch
437 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)(((format)&0xffffff00) == ((0x00000100)&0xffffff00))) {
438 goto Bail;
439 }
440 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
8
Taking true branch
441 nmetrics = pcfGetINT32(file, format);
442 else
443 nmetrics = pcfGetINT16(file, format);
444 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
9
Taking false branch
445 if (nmetrics < 0 || nmetrics > INT32_MAX(2147483647) / sizeof(CharInfoRec)) {
10
Assuming 'nmetrics' is >= 0
11
Taking false branch
446 pcfError("pcfReadFont(): invalid file format\n");
447 goto Bail;
448 }
449 metrics = malloc(nmetrics * sizeof(CharInfoRec));
450 if (!metrics) {
12
Assuming 'metrics' is non-null
13
Taking false branch
451 pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n",
452 nmetrics, (int) sizeof(CharInfoRec));
453 goto Bail;
454 }
455 for (i = 0; i < nmetrics; i++)
14
Assuming 'i' is >= 'nmetrics'
15
Loop condition is false. Execution continues on line 466
456 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00))) {
457 if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
458 goto Bail;
459 } else {
460 if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
461 goto Bail;
462 }
463
464 /* bitmaps */
465
466 if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS(1<<3), &format, &size))
16
Taking false branch
467 goto Bail;
468 format = pcfGetLSB32(file);
469 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
17
Taking false branch
470 goto Bail;
471
472 nbitmaps = pcfGetINT32(file, format);
473 if (nbitmaps != nmetrics || IS_EOF(file)((file)->eof == -1))
18
Assuming 'nbitmaps' is equal to 'nmetrics'
19
Taking false branch
474 goto Bail;
475 /* nmetrics is already ok, so nbitmap also is */
476 offsets = malloc(nbitmaps * sizeof(CARD32));
20
Call to 'malloc' has an allocation size of 0 bytes
477 if (!offsets) {
478 pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n",
479 nbitmaps, (int) sizeof(CARD32));
480 goto Bail;
481 }
482 for (i = 0; i < nbitmaps; i++) {
483 offsets[i] = pcfGetINT32(file, format);
484 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
485 }
486
487 for (i = 0; i < GLYPHPADOPTIONS4; i++) {
488 bitmapSizes[i] = pcfGetINT32(file, format);
489 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
490 if (bitmapSizes[i] < 0) goto Bail;
491 }
492
493 sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)((format) & (3<<0))];
494 /* guard against completely empty font */
495 bitmaps = malloc(sizebitmaps ? sizebitmaps : 1);
496 if (!bitmaps) {
497 pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
498 goto Bail;
499 }
500 FontFileRead(file, bitmaps, sizebitmaps)BufFileRead(file,bitmaps,sizebitmaps);
501 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
502 position += sizebitmaps;
503
504 if (PCF_BIT_ORDER(format)(((format) & (1<<3))?1:0) != bit)
505 BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
506 if ((PCF_BYTE_ORDER(format)(((format) & (1<<2))?1:0) == PCF_BIT_ORDER(format)(((format) & (1<<3))?1:0)) != (bit == byte)) {
507 switch (bit == byte ? PCF_SCAN_UNIT(format)(1<<(((format) & (3<<4)) >> 4)) : scan) {
508 case 1:
509 break;
510 case 2:
511 TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
512 break;
513 case 4:
514 FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
515 break;
516 }
517 }
518 if (PCF_GLYPH_PAD(format)(1<<((format) & (3<<0))) != glyph) {
519 char *padbitmaps;
520 int sizepadbitmaps;
521 int old,
522 new;
523 xCharInfo *metric;
524
525 sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)((glyph) == 4 ? 2 : (glyph) == 2 ? 1 : 0)];
526 padbitmaps = malloc(sizepadbitmaps);
527 if (!padbitmaps) {
528 pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
529 goto Bail;
530 }
531 new = 0;
532 for (i = 0; i < nbitmaps; i++) {
533 old = offsets[i];
534 metric = &metrics[i].metrics;
535 offsets[i] = new;
536 new += RepadBitmap(bitmaps + old, padbitmaps + new,
537 PCF_GLYPH_PAD(format)(1<<((format) & (3<<0))), glyph,
538 metric->rightSideBearing - metric->leftSideBearing,
539 metric->ascent + metric->descent);
540 }
541 free(bitmaps);
542 bitmaps = padbitmaps;
543 }
544 for (i = 0; i < nbitmaps; i++)
545 metrics[i].bits = bitmaps + offsets[i];
546
547 free(offsets);
548 offsets = NULL((void*)0);
549
550 /* ink metrics ? */
551
552 ink_metrics = NULL((void*)0);
553 if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS(1<<4), &format, &size)) {
554 format = pcfGetLSB32(file);
555 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)) &&
556 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)(((format)&0xffffff00) == ((0x00000100)&0xffffff00))) {
557 goto Bail;
558 }
559 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
560 nink_metrics = pcfGetINT32(file, format);
561 else
562 nink_metrics = pcfGetINT16(file, format);
563 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
564 if (nink_metrics != nmetrics)
565 goto Bail;
566 /* nmetrics already checked */
567 ink_metrics = malloc(nink_metrics * sizeof(xCharInfo));
568 if (!ink_metrics) {
569 pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n",
570 nink_metrics, (int) sizeof(xCharInfo));
571 goto Bail;
572 }
573 for (i = 0; i < nink_metrics; i++)
574 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00))) {
575 if (!pcfGetMetric(file, format, ink_metrics + i))
576 goto Bail;
577 } else {
578 if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
579 goto Bail;
580 }
581 }
582
583 /* encoding */
584
585 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS(1<<5), &format, &size))
586 goto Bail;
587 format = pcfGetLSB32(file);
588 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
589 goto Bail;
590
591 pFont->info.firstCol = pcfGetINT16(file, format);
592 pFont->info.lastCol = pcfGetINT16(file, format);
593 pFont->info.firstRow = pcfGetINT16(file, format);
594 pFont->info.lastRow = pcfGetINT16(file, format);
595 pFont->info.defaultCh = pcfGetINT16(file, format);
596 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
597 if (pFont->info.firstCol > pFont->info.lastCol ||
598 pFont->info.firstRow > pFont->info.lastRow ||
599 pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
600
601 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
602 (pFont->info.lastRow - pFont->info.firstRow + 1);
603
604 encoding = calloc(NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128), sizeof(CharInfoPtr*));
605 if (!encoding) {
606 pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n",
607 nencoding, (int) sizeof(CharInfoPtr));
608 goto Bail;
609 }
610
611 pFont->info.allExist = TRUE1;
612 for (i = 0; i < nencoding; i++) {
613 encodingOffset = pcfGetINT16(file, format);
614 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
615 if (encodingOffset == 0xFFFF) {
616 pFont->info.allExist = FALSE0;
617 } else {
618 if(!encoding[SEGMENT_MAJOR(i)((i)/128)]) {
619 encoding[SEGMENT_MAJOR(i)((i)/128)]=
620 calloc(BITMAP_FONT_SEGMENT_SIZE128, sizeof(CharInfoPtr));
621 if(!encoding[SEGMENT_MAJOR(i)((i)/128)])
622 goto Bail;
623 }
624 ACCESSENCODINGL(encoding, i)(encoding[(i)/128][(i)%128]) = metrics + encodingOffset;
625 }
626 }
627
628 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
629
630 if (hasBDFAccelerators)
631 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS(1<<8)))
632 goto Bail;
633
634 bitmapFont = malloc(sizeof *bitmapFont);
635 if (!bitmapFont) {
636 pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n",
637 (int) sizeof *bitmapFont);
638 goto Bail;
639 }
640
641 bitmapFont->version_num = PCF_FILE_VERSION(('p'<<24)|('c'<<16)|('f'<<8)|1);
642 bitmapFont->num_chars = nmetrics;
643 bitmapFont->num_tables = ntables;
644 bitmapFont->metrics = metrics;
645 bitmapFont->ink_metrics = ink_metrics;
646 bitmapFont->bitmaps = bitmaps;
647 bitmapFont->encoding = encoding;
648 bitmapFont->pDefault = (CharInfoPtr) 0;
649 if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR-1) {
650 unsigned int r,
651 c,
652 cols;
653
654 r = pFont->info.defaultCh >> 8;
655 c = pFont->info.defaultCh & 0xFF;
656 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
657 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
658 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
659 r = r - pFont->info.firstRow;
660 c = c - pFont->info.firstCol;
661 bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c)(encoding[(r * cols + c)/128]?(encoding[(r * cols + c)/128][(
r * cols + c)%128]):0)
;
662 }
663 }
664 bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
665 pFont->fontPrivate = (pointer) bitmapFont;
666 pFont->get_glyphs = bitmapGetGlyphs;
667 pFont->get_metrics = bitmapGetMetrics;
668 pFont->unload_font = pcfUnloadFont;
669 pFont->unload_glyphs = NULL((void*)0);
670 pFont->bit = bit;
671 pFont->byte = byte;
672 pFont->glyph = glyph;
673 pFont->scan = scan;
674 free(tables);
675 return Successful85;
676Bail:
677 free(ink_metrics);
678 if(encoding) {
679 for(i=0; i<NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128); i++)
680 free(encoding[i]);
681 }
682 free(encoding);
683 free(bitmaps);
684 free(metrics);
685 free(pFont->info.props);
686 pFont->info.nprops = 0;
687 pFont->info.props = 0;
688 free (pFont->info.isStringProp);
689 free(bitmapFont);
690 free(tables);
691 free(offsets);
692 return AllocError80;
693}
694
695int
696pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
697{
698 PCFTablePtr tables;
699 int ntables;
700 CARD32 format;
701 CARD32 size;
702 int nencoding;
703 Bool hasBDFAccelerators;
704
705 pFontInfo->isStringProp = NULL((void*)0);
706 pFontInfo->props = NULL((void*)0);
707 pFontInfo->nprops = 0;
708
709 if (!(tables = pcfReadTOC(file, &ntables)))
710 goto Bail;
711
712 /* properties */
713
714 if (!pcfGetProperties(pFontInfo, file, tables, ntables))
715 goto Bail;
716
717 /* Use the old accelerators if no BDF accelerators are in the file */
718
719 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS(1<<8));
720 if (!hasBDFAccelerators)
721 if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS(1<<1)))
722 goto Bail;
723
724 /* encoding */
725
726 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS(1<<5), &format, &size))
727 goto Bail;
728 format = pcfGetLSB32(file);
729 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)))
730 goto Bail;
731
732 pFontInfo->firstCol = pcfGetINT16(file, format);
733 pFontInfo->lastCol = pcfGetINT16(file, format);
734 pFontInfo->firstRow = pcfGetINT16(file, format);
735 pFontInfo->lastRow = pcfGetINT16(file, format);
736 pFontInfo->defaultCh = pcfGetINT16(file, format);
737 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
738 if (pFontInfo->firstCol > pFontInfo->lastCol ||
739 pFontInfo->firstRow > pFontInfo->lastRow ||
740 pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
741
742 nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
743 (pFontInfo->lastRow - pFontInfo->firstRow + 1);
744
745 pFontInfo->allExist = TRUE1;
746 while (nencoding--) {
747 if (pcfGetINT16(file, format) == 0xFFFF)
748 pFontInfo->allExist = FALSE0;
749 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
750 }
751 if (IS_EOF(file)((file)->eof == -1)) goto Bail;
752
753 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
754
755 if (hasBDFAccelerators)
756 if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS(1<<8)))
757 goto Bail;
758
759 free(tables);
760 return Successful85;
761Bail:
762 pFontInfo->nprops = 0;
763 free (pFontInfo->props);
764 free (pFontInfo->isStringProp);
765 free(tables);
766 return AllocError80;
767}
768
769static void
770pcfUnloadFont(FontPtr pFont)
771{
772 BitmapFontPtr bitmapFont;
773 int i,nencoding;
774
775 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
776 free(bitmapFont->ink_metrics);
777 if(bitmapFont->encoding) {
778 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
779 (pFont->info.lastRow - pFont->info.firstRow + 1);
780 for(i=0; i<NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128); i++)
781 free(bitmapFont->encoding[i]);
782 }
783 free(bitmapFont->encoding);
784 free(bitmapFont->bitmaps);
785 free(bitmapFont->metrics);
786 free(pFont->info.isStringProp);
787 free(pFont->info.props);
788 free(bitmapFont);
789 DestroyFontRec(pFont);
790}