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