/**
The NSFont class allows control of the fonts used for displaying text anywhere on the screen. The primary methods for getting a particular font are +fontWithName:matrix: and +fontWithName:size: which take the name and size of a particular font and return the NSFont object associated with that font. In addition there are several convenience mathods which make it easier to get certain types of fonts.
In particular, there are several methods to get the standard fonts used by the Application to display text for a partiuclar purpose. See the class methods listed below for more information. These default fonts can be set using the user defaults system. The default font names available are:
The default sizes are:
Font sizes list with (none) default to NSFontSize.
Returns the default bold font for use in menus and heading in standard gui components. If fontSize is <= 0, the default size is used.
See Also: +fontWithName:size:
*/ + (NSFont*) boldSystemFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleBoldSystemFont); } /**Returns the default font for use in menus and heading in standard gui components. If fontSize is <= 0, the default size is used.
See Also: +boldSystemFontOfSize: userFontOfSize: userFixedPitchFontOfSize: +fontWithName:size:
*/ + (NSFont*) systemFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleSystemFont); } /**Returns the default fixed pitch font for use in locations other than standard gui components. If fontSize is <= 0, the default size is used.
See Also: +setUserFixedPitchFont: +userFontOfSize: +boldSystemFontOfSize: +systemFontOfSize: +fontWithName:size:
*/ + (NSFont*) userFixedPitchFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleUserFixedPitchFont); } /**Returns the default font for use in locations other than standard gui components. If fontSize is <= 0, the default size is used.
See Also: +setUserFont: +boldSystemFontOfSize: systemFontOfSize: userFixedPitchFontOfSize: +fontWithName:size:
*/ + (NSFont*) userFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleUserFont); } /**Returns an array of the names of preferred fonts.
See Also: +setPreferredFontNames:
*/ + (NSArray*) preferredFontNames { return _preferredFonts; } /* Setting the preferred user fonts*/ + (void) setUserFixedPitchFont: (NSFont*)aFont { setNSFont (@"NSUserFixedPitchFont", aFont); } + (void) setUserFont: (NSFont*)aFont { setNSFont (@"NSUserFont", aFont); } /**Sets an array of the names of preferred fonts to fontsNames/
See Also: +preferredFontNames
*/ + (void) setPreferredFontNames: (NSArray*)fontNames { ASSIGN(_preferredFonts, fontNames); } /* Getting various fonts*/ + (NSFont*) controlContentFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleControlContentFont); } + (NSFont*) labelFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleLabelFont); } + (NSFont*) menuFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleMenuFont); } + (NSFont*) menuBarFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleMenuBarFont); } + (NSFont*) titleBarFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleTitleBarFont); } + (NSFont*) messageFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleMessageFont); } + (NSFont*) paletteFontOfSize: (float)fontSize { return getNSFont(fontSize, RolePaletteFont); } + (NSFont*) toolTipsFontOfSize: (float)fontSize { return getNSFont(fontSize, RoleToolTipsFont); } // // Font Sizes // + (float) labelFontSize { float fontSize = [defaults floatForKey: @"NSLabelFontSize"]; if (fontSize == 0) { return [self systemFontSize]; } return fontSize; } + (float) smallSystemFontSize { float fontSize = [defaults floatForKey: @"NSSmallFontSize"]; if (fontSize == 0) { fontSize = 9; } return fontSize; } + (float) systemFontSize { float fontSize = [defaults floatForKey: @"NSFontSize"]; if (fontSize == 0) { fontSize = 12; } return fontSize; } + (float) systemFontSizeForControlSize: (NSControlSize)controlSize { switch (controlSize) { case NSMiniControlSize: { float fontSize = [defaults floatForKey: @"NSMiniFontSize"]; if (fontSize == 0) { fontSize = 6; } return fontSize; } case NSSmallControlSize: return [self smallSystemFontSize]; case NSRegularControlSize: default: return [self systemFontSize]; } } /**Returns an autoreleased font with name aFontName and matrix fontMatrix .
The fontMatrix is a standard size element matrix as used in PostScript to describe the scaling of the font, typically it just includes the font size as [fontSize 0 0 fontSize 0 0]. You can use the constant NSFontIdentityMatrix in place of [1 0 0 1 0 0]. If NSFontIdentityMatrix, then the font will automatically flip itself when set in a flipped view.
*/ + (NSFont*) fontWithName: (NSString*)aFontName matrix: (const float*)fontMatrix { NSFont *font; BOOL fix; if (fontMatrix == NSFontIdentityMatrix) fix = NO; else fix = YES; font = [placeHolder initWithName: aFontName matrix: fontMatrix fix: fix screenFont: NO role: RoleExplicit]; return AUTORELEASE(font); } /**Returns an autoreleased font with name aFontName and size fontSize.
*Fonts created using this method will automatically flip themselves * when set in a flipped view.
*/ + (NSFont*) fontWithName: (NSString*)aFontName size: (float)fontSize { return [self _fontWithName: aFontName size: fontSize role: RoleExplicit]; } + (NSFont*) _fontWithName: (NSString*)aFontName size: (float)fontSize role: (int)aRole { NSFont *font; float fontMatrix[6] = { 0, 0, 0, 0, 0, 0 }; if (fontSize == 0) { fontSize = [defaults floatForKey: @"NSUserFontSize"]; if (fontSize == 0) { fontSize = 12; } } fontMatrix[0] = fontSize; fontMatrix[3] = fontSize; font = [placeHolder initWithName: aFontName matrix: fontMatrix fix: NO screenFont: NO role: aRole]; return AUTORELEASE(font); } /** */ + (void) useFont: (NSString*)aFontName { [GSCurrentContext() useFont: aFontName]; } // // Instance methods // - (id) init { [NSException raise: NSInternalInconsistencyException format: @"Called -init on NSFont ... illegal"]; return self; } /**This method returns nil in the GNUstep implementation
*/ - (NSString*) afmFileContents { return [fontInfo afmFileContents]; } - (NSFont*) printerFont { if (!screenFont) return self; return AUTORELEASE([placeHolder initWithName: fontName matrix: matrix fix: matrixExplicitlySet screenFont: NO role: role]); } - (NSFont*) screenFont { if (screenFont) return self; /* If we haven't already created the real screen font instance, do so now. Note that if the font has no corresponding screen font, cachedScreenFont will be set to nil. */ if (cachedScreenFont == placeHolder) cachedScreenFont = [placeHolder initWithName: fontName matrix: matrix fix: matrixExplicitlySet screenFont: YES role: role]; return AUTORELEASE(RETAIN(cachedScreenFont)); } - (float) ascender { return [fontInfo ascender]; } - (float) descender { return [fontInfo descender]; } - (float) capHeight { return [fontInfo capHeight]; } - (float) italicAngle { return [fontInfo italicAngle]; } - (NSSize) maximumAdvancement { return [fontInfo maximumAdvancement]; } - (NSSize) minimumAdvancement { return [fontInfo minimumAdvancement]; } - (float) underlinePosition { return [fontInfo underlinePosition]; } - (float) underlineThickness { return [fontInfo underlineThickness]; } - (float) xHeight { return [fontInfo xHeight]; } - (float) defaultLineHeightForFont { return [fontInfo defaultLineHeightForFont]; } /* Computing font metrics attributes*/ - (float) widthOfString: (NSString*)string { return [fontInfo widthOfString: string]; } - (unsigned) numberOfGlyphs { // FIXME return 0; } - (NSCharacterSet*) coveredCharacterSet { // FIXME return nil; } - (NSFontDescriptor*) fontDescriptor { // FIXME return nil; } /* The following methods have to be implemented by backends */ // // Manipulating Glyphs // - (NSSize) advancementForGlyph: (NSGlyph)aGlyph { return [fontInfo advancementForGlyph: aGlyph]; } - (NSRect) boundingRectForGlyph: (NSGlyph)aGlyph { return [fontInfo boundingRectForGlyph: aGlyph]; } - (BOOL) glyphIsEncoded: (NSGlyph)aGlyph { return [fontInfo glyphIsEncoded: aGlyph]; } - (NSMultibyteGlyphPacking) glyphPacking { return [fontInfo glyphPacking]; } - (NSGlyph) glyphWithName: (NSString*)glyphName { return [fontInfo glyphWithName: glyphName]; } - (NSPoint) positionOfGlyph: (NSGlyph)curGlyph precededByGlyph: (NSGlyph)prevGlyph isNominal: (BOOL*)nominal { return [fontInfo positionOfGlyph: curGlyph precededByGlyph: prevGlyph isNominal: nominal]; } - (NSPoint) positionOfGlyph: (NSGlyph)aGlyph forCharacter: (unichar)aChar struckOverRect: (NSRect)aRect { return [fontInfo positionOfGlyph: aGlyph forCharacter: aChar struckOverRect: aRect]; } - (NSPoint) positionOfGlyph: (NSGlyph)aGlyph struckOverGlyph: (NSGlyph)baseGlyph metricsExist: (BOOL *)flag { return [fontInfo positionOfGlyph: aGlyph struckOverGlyph: baseGlyph metricsExist: flag]; } - (NSPoint) positionOfGlyph: (NSGlyph)aGlyph struckOverRect: (NSRect)aRect metricsExist: (BOOL *)flag { return [fontInfo positionOfGlyph: aGlyph struckOverRect: aRect metricsExist: flag]; } - (NSPoint) positionOfGlyph: (NSGlyph)aGlyph withRelation: (NSGlyphRelation)relation toBaseGlyph: (NSGlyph)baseGlyph totalAdvancement: (NSSize *)offset metricsExist: (BOOL *)flag { return [fontInfo positionOfGlyph: aGlyph withRelation: relation toBaseGlyph: baseGlyph totalAdvancement: offset metricsExist: flag]; } - (int) positionsForCompositeSequence: (NSGlyph *)glyphs numberOfGlyphs: (int)numGlyphs pointArray: (NSPoint *)points { int i; NSGlyph base = glyphs[0]; points[0] = NSZeroPoint; for (i = 1; i < numGlyphs; i++) { BOOL flag; // This only places the glyphs relative to the base glyph // not to each other points[i] = [self positionOfGlyph: glyphs[i] struckOverGlyph: base metricsExist: &flag]; if (!flag) return i - 1; } return i; } - (NSStringEncoding) mostCompatibleStringEncoding { return [fontInfo mostCompatibleStringEncoding]; } // // NSCoding protocol // - (Class) classForCoder { return NSFontClass; } - (void) encodeWithCoder: (NSCoder*)aCoder { if ([aCoder allowsKeyedCoding]) { [aCoder encodeObject: fontName forKey: @"NSName"]; [aCoder encodeFloat: [self pointSize] forKey: @"NSSize"]; switch (role >> 1) { // FIXME: Many cases still missing case RoleControlContentFont: [aCoder encodeInt: 16 forKey: @"NSfFlags"]; break; case RoleLabelFont: [aCoder encodeInt: 20 forKey: @"NSfFlags"]; break; case RoleTitleBarFont: [aCoder encodeInt: 22 forKey: @"NSfFlags"]; break; default: break; } } else { [aCoder encodeValueOfObjCType: @encode(int) at: &role]; if (role == 0) { [aCoder encodeObject: fontName]; [aCoder encodeArrayOfObjCType: @encode(float) count: 6 at: matrix]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &matrixExplicitlySet]; } else if (role & 1) { [aCoder encodeValueOfObjCType: @encode(float) at: &matrix[0]]; } } } - (id) initWithCoder: (NSCoder*)aDecoder { if ([aDecoder allowsKeyedCoding]) { NSString *name = [aDecoder decodeObjectForKey: @"NSName"]; float size = [aDecoder decodeFloatForKey: @"NSSize"]; RELEASE(self); if ([aDecoder containsValueForKey: @"NSfFlags"]) { int flags = [aDecoder decodeIntForKey: @"NSfFlags"]; // FIXME if (flags == 16) { return RETAIN([NSFont controlContentFontOfSize: size]); } else if (flags == 20) { return RETAIN([NSFont labelFontOfSize: size]); } else if (flags == 22) { return RETAIN([NSFont titleBarFontOfSize: size]); } } self = [NSFont fontWithName: name size: size]; if (self == nil) { self = RETAIN([NSFont systemFontOfSize: size]); } return self; } else { int version = [aDecoder versionForClassName: @"NSFont"]; id name; float fontMatrix[6]; BOOL fix; int the_role; if (version == 3) { [aDecoder decodeValueOfObjCType: @encode(int) at: &the_role]; } else { the_role = RoleExplicit; } if (the_role == RoleExplicit) { /* The easy case: an explicit font, or a font encoded with version <= 2. */ name = [aDecoder decodeObject]; [aDecoder decodeArrayOfObjCType: @encode(float) count: 6 at: fontMatrix]; if (version >= 2) { [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &fix]; } else { if (fontMatrix[0] == fontMatrix[3] && fontMatrix[1] == 0.0 && fontMatrix[2] == 0.0) fix = NO; else fix = YES; } self = [self initWithName: name matrix: fontMatrix fix: fix screenFont: NO role: RoleExplicit]; if (self) return self; self = [NSFont userFontOfSize: fontMatrix[0]]; NSAssert(self != nil, @"Couldn't find a valid font when decoding."); return RETAIN(self); } else { /* A non-explicit font. */ float size; NSFont *new; if (the_role & 1) { [aDecoder decodeValueOfObjCType: @encode(float) at: &size]; } else { size = 0.0; } switch (the_role >> 1) { case RoleBoldSystemFont: new = [NSFont boldSystemFontOfSize: size]; break; case RoleSystemFont: new = [NSFont systemFontOfSize: size]; break; case RoleUserFixedPitchFont: new = [NSFont userFixedPitchFontOfSize: size]; break; case RoleTitleBarFont: new = [NSFont titleBarFontOfSize: size]; break; case RoleMenuFont: new = [NSFont menuFontOfSize: size]; break; case RoleMessageFont: new = [NSFont messageFontOfSize: size]; break; case RolePaletteFont: new = [NSFont paletteFontOfSize: size]; break; case RoleToolTipsFont: new = [NSFont toolTipsFontOfSize: size]; break; case RoleControlContentFont: new = [NSFont controlContentFontOfSize: size]; break; case RoleLabelFont: new = [NSFont labelFontOfSize: size]; break; case RoleMenuBarFont: new = [NSFont menuBarFontOfSize: size]; break; default: NSDebugLLog(@"NSFont", @"unknown role %i", the_role); /* fall through */ case RoleUserFont: new = [NSFont userFontOfSize: size]; break; } RELEASE(self); if (new) return RETAIN(new); new = [NSFont userFontOfSize: size]; NSAssert(new != nil, @"Couldn't find a valid font when decoding."); return RETAIN(new); } } } @end /* NSFont */ @implementation NSFont (GNUstep) // // Private method for NSFontManager and backend // - (GSFontInfo*) fontInfo { return fontInfo; } - (void *) fontRef { if (_fontRef == nil) _fontRef = [NSGraphicsContext CGFontReferenceFromFont: self]; return _fontRef; } @end int NSConvertGlyphsToPackedGlyphs(NSGlyph *glBuf, int count, NSMultibyteGlyphPacking packing, char *packedGlyphs) { int i; int j; j = 0; for (i = 0; i < count; i++) { NSGlyph g = glBuf[i]; switch (packing) { case NSOneByteGlyphPacking: packedGlyphs[j++] = (char)(g & 0xFF); break; case NSTwoByteGlyphPacking: packedGlyphs[j++] = (char)((g & 0xFF00) >> 8) ; packedGlyphs[j++] = (char)(g & 0xFF); break; case NSFourByteGlyphPacking: packedGlyphs[j++] = (char)((g & 0xFF000000) >> 24) ; packedGlyphs[j++] = (char)((g & 0xFF0000) >> 16); packedGlyphs[j++] = (char)((g & 0xFF00) >> 8) ; packedGlyphs[j++] = (char)(g & 0xFF); break; case NSJapaneseEUCGlyphPacking: case NSAsciiWithDoubleByteEUCGlyphPacking: default: // FIXME break; } } return j; }