fontdir.c revision 60da515c
1/* 2 3Copyright 1991, 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 in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27/* 28 * Author: Keith Packard, MIT X Consortium 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include <config.h> 33#endif 34#include "libxfontint.h" 35#include <X11/fonts/fntfilst.h> 36#include <X11/keysym.h> 37#include "src/util/replace.h" 38 39#if HAVE_STDINT_H 40#include <stdint.h> 41#elif !defined(INT32_MAX) 42#define INT32_MAX 0x7fffffff 43#endif 44 45Bool 46FontFileInitTable (FontTablePtr table, int size) 47{ 48 if (size < 0 || (size > INT32_MAX/sizeof(FontEntryRec))) 49 return FALSE; 50 if (size) 51 { 52 table->entries = mallocarray(size, sizeof(FontEntryRec)); 53 if (!table->entries) 54 return FALSE; 55 } 56 else 57 table->entries = 0; 58 table->used = 0; 59 table->size = size; 60 table->sorted = FALSE; 61 return TRUE; 62} 63 64void 65FontFileFreeEntry (FontEntryPtr entry) 66{ 67 FontScalableExtraPtr extra; 68 int i; 69 70 if (entry->name.name) 71 free(entry->name.name); 72 entry->name.name = NULL; 73 74 switch (entry->type) 75 { 76 case FONT_ENTRY_SCALABLE: 77 free (entry->u.scalable.fileName); 78 extra = entry->u.scalable.extra; 79 for (i = 0; i < extra->numScaled; i++) 80 if (extra->scaled[i].vals.ranges) 81 free (extra->scaled[i].vals.ranges); 82 free (extra->scaled); 83 free (extra); 84 break; 85 case FONT_ENTRY_BITMAP: 86 free (entry->u.bitmap.fileName); 87 entry->u.bitmap.fileName = NULL; 88 break; 89 case FONT_ENTRY_ALIAS: 90 free (entry->u.alias.resolved); 91 entry->u.alias.resolved = NULL; 92 break; 93 } 94} 95 96void 97FontFileFreeTable (FontTablePtr table) 98{ 99 int i; 100 101 for (i = 0; i < table->used; i++) 102 FontFileFreeEntry (&table->entries[i]); 103 free (table->entries); 104} 105 106FontDirectoryPtr 107FontFileMakeDir(const char *dirName, int size) 108{ 109 FontDirectoryPtr dir; 110 int dirlen; 111 int needslash = 0; 112 const char *attrib; 113 int attriblen; 114 115#if !defined(WIN32) 116 attrib = strchr(dirName, ':'); 117#else 118 /* OS/2 uses the colon in the drive letter descriptor, skip this */ 119 attrib = strchr(dirName+2, ':'); 120#endif 121 if (attrib) { 122 dirlen = attrib - dirName; 123 attriblen = strlen(attrib); 124 } else { 125 dirlen = strlen(dirName); 126 attriblen = 0; 127 } 128 if (dirlen && dirName[dirlen - 1] != '/') 129 needslash = 1; 130 dir = malloc(sizeof *dir + dirlen + needslash + 1 + 131 (attriblen ? attriblen + 1 : 0)); 132 if (!dir) 133 return (FontDirectoryPtr)0; 134 if (!FontFileInitTable (&dir->scalable, 0)) 135 { 136 free (dir); 137 return (FontDirectoryPtr)0; 138 } 139 if (!FontFileInitTable (&dir->nonScalable, size)) 140 { 141 FontFileFreeTable (&dir->scalable); 142 free (dir); 143 return (FontDirectoryPtr)0; 144 } 145 dir->directory = (char *) (dir + 1); 146 dir->dir_mtime = 0; 147 dir->alias_mtime = 0; 148 if (attriblen) 149 dir->attributes = dir->directory + dirlen + needslash + 1; 150 else 151 dir->attributes = NULL; 152 strncpy(dir->directory, dirName, dirlen); 153 if (needslash) 154 dir->directory[dirlen] = '/'; 155 dir->directory[dirlen + needslash] = '\0'; 156 if (dir->attributes) 157 strlcpy(dir->attributes, attrib, attriblen + 1); 158 return dir; 159} 160 161void 162FontFileFreeDir (FontDirectoryPtr dir) 163{ 164 FontFileFreeTable (&dir->scalable); 165 FontFileFreeTable (&dir->nonScalable); 166 free(dir); 167} 168 169FontEntryPtr 170FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype) 171{ 172 FontEntryPtr entry; 173 int newsize; 174 175 /* can't add entries to a sorted table, pointers get broken! */ 176 if (table->sorted) 177 return (FontEntryPtr) 0; /* "cannot" happen */ 178 if (table->used == table->size) { 179 if (table->size >= ((INT32_MAX / sizeof(FontEntryRec)) - 100)) 180 /* If we've read so many entries we're going to ask for 2gb 181 or more of memory, something is so wrong with this font 182 directory that we should just give up before we overflow. */ 183 return NULL; 184 newsize = table->size + 100; 185 entry = reallocarray(table->entries, newsize, sizeof(FontEntryRec)); 186 if (!entry) 187 return (FontEntryPtr)0; 188 table->size = newsize; 189 table->entries = entry; 190 } 191 entry = &table->entries[table->used]; 192 *entry = *prototype; 193 entry->name.name = malloc(prototype->name.length + 1); 194 if (!entry->name.name) 195 return (FontEntryPtr)0; 196 memcpy (entry->name.name, prototype->name.name, prototype->name.length); 197 entry->name.name[entry->name.length] = '\0'; 198 table->used++; 199 return entry; 200} 201 202/* 203 * Compare two strings just like strcmp, but preserve decimal integer 204 * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" < 205 * "iso10646-1". Strings are sorted as if sequences of digits were 206 * prefixed by a length indicator (i.e., does not ignore leading zeroes). 207 * 208 * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> 209 */ 210#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071') 211 212static int strcmpn(const char *s1, const char *s2) 213{ 214 int digits, predigits = 0; 215 const char *ss1, *ss2; 216 217 while (1) { 218 if (*s1 == 0 && *s2 == 0) 219 return 0; 220 digits = Xisdigit(*s1) && Xisdigit(*s2); 221 if (digits && !predigits) { 222 ss1 = s1; 223 ss2 = s2; 224 while (Xisdigit(*ss1) && Xisdigit(*ss2)) 225 ss1++, ss2++; 226 if (!Xisdigit(*ss1) && Xisdigit(*ss2)) 227 return -1; 228 if (Xisdigit(*ss1) && !Xisdigit(*ss2)) 229 return 1; 230 } 231 if ((unsigned char)*s1 < (unsigned char)*s2) 232 return -1; 233 if ((unsigned char)*s1 > (unsigned char)*s2) 234 return 1; 235 predigits = digits; 236 s1++, s2++; 237 } 238} 239 240 241static int 242FontFileNameCompare(const void* a, const void* b) 243{ 244 FontEntryPtr a_name = (FontEntryPtr) a, 245 b_name = (FontEntryPtr) b; 246 247 return strcmpn(a_name->name.name, b_name->name.name); 248} 249 250void 251FontFileSortTable (FontTablePtr table) 252{ 253 if (!table->sorted) { 254 qsort((char *) table->entries, table->used, sizeof(FontEntryRec), 255 FontFileNameCompare); 256 table->sorted = TRUE; 257 } 258} 259 260void 261FontFileSortDir(FontDirectoryPtr dir) 262{ 263 FontFileSortTable (&dir->scalable); 264 FontFileSortTable (&dir->nonScalable); 265 /* now that the table is fixed in size, swizzle the pointers */ 266 FontFileSwitchStringsToBitmapPointers (dir); 267} 268 269/* 270 Given a Font Table, SetupWildMatch() sets up various pointers and state 271 information so the table can be searched for name(s) that match a given 272 fontname pattern -- which may contain wildcards. Under certain 273 circumstances, SetupWildMatch() will find the one table entry that 274 matches the pattern. If those circumstances do not pertain, 275 SetupWildMatch() returns a range within the the table that should be 276 searched for matching name(s). With the information established by 277 SetupWildMatch(), including state information in "private", the 278 PatternMatch() procedure is then used to test names in the range for a 279 match. 280*/ 281 282#define isWild(c) ((c) == XK_asterisk || (c) == XK_question) 283#define isDigit(c) (XK_0 <= (c) && (c) <= XK_9) 284 285static int 286SetupWildMatch(FontTablePtr table, FontNamePtr pat, 287 int *leftp, int *rightp, int *privatep) 288{ 289 int nDashes; 290 char c; 291 char *t; 292 char *firstWild; 293 char *firstDigit; 294 int first; 295 int center, 296 left, 297 right; 298 int result; 299 char *name; 300 301 name = pat->name; 302 nDashes = pat->ndashes; 303 firstWild = 0; 304 firstDigit = 0; 305 t = name; 306 while ((c = *t++)) { 307 if (isWild(c)) { 308 if (!firstWild) 309 firstWild = t - 1; 310 } 311 if (isDigit(c)) { 312 if (!firstDigit) 313 firstDigit = t - 1; 314 } 315 } 316 left = 0; 317 right = table->used; 318 if (firstWild) 319 *privatep = nDashes; 320 else 321 *privatep = -1; 322 if (!table->sorted) { 323 *leftp = left; 324 *rightp = right; 325 return -1; 326 } else if (firstWild) { 327 if (firstDigit && firstDigit < firstWild) 328 first = firstDigit - name; 329 else 330 first = firstWild - name; 331 while (left < right) { 332 center = (left + right) / 2; 333 result = strncmp(name, table->entries[center].name.name, first); 334 if (result == 0) 335 break; 336 if (result < 0) 337 right = center; 338 else 339 left = center + 1; 340 } 341 *leftp = left; 342 *rightp = right; 343 return -1; 344 } else { 345 while (left < right) { 346 center = (left + right) / 2; 347 result = strcmpn(name, table->entries[center].name.name); 348 if (result == 0) 349 return center; 350 if (result < 0) 351 right = center; 352 else 353 left = center + 1; 354 } 355 *leftp = 1; 356 *rightp = 0; 357 return -1; 358 } 359} 360 361static int 362PatternMatch(char *pat, int patdashes, char *string, int stringdashes) 363{ 364 char c, 365 t; 366 367 if (stringdashes < patdashes) 368 return 0; 369 for (;;) { 370 switch (c = *pat++) { 371 case '*': 372 if (!(c = *pat++)) 373 return 1; 374 if (c == XK_minus) { 375 patdashes--; 376 for (;;) { 377 while ((t = *string++) != XK_minus) 378 if (!t) 379 return 0; 380 stringdashes--; 381 if (PatternMatch(pat, patdashes, string, stringdashes)) 382 return 1; 383 if (stringdashes == patdashes) 384 return 0; 385 } 386 } else { 387 for (;;) { 388 while ((t = *string++) != c) { 389 if (!t) 390 return 0; 391 if (t == XK_minus) { 392 if (stringdashes-- < patdashes) 393 return 0; 394 } 395 } 396 if (PatternMatch(pat, patdashes, string, stringdashes)) 397 return 1; 398 } 399 } 400 case '?': 401 if ((t = *string++) == XK_minus) 402 stringdashes--; 403 if (!t) 404 return 0; 405 break; 406 case '\0': 407 return (*string == '\0'); 408 case XK_minus: 409 if (*string++ == XK_minus) { 410 patdashes--; 411 stringdashes--; 412 break; 413 } 414 return 0; 415 default: 416 if (c == *string++) 417 break; 418 return 0; 419 } 420 } 421} 422 423int 424FontFileCountDashes (char *name, int namelen) 425{ 426 int ndashes = 0; 427 428 while (namelen--) 429 if (*name++ == '\055') /* avoid non ascii systems */ 430 ++ndashes; 431 return ndashes; 432} 433 434/* exported in public API in <X11/fonts/fntfil.h> */ 435char * 436FontFileSaveString (char *s) 437{ 438 return strdup(s); 439} 440#define FontFileSaveString(s) strdup(s) 441 442FontEntryPtr 443FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat, 444 FontScalablePtr vals) 445{ 446 int i, 447 start, 448 stop, 449 res, 450 private; 451 FontNamePtr name; 452 453 if (!table->entries) 454 return NULL; 455 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) 456 return &table->entries[i]; 457 for (i = start; i < stop; i++) { 458 name = &table->entries[i].name; 459 res = PatternMatch(pat->name, private, name->name, name->ndashes); 460 if (res > 0) 461 { 462 /* Check to see if enhancements requested are available */ 463 if (vals) 464 { 465 int vs = vals->values_supplied; 466 int cap; 467 468 if (table->entries[i].type == FONT_ENTRY_SCALABLE) 469 cap = table->entries[i].u.scalable.renderer->capabilities; 470 else if (table->entries[i].type == FONT_ENTRY_ALIAS) 471 cap = ~0; /* Calling code will have to see if true */ 472 else 473 cap = 0; 474 if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || 475 (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && 476 !(cap & CAP_MATRIX)) || 477 ((vs & CHARSUBSET_SPECIFIED) && 478 !(cap & CAP_CHARSUBSETTING))) 479 continue; 480 } 481 return &table->entries[i]; 482 } 483 if (res < 0) 484 break; 485 } 486 return (FontEntryPtr)0; 487} 488 489FontEntryPtr 490FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat) 491{ 492 return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0); 493} 494 495int 496FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max, 497 FontNamesPtr names, FontScalablePtr vals, 498 int alias_behavior, int *newmax) 499{ 500 int i, 501 start, 502 stop, 503 res, 504 private; 505 int ret = Successful; 506 FontEntryPtr fname; 507 FontNamePtr name; 508 509 if (max <= 0) 510 return Successful; 511 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) { 512 if (alias_behavior == NORMAL_ALIAS_BEHAVIOR || 513 table->entries[i].type != FONT_ENTRY_ALIAS) 514 { 515 name = &table->entries[i].name; 516 if (newmax) *newmax = max - 1; 517 return xfont2_add_font_names_name(names, name->name, name->length); 518 } 519 start = i; 520 stop = i + 1; 521 } 522 for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) { 523 res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes); 524 if (res > 0) { 525 if (vals) 526 { 527 int vs = vals->values_supplied; 528 int cap; 529 530 if (fname->type == FONT_ENTRY_SCALABLE) 531 cap = fname->u.scalable.renderer->capabilities; 532 else if (fname->type == FONT_ENTRY_ALIAS) 533 cap = ~0; /* Calling code will have to see if true */ 534 else 535 cap = 0; 536 if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || 537 (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && 538 !(cap & CAP_MATRIX)) || 539 ((vs & CHARSUBSET_SPECIFIED) && 540 !(cap & CAP_CHARSUBSETTING))) 541 continue; 542 } 543 544 if ((alias_behavior & IGNORE_SCALABLE_ALIASES) && 545 fname->type == FONT_ENTRY_ALIAS) 546 { 547 FontScalableRec tmpvals; 548 if (FontParseXLFDName (fname->name.name, &tmpvals, 549 FONT_XLFD_REPLACE_NONE) && 550 !(tmpvals.values_supplied & SIZE_SPECIFY_MASK)) 551 continue; 552 } 553 554 ret = xfont2_add_font_names_name(names, fname->name.name, fname->name.length); 555 if (ret != Successful) 556 goto bail; 557 558 /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark 559 this entry as an alias by negating its length and follow 560 it by the resolved name */ 561 if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES) && 562 fname->type == FONT_ENTRY_ALIAS) 563 { 564 names->length[names->nnames - 1] = 565 -names->length[names->nnames - 1]; 566 ret = xfont2_add_font_names_name(names, fname->u.alias.resolved, 567 strlen(fname->u.alias.resolved)); 568 if (ret != Successful) 569 goto bail; 570 } 571 572 if (--max <= 0) 573 break; 574 } else if (res < 0) 575 break; 576 } 577 bail: ; 578 if (newmax) *newmax = max; 579 return ret; 580} 581 582int 583FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat, 584 int max, FontNamesPtr names) 585{ 586 return FontFileFindNamesInScalableDir(table, pat, max, names, 587 (FontScalablePtr)0, 588 NORMAL_ALIAS_BEHAVIOR, (int *)0); 589} 590 591Bool 592FontFileMatchName(char *name, int length, FontNamePtr pat) 593{ 594 /* Perform a fontfile-type name match on a single name */ 595 FontTableRec table; 596 FontEntryRec entries[1]; 597 598 /* Dummy up a table */ 599 table.used = 1; 600 table.size = 1; 601 table.sorted = TRUE; 602 table.entries = entries; 603 entries[0].name.name = name; 604 entries[0].name.length = length; 605 entries[0].name.ndashes = FontFileCountDashes(name, length); 606 607 return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0; 608} 609 610/* 611 * Add a font file to a directory. This handles bitmap and 612 * scalable names both 613 */ 614 615Bool 616FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName) 617{ 618 FontEntryRec entry; 619 FontScalableRec vals, zeroVals; 620 FontRendererPtr renderer; 621 FontEntryPtr existing; 622 FontScalableExtraPtr extra; 623 FontEntryPtr bitmap = 0, scalable; 624 Bool isscale; 625 Bool scalable_xlfd; 626 627 renderer = FontFileMatchRenderer (fileName); 628 if (!renderer) 629 return FALSE; 630 entry.name.length = strlen (fontName); 631 if (entry.name.length > MAXFONTNAMELEN) 632 entry.name.length = MAXFONTNAMELEN; 633 entry.name.name = fontName; 634 CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length); 635 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); 636 entry.name.name[entry.name.length] = '\0'; 637 /* 638 * Add a bitmap name if the incoming name isn't an XLFD name, or 639 * if it isn't a scalable name (i.e. non-zero scalable fields) 640 * 641 * If name of bitmapped font contains XLFD enhancements, do not add 642 * a scalable version of the name... this can lead to confusion and 643 * ambiguity between the font name and the field enhancements. 644 */ 645 isscale = entry.name.ndashes == 14 && 646 FontParseXLFDName(entry.name.name, 647 &vals, FONT_XLFD_REPLACE_NONE) && 648 (vals.values_supplied & PIXELSIZE_MASK) != PIXELSIZE_ARRAY && 649 (vals.values_supplied & POINTSIZE_MASK) != POINTSIZE_ARRAY && 650 !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK); 651#define UNSCALED_ATTRIB "unscaled" 652 scalable_xlfd = (isscale && 653 (((vals.values_supplied & PIXELSIZE_MASK) == 0) || 654 ((vals.values_supplied & POINTSIZE_MASK) == 0))); 655 /* 656 * For scalable fonts without a scalable XFLD, check if the "unscaled" 657 * attribute is present. 658 */ 659 if (isscale && !scalable_xlfd && 660 dir->attributes && dir->attributes[0] == ':') { 661 char *ptr1 = dir->attributes + 1; 662 char *ptr2; 663 int length; 664 int uslength = strlen(UNSCALED_ATTRIB); 665 666 do { 667 ptr2 = strchr(ptr1, ':'); 668 if (ptr2) 669 length = ptr2 - ptr1; 670 else 671 length = dir->attributes + strlen(dir->attributes) - ptr1; 672 if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB, uslength)) 673 isscale = FALSE; 674 if (ptr2) 675 ptr1 = ptr2 + 1; 676 } while (ptr2); 677 } 678 if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK)) 679 { 680 /* 681 * If the renderer doesn't support OpenBitmap, FontFileOpenFont 682 * will still do the right thing. 683 */ 684 entry.type = FONT_ENTRY_BITMAP; 685 entry.u.bitmap.renderer = renderer; 686 entry.u.bitmap.pFont = NullFont; 687 if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName))) 688 return FALSE; 689 if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry))) 690 { 691 free (entry.u.bitmap.fileName); 692 return FALSE; 693 } 694 } 695 /* 696 * Parse out scalable fields from XLFD names - a scalable name 697 * just gets inserted, a scaled name has more things to do. 698 */ 699 if (isscale) 700 { 701 if (vals.values_supplied & SIZE_SPECIFY_MASK) 702 { 703 bzero((char *)&zeroVals, sizeof(zeroVals)); 704 zeroVals.x = vals.x; 705 zeroVals.y = vals.y; 706 zeroVals.values_supplied = PIXELSIZE_SCALAR | POINTSIZE_SCALAR; 707 FontParseXLFDName (entry.name.name, &zeroVals, 708 FONT_XLFD_REPLACE_VALUE); 709 entry.name.length = strlen (entry.name.name); 710 existing = FontFileFindNameInDir (&dir->scalable, &entry.name); 711 if (existing) 712 { 713 if ((vals.values_supplied & POINTSIZE_MASK) == 714 POINTSIZE_SCALAR && 715 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) 716 { 717 existing->u.scalable.extra->defaults = vals; 718 719 free (existing->u.scalable.fileName); 720 if (!(existing->u.scalable.fileName = FontFileSaveString (fileName))) 721 return FALSE; 722 } 723 if(bitmap) 724 { 725 FontFileCompleteXLFD(&vals, &vals); 726 FontFileAddScaledInstance (existing, &vals, NullFont, 727 bitmap->name.name); 728 return TRUE; 729 } 730 } 731 } 732 if (!(entry.u.scalable.fileName = FontFileSaveString (fileName))) 733 return FALSE; 734 extra = malloc (sizeof (FontScalableExtraRec)); 735 if (!extra) 736 { 737 free (entry.u.scalable.fileName); 738 return FALSE; 739 } 740 bzero((char *)&extra->defaults, sizeof(extra->defaults)); 741 if ((vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR && 742 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) 743 extra->defaults = vals; 744 else 745 { 746 FontResolutionPtr resolution; 747 int num; 748 int default_point_size = GetDefaultPointSize(); 749 750 extra->defaults.point_matrix[0] = 751 extra->defaults.point_matrix[3] = 752 (double)default_point_size / 10.0; 753 extra->defaults.point_matrix[1] = 754 extra->defaults.point_matrix[2] = 0.0; 755 extra->defaults.values_supplied = 756 POINTSIZE_SCALAR | PIXELSIZE_UNDEFINED; 757 extra->defaults.width = -1; 758 if (vals.x <= 0 || vals.y <= 0) 759 { 760 resolution = GetClientResolutions (&num); 761 if (resolution && num > 0) 762 { 763 extra->defaults.x = resolution->x_resolution; 764 extra->defaults.y = resolution->y_resolution; 765 } 766 else 767 { 768 extra->defaults.x = 75; 769 extra->defaults.y = 75; 770 } 771 } 772 else 773 { 774 extra->defaults.x = vals.x; 775 extra->defaults.y = vals.y; 776 } 777 FontFileCompleteXLFD (&extra->defaults, &extra->defaults); 778 } 779 extra->numScaled = 0; 780 extra->sizeScaled = 0; 781 extra->scaled = 0; 782 extra->private = 0; 783 entry.type = FONT_ENTRY_SCALABLE; 784 entry.u.scalable.renderer = renderer; 785 entry.u.scalable.extra = extra; 786 if (!(scalable = FontFileAddEntry (&dir->scalable, &entry))) 787 { 788 free (extra); 789 free (entry.u.scalable.fileName); 790 return FALSE; 791 } 792 if (vals.values_supplied & SIZE_SPECIFY_MASK) 793 { 794 if(bitmap) 795 { 796 FontFileCompleteXLFD(&vals, &vals); 797 FontFileAddScaledInstance (scalable, &vals, NullFont, 798 bitmap->name.name); 799 } 800 } 801 } 802 return TRUE; 803} 804 805Bool 806FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName) 807{ 808 FontEntryRec entry; 809 810 if (strcmp(aliasName,fontName) == 0) { 811 /* Don't allow an alias to point to itself and create a loop */ 812 return FALSE; 813 } 814 entry.name.length = strlen (aliasName); 815 CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length); 816 entry.name.name = aliasName; 817 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); 818 entry.type = FONT_ENTRY_ALIAS; 819 if (!(entry.u.alias.resolved = FontFileSaveString (fontName))) 820 return FALSE; 821 if (!FontFileAddEntry (&dir->nonScalable, &entry)) 822 { 823 free (entry.u.alias.resolved); 824 return FALSE; 825 } 826 return TRUE; 827} 828