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.
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.
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.
| fontName font | fontName := '8x13'. font := CgDisplay default loadFont: fontName.
| fontName fontStruct | fontName := '8x13'. fontStruct := CgDisplay default loadQueryFont: fontName.
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:
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: