Chapter Contents

Previous

Next
The GFONT Procedure

Creating a Font

To create a font, you must create a data set that contains font information. Typically, you use a DATA step to create a SAS data set from which the GFONT procedure generates the font. The data set is referred to as the font data set and you can specify it with the DATA= argument.

To produce the font, invoke the GFONT procedure and specify the data set that contains the font information. In addition you can include options to modify the design and appearance of the font. For example, the following statement uses the data set FONTDATA to generate the font MYLOGO:

proc gfont data=fontdata name=mylogo;

For a demonstration of the font creation process, see Creating Figures for a Symbol Font.

The GFONT procedure uses three types of data sets: the font data set, the kern data set, and the space data set. Each type of data set must contain certain variables and meet certain requirements. The following sections explain what each data set contains, how it is built, and what the requirements of the variables are.

The Font Data Set

The font data set consists of a series of observations that include the horizontal and vertical coordinate values and line segment numbers that the GFONT procedure uses to generate each character. In addition, each observation must include a character code that is associated with the font character and is used to specify the font character in a text string. The font data set also determines whether the font is stroked or polygon. A font data set that generates a polygon font produces an outline font by default. You can use the FILLED option with the same data set to generate a filled font.

The variables in the font data set must be assigned certain names and types. The table below summarizes the characteristics of the variables which are described further in Font Data Set Variables.

Font Data Set Variables
Variable Description Type Length Valid Values With Stroked Fonts With Polygon Fonts
CHAR the character code associated with the font character character 1 or 2 keyboard characters or hexadecimal values required required
LP the type of line segment being drawn, either a line or a polygon character 1 L or P optional required
PTYPE the type of data in the observation character 1 V or C or W optional optional
SEGMENT the number of the line segment or polygon being drawn numeric
number required required
X the horizontal coordinate numeric
number required required
Y the vertical coordinate numeric
number required required


Font Data Set Variables

CHAR
provides a code for the character or figure that you are creating. CHAR is a character variable with a length of 1 or 2 and is required for all fonts.
CAUTION:
Using reserved or undefined hexadecimal codes as CHAR values may require the use of the NOKEYMAP option.   [cautionend]

The CHAR variable takes any character as its value, including characters that you can enter from your keyboard and hexadecimal values from '00'x to 'FF'x. (If you use hexadecimal values as CHAR values, your font may not work correctly under a key map that is different from the one under which the font was created because positions that are not defined in one key map may be defined in another.)

When you specify the code character in a text string, the associated font character is drawn. For example, if you create a Roman alphabet font, typically the characters you specify for CHAR are keyboard characters that match the character in the font. All of the observations that build the letter A have a CHAR value of A. When you specify 'A' in a text string this produces A in the output.

However, if you build a symbol font, the symbols may not have corresponding keyboard characters. In that case, you select a character or hexadecimal value to represent each symbol in the font and assign it to CHAR. For example, in the Special font, the letter G is assigned as the code for the fleur-de-lis symbol. When you specify the code in a text string, the associated symbol displays.

If the CODELEN= option is set to 2, the values for CHAR represent two characters, such as AA, or a four-digit hexadecimal value, such as '00A5'x.

LP
tells the GFONT procedure whether the coordinates of each segment form a line or a polygon. LP is a character variable with a length of 1. It is required for polygon fonts but optional for stroked fonts. You can assign the LP variable either of the following values:
L lines
P polygons.

Every group of line segments with an LP value of P is designated as a polygon; if the observations do not draw a completely closed figure, the program closes the figure automatically. For example, the following observations do not contain an LP variable. They produce a shape like the one in Using an LP Value of Line.

OBS CHAR SEG X Y
1 b 1 1 1
2 b 1 1 3
3 b 1 3 3
4 b 1 3 1

Using an LP Value of Line

[IMAGE]

LP (continued)
An LP variable with a value of P for all observations added to the data set produces a complete box like the one in Using an LP Value of Polygon.

OBS CHAR SEG X Y LP
1 b 1 1 1 P
2 b 1 1 3 P
3 b 1 3 3 P
4 b 1 3 1 P

Using an LP Value of Polygon

[IMAGE]

LP (continued)
The LP variable allows you to mix lines and polygons when you create characters in a font. For example, the following observations produce the single figure that is composed of a polygon and a line segment, as shown in Mixing LP Values of Line and Polygon:

OBS CHAR SEG X Y LP
1 b 1 1 1 P
2 b 1 1 3 P
3 b 1 3 3 P
4 b 1 3 1 P
5 b 2 0 0 L
6 b 2 2 4 L
7 b 2 4 0 L

Mixing LP Values of Line and Polygon

[IMAGE]

PTYPE
tells the GFONT procedure what type of data are in the observation. PTYPE is a character variable of length 1 that is optional for both stroked and polygon fonts. For each observation, the PTYPE variable assigns a characteristic to the point that is determined by the X and Y values. You can assign the PTYPE variable any of the following values:
V normal point in the line segment
C center of a circular arc joining two V points
W width value for CHARSPACETYPE=DATA.

If the GFONT procedure encounters the sequence V-C-V in consecutive observations, it draws an arc that connects the two V points and has its center at the C point. If a circle cannot be centered at C and pass through both V points, the results are unpredictable. Arcs are limited to 106 degrees or less.

If you specify an observation with a PTYPE value of W, it must always be the first observation for a character. Instead of providing digitizing data to the procedure, the observation gives the minimum and maximum X values for the character. Note that in this case, the Y variable observation actually contains the maximum X value. Usually, these values include a little extra space for intercharacter spacing. Use a PTYPE of W only if you have specified CHARSPACETYPE=DATA; otherwise, the points are ignored. For more information on intercharacter spacing, see the description of the CHARSPACETYPE= option .

If you do not specify a PTYPE variable in the font data set, all points are assumed to be V-type points.

The following observations illustrate how the PTYPE variable is used to draw an arc similar to Using the PTYPE Variable to Create an Arc. (After the figure was generated, a grid was overlaid on it to show the location of the points.) A comment following each observation explains its function.

OBS CHAR SEG X Y LP PTYPE Comment
1 a 1 40 60 P W define width of character as 20 font units, which is the number of units from left margin, 40, to right margin, 60
2 a 1 45 40 P V start line segment at position 45,40
3 a 1 45 50 P V draw a line to position 45,50, which is start point of arc
4 a 1 45 40 P C draw an arc whose center is at 45,40
5 a 1 55 40 P V finish drawing the arc at 55,40

Using the PTYPE Variable to Create an Arc

[IMAGE]

Note the following:

SEGMENT
numbers the line segments that compose a character or symbol. SEGMENT is a numeric variable that is required for both polygon and stroked fonts. All the observations for a given line segment have the same segment number. The segment number changes when a new line segment starts.

When the GFONT procedure draws a stroked character with more than one line segment (for example, the letter E), or a polygon character with a hole (for example, the letter A), it needs to know when one line stops and where the next line begins. There are two ways to do this, as follows:

  1. Change the segment number when a new line segment starts. If the value of LP is L (line), a change in segment numbers tells the GFONT procedure not to connect the last point in line segment 1 and the first point in line segment 2. If the value of LP is P (polygon), a change in segment numbers causes both of the following:

    • The last point in line segment 1 is joined to the first point in line segment 1, thus closing the polygon.

    • The program starts a new polygon. If the value of CHAR has not changed, the new polygon is part of the same character.

    Use this method for characters that are composed of two polygons, such as a question mark (?). If you draw a polygon with a hole in it, such as the letter A, use the second method.

  2. Keep the same segment number for all lines, but insert an observation with missing values for X and Y between the observation that marks the end of the first line and the observation that begins the next line. For example, if you are drawing the letter O, insert an observation with a missing value between the line that draws the outer circle and the beginning of the line that draws the inner circle.

The first method is preferred, unless you are creating a polygon character with a hole in it. In this case, you should separate the lines with a missing value and keep the same segment numbers. (Note that if you use separate line segments when you create a polygon with a hole, the results may be unpredictable.) For example, observations such as the following from a data set called BOXES were used to draw the hollow square in Drawing Nested Polygons. The data points that form the figure are laid out on a grid shown next to the square.

OBS CHAR SEG X Y LP
1 b 1 1 1 P
2 b 1 1 3 P
3 b 1 3 3 P
4 b 1 3 1 P
5 b 1 - - P
6 b 1 0 0 P
7 b 1 0 4 P
8 b 1 4 4 P
9 b 1 4 0 P

Note that observation 5, which has missing values for X and Y, separates the observations that draw the inner box from those that draw the outer box and that the segment number is the same for all the observations. Drawing Nested Polygons was generated with a GFONT statement like the following:

proc gfont data=boxes name=boxes filled;

Note that the FILLED option is included and that only the space between the two squares is filled.

Drawing Nested Polygons

[IMAGE]

X Y
specify the horizontal and vertical coordinates of the points for each character. These variables must be numeric, and they must be named X and Y for the horizontal and vertical coordinates, respectively. Their values describe the position of the points on the character. These values can be in any range that you choose, but both variables must describe the character in the same scale or font units. In other words, 10 horizontal units must be the same distance as 10 vertical units. You should define vertical coordinates for all characters on the same baseline.

Note:   When you specify PTYPE=W, both X and Y contain horizontal coordinate values.  [cautionend]


Creating a Font Data Set

You can create a font data set by digitizing the shape of the characters or figures either manually or with special digitizing equipment. To create a font data set by digitizing the characters manually, follow these steps:

  1. Determine the coordinate points for each line segment by drawing the characters on a grid.

  2. Lay out the observations for each character. Each observation describes a move from one point to another along a line segment. For each line segment, enter the coordinate points in the order in which they are drawn. For a stroked font, when you start a new line segment, change the segment number. For a polygon font, when you start a new polygon, change the line segment number.

    If the polygon has a hole in it, as in the letter O, keep the line segment number and separate the lines with a missing value. Use the same value for CHAR for all of the observations that describe one character.

  3. Create a SAS data set that contains the variables CHAR, SEGMENT, X, and Y, and read in the data for each observation. Include the variables LP and PTYPE if necessary.

  4. Sort the data set by CHAR and SEGMENT.

  5. Assign the font data set with the DATA= argument.

This process is illustrated in Creating Figures for a Symbol Font.

The Kern Data Set

The kern data set consists of observations that specify how much space to add or remove between any two characters when they appear in combination. This process, called kerning, increases or decreases space between the characters. Kerning usually is applied to certain pairs of characters that, because of their shape, have too much space between them. Reducing the space between characters may allow part of one character to extend over the body of the next. Examples of some combinations that should be kerned are AT, AV, AW, TA, VA, and WA.

You can apply kerning to the intercharacter spacing that you specify with the CHARSPACETYPE= option (except for uniform fonts). You can refine the kerning of your characters as little or as much as you like. You assign the kern data set with the KERNDATA= option.

Kern Data Set Variables

The kern data set must contain these variables:

CHAR1
specifies the first character in the pair to be kerned. CHAR1 is a character variable with a length of 1.

CHAR2
specifies the second character in the pair to be kerned. CHAR2 is a character variable with a length of 1.

XADJ
specifies the amount of space to add or remove between the two characters. XADJ is a numeric variable that uses the same font units as the font data set. The value of XADJ specifies the horizontal adjustment to be applied to CHAR2 whenever CHAR1 is followed immediately by CHAR2. Negative numbers decrease the spacing, and positive numbers increase the spacing.


Creating a Kern Data Set

Each observation in a kern data set names the pair of characters to be kerned and the amount of space to be added or deleted between them. To create a kern data set, follow these steps:

  1. Select the pairs of characters to be kerned, and specify the space adjustment (in font units) for each pair as a positive number (more space) or negative number (less space).

  2. Create a SAS data set that contains the variables CHAR1, CHAR2, and XADJ; produce one observation for each pair of characters and the corresponding space adjustment.
    data kern1;
       input char1 $ char2 $ xadj;
       datalines;
    A T -4
    D A -3
    T A -4
    ;

  3. Assign the kern data set with the KERNDATA= option.
    proc gfont data=fontdata
               name=font2
               charspacetype=data
               kerndata=kern1
               nodisplay;
    run;

Comparison of Kerned and Unkerned Text illustrates how you can use the KERNDATA= option to create a font in which the space between specified pairs of letters is reduced. The characters A, D, and T are shown as the word DATA. The first line uses the unkerned font, FONT1, and the second line uses the kerned font, FONT2. Note that the characters in FONT2 are spaced more closely than the characters in FONT1.

The following title statements specify the kerned and unkerned fonts and are used with the GSLIDE procedure to produce Comparison of Kerned and Unkerned Text:

title2 lspace=6 f=font1 h=10 j=l 'DATA';
title3 lspace=4 f=font2 h=10 j=l 'DATA';

Comparison of Kerned and Unkerned Text

[IMAGE]


The Space Data Set

As the height (point size) of a font increases, less space is required between letters in relation to their height. If the point size decreases, more space may be needed. The space data set tells the GFONT procedure how much to increase or decrease the intercharacter spacing for a given point size. Like kerning, spacing is added to or subtracted from the intercharacter spacing that is specified by the CHARSPACETYPE= option. However, kerning applies the adjustment to specified pairs of characters, while spacing is applied uniformly to all characters.

Values that are specified in the space data set are added to the normal intercharacter spacing and any kerning data. Normal intercharacter spacing is determined by the CHARSPACETYPE= option.

Space Data Set Variables

The space data set must contain these variables:

SIZE
specifies the point size of the font. SIZE is a numeric variable.

ADJ
specifies the spacing adjustment for the point size in hundredths (1/100) of a point. (A point is equal to 1/72 of an inch.) ADJ is a numeric variable. Positive values for the ADJ variable increase the spacing between characters; negative values reduce the space.


Creating a Space Data Set

Each observation in a space data set specifies a point size (SIZE) and the amount of space (ADJ) to be added or subtracted between characters when a font of that point size is requested. When you specify a point size that is not in the space data set, the adjustment for the next smaller size is used. To create a space data set, follow these steps:

  1. Determine the amount of adjustment that is required for typical point sizes; positive numbers increase spacing, and negative numbers decrease spacing.

  2. Create a SAS data set that contains the variables SIZE and ADJ; produce one observation for each point size and corresponding space adjustment.
    data space1;
       input size adj;
       datalines;
     6   40
    12    0
    18  -40
    24  -90
    30 -150
    36 -300
    42 -620
    ;

  3. Assign the space data set with the SPACEDATA= option.
    proc gfont data=reflib.fontdata
               name=font3
               charspacetype=data
               spacedata=space1
               nodisplay;
    run;

Comparison of Text with and without Spacing Adjustments illustrates how to use the SPACEDATA= option to generate a font in which intercharacter spacing is adjusted according to the height of the characters. The characters A, D, and T are shown as the word DATA. Each pair of lines displays the word DATA and at the same size uses first the font with spacing adjustment (FONT3) and then the original font (FONT1). Note that as the size of the characters increases, the space between them decreases.

The following title statements are used with the GSLIDE procedure to produce Comparison of Text with and without Spacing Adjustments:

title2;
title3 f=font3 h=.25in j=l 'DATA'; /* 18 points */
title4 f=font1 h=.25in j=l 'DATA';
title5;
title6 f=font3 h=.50in j=l 'DATA'; /* 36 points */
title7 f=font1 h=.50in j=l 'DATA';
title8;
title9 f=font3 h=1.0in j=l 'DATA'; /* 72 points */
title10 f=font1 h=1.0in j=l 'DATA';

Comparison of Text with and without Spacing Adjustments

[IMAGE]


Chapter Contents

Previous

Next

Top of Page

Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.