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