File: | bitmap/pcfread.c |
Location: | line 476, column 15 |
Description: | Call to 'malloc' has an allocation size of 0 bytes |
1 | /* | ||
2 | |||
3 | Copyright 1990, 1998 The Open Group | ||
4 | |||
5 | Permission to use, copy, modify, distribute, and sell this software and its | ||
6 | documentation for any purpose is hereby granted without fee, provided that | ||
7 | the above copyright notice appear in all copies and that both that | ||
8 | copyright notice and this permission notice appear in supporting | ||
9 | documentation. | ||
10 | |||
11 | The above copyright notice and this permission notice shall be included | ||
12 | in all copies or substantial portions of the Software. | ||
13 | |||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
17 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | OTHER DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | Except as contained in this notice, the name of The Open Group shall | ||
23 | not be used in advertising or otherwise to promote the sale, use or | ||
24 | other dealings in this Software without prior written authorization | ||
25 | from 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 | |||
48 | void | ||
49 | pcfError(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 | |||
62 | static void pcfUnloadFont ( FontPtr pFont ); | ||
63 | static 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 | |||
70 | static int | ||
71 | pcfGetLSB32(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 | |||
83 | static int | ||
84 | pcfGetINT32(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 | |||
103 | static int | ||
104 | pcfGetINT16(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 | |||
121 | static PCFTablePtr | ||
122 | pcfReadTOC(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 | |||
168 | static Bool | ||
169 | pcfGetMetric(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 | |||
182 | static Bool | ||
183 | pcfGetCompressedMetric(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 | */ | ||
200 | static Bool | ||
201 | pcfSeekToType(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 | |||
220 | static Bool | ||
221 | pcfHasType (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 | |||
238 | static Bool | ||
239 | pcfGetProperties(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; | ||
325 | Bail: | ||
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 | |||
339 | static Bool | ||
340 | pcfGetAccel(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; | ||
383 | Bail: | ||
384 | return FALSE0; | ||
385 | } | ||
386 | |||
387 | int | ||
388 | pcfReadFont(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))) | ||
| |||
| |||
416 | goto Bail; | ||
417 | |||
418 | /* properties */ | ||
419 | |||
420 | if (!pcfGetProperties(&pFont->info, file, tables, ntables)) | ||
| |||
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) | ||
| |||
| |||
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)) { | ||
| |||
433 | goto Bail; | ||
434 | } | ||
435 | format = pcfGetLSB32(file); | ||
436 | if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00)) && | ||
| |||
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))) | ||
| |||
441 | nmetrics = pcfGetINT32(file, format); | ||
442 | else | ||
443 | nmetrics = pcfGetINT16(file, format); | ||
444 | if (IS_EOF(file)((file)->eof == -1)) goto Bail; | ||
| |||
445 | if (nmetrics < 0 || nmetrics > INT32_MAX(2147483647) / sizeof(CharInfoRec)) { | ||
| |||
| |||
446 | pcfError("pcfReadFont(): invalid file format\n"); | ||
447 | goto Bail; | ||
448 | } | ||
449 | metrics = malloc(nmetrics * sizeof(CharInfoRec)); | ||
450 | if (!metrics) { | ||
| |||
| |||
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++) | ||
| |||
| |||
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)) | ||
| |||
467 | goto Bail; | ||
468 | format = pcfGetLSB32(file); | ||
469 | if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)(((format)&0xffffff00) == ((0x00000000)&0xffffff00))) | ||
| |||
470 | goto Bail; | ||
471 | |||
472 | nbitmaps = pcfGetINT32(file, format); | ||
473 | if (nbitmaps != nmetrics || IS_EOF(file)((file)->eof == -1)) | ||
| |||
| |||
474 | goto Bail; | ||
475 | /* nmetrics is already ok, so nbitmap also is */ | ||
476 | offsets = malloc(nbitmaps * sizeof(CARD32)); | ||
| |||
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; | ||
676 | Bail: | ||
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 | |||
695 | int | ||
696 | pcfReadFontInfo(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; | ||
761 | Bail: | ||
762 | pFontInfo->nprops = 0; | ||
763 | free (pFontInfo->props); | ||
764 | free (pFontInfo->isStringProp); | ||
765 | free(tables); | ||
766 | return AllocError80; | ||
767 | } | ||
768 | |||
769 | static void | ||
770 | pcfUnloadFont(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 | } |