| 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 | } |