pcfread.c revision a96d7823
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#include "libxfontint.h" 37 38#include <X11/fonts/fntfilst.h> 39#include <X11/fonts/bitmap.h> 40#include <X11/fonts/pcf.h> 41 42#ifndef MAX 43#define MAX(a,b) (((a)>(b)) ? a : b) 44#endif 45 46#include <stdarg.h> 47#include <stdint.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 props[i].name = MakeAtom(strings + props[i].name, 315 strlen(strings + props[i].name), TRUE); 316 if (isStringProp[i]) { 317 props[i].value = MakeAtom(strings + props[i].value, 318 strlen(strings + props[i].value), TRUE); 319 } 320 } 321 free(strings); 322 pFontInfo->isStringProp = isStringProp; 323 pFontInfo->props = props; 324 pFontInfo->nprops = nprops; 325 return TRUE; 326Bail: 327 free(isStringProp); 328 free(props); 329 return FALSE; 330} 331 332 333/* 334 * pcfReadAccel 335 * 336 * Fill in the accelerator information from the font file; used 337 * to read both BDF_ACCELERATORS and old style ACCELERATORS 338 */ 339 340static Bool 341pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file, 342 PCFTablePtr tables, int ntables, CARD32 type) 343{ 344 CARD32 format; 345 CARD32 size; 346 347 if (!pcfSeekToType(file, tables, ntables, type, &format, &size) || 348 IS_EOF(file)) 349 goto Bail; 350 format = pcfGetLSB32(file); 351 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && 352 !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) 353 { 354 goto Bail; 355 } 356 pFontInfo->noOverlap = pcfGetINT8(file, format); 357 pFontInfo->constantMetrics = pcfGetINT8(file, format); 358 pFontInfo->terminalFont = pcfGetINT8(file, format); 359 pFontInfo->constantWidth = pcfGetINT8(file, format); 360 pFontInfo->inkInside = pcfGetINT8(file, format); 361 pFontInfo->inkMetrics = pcfGetINT8(file, format); 362 pFontInfo->drawDirection = pcfGetINT8(file, format); 363 pFontInfo->anamorphic = FALSE; 364 pFontInfo->cachable = TRUE; 365 /* natural alignment */ pcfGetINT8(file, format); 366 pFontInfo->fontAscent = pcfGetINT32(file, format); 367 pFontInfo->fontDescent = pcfGetINT32(file, format); 368 pFontInfo->maxOverlap = pcfGetINT32(file, format); 369 if (IS_EOF(file)) goto Bail; 370 if (!pcfGetMetric(file, format, &pFontInfo->minbounds)) 371 goto Bail; 372 if (!pcfGetMetric(file, format, &pFontInfo->maxbounds)) 373 goto Bail; 374 if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) { 375 if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds)) 376 goto Bail; 377 if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds)) 378 goto Bail; 379 } else { 380 pFontInfo->ink_minbounds = pFontInfo->minbounds; 381 pFontInfo->ink_maxbounds = pFontInfo->maxbounds; 382 } 383 return TRUE; 384Bail: 385 return FALSE; 386} 387 388int 389pcfReadFont(FontPtr pFont, FontFilePtr file, 390 int bit, int byte, int glyph, int scan) 391{ 392 CARD32 format; 393 CARD32 size; 394 BitmapFontPtr bitmapFont = 0; 395 int i; 396 PCFTablePtr tables = 0; 397 int ntables; 398 int nmetrics; 399 int nbitmaps; 400 int sizebitmaps; 401 int nink_metrics; 402 CharInfoPtr metrics = 0; 403 xCharInfo *ink_metrics = 0; 404 char *bitmaps = 0; 405 CharInfoPtr **encoding = 0; 406 int nencoding = 0; 407 int encodingOffset; 408 CARD32 bitmapSizes[GLYPHPADOPTIONS]; 409 CARD32 *offsets = 0; 410 Bool hasBDFAccelerators; 411 412 pFont->info.nprops = 0; 413 pFont->info.props = 0; 414 pFont->info.isStringProp=0; 415 416 if (!(tables = pcfReadTOC(file, &ntables))) 417 goto Bail; 418 419 /* properties */ 420 421 if (!pcfGetProperties(&pFont->info, file, tables, ntables)) 422 goto Bail; 423 424 /* Use the old accelerators if no BDF accelerators are in the file */ 425 426 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS); 427 if (!hasBDFAccelerators) 428 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS)) 429 goto Bail; 430 431 /* metrics */ 432 433 if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) { 434 goto Bail; 435 } 436 format = pcfGetLSB32(file); 437 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && 438 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { 439 goto Bail; 440 } 441 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) 442 nmetrics = pcfGetINT32(file, format); 443 else 444 nmetrics = pcfGetINT16(file, format); 445 if (IS_EOF(file)) goto Bail; 446 if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) { 447 pcfError("pcfReadFont(): invalid file format\n"); 448 goto Bail; 449 } 450 metrics = malloc(nmetrics * sizeof(CharInfoRec)); 451 if (!metrics) { 452 pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", 453 nmetrics, (int) sizeof(CharInfoRec)); 454 goto Bail; 455 } 456 for (i = 0; i < nmetrics; i++) 457 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) { 458 if (!pcfGetMetric(file, format, &(metrics + i)->metrics)) 459 goto Bail; 460 } else { 461 if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics)) 462 goto Bail; 463 } 464 465 /* bitmaps */ 466 467 if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size)) 468 goto Bail; 469 format = pcfGetLSB32(file); 470 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) 471 goto Bail; 472 473 nbitmaps = pcfGetINT32(file, format); 474 if (nbitmaps != nmetrics || IS_EOF(file)) 475 goto Bail; 476 /* nmetrics is already ok, so nbitmap also is */ 477 offsets = malloc(nbitmaps * sizeof(CARD32)); 478 if (!offsets) { 479 pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", 480 nbitmaps, (int) sizeof(CARD32)); 481 goto Bail; 482 } 483 for (i = 0; i < nbitmaps; i++) { 484 offsets[i] = pcfGetINT32(file, format); 485 if (IS_EOF(file)) goto Bail; 486 } 487 488 for (i = 0; i < GLYPHPADOPTIONS; i++) { 489 bitmapSizes[i] = pcfGetINT32(file, format); 490 if (IS_EOF(file)) goto Bail; 491 } 492 493 sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)]; 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); 501 if (IS_EOF(file)) goto Bail; 502 position += sizebitmaps; 503 504 if (PCF_BIT_ORDER(format) != bit) 505 BitOrderInvert((unsigned char *)bitmaps, sizebitmaps); 506 if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) { 507 switch (bit == byte ? PCF_SCAN_UNIT(format) : 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) != glyph) { 519 char *padbitmaps; 520 int sizepadbitmaps; 521 int old, 522 new; 523 xCharInfo *metric; 524 525 sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)]; 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), 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; 549 550 /* ink metrics ? */ 551 552 ink_metrics = NULL; 553 if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) { 554 format = pcfGetLSB32(file); 555 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && 556 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { 557 goto Bail; 558 } 559 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) 560 nink_metrics = pcfGetINT32(file, format); 561 else 562 nink_metrics = pcfGetINT16(file, format); 563 if (IS_EOF(file)) 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)) { 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, &format, &size)) 586 goto Bail; 587 format = pcfGetLSB32(file); 588 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) 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)) 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), 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 = TRUE; 612 for (i = 0; i < nencoding; i++) { 613 encodingOffset = pcfGetINT16(file, format); 614 if (IS_EOF(file)) goto Bail; 615 if (encodingOffset == 0xFFFF) { 616 pFont->info.allExist = FALSE; 617 } else { 618 if(!encoding[SEGMENT_MAJOR(i)]) { 619 encoding[SEGMENT_MAJOR(i)]= 620 calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr)); 621 if(!encoding[SEGMENT_MAJOR(i)]) 622 goto Bail; 623 } 624 ACCESSENCODINGL(encoding, i) = 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)) 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; 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) { 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); 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; 670 pFont->bit = bit; 671 pFont->byte = byte; 672 pFont->glyph = glyph; 673 pFont->scan = scan; 674 free(tables); 675 return Successful; 676Bail: 677 free(ink_metrics); 678 if(encoding) { 679 for(i=0; i<NUM_SEGMENTS(nencoding); 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 AllocError; 693} 694 695int 696pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) 697{ 698 PCFTablePtr tables; 699 int ntables; 700 CARD32 format; 701 CARD32 size; 702 int nencoding; 703 Bool hasBDFAccelerators; 704 705 pFontInfo->isStringProp = NULL; 706 pFontInfo->props = NULL; 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); 720 if (!hasBDFAccelerators) 721 if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS)) 722 goto Bail; 723 724 /* encoding */ 725 726 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size)) 727 goto Bail; 728 format = pcfGetLSB32(file); 729 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) 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)) 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 = TRUE; 746 while (nencoding--) { 747 if (pcfGetINT16(file, format) == 0xFFFF) 748 pFontInfo->allExist = FALSE; 749 if (IS_EOF(file)) goto Bail; 750 } 751 if (IS_EOF(file)) 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)) 757 goto Bail; 758 759 free(tables); 760 return Successful; 761Bail: 762 pFontInfo->nprops = 0; 763 free (pFontInfo->props); 764 free (pFontInfo->isStringProp); 765 free(tables); 766 return AllocError; 767} 768 769static void 770pcfUnloadFont(FontPtr pFont) 771{ 772 BitmapFontPtr bitmapFont; 773 int i,nencoding; 774 775 bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 776 free(bitmapFont->ink_metrics); 777 if(bitmapFont->encoding) { 778 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * 779 (pFont->info.lastRow - pFont->info.firstRow + 1); 780 for(i=0; i<NUM_SEGMENTS(nencoding); 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} 791