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 &lt;= 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 &lt;= 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 &lt;= 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 &lt;= 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