Previous Page | Next Page

The GFONT Procedure

Creating Fonts

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 MYLOG:

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.

See Creating Figures for a Symbol Font.


The Font Data Set

The font data set consists of a series of observations that include the horizontal and vertical coordinate values. It also includes 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

data sashelp. fontdata;
 proc gfont data=fontdata name=mylogo;
run;

Specify the font data set with the DATA= argument. The font data set consists of a series of observations that include detailed characteristics of the variables described 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 you are creating. CHAR is a character variable with a length of 1 or 2. CHAR is required for all fonts.

CAUTION:
Using reserved or undefined hexadecimal codes as CHAR values might require the use of the NOKEYMAP option.   [cautionend]

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

When you specify the code for the 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 creates an A in the output.

However, If you build a symbol font, the symbols might 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.

Note:   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.  [cautionend]

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. Assign the LP variable either of the following values:

L

lines

Featured in: LP Value of L.
Note: Optional for stroked fonts.
Note: Observations that do not contain an LP variable create a shape like the one in LP Value of L.
P

polygons. If the observations do not draw a completely closed figure then the figure is closed by the GFONT procedure.

Note: Required for polygons.
Featured in: An LP variable with a value of P for all observations creates a complete box. LP Value of P
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

LP Value of L

[Using a LP Value of LIne]

LP (continued)

.

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

LP Value of P

[Using a LP Value of Polygon]

LP (continued)

The LP variable enables you to mix lines and polygons. These observations create the figure consisting 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

[Making LP Values of Line and Polygon]

PTYPE

tells the GFONT procedure what type of data is in the observation. PTYPE is a character variable of length 1 that is optional. 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 to any of these values:

V

normal point in the line segment

Note: If a PTYPE variable is not specified then all points are assumed to be V-type points.
Note: 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 can be unpredictable.
C

center of a circular arc joining two V points

Restriction: Arcs are limited to 106 degrees or less.
Featured in: Using the PTYPE Variable to Create an Arc.
Note: After the figure was created, a grid was overlaid, to show the location of the points.
W

width value for CHARSPACETYPE=DATA. An observation with a PTYPE value of W, must always be the first observation for a character. The observation gives the minimum and maximum X values for the character. The Y variable observation contains the maximum X value. Usually, these values include a little extra space for intercharacter spacing.

Restriction: Use a PTYPE of W only if you have specified CHARSPACETYPE=DATA; otherwise, the points are ignored.
Featured in: CHARSPACETYPE= option.
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

[Using the PTYPE Variable to Create an Arc]

PTYPE (continued)

  • Three observations are required to draw an arc: observation 3 and observation 5 denote the start point and the end point of the arc. Observation 4 locates the center of the arc.

  • The figure is closed because the line segments have an LP value of P (polygon).

  • The font that contains the figure of the arc was created with a similar PROC GFONT statement:

    proc gfont data=arc name=arcfig charspacetype=data filled ;

    The GFONT procedure CHARSPACETYPE= DATA specifies that the first observation sets the width of the character. The FILLED option fills the area of the arc.

SEGMENT

numbers the line segments that compose a character or symbol. SEGMENT is a required numeric variable. All observations for a given line segment have the same segment number. To start a new line segment, change the segment number.

The GFONT procedure requires special instructions to do the following:

  • create a stroked character with more than one line segment (an E)

  • create a polygon character with an opening (A)

To indicate when one line stops and where the next line begins you can do either of the following:
  1. Change the segment number when a new line begins. If the value of LP is L (line), a change in segment number causes the following:

    • The last point in line segment 1 ends the line.

    • The first point in line segment 2 starts a new line.

    If the value of LP is P (polygon), a change in segment numbers causes the following:

    • The last point in line segment 1 joins the first point in line segment 1, which closes the polygon.

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

    Use this method for characters that consist of two polygons such as a question mark. This method is preferred, unless you are creating a polygon character with a hole in it.

  2. Keep the same segment number for all lines. Insert an observation with missing values for X and Y. Insert the new observation between the observation that marks the end of the first line, and the observation that begins the next line.

    The second method is preferred when creating a polygon with a character with a hole in it. In this case, you should separate the lines with a missing value and keep the same segment numbers. If you use separate line segments when you create a polygon with a hole, the results can be unpredictable.

    These observations 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 observation 5 has missing values for X and Y. This separates the observations that draw the inner box from those that draw the outer box. The segment number is the same for all the observations. Drawing Nested Polygons was created with a similar GFONT statement:

proc gfont data=boxes name=boxes filled;

Note:   The FILLED option is included, and only the space between the two squares is filled.  [cautionend]

Drawing Nested Polygons

[Drawing Nested Polygons]

X and Y

specify the horizontal and vertical coordinates of the points for each character. Their values describe the position of the points on the character. These variables have the following characteristics:

  • They must be numeric.

  • They must be named X and Y for the horizontal and vertical coordinates, respectively.

  • The values specified by them can be in any range.

  • They both must describe the character in the same scale or font units.

  • Vertical (Y) coordinates for all characters should be defined on the same baseline.

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


Creating a Font Data Set

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:

  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 have too much space between them. Reducing the space between characters might result in part of one character extending 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). Assign the kern data set with the KERNDATA= option.


Kern Data Set Variables

Required kern data set 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. The amount of space to be added or deleted between them is specified. To create a kern data set:

  1. Select the pairs of characters to be kerned. Specify the space adjustment (in font units) for each pair.

  2. Create a SAS data set that contains the variables CHAR1, CHAR2, and XADJ; define one observation for each pair of characters and the corresponding space adjustment as follows:

    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 as follows:

    proc gfont data=fontdata
           name=font2
               charspacetype=data
               kerndata=kern1
               nodisplay;
    run;

Creating a Kern Data Set illustrates how to 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.

These statements specify the kerned and unkerned fonts, and are used with the GSLIDE procedure to create the fonts:

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

[Comparison of Kerned and Unkerned Text]


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 height decreases, more space might be needed. The space data set tells the GFONT procedure how much to increase or decrease the intercharacter spacing for a given point size. Spacing is added to or subtracted from the intercharacter spacing that is specified by the CHARSPACETYPE= option. 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

Required space data set 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 ADJ increase the space between characters; negative values for ADJ reduce the space between characters.


Creating a Space Data Set

Each observation in a space data set specifies the following:

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:
  1. Determine the amount of adjustment that is required for typical point sizes.

  2. Create a data set that contains the variables SIZE and ADJ. Create one observation for each point size and corresponding space adjustment as follows:

    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 as follows:

    proc gfont data=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 create 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

[Comparison of Text with and without Spacing Adjustments]

Previous Page | Next Page | Top of Page