1/** <title>NSFont</title> 2 3 <abstract>The font class</abstract> 4 5 Copyright (C) 1996 Free Software Foundation, Inc. 6 7 Author: Ovidiu Predescu <ovidiu@net-community.com> 8 Date: February 1997 9 A completely rewritten version of the original source by Scott Christley. 10 11 This file is part of the GNUstep GUI Library. 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; see the file COPYING.LIB. 25 If not, see <http://www.gnu.org/licenses/> or write to the 26 Free Software Foundation, 51 Franklin Street, Fifth Floor, 27 Boston, MA 02110-1301, USA. 28*/ 29 30#include "config.h" 31#import <Foundation/NSAffineTransform.h> 32#import <Foundation/NSCoder.h> 33#import <Foundation/NSDictionary.h> 34#import <Foundation/NSString.h> 35#import <Foundation/NSUserDefaults.h> 36#import <Foundation/NSSet.h> 37#import <Foundation/NSMapTable.h> 38#import <Foundation/NSException.h> 39#import <Foundation/NSDebug.h> 40#import <Foundation/NSValue.h> 41 42#import "AppKit/NSGraphicsContext.h" 43#import "AppKit/NSFont.h" 44#import "AppKit/NSFontDescriptor.h" 45#import "AppKit/NSFontManager.h" 46#import "AppKit/NSView.h" 47#import "GNUstepGUI/GSFontInfo.h" 48 49 50@interface NSFont (Private) 51- (id) initWithName: (NSString*)name 52 matrix: (const CGFloat*)fontMatrix 53 screenFont: (BOOL)screenFont 54 role: (int)role; 55+ (NSFont*) _fontWithName: (NSString*)aFontName 56 size: (CGFloat)fontSize 57 role: (int)role; 58@end 59 60static int currentVersion = 3; 61 62 63/* 64Instances of GSFontMapKey are used to find cached font instances in 65globalFontMap. 66*/ 67@interface GSFontMapKey : NSObject 68{ 69@public 70 NSString *name; 71 BOOL screenFont; 72 int role; 73 int matrix[6]; 74 75 unsigned int hash; 76} 77@end 78@implementation GSFontMapKey 79-(NSUInteger) hash 80{ 81 return hash; 82} 83-(BOOL) isEqual: (id)other 84{ 85 GSFontMapKey *o; 86 if (![other isKindOfClass: object_getClass(self)]) 87 return NO; 88 o = other; 89 if (hash != o->hash || screenFont != o->screenFont || role != o->role) 90 return NO; 91 if (![name isEqualToString: o->name]) 92 return NO; 93 if (matrix[0] != o->matrix[0] 94 || matrix[1] != o->matrix[1] 95 || matrix[2] != o->matrix[2] 96 || matrix[3] != o->matrix[3] 97 || matrix[4] != o->matrix[4] 98 || matrix[5] != o->matrix[5]) 99 return NO; 100 return YES; 101} 102-(void) dealloc 103{ 104 DESTROY(name); 105 [super dealloc]; 106} 107@end 108 109static GSFontMapKey * 110keyForFont(NSString *name, const CGFloat *matrix, 111 BOOL screenFont, int role) 112{ 113 GSFontMapKey *d; 114 d=[GSFontMapKey alloc]; 115 d->name = [name copy]; 116 d->screenFont = screenFont; 117 d->role = role; 118 d->matrix[0] = matrix[0] * 1000; 119 d->matrix[1] = matrix[1] * 1000; 120 d->matrix[2] = matrix[2] * 1000; 121 d->matrix[3] = matrix[3] * 1000; 122 d->matrix[4] = matrix[4] * 1000; 123 d->matrix[5] = matrix[5] * 1000; 124 d->hash = [d->name hash] + screenFont + role * 4 125 + d->matrix[0] + d->matrix[1] + d->matrix[2] + d->matrix[3]; 126 return d; 127} 128 129/** 130 <unit> 131 <heading>NSFont</heading> 132 133 <p>The NSFont class allows control of the fonts used for displaying 134 text anywhere on the screen. The primary methods for getting a 135 particular font are +fontWithName:matrix: and +fontWithName:size: which 136 take the name and size of a particular font and return the NSFont object 137 associated with that font. In addition there are several convenience 138 mathods which make it easier to get certain types of fonts. </p> 139 140 <p>In particular, there are several methods to get the standard fonts 141 used by the Application to display text for a partiuclar purpose. See 142 the class methods listed below for more information. These default 143 fonts can be set using the user defaults system. The default 144 font names available are: 145 </p> 146 <list> 147 <item>NSBoldFont Helvetica-Bold (System bold font)</item> 148 <item>NSControlContentFont System font</item> 149 <item>NSFont Helvetica (System Font)</item> 150 <item>NSLabelFont System font</item> 151 <item>NSMenuFont System font</item> 152 <item>NSMenuBarFont System font</item> 153 <item>NSMessageFont System font</item> 154 <item>NSPaletteFont System bold font</item> 155 <item>NSTitleBarFont System bold font</item> 156 <item>NSToolTipsFont System font</item> 157 <item>NSUserFixedPitchFont Courier</item> 158 <item>NSUserFont System font</item> 159 </list> 160 <p> 161 The default sizes are: 162 </p> 163 <list> 164 <item>NSBoldFontSize (none)</item> 165 <item>NSControlContentFontSize (none)</item> 166 <item>NSFontSize 12 (System Font Size)</item> 167 <item>NSLabelFontSize (none)</item> 168 <item>NSMenuFontSize (none)</item> 169 <item>NSMiniFontSize 8</item> 170 <item>NSMessageFontSize (none)</item> 171 <item>NSPaletteFontSize (none)</item> 172 <item>NSSmallFontSize 10</item> 173 <item>NSTitleBarFontSize (none)</item> 174 <item>NSToolTipsFontSize (none)</item> 175 <item>NSUserFixedPitchFontSize (none)</item> 176 <item>NSUserFontSize (none)</item> 177 </list> 178 <p> 179 Font sizes list with (none) default to NSFontSize. 180 </p> 181 182 </unit> */ 183 184@implementation NSFont 185 186/* Class variables*/ 187 188/* See comments in +initialize. */ 189static NSFont *placeHolder = nil; 190 191/* Fonts that are preferred by the application */ 192static NSArray *_preferredFonts; 193 194/* Class for fonts */ 195static Class NSFontClass = 0; 196 197/* Cache all created fonts for reuse. */ 198static NSMapTable* globalFontMap = 0; 199 200static NSUserDefaults *defaults = nil; 201 202 203/* 204The valid font roles. Note that these values are used when encoding and 205decoding, so entries may never be removed. Entries may be added after the 206last entry, and entries don't have to actually be handled. 207 208Note that these values are multiplied by two before they are used since the 209lowest bit is used to indicate an explicit size. If the lowest bit is set, 210the size is explicitly specified and encoded. 211*/ 212enum FontRoles 213{ 214RoleExplicit=0, 215RoleBoldSystemFont, 216RoleSystemFont, 217RoleUserFixedPitchFont, 218RoleUserFont, 219RoleTitleBarFont, 220RoleMenuFont, 221RoleMessageFont, 222RolePaletteFont, 223RoleToolTipsFont, 224RoleControlContentFont, 225RoleLabelFont, 226RoleMenuBarFont, 227RoleMax 228}; 229 230typedef struct 231{ 232 /* Defaults key for this font. */ 233 NSString *key; 234 235 /* If there's no defaults key, fall back to the font for this role. */ 236 int fallback; 237 238 /* If there's no other role to fall back to, use this font. */ 239 NSString *defaultFont; 240 241 /* Cached font for the default size of this role. */ 242 NSFont *cachedFont; 243} font_role_info_t; 244 245/* 246This table, through getNSFont, controls the behavior of getting the standard 247fonts, and must match the table in the documentation above. Each entry should 248have a fallback or a defaultFont. There must be a default font for the system 249font. Bad Things will happen if entries are invalid. 250*/ 251static font_role_info_t font_roles[RoleMax]={ 252 {nil , 0 , nil, nil}, 253 {@"NSBoldFont" , 0 , nil /* set by init_font_roles */, nil}, 254 {@"NSFont" , 0 , nil /* set by init_font_roles */, nil}, 255 {@"NSUserFixedPitchFont", 0 , nil /* set by init_font_roles */, nil}, 256 {@"NSUserFont" , RoleSystemFont , nil, nil}, 257 {@"NSTitleBarFont" , RoleBoldSystemFont, nil, nil}, 258 {@"NSMenuFont" , RoleSystemFont , nil, nil}, 259 {@"NSMessageFont" , RoleSystemFont , nil, nil}, 260 {@"NSPaletteFont" , RoleBoldSystemFont, nil, nil}, 261 {@"NSToolTipsFont" , RoleSystemFont , nil, nil}, 262 {@"NSControlContentFont", RoleSystemFont , nil, nil}, 263 {@"NSLabelFont" , RoleSystemFont , nil, nil}, 264 {@"NSMenuBarFont" , RoleSystemFont , nil, nil} 265}; 266 267 268static BOOL did_init_font_roles; 269 270/* 271Called by getNSFont, since font_roles is only accessed from that function 272(or fontNameForRole, which is only called by getNSFont). This assures that the 273function is called before the table is used, and that it's called _after_ the 274backend has been loaded (or, if it isn't, the _fontWithName:... calls will 275fail anyway). 276*/ 277static void init_font_roles(void) 278{ 279 GSFontEnumerator *e = [GSFontEnumerator sharedEnumerator]; 280 281 font_roles[RoleSystemFont].defaultFont = [e defaultSystemFontName]; 282 font_roles[RoleBoldSystemFont].defaultFont = [e defaultBoldSystemFontName]; 283 font_roles[RoleUserFixedPitchFont].defaultFont = [e defaultFixedPitchFontName]; 284} 285 286 287static NSString *fontNameForRole(int role, int *actual_entry) 288{ 289 int i; 290 NSString *fontName; 291 292 i = role; 293 while (1) 294 { 295 fontName = [defaults stringForKey: font_roles[i].key]; 296 if (fontName) 297 { 298 break; 299 } 300 else if (font_roles[i].fallback) 301 { 302 i = font_roles[i].fallback; 303 } 304 else if (font_roles[i].defaultFont) 305 { 306 fontName = font_roles[i].defaultFont; 307 break; 308 } 309 else 310 { 311 NSCAssert(NO, @"Invalid font role table entry."); 312 } 313 } 314 if (actual_entry) 315 *actual_entry = i; 316 return fontName; 317} 318 319static NSFont *getNSFont(CGFloat fontSize, int role) 320{ 321 NSString *fontName; 322 NSFont *font; 323 BOOL defaultSize; 324 int i; 325 int font_role; 326 327 NSCAssert(role > RoleExplicit && role < RoleMax, @"Invalid font role."); 328 329 if (!did_init_font_roles) 330 { 331 init_font_roles(); 332 did_init_font_roles = YES; 333 } 334 335 font_role = role * 2; 336 337 defaultSize = (fontSize <= 0.0); 338 if (defaultSize) 339 { 340 if (font_roles[role].cachedFont) 341 return AUTORELEASE(RETAIN(font_roles[role].cachedFont)); 342 343 fontSize = [defaults floatForKey: 344 [NSString stringWithFormat: @"%@Size", font_roles[role].key]]; 345 346 if (!fontSize) 347 fontSize = [NSFont systemFontSize]; 348 } 349 else 350 { 351 font_role |= 1; 352 } 353 354 fontName = fontNameForRole(role, &i); 355 font = [NSFontClass _fontWithName: fontName 356 size: fontSize 357 role: font_role]; 358 359 /* That font couldn't be found. */ 360 if (font == nil) 361 { 362 /* Warn using the role that specified the invalid font. */ 363 NSLog(@"The font specified for %@, %@, can't be found.", 364 font_roles[i].key, fontName); 365 366 /* Try the system font. */ 367 fontName = fontNameForRole(RoleSystemFont, NULL); 368 font = [NSFontClass _fontWithName: fontName 369 size: fontSize 370 role: font_role]; 371 372 if (font == nil) 373 { 374 /* Try the default system font and size. */ 375 fontName = font_roles[RoleSystemFont].defaultFont; 376 font = [NSFontClass _fontWithName: fontName 377 size: 12.0 378 role: font_role]; 379 380 /* It seems we can't get any font here! Try some well known 381 * fonts as a last resort. */ 382 if (font == nil) 383 { 384 font = [NSFontClass _fontWithName: @"Helvetica" 385 size: 12.0 386 role: font_role]; 387 } 388 if (font == nil) 389 { 390 font = [NSFontClass _fontWithName: @"Courier" 391 size: 12.0 392 role: font_role]; 393 } 394 if (font == nil) 395 { 396 font = [NSFontClass _fontWithName: @"Fixed" 397 size: 12.0 398 role: font_role]; 399 } 400 } 401 } 402 403 if (defaultSize) 404 ASSIGN(font_roles[role].cachedFont, font); 405 406 return font; 407} 408 409static void setNSFont(NSString *key, NSFont *font) 410{ 411 int i; 412 413 [defaults setObject: [font fontName] forKey: key]; 414 [defaults setObject: [NSNumber numberWithFloat: [font pointSize]] 415 forKey: [NSString stringWithFormat: @"%@Size",key]]; 416 417 for (i = 1; i < RoleMax; i++) 418 { 419 DESTROY(font_roles[i].cachedFont); 420 } 421 422 /* Don't care about errors */ 423 [defaults synchronize]; 424} 425 426 427// 428// Class methods 429// 430+ (void) initialize 431{ 432 if (self == [NSFont class]) 433 { 434 NSFontClass = self; 435 436 /* 437 * The placeHolder is a dummy NSFont instance which is never used 438 * as a font ... the initialiser knows that whenever it gets the 439 * placeHolder it should either return a cached font or return a 440 * newly allocated font to replace it. This mechanism stops the 441 * +fontWithName:... methods from having to allocate fonts instances 442 * which would immediately have to be released for replacement by 443 * a cache object. 444 */ 445 placeHolder = [self alloc]; 446 globalFontMap = NSCreateMapTable(NSObjectMapKeyCallBacks, 447 NSNonRetainedObjectMapValueCallBacks, 64); 448 449 if (defaults == nil) 450 { 451 defaults = RETAIN([NSUserDefaults standardUserDefaults]); 452 } 453 454 _preferredFonts = [defaults objectForKey: @"NSPreferredFonts"]; 455 [self setVersion: currentVersion]; 456 } 457} 458 459/* Getting the preferred user fonts. */ 460 461/**<p>Returns the default bold font for use in menus and heading in standard 462 gui components. If fontSize is <= 0, the default 463 size is used.</p><p>See Also: +fontWithName:size:</p> 464 */ 465+ (NSFont*) boldSystemFontOfSize: (CGFloat)fontSize 466{ 467 return getNSFont(fontSize, RoleBoldSystemFont); 468} 469 470/**<p> Returns the default font for use in menus and heading in standard 471 gui components. If fontSize is <= 0, the default 472 size is used.</p><p>See Also: +boldSystemFontOfSize: userFontOfSize: 473 userFixedPitchFontOfSize: +fontWithName:size:</p> 474 */ 475+ (NSFont*) systemFontOfSize: (CGFloat)fontSize 476{ 477 return getNSFont(fontSize, RoleSystemFont); 478} 479 480/**<p>Returns the default fixed pitch font for use in locations other 481 than standard gui components. If fontSize is <= 0, the default 482 size is used.</p><p>See Also: +setUserFixedPitchFont: +userFontOfSize: 483 +boldSystemFontOfSize: +systemFontOfSize: +fontWithName:size:</p> 484 */ 485+ (NSFont*) userFixedPitchFontOfSize: (CGFloat)fontSize 486{ 487 return getNSFont(fontSize, RoleUserFixedPitchFont); 488} 489 490/**<p> Returns the default font for use in locations other 491 than standard gui components. If fontSize is <= 0, the default 492 size is used.</p><p>See Also: +setUserFont: +boldSystemFontOfSize: 493 systemFontOfSize: userFixedPitchFontOfSize: +fontWithName:size:</p> 494 */ 495+ (NSFont*) userFontOfSize: (CGFloat)fontSize 496{ 497 return getNSFont(fontSize, RoleUserFont); 498} 499 500+ (NSFont *) fontWithDescriptor: (NSFontDescriptor *)descriptor 501 size: (CGFloat)size 502{ 503 NSArray *a; 504 505 descriptor = [descriptor matchingFontDescriptorWithMandatoryKeys: 506 [NSSet setWithArray: [[descriptor fontAttributes] allKeys]]]; 507 508 if (descriptor == nil) 509 return nil; 510 511 a = [[NSFontManager sharedFontManager] availableFontNamesMatchingFontDescriptor: 512 descriptor]; 513 if ((a == nil) || ([a count] == 0)) 514 return nil; 515 516 return [self fontWithName: [a objectAtIndex: 0] 517 size: size]; 518} 519 520+ (NSFont*) fontWithDescriptor: (NSFontDescriptor*)descriptor 521 textTransform: (NSAffineTransform*)transform 522{ 523 NSArray *a; 524 CGFloat fontMatrix[6]; 525 NSAffineTransformStruct ats; 526 527 descriptor = [descriptor matchingFontDescriptorWithMandatoryKeys: 528 [NSSet setWithArray: [[descriptor fontAttributes] allKeys]]]; 529 530 if (descriptor == nil) 531 return nil; 532 533 a = [[NSFontManager sharedFontManager] availableFontNamesMatchingFontDescriptor: 534 descriptor]; 535 if ((a == nil) || ([a count] == 0)) 536 return nil; 537 538 ats = [transform transformStruct]; 539 fontMatrix[0] = ats.m11; 540 fontMatrix[1] = ats.m12; 541 fontMatrix[2] = ats.m21; 542 fontMatrix[3] = ats.m22; 543 fontMatrix[4] = ats.tX; 544 fontMatrix[5] = ats.tY; 545 546 return [self fontWithName: [a objectAtIndex: 0] 547 matrix: fontMatrix]; 548} 549 550+ (NSFont *) fontWithDescriptor: (NSFontDescriptor *)descriptor 551 size: (CGFloat)size 552 textTransform: (NSAffineTransform *)transform 553{ 554 if (transform) 555 { 556 return [self fontWithDescriptor: descriptor 557 textTransform: transform]; 558 } 559 else 560 { 561 return [self fontWithDescriptor: descriptor 562 size: size]; 563 } 564} 565 566 567/**<p>Returns an array of the names of preferred fonts.</p> 568 <p>See Also: +setPreferredFontNames:</p> 569 */ 570+ (NSArray*) preferredFontNames 571{ 572 return _preferredFonts; 573} 574 575/* Setting the preferred user fonts*/ 576 577+ (void) setUserFixedPitchFont: (NSFont*)aFont 578{ 579 setNSFont (@"NSUserFixedPitchFont", aFont); 580} 581 582+ (void) setUserFont: (NSFont*)aFont 583{ 584 setNSFont (@"NSUserFont", aFont); 585} 586 587/** <p>Sets an array of the names of preferred fonts to fontsNames/</p> 588 <p>See Also: +preferredFontNames</p> 589 */ 590+ (void) setPreferredFontNames: (NSArray*)fontNames 591{ 592 ASSIGN(_preferredFonts, fontNames); 593 // FIXME: Should this store back the preferred fonts in the user defaults? 594} 595 596/* Getting various fonts*/ 597 598+ (NSFont*) controlContentFontOfSize: (CGFloat)fontSize 599{ 600 return getNSFont(fontSize, RoleControlContentFont); 601} 602 603+ (NSFont*) labelFontOfSize: (CGFloat)fontSize 604{ 605 return getNSFont(fontSize, RoleLabelFont); 606} 607 608+ (NSFont*) menuFontOfSize: (CGFloat)fontSize 609{ 610 return getNSFont(fontSize, RoleMenuFont); 611} 612 613+ (NSFont*) menuBarFontOfSize: (CGFloat)fontSize 614{ 615 return getNSFont(fontSize, RoleMenuBarFont); 616} 617 618+ (NSFont*) titleBarFontOfSize: (CGFloat)fontSize 619{ 620 return getNSFont(fontSize, RoleTitleBarFont); 621} 622 623+ (NSFont*) messageFontOfSize: (CGFloat)fontSize 624{ 625 return getNSFont(fontSize, RoleMessageFont); 626} 627 628+ (NSFont*) paletteFontOfSize: (CGFloat)fontSize 629{ 630 return getNSFont(fontSize, RolePaletteFont); 631} 632 633+ (NSFont*) toolTipsFontOfSize: (CGFloat)fontSize 634{ 635 return getNSFont(fontSize, RoleToolTipsFont); 636} 637 638// 639// Font Sizes 640// 641+ (CGFloat) labelFontSize 642{ 643 CGFloat fontSize = [defaults floatForKey: @"NSLabelFontSize"]; 644 645 if (fontSize == 0) 646 { 647 return [self systemFontSize]; 648 } 649 650 return fontSize; 651} 652 653+ (CGFloat) smallSystemFontSize 654{ 655 CGFloat fontSize = [defaults floatForKey: @"NSSmallFontSize"]; 656 657 if (fontSize == 0) 658 { 659 fontSize = 10; 660 } 661 662 return fontSize; 663} 664 665+ (CGFloat) systemFontSize 666{ 667 CGFloat fontSize = [defaults floatForKey: @"NSFontSize"]; 668 669 if (fontSize == 0) 670 { 671 fontSize = 12; 672 } 673 674 return fontSize; 675} 676 677+ (CGFloat) systemFontSizeForControlSize: (NSControlSize)controlSize 678{ 679 switch (controlSize) 680 { 681 case NSMiniControlSize: 682 { 683 CGFloat fontSize = [defaults floatForKey: @"NSMiniFontSize"]; 684 685 if (fontSize == 0) 686 { 687 fontSize = 8; 688 } 689 690 return fontSize; 691 } 692 case NSSmallControlSize: 693 return [self smallSystemFontSize]; 694 case NSRegularControlSize: 695 default: 696 return [self systemFontSize]; 697 } 698} 699 700/** <p>Returns an autoreleased font with name aFontName and matrix fontMatrix 701 .</p><p>The fontMatrix is a standard size element matrix as used in 702 PostScript to describe the scaling of the font, typically it just includes 703 the font size as [fontSize 0 0 fontSize 0 0]. You can use the constant 704 NSFontIdentityMatrix in place of [1 0 0 1 0 0]. If NSFontIdentityMatrix, 705 then the font will automatically flip itself when set in a flipped view. 706 </p> 707 */ 708+ (NSFont*) fontWithName: (NSString*)aFontName 709 matrix: (const CGFloat*)fontMatrix 710{ 711 NSFont *font; 712 713 font = [placeHolder initWithName: aFontName 714 matrix: fontMatrix 715 screenFont: NO 716 role: RoleExplicit]; 717 718 return AUTORELEASE(font); 719} 720 721/**<p> Returns an autoreleased font with name aFontName and size fontSize.</p> 722 * <p>Fonts created using this method will automatically flip themselves 723 * when set in a flipped view.</p> 724 */ 725+ (NSFont*) fontWithName: (NSString*)aFontName 726 size: (CGFloat)fontSize 727{ 728 return [self _fontWithName: aFontName 729 size: fontSize 730 role: RoleExplicit]; 731} 732 733+ (NSFont*) _fontWithName: (NSString*)aFontName 734 size: (CGFloat)fontSize 735 role: (int)aRole 736{ 737 NSFont *font; 738 CGFloat fontMatrix[6] = { 0, 0, 0, 0, 0, 0 }; 739 740 if (fontSize == 0) 741 { 742 fontSize = [defaults floatForKey: @"NSUserFontSize"]; 743 if (fontSize == 0) 744 { 745 fontSize = 12; 746 } 747 } 748 fontMatrix[0] = fontSize; 749 fontMatrix[3] = fontSize; 750 751 font = [placeHolder initWithName: aFontName 752 matrix: fontMatrix 753 screenFont: NO 754 role: aRole]; 755 return AUTORELEASE(font); 756} 757 758/** 759 */ 760+ (void) useFont: (NSString*)aFontName 761{ 762 [GSCurrentContext() useFont: aFontName]; 763} 764 765// 766// Instance methods 767// 768- (id) init 769{ 770 [NSException raise: NSInternalInconsistencyException 771 format: @"Called -init on NSFont ... illegal"]; 772 return self; 773} 774 775/* 776 Last fallback: If a system font was explicitly requested 777 and this font does not exist, try to replace it with the 778 corresponding font in the current setup. 779*/ 780- (NSString*) _replacementFontName 781{ 782 if (([fontName isEqualToString: @"Helvetica"] && 783 ![font_roles[RoleSystemFont].defaultFont isEqualToString: @"Helvetica"]) 784 || ([fontName isEqualToString: @"LucidaGrande"])) 785 { 786 return font_roles[RoleSystemFont].defaultFont; 787 } 788 else if (([fontName isEqualToString: @"Helvetica-Bold"] && 789 ![font_roles[RoleBoldSystemFont].defaultFont isEqualToString: @"Helvetica-Bold"]) 790 || ([fontName isEqualToString: @"LucidaGrande-Bold"])) 791 { 792 return font_roles[RoleBoldSystemFont].defaultFont; 793 } 794 else if ([fontName isEqualToString: @"Courier"] && 795 ![font_roles[RoleUserFixedPitchFont].defaultFont isEqualToString: @"Courier"]) 796 { 797 return font_roles[RoleUserFixedPitchFont].defaultFont; 798 } 799 else if ([fontName hasPrefix: @"Helvetica-"] && 800 ![font_roles[RoleSystemFont].defaultFont isEqualToString: @"Helvetica"]) 801 { 802 return [NSString stringWithFormat: @"%@-%@", 803 font_roles[RoleSystemFont].defaultFont, 804 [fontName substringFromIndex: 10]]; 805 } 806 return nil; 807} 808 809/** <init /> 810 * Initializes a newly created font instance from the name and 811 * information given in the fontMatrix. The fontMatrix is a standard 812 * size element matrix as used in PostScript to describe the scaling 813 * of the font, typically it just includes the font size as 814 * [fontSize 0 0 fontSize 0 0].<br /> 815 * This method may destroy the receiver and return a cached instance. 816 */ 817- (id) initWithName: (NSString*)name 818 matrix: (const CGFloat*)fontMatrix 819 screenFont: (BOOL)screen 820 role: (int)aRole 821{ 822 GSFontMapKey *key; 823 NSFont *font; 824 825 /* Should never be called on an initialised font! */ 826 NSAssert(fontName == nil, NSInternalInconsistencyException); 827 828 /* Check whether the font is cached */ 829 key = keyForFont(name, fontMatrix, 830 screen, aRole); 831 font = (id)NSMapGet(globalFontMap, (void *)key); 832 if (font == nil) 833 { 834 if (self == placeHolder) 835 { 836 /* 837 * If we are initialising the placeHolder, we actually want to 838 * leave it be (for later re-use) and initialise a newly created 839 * instance instead. 840 */ 841 self = [NSFontClass alloc]; 842 } 843 fontName = [name copy]; 844 memcpy(matrix, fontMatrix, sizeof(matrix)); 845 screenFont = screen; 846 role = aRole; 847 fontInfo = RETAIN([GSFontInfo fontInfoForFontName: fontName 848 matrix: fontMatrix 849 screenFont: screen]); 850 if ((fontInfo == nil) && (aRole == RoleExplicit)) 851 { 852 NSString *replacementFontName = [self _replacementFontName]; 853 854 if (replacementFontName != nil) 855 { 856 fontInfo = RETAIN([GSFontInfo fontInfoForFontName: replacementFontName 857 matrix: fontMatrix 858 screenFont: screen]); 859 } 860 } 861 if (fontInfo == nil) 862 { 863 DESTROY(fontName); 864 DESTROY(key); 865 RELEASE(self); 866 return nil; 867 } 868 869 /* Cache the font for later use */ 870 NSMapInsert(globalFontMap, (void *)key, (void *)self); 871 } 872 else 873 { 874 if (self != placeHolder) 875 { 876 RELEASE(self); 877 } 878 self = RETAIN(font); 879 } 880 RELEASE(key); 881 882 return self; 883} 884 885- (void) dealloc 886{ 887 if (fontName != nil) 888 { 889 GSFontMapKey *key; 890 891 key = keyForFont(fontName, matrix, 892 screenFont, role); 893 NSMapRemove(globalFontMap, (void *)key); 894 RELEASE(key); 895 RELEASE(fontName); 896 } 897 TEST_RELEASE(fontInfo); 898 DESTROY(cachedFlippedFont); 899 DESTROY(cachedScreenFont); 900 [super dealloc]; 901} 902 903- (NSString *) description 904{ 905 NSString *nameWithMatrix; 906 NSString *description; 907 908 nameWithMatrix = [[NSString alloc] initWithFormat: 909 @"%@ %.3f %.3f %.3f %.3f %.3f %.3f %c %i", fontName, 910 matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], 911 screenFont ? 'S' : 'P', 912 role]; 913 description = [[super description] stringByAppendingFormat: @" %@", 914 nameWithMatrix]; 915 RELEASE(nameWithMatrix); 916 return description; 917} 918 919- (BOOL) isEqual: (id)anObject 920{ 921 if (anObject == self) 922 return YES; 923 if ([anObject isKindOfClass: object_getClass(self)] == NO) 924 return NO; 925 if ([[anObject fontName] isEqual: fontName] == NO) 926 return NO; 927 if (memcmp(matrix, [(NSFont*)anObject matrix], sizeof(matrix)) != 0) 928 return NO; 929 return YES; 930} 931 932- (NSUInteger) hash 933{ 934 int i, sum; 935 sum = 0; 936 for (i = 0; i < 6; i++) 937 sum += matrix[i] * ((i+1) * 17); 938 return ([fontName hash] + sum); 939} 940 941/** 942 * The NSFont class caches instances ... to actually make copies 943 * of instances would defeat the whole point of caching, so the 944 * effect of copying an NSFont is imply to retain it. 945 */ 946- (id) copyWithZone: (NSZone*)zone 947{ 948 return RETAIN(self); 949} 950 951- (NSFont *)_flippedViewFont 952{ 953 if (cachedFlippedFont == nil) 954 { 955 CGFloat fontMatrix[6]; 956 memcpy(fontMatrix, matrix, sizeof(matrix)); 957 fontMatrix[3] *= -1; 958 cachedFlippedFont = [placeHolder initWithName: fontName 959 matrix: fontMatrix 960 screenFont: screenFont 961 role: role]; 962 } 963 return AUTORELEASE(RETAIN(cachedFlippedFont)); 964} 965 966static BOOL flip_hack; 967+(void) _setFontFlipHack: (BOOL)flip 968{ 969 flip_hack = flip; 970} 971 972// 973// Setting the Font 974// 975/** Sets the receiver as the font used for text drawing operations. If the 976 current view is a flipped view, the reciever automatically flips itself 977 to display correctly in the flipped view */ 978- (void) set 979{ 980 [self setInContext: GSCurrentContext()]; 981} 982 983- (void) setInContext: (NSGraphicsContext*)context 984{ 985 if ([[NSView focusView] isFlipped] || flip_hack) 986 [context GSSetFont: [[self _flippedViewFont] fontRef]]; 987 else 988 [context GSSetFont: [self fontRef]]; 989 990 [context useFont: fontName]; 991} 992 993// 994// Querying the Font 995// 996- (CGFloat) pointSize 997{ 998 return [fontInfo pointSize]; 999} 1000 1001- (NSString*) fontName 1002{ 1003 return fontName; 1004} 1005 1006- (const CGFloat*) matrix 1007{ 1008 return matrix; 1009} 1010 1011- (NSAffineTransform*) textTransform 1012{ 1013 NSAffineTransform *transform; 1014 NSAffineTransformStruct tstruct; 1015 1016 tstruct.m11 = matrix[0]; 1017 tstruct.m12 = matrix[1]; 1018 tstruct.m21 = matrix[2]; 1019 tstruct.m22 = matrix[3]; 1020 tstruct.tX = matrix[4]; 1021 tstruct.tY = matrix[5]; 1022 1023 transform = [NSAffineTransform transform]; 1024 [transform setTransformStruct: tstruct]; 1025 return transform; 1026} 1027 1028- (NSString*) encodingScheme 1029{ 1030 return [fontInfo encodingScheme]; 1031} 1032 1033- (NSString*) familyName 1034{ 1035 return [fontInfo familyName]; 1036} 1037 1038- (NSRect) boundingRectForFont 1039{ 1040 return [fontInfo boundingRectForFont]; 1041} 1042 1043- (BOOL) isFixedPitch 1044{ 1045 return [fontInfo isFixedPitch]; 1046} 1047 1048- (BOOL) isBaseFont 1049{ 1050 return [fontInfo isBaseFont]; 1051} 1052 1053/* Usually the display name of font is the font name.*/ 1054- (NSString*) displayName 1055{ 1056 return fontName; 1057} 1058 1059- (NSDictionary*) afmDictionary 1060{ 1061 return [fontInfo afmDictionary]; 1062} 1063 1064/**<p>This method returns nil in the GNUstep implementation</p> 1065 */ 1066- (NSString*) afmFileContents 1067{ 1068 return [fontInfo afmFileContents]; 1069} 1070 1071- (NSFont*) printerFont 1072{ 1073 if (!screenFont) 1074 return self; 1075 return AUTORELEASE([placeHolder initWithName: fontName 1076 matrix: matrix 1077 screenFont: NO 1078 role: role]); 1079} 1080 1081- (NSFont*) screenFont 1082{ 1083 if (screenFont) 1084 return self; 1085 /* 1086 If we haven't already created the real screen font instance, do so now. 1087 Note that if the font has no corresponding screen font, cachedScreenFont 1088 will be set to nil. 1089 */ 1090 if (cachedScreenFont == nil) 1091 cachedScreenFont = [placeHolder initWithName: fontName 1092 matrix: matrix 1093 screenFont: YES 1094 role: role]; 1095 return AUTORELEASE(RETAIN(cachedScreenFont)); 1096} 1097 1098- (NSFont*) screenFontWithRenderingMode: (NSFontRenderingMode)mode 1099{ 1100 // FIXME 1101 return [self screenFont]; 1102} 1103 1104- (NSFontRenderingMode) renderingMode 1105{ 1106 // FIXME 1107 return NSFontDefaultRenderingMode; 1108} 1109 1110- (CGFloat) ascender { return [fontInfo ascender]; } 1111- (CGFloat) descender { return [fontInfo descender]; } 1112- (CGFloat) capHeight { return [fontInfo capHeight]; } 1113- (CGFloat) italicAngle { return [fontInfo italicAngle]; } 1114- (NSSize) maximumAdvancement { return [fontInfo maximumAdvancement]; } 1115- (NSSize) minimumAdvancement { return [fontInfo minimumAdvancement]; } 1116- (CGFloat) underlinePosition { return [fontInfo underlinePosition]; } 1117- (CGFloat) underlineThickness { return [fontInfo underlineThickness]; } 1118- (CGFloat) xHeight { return [fontInfo xHeight]; } 1119- (CGFloat) defaultLineHeightForFont { return [fontInfo defaultLineHeightForFont]; } 1120 1121- (CGFloat) leading 1122{ 1123 // FIXME 1124 return 0.0; 1125} 1126 1127/* Computing font metrics attributes*/ 1128- (CGFloat) widthOfString: (NSString*)string 1129{ 1130 return [fontInfo widthOfString: string]; 1131} 1132 1133- (NSUInteger) numberOfGlyphs 1134{ 1135 return [fontInfo numberOfGlyphs]; 1136} 1137 1138- (NSCharacterSet*) coveredCharacterSet 1139{ 1140 return [fontInfo coveredCharacterSet]; 1141} 1142 1143- (NSFontDescriptor*) fontDescriptor 1144{ 1145 return [fontInfo fontDescriptor]; 1146} 1147 1148/* The following methods have to be implemented by backends */ 1149 1150// 1151// Manipulating Glyphs 1152// 1153- (NSSize) advancementForGlyph: (NSGlyph)aGlyph 1154{ 1155 return [fontInfo advancementForGlyph: aGlyph]; 1156} 1157 1158- (NSRect) boundingRectForGlyph: (NSGlyph)aGlyph 1159{ 1160 return [fontInfo boundingRectForGlyph: aGlyph]; 1161} 1162 1163- (BOOL) glyphIsEncoded: (NSGlyph)aGlyph 1164{ 1165 return [fontInfo glyphIsEncoded: aGlyph]; 1166} 1167 1168- (NSMultibyteGlyphPacking) glyphPacking 1169{ 1170 return [fontInfo glyphPacking]; 1171} 1172 1173- (NSGlyph) glyphWithName: (NSString*)glyphName 1174{ 1175 return [fontInfo glyphWithName: glyphName]; 1176} 1177 1178- (NSPoint) positionOfGlyph: (NSGlyph)curGlyph 1179 precededByGlyph: (NSGlyph)prevGlyph 1180 isNominal: (BOOL*)nominal 1181{ 1182 return [fontInfo positionOfGlyph: curGlyph precededByGlyph: prevGlyph 1183 isNominal: nominal]; 1184} 1185 1186- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph 1187 forCharacter: (unichar)aChar 1188 struckOverRect: (NSRect)aRect 1189{ 1190 return [fontInfo positionOfGlyph: aGlyph 1191 forCharacter: aChar 1192 struckOverRect: aRect]; 1193} 1194 1195- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph 1196 struckOverGlyph: (NSGlyph)baseGlyph 1197 metricsExist: (BOOL *)flag 1198{ 1199 return [fontInfo positionOfGlyph: aGlyph 1200 struckOverGlyph: baseGlyph 1201 metricsExist: flag]; 1202} 1203 1204- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph 1205 struckOverRect: (NSRect)aRect 1206 metricsExist: (BOOL *)flag 1207{ 1208 return [fontInfo positionOfGlyph: aGlyph 1209 struckOverRect: aRect 1210 metricsExist: flag]; 1211} 1212 1213- (NSPoint) positionOfGlyph: (NSGlyph)aGlyph 1214 withRelation: (NSGlyphRelation)relation 1215 toBaseGlyph: (NSGlyph)baseGlyph 1216 totalAdvancement: (NSSize *)offset 1217 metricsExist: (BOOL *)flag 1218{ 1219 return [fontInfo positionOfGlyph: aGlyph 1220 withRelation: relation 1221 toBaseGlyph: baseGlyph 1222 totalAdvancement: offset 1223 metricsExist: flag]; 1224} 1225 1226- (int) positionsForCompositeSequence: (NSGlyph *)glyphs 1227 numberOfGlyphs: (int)numGlyphs 1228 pointArray: (NSPoint *)points 1229{ 1230 int i; 1231 NSGlyph base = glyphs[0]; 1232 1233 points[0] = NSZeroPoint; 1234 1235 for (i = 1; i < numGlyphs; i++) 1236 { 1237 BOOL flag; 1238 // This only places the glyphs relative to the base glyph 1239 // not to each other 1240 points[i] = [self positionOfGlyph: glyphs[i] 1241 struckOverGlyph: base 1242 metricsExist: &flag]; 1243 if (!flag) 1244 return i - 1; 1245 } 1246 1247 return i; 1248} 1249 1250- (void) getAdvancements: (NSSizeArray)advancements 1251 forGlyphs: (const NSGlyph*)glyphs 1252 count: (NSUInteger)count 1253{ 1254 // FIXME 1255 int i; 1256 1257 for (i = 0; i < count; i++) 1258 { 1259 advancements[i] = [self advancementForGlyph: glyphs[i]]; 1260 } 1261} 1262 1263- (void) getAdvancements: (NSSizeArray)advancements 1264 forPackedGlyphs: (const void*)glyphs 1265 count: (NSUInteger)count 1266{ 1267 // FIXME 1268} 1269 1270- (void) getBoundingRects: (NSRectArray)bounds 1271 forGlyphs: (const NSGlyph*)glyphs 1272 count: (NSUInteger)count 1273{ 1274 // FIXME 1275 int i; 1276 1277 for (i = 0; i < count; i++) 1278 { 1279 bounds[i] = [self boundingRectForGlyph: glyphs[i]]; 1280 } 1281} 1282 1283- (NSStringEncoding) mostCompatibleStringEncoding 1284{ 1285 return [fontInfo mostCompatibleStringEncoding]; 1286} 1287 1288// 1289// NSCoding protocol 1290// 1291- (Class) classForCoder 1292{ 1293 return NSFontClass; 1294} 1295 1296- (void) encodeWithCoder: (NSCoder*)aCoder 1297{ 1298 if ([aCoder allowsKeyedCoding]) 1299 { 1300 [aCoder encodeObject: fontName forKey: @"NSName"]; 1301 [aCoder encodeFloat: [self pointSize] forKey: @"NSSize"]; 1302 1303 switch (role >> 1) 1304 { 1305 // FIXME: Many cases still missing 1306 case RoleControlContentFont: 1307 [aCoder encodeInt: 16 forKey: @"NSfFlags"]; 1308 break; 1309 case RoleLabelFont: 1310 [aCoder encodeInt: 20 forKey: @"NSfFlags"]; 1311 break; 1312 case RoleTitleBarFont: 1313 [aCoder encodeInt: 22 forKey: @"NSfFlags"]; 1314 break; 1315 default: 1316 break; 1317 } 1318 } 1319 else 1320 { 1321 [aCoder encodeValueOfObjCType: @encode(int) at: &role]; 1322 1323 if (role == 0) 1324 { 1325 float fontMatrix[6]; 1326 BOOL fix = NO; 1327 1328 fontMatrix[0] = matrix[0]; 1329 fontMatrix[1] = matrix[1]; 1330 fontMatrix[2] = matrix[2]; 1331 fontMatrix[3] = matrix[3]; 1332 fontMatrix[4] = matrix[4]; 1333 fontMatrix[5] = matrix[5]; 1334 [aCoder encodeObject: fontName]; 1335 [aCoder encodeArrayOfObjCType: @encode(float) count: 6 at: fontMatrix]; 1336 [aCoder encodeValueOfObjCType: @encode(BOOL) at: &fix]; 1337 } 1338 else if (role & 1) 1339 { 1340 float size = matrix[0]; 1341 [aCoder encodeValueOfObjCType: @encode(float) at: &size]; 1342 } 1343 } 1344} 1345 1346- (id) initWithCoder: (NSCoder*)aDecoder 1347{ 1348 if ([aDecoder allowsKeyedCoding]) 1349 { 1350 NSString *name = [aDecoder decodeObjectForKey: @"NSName"]; 1351 float size = [aDecoder decodeFloatForKey: @"NSSize"]; 1352 1353 DESTROY(self); 1354 if ([aDecoder containsValueForKey: @"IBIsSystemFont"]) 1355 { 1356 self = RETAIN([NSFont systemFontOfSize: size]); 1357 } 1358 else 1359 { 1360 self = RETAIN([NSFont fontWithName: name size: size]); 1361 } 1362 if (self == nil) 1363 { 1364 if ([aDecoder containsValueForKey: @"NSfFlags"]) 1365 { 1366 int flags = [aDecoder decodeIntForKey: @"NSfFlags"]; 1367 // FIXME 1368 if (flags == 16) 1369 { 1370 return RETAIN([NSFont controlContentFontOfSize: size]); 1371 } 1372 else if (flags == 20) 1373 { 1374 return RETAIN([NSFont labelFontOfSize: size]); 1375 } 1376 else if (flags == 22) 1377 { 1378 return RETAIN([NSFont titleBarFontOfSize: size]); 1379 } 1380 } 1381 self = RETAIN([NSFont systemFontOfSize: size]); 1382 } 1383 1384 return self; 1385 } 1386 else 1387 { 1388 int version = [aDecoder versionForClassName: @"NSFont"]; 1389 id name; 1390 float fontMatrix[6]; 1391 CGFloat cgMatrix[6]; 1392 int the_role; 1393 1394 if (version == 3) 1395 { 1396 [aDecoder decodeValueOfObjCType: @encode(int) 1397 at: &the_role]; 1398 } 1399 else 1400 { 1401 the_role = RoleExplicit; 1402 } 1403 1404 if (the_role == RoleExplicit) 1405 { 1406 /* The easy case: an explicit font, or a font encoded with 1407 version <= 2. */ 1408 name = [aDecoder decodeObject]; 1409 [aDecoder decodeArrayOfObjCType: @encode(float) 1410 count: 6 1411 at: fontMatrix]; 1412 1413 if (version >= 2) 1414 { 1415 BOOL fix; 1416 [aDecoder decodeValueOfObjCType: @encode(BOOL) 1417 at: &fix]; 1418 } 1419 1420 cgMatrix[0] = fontMatrix[0]; 1421 cgMatrix[1] = fontMatrix[1]; 1422 cgMatrix[2] = fontMatrix[2]; 1423 cgMatrix[3] = fontMatrix[3]; 1424 cgMatrix[4] = fontMatrix[4]; 1425 cgMatrix[5] = fontMatrix[5]; 1426 self = [self initWithName: name 1427 matrix: cgMatrix 1428 screenFont: NO 1429 role: RoleExplicit]; 1430 if (self) 1431 return self; 1432 1433 self = [NSFont userFontOfSize: fontMatrix[0]]; 1434 NSAssert(self != nil, @"Couldn't find a valid font when decoding."); 1435 return RETAIN(self); 1436 } 1437 else 1438 { 1439 /* A non-explicit font. */ 1440 float size; 1441 NSFont *new; 1442 1443 if (the_role & 1) 1444 { 1445 [aDecoder decodeValueOfObjCType: @encode(float) 1446 at: &size]; 1447 } 1448 else 1449 { 1450 size = 0.0; 1451 } 1452 1453 switch (the_role >> 1) 1454 { 1455 case RoleBoldSystemFont: 1456 new = [NSFont boldSystemFontOfSize: size]; 1457 break; 1458 case RoleSystemFont: 1459 new = [NSFont systemFontOfSize: size]; 1460 break; 1461 case RoleUserFixedPitchFont: 1462 new = [NSFont userFixedPitchFontOfSize: size]; 1463 break; 1464 case RoleTitleBarFont: 1465 new = [NSFont titleBarFontOfSize: size]; 1466 break; 1467 case RoleMenuFont: 1468 new = [NSFont menuFontOfSize: size]; 1469 break; 1470 case RoleMessageFont: 1471 new = [NSFont messageFontOfSize: size]; 1472 break; 1473 case RolePaletteFont: 1474 new = [NSFont paletteFontOfSize: size]; 1475 break; 1476 case RoleToolTipsFont: 1477 new = [NSFont toolTipsFontOfSize: size]; 1478 break; 1479 case RoleControlContentFont: 1480 new = [NSFont controlContentFontOfSize: size]; 1481 break; 1482 case RoleLabelFont: 1483 new = [NSFont labelFontOfSize: size]; 1484 break; 1485 case RoleMenuBarFont: 1486 new = [NSFont menuBarFontOfSize: size]; 1487 break; 1488 1489 default: 1490 NSDebugLLog(@"NSFont", @"unknown role %i", the_role); 1491 /* fall through */ 1492 case RoleUserFont: 1493 new = [NSFont userFontOfSize: size]; 1494 break; 1495 } 1496 1497 RELEASE(self); 1498 if (new) 1499 return RETAIN(new); 1500 1501 new = [NSFont userFontOfSize: size]; 1502 NSAssert(new != nil, @"Couldn't find a valid font when decoding."); 1503 return RETAIN(new); 1504 } 1505 } 1506} 1507 1508@end /* NSFont */ 1509 1510@implementation NSFont (GNUstep) 1511// 1512// Private method for NSFontManager and backend 1513// 1514- (GSFontInfo*) fontInfo 1515{ 1516 return fontInfo; 1517} 1518 1519- (void *) fontRef 1520{ 1521 if (_fontRef == nil) 1522 _fontRef = fontInfo; 1523 return _fontRef; 1524} 1525 1526// This is a private but popular Cocoa method. 1527- (NSGlyph) _defaultGlyphForChar: (unichar)theChar 1528{ 1529 return [fontInfo glyphForCharacter: theChar]; 1530} 1531 1532@end 1533 1534 1535int NSConvertGlyphsToPackedGlyphs(NSGlyph *glBuf, 1536 int count, 1537 NSMultibyteGlyphPacking packing, 1538 char *packedGlyphs) 1539{ 1540 int i; 1541 int j; 1542 1543 j = 0; 1544 // Store the number of glyphs in the first byte. 1545 packedGlyphs[j++] = count; 1546 for (i = 0; i < count; i++) 1547 { 1548 NSGlyph g = glBuf[i]; 1549 1550 switch (packing) 1551 { 1552 case NSOneByteGlyphPacking: 1553 packedGlyphs[j++] = (char)(g & 0xFF); 1554 break; 1555 case NSTwoByteGlyphPacking: 1556 packedGlyphs[j++] = (char)((g & 0xFF00) >> 8) ; 1557 packedGlyphs[j++] = (char)(g & 0xFF); 1558 break; 1559 case NSFourByteGlyphPacking: 1560 packedGlyphs[j++] = (char)((g & 0xFF000000) >> 24) ; 1561 packedGlyphs[j++] = (char)((g & 0xFF0000) >> 16); 1562 packedGlyphs[j++] = (char)((g & 0xFF00) >> 8) ; 1563 packedGlyphs[j++] = (char)(g & 0xFF); 1564 break; 1565 case NSJapaneseEUCGlyphPacking: 1566 case NSAsciiWithDoubleByteEUCGlyphPacking: 1567 default: 1568 // FIXME 1569 break; 1570 } 1571 } 1572 1573 return j; 1574} 1575