Loading fonts
Common Graphics supports both scalable and nonscalable fonts. Scalable fonts are a variable font definition that can be scaled to different sized fonts. Nonscalable fonts cannot be scaled and, when loaded, are always the same size. Scalable fonts are indicated by zeros in the pixel size, point size, and average width fields of the font name.
To load a scalable font successfully, you must specify the size of the font by changing the pixel size or the point size field in the font name prior to issuing one of the font loading methods. Because a nonscalable font has a predetermined size, its font name is passed directly to the font loading methods without any preprocessing.
Determining whether a font is scalable
Consider the two font names that follow. In the first font name, the pixel size, point size and average width fields contain zeros (-0-0-...-0-) indicating that it is a scalable font. In the second font name, all three fields have actual values (-33-240-...-180-) indicating that it is a nonscalable, or fixed size, font.
-adobe-helvetica-bold-i-normal-sans serif-0-0-100-100-p-0-iso8859-1
-adobe-helvetica-bold-i-normal-sans serif-33-240-100-100-p-180-iso8859-1
CgLogicalFontDescription class can be used to parse and modify an XLFD name. The following example determines whether or not a font is scalable by first creating a CgLogicalFontDescription object for the font.
| fontName description |
"Ask the system for any font name."
fontName := (CgDisplay default
listFonts: '-*-*-*-*-*-*-*-*-*-*-*-*-*-*'
maxnames: 1) first.
"Create a font description object for the font name."
description := CgLogicalFontDescription name: fontName.
"Answer true if the font is scalable, false otherwise."
^description isScalable.
Parsing a scalable font name
To load a scalable font, the zeros in the size fields of the font name must be replaced by actual values and passed to one of the font loading methods. The following example illustrates the use of a CgLogicalFontDescription object to specify the point size in a scalable font name. Point size is specified in 1/10ths of 1/72 of an inch (tenths of a point), so a 24-point font is represented as 240. Also note that the pixel size and average width fields are changed to wildcards, indicating that they will be computed based on the point size.
| fontName description |
fontName := '-adobe-helvetica-bold-i-normal-sans serif-0-0-100-100-p-0-iso8859-1'.
"Create a font description object for the name."
description := CgLogicalFontDescription name: fontName.
"Replace point size, pixel size, and average character width fields."
description
points: '240';
pixels: '*';
averageWidth: '*'.
"Get the modified name back as a string."
description name
The preceding code returns this:
'-adobe-helvetica-bold-i-normal-sans serif-*-240-100-100-p-*-iso8859-1'
Once the scalable font name has been modified to specify a fixed size, it is then referred to as a scaled font name. It can then be passed to one of the font loading methods that follow. Fonts are loaded into memory by sending the loadFont: or loadQueryFont: messages to a CgDisplay object. The loadFont: method takes a font name and returns a CgFont object. The loadQueryFont: method takes a font name and returns a CgFontStruct object.
Loading a CgFont
| fontName font |
fontName := '8x13'.
font := CgDisplay default
loadFont: fontName.
Loading a CgFontStruct
| fontName fontStruct |
fontName := '8x13'.
fontStruct := CgDisplay default
loadQueryFont: fontName.
More about CgFont and CgFontStruct
In the last example, two different operations were used to load a CgFontStruct and a CgFont object. These two objects, while both representing a font, provide different kinds of information to the application.
CgFont is a handle to the font in the operating system. It is useful in applications where you simply wish to draw text and do not require a measure of the dimensions of the text.
CgFontStruct is a more detailed description of the font. It provides information that is useful when you need to perform calculations based on text width or text height, for example, centering a label in a window.
Here are some of the more useful CgFontStruct access methods:
font
Returns the CgFont.
name
Returns the name of the font.
ascent
Returns the integer height in pixels of the font ascender.
descent
Returns the integer height in pixels of the font descender.
height
Returns the integer height in pixels of the font (ascent plus descent).
defaultChar
Returns the character index to use for undefined characters.
numChars
Returns the number of characters in the font.
perChar
Returns the first row of an array of CgCharStructs describing the dimensions of each character in the font.
perCharAtRow:
Returns the specified row of an array of CgCharStructs describing the dimensions of each character in the font. Use for double-byte fonts.
perCharNumRows
Returns the number of rows in the font's per-char information.
perCharNumColumns
Returns the number of columns in the font's per-char information.
maxBounds
Returns a CgCharStruct describing the maximum bounds over all characters in the font.
minBounds
Returns a CgCharStruct describing the minimum bounds over all characters in the font.
textWidth:
Returns the width in pixels of the text string provided.
textExtents:directionReturn:fontAscentReturn:fontDescentReturn:overallReturn:
Returns the direction in which text is drawn, the font ascender, the font descender, and a CgCharStruct describing the overall size of the text.
More about CgCharStruct
While a
CgFontStruct holds information about the entire font, a
CgCharStruct holds information about each individual character in the font. The following diagram shows some of the commonly used metrics of both
CgFontStruct and
CgCharStruct as they pertain to two characters 'A' and 'j' in a typical font.
Note that the origin of each character is on the baseline, and not in the upper left. A CgCharStruct's origin is the leftmost pixel along its baseline; therefore, it is actually at a point that is 0 @ ascent with respect to the upper left corner of the CgCharStruct. This is useful to know when drawing a string inside of a rectangle drawn at x @ y. The string must be drawn at x @ (y + ascent). This is in keeping with typographic convention. The ascent, descent, and width of a CgFontStruct are equal to the largest CgCharStruct ascent, descent, and width in the font. The lbearing, rbearing, and bearing metrics are only shown for 'A.' Additional CgCharStruct instance methods follow:
ascent
Returns the number of pixels between the baseline and the top edge of the raster.
descent
Returns the number of pixels between the baseline and the bottom edge of the raster.
height
Returns the number of pixels between the top edge of the raster and the bottom edge of the raster.
extent
Returns a point in which the x-coordinate is the character's height, and the y-coordinate is the character's width.
bearing
Returns the number of pixels between the left edge of the raster and the right edge of the raster.
lbearing
Returns the number of pixels between the origin and the left edge of the raster.
rbearing
Returns the number of pixels between the origin and the right edge of the raster.
width
Returns the number of pixels to advance to the next character's origin.