Contents
TrueType Font Specifications Help

Chapter 1 - TrueType Fundamentals

From design to font file

Digitizing a design

Scaling a glyph

Grid-fitting a glyph outline

The scan converter

Chapter 2 - Instructing Glyphs

Instructing glyphs

Chapter 3 - The TrueType Instruction Set

Anatomy of a TrueType Instruction

Data types - the instruction stream

Pushing data onto the interpreter stack

Managing the Storage Area

Managing outlines

Managing the stack

Managing the flow of control

Debugging

Miscellaneous instructions

Chapter 4 - The TrueType Font File

Data Types

The Table Directory

'cmap' - Character To Glyph Index Mapping Table

'glyf' - Glyph Data

'head' - Font Header

'hhea' - Horizontal Header

'hmtx' - Horizontal Metrics

'loca' - Index to Location

'maxp' - Maximum Profile

'name' - Naming Table

'OS/2' - OS/2 and Windows Metrics

'post' - PostScript

'cvt ' - Control Value Table

'fpgm' - Font Program

'hdmx' - Horizontal Device Metrics

'kern'- Kerning

'LTSH' - Linear Threshold

'prep' - Control Value Program

'VDMX' - Vertical Device Metrics

'PCLT' - PCL 5 Table

Chapter 5 - Microsoft UGL Character Set

Support of Macintosh Character set

New UGL definition

Windows 3.1 Character Set

Minimum Character Set Requirements

Appendix A - Instruction Set Summary

Instructions by Category

Instructions by Name

Appendix B - Graphics State Summary

Graphics State Summary

Appendix C - Macintosh to Microsoft UGL Mapping

Standard Macintosh Character Set to UGL

PostScript Text Characters in the Macintosh Set

Other Miscellaneous Characters

Apples Mapping Requirements and Recommendations

Glyph Ordering

Appendix D - Microsoft TrueType Files

Table Requirements & Recommendations

Non-UGL Fonts

Device Resolutions

Baseline to Baseline Distances

Style Bits

Miscellaneous Recommendations


From design to font file

This chapter introduces the basic concepts needed to create and instruct a TrueType font. It begins with an overview of the steps involved in taking a design from paper to the creation of a bitmap that can be sent to an output device and follows with a closer look at each of the steps in the process.

A TrueType font can originate as a new design drawn on paper or created on a computer screen. TrueType fonts can also be obtained by converting fonts from other formats. Whatever the case, it is necessary to create a TrueType font file that, among other things, describes each glyph in the font as an outline in the TrueType format.

From Font File to Paper

This section describes the process that allows glyphs from a TrueType font file to be displayed on raster devices.

First, the outline stored in the font file is scaled to the requested size. Once scaled, the points that make up the outline are no longer recorded in the FUnits used to describe the original outline, but have become device specific pixel coordinates.

Next the instructions associated with this glyph are carried out by the interpreter. The result of carrying out the instructions is a grid-fitted outline for the requested glyph. This outline is then scan converted to produce a bitmap that can be rendered on the target device.


Digitizing a design

This section describes the coordinate system used to establish the locations of the points that define a glyph outline. It also documents the placement of glyphs with respect to the coordinate axes.

Outlines

In a TrueType font, glyph shapes are described by their outlines. A glyph outline consists of a series of contours. A simple glyph may have only one contour. More complex glyphs can have two or more contours. Composite glyphs can be constructed by combining two or more simpler glyphs. Certain control characters that have no visible manifestation will map to the glyph with no contours.

Figure 1-1 	Glyphs with one, two, three contours respectively

Contours are composed of straight lines and curves. Curves are defined by a series of points that describe second order Bezier-splines. The TrueType Bezier-spline format uses two types of points to define curves, those that are on the curve and those that are off the curve. Any combination of off and on curve points is acceptable when defining a curve. Straight lines are defined by two consecutive on curve points.

Figure 1-2	A glyph description consisting of a series of on and off curve points

The points that make up a curve must be numbered in consecutive order. It makes a difference whether the order is increasing or decreasing in determining the fill pattern of the shapes that make up the glyph. The direction of the curves has to be such that, if the curve is followed in the direction of increasing point numbers, the black space (the filled area) will always be to the right.

FUnits and the em square

In a TrueType font file point locations are described in font units, or FUnits. An FUnit is the smallest measurable unit in the em square, an imaginary square that is used to size and align glyphs. The dimensions of the em square typically are those of the full body height of a font plus some extra spacing to prevent lines of text from colliding when typeset without extra leading.

While in the days of metal type, glyphs could not extend beyond the em square, digital typefaces are not so constrained. The em square may be made large enough to completely contain all glyphs, including accented glyphs. Or, if it proves convenient, portions of glyphs may extend outside the em square. TrueType fonts can handle either approach so the choice is that of the font manufacturer.

Figure 1-3	A character that extends outside of the em square

The em square defines a two-dimensional coordinate grid whose x-axis describes movement in a horizontal direction and whose y-axis describes movement in a vertical direction. This is discussed in more detail below.

FUnits and the grid

A key decision in digitizing a font is determining the resolution at which the points that make up glyph outlines will be described. The points represent locations in a grid whose smallest addressable unit is known as an FUnit or font Unit. The grid is a two-dimensional coordinate system whose x-axis describes movement in a horizontal direction and whose y-axis describes movement in a vertical direction. The grid origin has the coordinates (0,0). The grid is not an infinite plane. Each point must be within the range -16384 and +16383 FUnits. Depending upon the resolution chosen, the range of addressable grid locations will be smaller.

The choice of the granularity of the coordinate grid - that is, number of units per em (upem - is made by the font manufacturer. Outline scaling will be fastest if units per em is chosen to be a power of 2, such as 2048.

Figure 1-4 	The coordinate system

The origin of the em square need not have any consistent relationship to the glyph outlines. In practice, however, applications depend upon the existence of some convention for the placement of glyphs for a given font. For Roman fonts, which are intended to be laid out horizontally, a y-coordinate value of 0 typically is assumed to correspond to the baseline of the font.  No particular meaning is assigned to an x-coordinate of 0 but manufacturers may improve the performance of applications by choosing a standard meaning for the x-origin.

For example, you might place a glyph so that its aesthetic center is at the x-coordinate value of 0. That is, a set of glyphs so designed when placed in a column such that their x-coordinate values of 0 are coincident will appear to be nicely centered. This option would be used for Kanji or any fonts that are typeset vertically.  Another alternative is to place each glyph so that its leftmost extreme outline point has an x-value equal to the left-side-bearing of the glyph. Fonts created in this way may allow some applications to print more quickly to PostScript printers.

Figure 1-5 	Two possible choices for the glyph origin in a Roman font. In the first case (left) the left side bearing is x-zero. In the second (right), the aesthetic center of the character is x-zero

Non-Roman fonts may wish to use other conventions for the meaning of the x-origin and y-origin. For best results with high-lighting and carets, the body of the character should be roughly centered within the advance width. For example, a symmetrical character would have equal left and right side bearings.

The granularity of the em square is determined by the number of FUnits per em, or more simply units per em . The em square as divided into FUnits defines a coordinate system with one unit equalling an FUnit. All points defined in this coordinate system must have integral locations. The greater the number of units per em, the greater the precision available in addressing locations within the em square.

Figure 1-6	Two em squares, 8 units per em (left), 16 units per em (right)

FUnits are relative units because they vary in size as the size of the em square changes. The number of units per em remains constant for a given font regardless of the point size. The number of points per em, however, will vary with the point size of a glyph. An em square is exactly 9 points high when a glyph is displayed at 9 points, exactly 10 points high when the font is displayed at 10 point and so on. Since the number of units per em does not vary with the point size at which the font is displayed, the absolute size of an FUnit varies as the point size varies.

Figure 1-7	72 point M and 127 point M and their em squares.

Upem equals 8 in both cases

Because FUnits are relative to the em square, a given location on a glyph will have the same coordinate location in FUnits regardless of the point size at which the font is rendered. This is convenient because it makes it possible to instruct outline points once considering only the original outline and have the changes apply to the glyph at whatever size and resolution it is ultimately rendered.


Scaling a glyph

This section describes how glyph outlines are scaled from the master size stored in the font file to the size requested by an application.

Device space

Whatever the resolution of the em square used to define a glyph outline, before that glyph can be displayed it must be scaled to reflect the size, transformation and the characteristics of the output device on which it is to be displayed. The scaled outline must describe the character outline in units that reflect an absolute rather than relative system of measurement. In this case the points that make up a glyph outline are described in terms of pixels.

Intuitively, pixels are the actual output bits that will appear on screen or printer. To allow for greater precision in managing outlines, TrueType describes pixel coordinates to the nearest sixty-fourth of a pixel.

Converting FUnits to pixels

Values in the em square are converted to values in the pixel coordinate system by multiplying them by a scale. This scale is:

where pointSize is the size at which the glyph is to be displayed, resolution is the resolution of the output device. The 72 in the denominator reflects the number of points per inch.

For example, assume that a glyph feature is 550 FUnits in length on a 72 dpi screen at 18 point. There are 2048 units per em. The following calculation reveals that the feature is 4.83 pixels long.

Display device characteristics

The resolution of any particular display device is specified by the number of dots or pixels per inch (dpi) that are displayed. For example, a VGA under OS/2 and Windows is treated as a 96 dpi device, and most laser printers have a resolution of 300 dpi. Some devices, such as an EGA, have different resolution in the horizontal and vertical directions (i.e. non-square pixels); in the case of the EGA this resolution is 96 x 72. In such cases, horizontal dots per inch must be distinguished from vertical dots per inch.

The number of pixels per em is dependent on the resolution of the output device. An 18 point character will have 18 pixels per em on a 72 dpi device. Change the resolution to 300 dpi and it has 75 pixels per em, or to 1200 dpi and it has 300 pixels per em.

Figure 1-8	18 point figure 8 at 72 dpi, 300 dpi and 1200 dpi

Displaying type on a particular device at a specific point size yields an effective resolution measured in pixels per em (ppem). The formula for calculating pixels per em is:

= (pixels per inch) * (inches per pica point) * (pica points per em)

On a 300 dpi laser printer, a 12 point glyph would have 12*300/72 or 50 ppem. On a typesetter with 2400 dpi, it would have 12*2400/72 or 400 ppem. On a VGA, a 12 point glyph would have 12*96/72 or 16 ppem. Similarly, the ppem for a 12 point character on a 72 dpi device would be 12*72/72, or 12. This last calculation points to a useful rule of thumb: on any 72 dpi device, points and pixels per em are equal. Note, however, that in traditional typography an inch contains 72.2752 points (rather than 72); that is, one point equals .013836 inches.

If you know the ppem, the formula to convert between FUnits and pixel space coordinates is:

pixel_coordinate = em_coordinate

An em_coordinate position of (1024, 0) would yield a device_pixels coordinate of (6, 0), given  2048 units per em and 12 pixels per em.


Grid-fitting a glyph outline

The fundamental task of instructing a glyph is one of identifying the critical characteristics of the original design and using instructions to ensure that those characteristics will be preserved when the glyph is rendered at different sizes on different devices. Consistent stem weights, consistent color, even spacing, and the elimination of pixel dropouts are common goals.

To accomplish these goals, it is necessary to ensure that the correct pixels are turned on when a glyph is rasterized. It is the pixels that are turned on that create the bitmap image of the glyph. Since it is the shape of the glyph outline that determines which pixels will make up the bitmap image of that character at a given size, it is sometimes necessary to change or distort the original outline description to produce a high quality image. This distortion of the outline is known as grid-fitting.

The figure below illustrates how grid-fitting a character distorts the outline found in the original design.

Figure 1-9	12 point outlines ungrid-fitted (left) and grid-fitted (right)

As the illustration above suggests, the grid-fitting employed in TrueType goes well beyond aligning a glyph's left side bearing to the pixel grid. This sophisticated grid-fitting is guided by instructions. The beneficial effects of grid-fitting are illustrated in the next figure.

Figure 1-10	12 point outlines and bitmap ungrid-fitted (left) and
grid-fitted (right)

Grid-fitting is the process of stretching the outline of a glyph according to the instructions associated with it. Once a glyph is grid-fitted, the point numbers will be unchanged but the actual location of that point in the coordinate grid may have shifted. That is, the coordinates for a given point number will, very likely, have changed after a glyph is grid-fitted.

What are instructions?

The TrueType instruction set provides a large number of commands designed to allow designers to specify how character features should be rendered. Instructions are the mechanism by which the design of a character is preserved when it is scaled. In other words, instructions control the way in which a glyph outline will be grid-fitted for a particular size or device.

Instructing a font will reshape the outline for a given glyph at a specific size on a given target device in such a way that the correct pixels are included within its outline. Reshaping the outline means moving outline points. Points that have been acted upon by an instruction are said to have been touched. Note that a point need not actually be moved to be touched. It must simply be acted upon by an instruction. (See MDAP, chapter 3.)

TrueType fonts can be used with or without instructions. Uninstructed fonts will generally produce good quality results at sufficiently high resolutions and point sizes. The range of sizes over which an uninstructed font will produce good quality results depends not only on the output device resolution and point size of the character but also on the particular font design.  The intended use of the font can also be a factor in determining whether or not a particular font should be instructed. For most fonts, if legibility of small point sizes on low resolution devices is important, adding instructions will be critical.

Instructing a font is a process that involves analyzing the key elements of a glyph's design and using the TrueType instruction set to ensure that they are preserved. The instructions are flexible enough to allow characteristics that are roughly the same to be homogenized at small sizes while allowing the full flavor of the original design to emerge at sizes where there are sufficiently many pixels.

How does the TrueType interpreter know the manner in which an outline should be distorted to produce a desirable result? This information is contained in instructions attached to each character in the font. Instructions specify aspects of a character's design that are to be preserved as it is scaled. For example, using instructions it is possible to control the height of an individual character or of all the characters in a font. You can also preserve the relationship between design elements within a character thereby ensuring, for example, that the widths of the three vertical stems in the lower case m will not differ dramatically at small sizes.

The figure below illustrates how changing a glyph's outline at a specific size will yield a superior result. They show that an uninstructed 9 point Helvetica lower case m suffers the loss of a stem due to chance effects in the relationship of stems to pixel centers. In the second glyph, instructions have aligned the stems to the grid so that the glyph suffers no similar loss.

Figure 1-11	9 point Helvetica m--uninstructed (left), instructed (right)

The TrueType interpreter

This section describes the actions of the TrueType interpreter. It is the interpreter, as the name suggests, that interprets or carries out the instructions.

More concretely, the interpreter processes a stream or sequence of instructions. Typically these instructions take their arguments from the interpreter stack and place their results on that stack. The only exceptions are a small number of instructions that are used to push data onto the interpreter stack. These instructions take their arguments from the instruction stream.

All of the interpreter's actions are carried on in the context of the Graphics State, a set of variables whose values guide the actions of the interpreter and determine the exact effect of a particular instruction.

The interpreter's actions can be summarized as follows:

1.	The interpreter fetches an instruction from the instruction stream, an ordered sequence of instruction opcodes and data. Opcodes are 1-byte in size. Data can consist of a single byte or two bytes (a word).  If an instruction takes words from the instruction stream it will create those words by putting together two bytes. The high byte appears first in the instruction stream and the low byte appears second.

The instruction stream is depicted below as it will be shown in the examples that follow.  Note that the pointer indicates the next instruction to be executed.

2.	The instruction is executed

If it is a push instruction it will take its arguments from the instruction stream.

Any other instruction will pop any data it needs from the stack. A pop is illustrated below.

Any data the instruction produces is pushed onto the the interpreter stack. A push is illustrated below.

As the previous discussion indicates, the interpreter stack is a LIFO or last in first out data structure. An instruction takes any data it needs from the last item placed on the stack. The action of removing the top item from the stack is commonly termed a pop. When an instruction produces some result it pushes that result to the top of the stack where it is potential input to the next instruction.

The instruction set includes a full range of operators for manipulating the stack including operators for pushing items onto the stack, popping items from the stack, clearing the stack, duplicating stack elements and so forth.

The effect of execution depends on the values of the variables that make up the Graphics State.

The instruction may modify one or more Graphics State variables. In the illustration shown, the Graphics State variable rp0 is updated using a value taken from the interpreter stack.

3.	The process is repeated until there are no further instructions to be executed.

Using instructions

Instructions can appear in a number of places in the font file tables that make up a TrueType font. They can appear as part of the Font Program, the CVT Program, or as glyph data. Instructions appearing in the first two apply to the font as a whole. Those found in glyph data ('glyf') apply to individual glyphs within a font.

The Font Program

The Font Program consists of a set of instructions that is executed once, the first time a font is accessed by an application. It is used to create function definitions (FDEFs) and instruction definitions (IDEFs). Functions and instructions defined in the Font Program can be used elsewhere in the font file.

The CVT Program

The CVT Program is a sequence of TrueType instructions executed every time the point size or transformation change. It is used to make font wide changes rather than to manage individual glyphs. The CVT Program is used to establish the values in the Control Value Table.

The  purpose of the Control Value Table or CVT is to simplify the task of maintaining consistency when instructing a font. It is a numbered list of values that can be referenced by either of two indirect instructions (MIRP and MIAP). CVT entries can be used to store values that need to be the same across a number of glyphs in a font. For example an instruction might refer to a CVT entry whose purpose is to regularize stem weights across a font.

Figure 1-12 	Some sample CVT entries

Entry #	Value	Description
0	0	upper and lower case flat base (base line)
1	-39	upper case round base
2	-35	lower case round base
3	-33	figure round base
4	1082	x-height flat
5	1114	x-height round overlap
6	1493	flat cap
7	1522	round cap
8	1463	numbers flat
9	1491	numbers round top
10	1493	flat ascender
11	1514	round ascender
12	157	x stem weight
13	127	y stem weight
14	57	serif
15	83	space between the dot and the i

Instructions that refer to values in the CVT are called indirect instructions as opposed to the direct instructions which take their values from the glyph outline.

As part of the TrueType font file, the values in the CVT are expressed in FUnits. When the outlines are converted from FUnits to pixel units, values in the CVT are also converted.

When writing to the CVT you may use a value that is in the glyph coordinate system (using WCVTP) or you can use a value that is in the original FUnits (using WCVTF). The interpreter will scale all values appropriately. Values read from the CVT are always in pixels (F26Dot6).

The Storage Area

The interpreter also maintains a Storage Area consisting of a portion of memory that can be used for temporary storage of data from the interpreter stack. Instructions exist that make it possible to read the values of stored data and to write new values to storage. Storage locations range from 0 to n-1 where n is the value established in the maxStorage entry in the maxProfile table of the font file. Values are 32 bit numbers.

Figure 1-13	Some storage area entries

Address	Value
0	343
1	241
2	-27
3	4654
4	125
5	11
The Graphics State

The Graphics State consists of a table of variables and their values. All instructions act within the context of the Graphics State. Graphics State variables have default values as specified in Appendix B, "Graphics State Summary". Their values can be determined or changed using instructions.

The Graphics State establishes the context within which all glyphs are interpreted. All Graphics State variables have a default value. Some of these values can be changed in the CVT Program if desired. Whatever the default value, it will be reestablished at the start of interpretation of any glyph. In other words, the Graphics State has no inter-glyph memory. Changing the value of a Graphics State variable while processing an individual glyph will result in a change that remains in effect only for that glyph.


The scan converter

The TrueType scan converter takes an outline description of a glyph and produces a bitmap image for that glyph.

The TrueType scan converter offers two modes. In the first mode, the scan converter uses a simple algorithm for determining which pixels are part of that glyph. The rules can be stated as follows:

Rule 1

If a pixel's center falls within the glyph outline, that pixel is turned on and becomes part of that glyph.

Rule 2

If a contour falls exactly on a pixel's center, that pixel is turned on.

A point is considered to be an interior point of a glyph if it has a non-zero winding number. The winding number is itself determined by drawing a ray from the point in question toward infinity. (The direction in which the ray points in unimportant.) Starting with a count of zero, we subtract one each time a glyph contour crosses the ray from right to left or bottom to top. Such a crossing is termed an on transition. We add one each time a contour of the glyph crossed the ray from left to right or top to bottom. Such a crossing is termed an off transition. If the final count is non-zero, the point is an interior point.

The direction of a contour can be determined by looking at the point numbers. The direction is always from lower point number toward higher point number.

The illustration that follows demonstrates the use of winding numbers in determining whether a point is inside a glyph. The point p1 undergoes a sequence of four transitions (on transition, off transition, on transition, off transition). Since the sequence is even, the winding number is zero and the point is not inside the glyph. The second point, p2, undergoes an off transition followed by an on transition followed by an off transition yielding a winding number of +1. The point is in the interior of the glyph.

Figure 1-14	Determining the winding number of a point

What is a dropout?

A dropout occurs whenever there is a connected region of a glyph interior that contains two black pixels that cannot be connected by a straight line that only passes through black pixels.

Figure 1-15	The letter m with two dropouts

Preventing dropouts

The TrueType instructions are designed to allow you to gridfit a glyph so that the desired pixels will be turned on by the simple scan converter regardless of the point size or the transformation used. It may prove difficult to foresee all possible transformations that a glyph might undergo. It is therefore difficult to instruct a glyph to ensure that the proper grid-fitting distortion of the outline will take place for every desired transformation. This problem is especially difficult for very small numbers of pixels per em and for complex typefaces. In these situations, some renditions of a glyph may contain dropouts.

It is possible to test for potential dropouts by looking at an imaginary line segment connecting two adjacent pixel centers. If this line segment is intersected by both an on-Transition contour and an off-Transition contour, a potential dropout condition exists. The potential dropout only becomes an actual dropout if the two contour lines continue on in both directions to cut other line segments between adjacent pixel centers. If the two contours join together immediately after crossing a scan line (forming a stub), a dropout does not occur, although a stem of the glyph may become shorter than desired.

To prevent dropouts, type manufacturers can choose to have the scan converter use two additional rules:

Rule 3

If a scan line between two adjacent pixel centers (either vertical or horizontal)  is intersected by both an on-Transition contour and an off-Transition contour and neither of the pixels was already turned on by rules 1 and 2, turn on the left-most pixel (horizontal scan line) or the bottom-most pixel (vertical scan line)

Rule 4

Apply Rule 3 only if the two contours continue to intersect other scan lines in both directions. That is do not turn on pixels for 'stubs'. The scanline segments that form a square with the intersected scan line segment are examined to verify that they are intersected by two contours. It is possible that these could be different contours than the ones intersecting the dropout scan line segment.  This is very unlikely but may have to be controlled with grid-fitting in some exotic glyphs.

The type manufacturer can choose to use the simple scan converter employing rules 1 and 2 only or may optionally invoke either rule 3 or rule 4. The decision about which scan converter to use can be made on a font wide basis or a different choice can be specified for each glyph. The selection made in the preProgram will be the default for the entire font. A change made to the default in the instructions for an individual glyph will apply only to that glyph.


Instructing Glyphs

This chapter gives an overview of the fundamental tasks involved in instructing a glyph.

Choosing a scan conversion setting

One of the key decisions to be made in instructing a TrueType font is the choice of scan conversion mode. Font designers can choose between a fast scan conversion mode and a dropout control scan conversion mode. This choice is made by setting the value of the Graphics State variable scan_control. The interpreter considers each of three conditions in determining  whether dropout control mode will be used:

Is the glyph rotated?

Is the glyph stretched?

Is the current setting for ppem less than a specified ppem value?

It is also possible to turn dropout control off completely.

Controlling rounding

The TrueType interpreter uses the round_state to determine the manner in which values will be rounded. Instructions are used to set the value of the round_state, a Graphics State variable. The setting of round_state determines how values will be rounded by the interpreter.

The instruction set makes it easy to set a number of predefined round states that will round values to the grid, pixel centers (half grid), or to either the grid or pixel centers. It is also possible to specify that values should be rounded down or rounded up. If none of the predefined rounding options suffices, the SROUND instructions provide very fine control of the rounding of values, making it possible to choose a phase, threshold, and period for the rounding function. The S45ROUND allows the same fine control as SROUND but is used when movement is along a 45 degree axis with the x-y plane.

A number of instructions round the value they obtain before moving any points. The effect of using any of the MDRP, MIRP, MIAP, MDAP, or ROUND instructions depends on the value of the round_state graphics state variable along with that of the control_value_cut_in.

The ROFF instruction turns off rounding but allows the instruction to continue looking at the cut-in value.

Points

Outline points are specified by their location in the coordinate grid and by whether they are on or off curve points. Managing a point means managing its position in space and its status as an on or off curve point. The interpreter uses zones and reference points to manage the set of points that comprise the current glyph and to refer to specific points within that set.

Zones

Any point the font scaler interpreter references is in one of two zones, that is one of two sets of points that potentially make up a glyph description. The first of these referenced zones is zone 1 (Z1) and always contains the glyph currently being interpreted.

The second, zone 0 (Z0), is used for temporary storage of point coordinates that do not correspond to any actual points in the glyph in zone 1. Zone 0 is useful when there is a need to manipulate a point that does not exist on the glyph or if you need to remember an intermediate point position. (This is the twilight zone.)

The profile table establishes the maximum number of twilight points. These are numbers 0 through maxTwilightPoints -1 and are all set to the origin. These points can be moved in the same manner as any of the points in zone 1.

Points in zone 0 are moved to useful positions by using the MIAP and MIRP instructions and setting gep0 to point to Z0. Frequently, it is useful to set points in Z0 to key metric positions for the font.

Zone pointers

Three zone pointers, gep0, gep1 and gep2 are used to reference either of zone  0 or zone 1. Initially, all three zone pointers will point to zone 1.

Figure 2-1	gep0 and gep1 point to zone 1 (the current glyph), gep2 points to zone 0 (the twilight zone)

Reference points

Zone pointers provide access to a group of points. Reference points provide access to specific points within the group. The interpreter uses three numbered reference points: rp0, rp1, and rp2. Each can be set to a number corresponding to any of the outline points in the glyph in zone 1 or any of the points in zone 0.

As shown in the figure below, two different reference points can refer to the same outline point.

Figure 2-2	A glyph pointed to by all three reference points

Collectively the zone pointers and reference points belong to the Graphics State. Their values can be altered using instructions. Many TrueType instructions rely on the graphics zone pointers and the reference points to fully specify their actions.

Phantom points

The font scaler will always add two "phantom points" to the end of every outline. If the entire set of contours for a glyph requires "n" points (i.e., contour points numbered from 0 to n-1), then the scaler will add points n and n+1. These points will be placed on the character baseline. Point n will appear at the character origin, while "n+1" will be placed at the advance width point.

Both points (n and n+1) may be controlled by TrueType instructions, with corresponding effects on the sidebearings and advance width of the instructed glyph. The side bearings and advance width that are computed using these phantom points are called the device-specific widths (since they reflect the results of grid fitting the width along with the glyph to the characteristics of the device). The device-specific widths can be different from or identical to the linearly scaled widths (obtained by simple scaling operations), depending on the instructions applied to the phantom points.

Determining distances

At the lowest level, instructing a glyph means managing the distances between points. The first step in managing a distance is often one of determining its magnitude. For example, the first step in setting up the Control Value Table involves measuring the distances between key points in a font. Measuring the distance between two points in a glyph outline, while not difficult, must take into account certain factors.

All distance measurements are made parallel to the projection_vector, a unit vector whose direction will be indicated by a radius of a circle. Distances are projected onto this vector and measured along it. Distances have a direction that reflects the direction of the vector.

Measurements can refer to the distance between points in the original character outline or between points in the grid-fitted outline. The instruction that measures distances (MD) takes a Boolean value which determines whether distances will be measured on the original outline or in the grid-fitted outline.

Additionally, the TrueType interpreter distinguishes between three different types of distances: black, white, and grey. Certain instructions (MDRP, MIRP, ROUND) require that you specify a distance type.

Black distances cross only black areas; white distances, white areas; and grey distances a combination of the two. In the illustration below, examples of black,white, and grey distances are shown. The distance [2,1] is black; [3,0] is grey and [4,6] is white.

Figure 2-3	White, black and grey distances

The distance type is used in determining how the ROUND and instructions that use the round_state will work with different output devices. For gray distances, rounding is unaffected. Black or white distances, however, require a compensation term be added or subtracted before rounding takes place. The amount of compensation needed will be set by the device driver. For example, if a printing engine has large pixels, the interpreter will compensate by shrinking black distances and growing white distances. Gray distances, because they combine black and white distances, will not change.

When the distance between two points is determined, the distance is always measured in the direction specified by the projection_vector. Similarly, when a point is moved, the distance it is moved will be measured along the projection_vector. When thinking about how the interpreter will project a distance, you may find it convenient to imagine that distances are projected onto a ruled line that is parallel to the projection vector.

In the example shown, distances are measured along a line that is parallel to the projection_vector. The distance from point 1 to point 2 must be projected onto the projection_vector (that is a line parallel to the projection_vector) before being measured. Since the line from point 1 to point 3 is parallel to the vector, the projection of the distance can be thought of as simply the line from 1 to 3. Since the projection of the line from point 4 to point 1 is perpendicular to the vector, the distance from point 4 to point 1 is zero despite the fact that the points do not coincide.

The vector can be set in any direction desired. In a simple case, the projection vector might be set to measure distance in the x-direction. In such a case, the vector is parallel to the x-axis. Similarly to measure distance in the y-direction, the projection_vector must be parallel to the y-axis.

To determine the distance between two points when the projection_vector points in the positive x-direction, one need only take the difference between their x coordinates. For example, the distance between the points (2, 1) and (7, 5) will be 5 units. Similarly, if the projection_vector pointed in the positive y-direction, the distance between the points would be 4 units.

Note that because the projection_vector has a direction, distances have a sign. Positive distances are those that are measured with the projection_vector. Negative distances are those that are measured against the projection_vector.

In the example below, the projection_vector points east (in the direction of the positive x-axis). The distance between points 1 and 2 is positive when measured from west to east (from point 1 to point 2). It is negative when measured from east to west (from point 2 to point 1).

Figure 2-4 	Measuring the distance between two points

In many cases, it is convenient to disregard the sign associated with a distance. When the auto_flip Graphics State variable is set to TRUE, the sign of CVT entries will be changed when needed to match the sign of the actual measurement. This makes it possible to control distances measured with or against the projection_vector with a single CVT entry.

Controlling movement

The direction in which points can move is established by the Graphics State variable freedom_vector.

When a point is moved, its movement is constrained to be in a direction parallel to that of the freedom_vector. Assuming the freedom_vector is pointing in the direction of the positive x-axis (points east), movement in the positive x-direction (from west to east) will have a positive magnitude. Movement in the negative x-direction (from east to west) will have a negative magnitude.

Moving points

WARNING:	When moving points, it is illegal for the freedom_vector and the projection_vector to be orthogonal.

There are several instructions that move outline points. These instructions either move points relative to a reference point (the relative instructions) or move points to a specified location in the coordinate system (the absolute instructions).

The figure below illustrates a relative move. The point p is moved so that it is at distance d from the reference point rp.

Figure 2-5 	A relative move

The figure below illustrates an absolute move. Here the point p is moved a distance d from its current position to a new position. The distance is measured along the projection_vector. Movement is along the freedom_vector.

Figure 2-6 	An absolute move

In specifying a move, some move instructions use the outline distance (direct instructions). Other instructions specify the value of d only indirectly by referring to a value in the CVT or to a value on the stack (indirect instructions).

In attempting to move a point you must first decide on the direction and distance. Beyond this, decide whether you want to move that point an absolute distance or relative to another point. If the move is relative be sure you know which reference point will be used by the instruction. In some cases, you may need to change the value of that reference point to the one you desire. Finally decide whether you will use the original outline distance or will refer to a distance in the CVT or the stack.

By choosing to use the original outline distance you can preserve the original design distance between two points. In contrast, if you choose an indirect method of specifying a distance, that is you use the CVT, you allow that distance to be matched to some important value for that font or glyph.

All of the move instructions with the sole exception of MSIRP are affected by the round_state. The instructions allow you to choose whether they should take into account the setting of the round_state variable. In effect this means that, if rounding is turned on, the distance a point is actually moved will be affected by the type of rounding that is performed.

In the example below, point p is moved distance d to a new location p' and then rounded to the nearest grid boundary.

Figure 2-7  	An absolute move with round_state set to round to grid

Managing the direction of distances

The auto_flip variable owes its existence to the fact that the TrueType interpreter distinguishes between distances measured in the direction of the projection_vector (positive distances) and those that are measured in the direction opposite to the projection_vector (negative distances).

The setting of the auto_flip Boolean determines whether the sign of values in the Control Value Table is significant. If auto_flip is set to TRUE, the values of CVT entries will be changed when necessary to match the sign of the actual measurement. This makes it possible to control distances measured with or against the projection vector.

For example, the CVT might contain an entry for uppercase stem widths. At times it may be convenient to control widths from left to right while at other times it may be convenient to control them from right to left. One case will produce a positive distance, the other a negative distance. Without auto_flip it would be necessary to have two CVT entries (+UC_Stem and - UC_Stem) instead of just one. Setting auto_flip to TRUE makes the sign of the value read from the CVT the same as the sign of the distance between the points we are controlling in the original unmodified domain.

Generally, auto_flip is set to TRUE, but if it becomes necessary to distinguish between a positive or negative distance, the variable must be set to FALSE.

Interpolating points

When instructions are used to change the position of a few of the points in a character outline, the curves that make up the character may become kinked or otherwise distorted. It may be desirable to smooth out the resulting curve. This smoothing out process is actually a redistribution of all points that have not been moved so that their positions relative to the moved points remain consistent.

To assist in managing the shape of outlines, the interpreter uses the concept of touching a point. Whenever an instruction has the effect of moving a point, that point is marked as touched in the x-direction or y-direction or both. The IUP instruction will affect only untouched points. It is possible to explicitly untouch a point so that it will be affected by an interpolation instruction.

Maintaining minimum_distance

When the width of a glyph feature decreases below a certain size, rounded values may become zero. Allowing values to round to zero can result in certain glyph features disappearing. For example, a stem might disappear entirely at small point sizes. By setting a minimum_distance of one pixel you can assure that even at small sizes those features will not disappear.

In the example shown below, the minimum_distance value is used to ensure that the stem of the r does not disappear at small sizes. By ensuring that the distance from point 9 to point 10 is always at least one pixel, this goal is accomplished.

Controlling regularization using the cut_in

The TrueType language offers several means of coordinating values for glyph features across a font. Such coordination results in a uniformity of appearance known as regularization. Regularization is useful when the number of pixels available for a feature or glyph are few in number. It prevents small differences in the size of features from becoming vastly exaggerated by the change in the placement of pixel centers within a glyph outline. Regularization becomes a liability when small differences in the size or placement of features can be effectively represented by the number of available pixels.

TrueType allows you the best of two worlds in making it possible to regularize features at small numbers of pixels per em while allowing the outline to revert to the original design once a sufficient number of pixels is available. There are two different ways to accomplish this goal. Each one uses a cut_in value. The first method uses the Control Value Table and the control_value_cut_in and allows you to coordinate values using entries in the CVT. This method allows for a variety of values to be coordinated. The second method takes regularization a step further and forces all values to revert to a single value. It relies on the single_width_cut_in and the single_width_value.

Control_value_cut_in

The control_value_cut_in makes it possible to limit the regularizing effects of the CVT to cases where the difference between the table value and the measurement taken from the original outline is sufficiently small. It allows the interpreter to choose, at some sizes, to use the CVT value while, at other sizes, to revert to the original outline. When the absolute difference between the value in the table and the measurement directly from the outline is greater than the cut_in value, the outline measurement is used.

The effect of the control_value_cut_in is to allow regularization below a certain cut off point while allowing the subtlety of the design to take over at larger sizes.

The cut_in value affects only instructions that refer to values in the CVT, the so called indirect instructions, MIRP and MIAP, and only if the third Boolean is set to TRUE.

CVT Value	Original Outline Value	|Diff|		|Diff| > cut_in use outline	|Diff| _ cut_in use CVT
93	80	13	17/16	80	-
100	99 5/16	11/16	17/16	-	100
97	95 15/16	17/16	17/16		97

17/16 is the default value for the control_value_cut_in

In the example shown, the capital J dips below the base line in the original design. When the character is grid-fitted, however, the curve is held to the baseline by an indirect instruction. That instruction references the CVT, subject to the default cut_in value of 17/16. At this value the curve is held to the base line through 81 pixels per em but reverts to its original design at 82 pixels per em as shown.

Figure 2-8	81 pixels per em (left) and 82 pixels per em (right)

The effect of the cut_in varies with its value. Decreasing the value of the cut_in will have the affect of causing the outline to revert to the original design at a smaller ppem value. Increasing the value of the cut_in will cause the outline to revert to the original design at a higher ppem value.

The single_width_cut_in

The single_width_cut_in is the distance difference at which the interpreter will ignore the values in the Control Value Table and in the outline in favor of a single-width value. It allows features to revert to a single predetermined size for small numbers of pixels per em.

Having all controlled glyph features assume the same dimensions might be an advantage for certain fonts at very small grid sizes. The single_width_value is used when the absolute difference between the single_width_value and the original value is smaller than this single_width_cut_in.

The default value for the single_width_cut_in is zero. In effect, this means that the default is ignore this cut_in value. Like the control_value_cut_in, the single_width_cut_in only applies to the indirect instructions.

The single_width_value

The single_width_value is used when  the difference between the Control Value Table and the single_width_value is less than the single_width_cut_in. For example, if the single_width_value were set to 2 pixels, features meeting the single_width_cut_in test would be regularized to be 2 pixels wide.

Managing at specific sizes

Most TrueType instructions are independent of size. They are used to control a feature over the full range of sizes. Occasionally, it is necessary to alter a glyph outline at a specific size to include or exclude certain pixels. In other words, occasionally it is desirable to make an exception to the outline that would otherwise be produced by the other instructions. Such exceptions are made using the DELTA instructions.

There are two types of DELTA instructions. The DELTAP instructions work by moving points. The DELTAC instructions work by changing values in the CVT.

For example, without a DELTA instruction the circumflex accent shrinks to a single pixel at  9 ppem. Using DELTAs, the appearance is improved by lowering points 5, 2 and 1 by one pixel at 9 ppem.

Note: DELTA instructions should be used sparingly, since they are associated with a relatively high storage overhead. They can be useful for solving otherwise impossible cases.

The delta_base

The delta_base is the base value used to calculate the range of point sizes to which a delta instruction will apply. Changing the delta_base allows you to change the range of ppem sizes affected by each of the DELTA instructions.

The three pairs of DELTA instructions are grouped according to the range of pixels they potentially affect, with each group beginning at 16 pixels per em larger than the previous group. All DELTAC1 and DELTAP1 instructions potentially can affect glyphs at sizes beginning at delta_base pixels per em through delta_base plus 15 pixels per em. The DELTAP2 and DELTAC2 instructions affects the range beginning at delta_base plus 16 pixels per em. The DELTAP3 and DELTAC3 instructions affect delta_base plus 32 pixels per em.

The delta_shift

The delta_shift value is the power to which an exception is raised. By varying the value of the delta_shift,  you trade off fine control of outline movement as opposed to total range of movement. A low delta_shift favors range of movement over fine control. A high delta_shift favors fine control over range of movement.

Points can be moved by multiples of a fixed amount called a step. The size of the step is 1 divided by 2 to the power delta_shift.


Anatomy of a TrueType Instruction

TrueType provides instructions for each of the following tasks and a set of general purpose instructions. This chapter describes the TrueType instruction set. Instruction descriptions are organized by category based on their function.

Pushing data onto the interpreter stack

Managing the Storage Area

Managing the Control Value Table

Modifying Graphics State settings

Managing outlines

General purpose instructions

TrueType instructions are uniquely specified by their opcodes. For convenience, this book will refer to instructions by their names. Each instruction name is a mnemonic intended to aid in remembering that instruction's function. For example, the MDAP instruction stands for Move Direct Absolute Point. Similarly, RUTG is short for Round Up To Grid. A brief description of each instruction clarifying the mnemonic marks the start of a new instruction.

One name may actually refer to several different but closely related instructions. A bracketed list of Boolean values follows each name to uniquely specify a particular variant of a given instruction. The Boolean list can be converted to a binary number and that number added to the base opcode for the instruction to obtain the opcode for any instruction variant.

To obtain the opcode for any instruction, take the lower of the two opcode values given in the code range and add the unsigned binary number represented by the list of binary digits. The left most bit is the most significant. For example, given an instruction with the opcode range 0xCO-0xDF and five Boolean flags (a through e) the opcode for a given instruction base can be computed as shown:

If  these flags were set to 11101 the code would be computed as follows:

= 0xC0 + 0x10 + 0x8 + 0x4 + 0x1
= 0xC0 + 0x1D= 0xDD

Instruction opcodes are part of the instruction stream, a sequence of opcodes and data. The instruction stream is not a stack. While the stream of opcodes and data on the instruction stream is gradually used up, no new data is added to the instruction stream by the execution of another instruction (i.e. there is no equivalent of a push instruction that adds data to the instruction stream). It is possible to alter the flow of control through the instruction steam using one of the jump instructions described in a later section.

The instruction stream is shown as a sequence of opcodes and data. Since the instruction stream is 1-byte wide, words will be broken up into high bytes and low bytes with high bytes appearing first in the stream. For added readability, instruction names are used in illustrations instead of opcodes. An arrow  will point to the next instruction awaiting execution.

Figure 3-1	The instruction stream with a push byte instruction (left) and a push word instruction (right)

A few instructions known collectively as push instructions move data from the instruction stream to the interpreter stack. These instructions are unique in taking their arguments from the instruction stream. All other TrueType instructions take any data needed from the stack at the time they are executed. Any results produced by a TrueType instruction are pushed onto the interpreter stack.

An instruction that expects two arguments and pushes a third would expect the two arguments to be at the top of the stack. Any result pushed by that instruction appears at the top of the stack.

The listing a b c denotes a stack consisting of three elements with a being at the top of the stack, b being in the middle, and c at the bottom as shown.

The statement push d, e means push d then push e adding two elements to the stack as shown.

To indicate that the top two stack elements are to be removed the statement would be pop e, d.

It has already been noted that the bracketed list of binary digits that follows the instruction name uniquely identifies an instruction variant. This is done by having the bits represent a list of Boolean flags that can be set to TRUE with a value of 1 or to FALSE with a value of 0. Binary digits that follow the name can also be grouped to form a larger binary number. In such cases, the documentation specifies the meaning associated with each possible numerical combination.

An instruction specification consists of the instruction name followed by its bracketed Boolean flags. Additional information describing the flags and explaining the stack interaction and any Graphics State dependencies is provided in tabular form:

Code Range	the range of hexadecimal codes identifying this instruction and its variants

Flags	an explanation of the meaning of a bracketed binary number

From IS	any arguments taken from the instruction stream by push instructions

Pops	any arguments popped from the stack

Pushes	any arguments pushed onto the stack

Uses	any state variables whose value this instruction depends upon

Sets	any state variables set by this instruction

Instruction descriptions include illustrations intended to clarify stack interactions, Graphics State effects, and changes to interpreter tables.

In the case of instructions that move points, an illustration will be provided to clarify the direction and magnitude of the movement. In these illustrations, shades of grey will be used to indicate the sequence in which points have been moved. The darker the fill, the more recently a point has been moved.


Data types - The instruction stream

Instruction opcodes are always bytes. Values in the instruction stream are bytes.

The stack

Values pushed onto the stack or popped from the stack are always 32-bit quantities (LONG or ULONG). When values that are less than 32 bits are pushed onto the stack, bytes are expanded to 32-bit quantities by padding the upper bits with zeroes and words are sign extended to 32 bits. In cases where two instruction stream bytes are combined to form a word, the high order bits appear first in the instruction stream.

NOTE: On a 16-bit system, such as Windows, all stack operations are on 16-bit values (SHORT or USHORT). Care must be taken to avoid overflow. It is also important to note that F26dot6 values (used for internal scalar math) are represented instead as 10 dot 6 values (i.e. the upper 16 bits are not supported).

Figure 3-2	A byte padded to a 32-bit long word (ULONG)

Figure 3-3	A word sign extended to a 32-bit long word (ULONG)

 All values on the stack are signed. Instructions, however, interpret these 32-bit quantities in a variety of ways. The interpreter variously understands quantities as integers and as fixed point numbers.

Values such as pixel coordinates are represented as 32-bit quantities consisting of 26 bits of whole number and 6 bits of fraction. These are fixed point numbers with the data type name F26Dot6.

The setting of the freedom_vector and projection_vector are represented as 2.14 fixed point numbers. The upper 16 bits of the 32-bit quantity are ignored.

A given set of 32 bits will have a different value depending upon how it is interpreted. The following  32-bit value interpreted as an integer has the value 264.

The same 32-bit quantity interpreted as a F26Dot6 fixed point number has the value 4.125.

The figure below gives several examples of expressing pixel values as 26.6 words.


Pushing data onto the interpreter stack

Most TrueType instructions take their arguments from the interpreter stack. A few instructions, however, take their arguments from the instruction stream. Their purpose is to move data from the instruction stream to the interpreter stack. Collectively these instructions are known as the push instructions.

PUSH N Bytes

NPUSHB[ ]

Code Range	0x40

From  IS	n: number of bytes to push (1 byte interpreted as an integer)
b1, b2,...bn: sequence of n bytes

Pushes 	b1, b2,...bn: sequence of n bytes each padded to 32 bits (ULONG)

Takes n unsigned bytes from the instruction stream, where n is an unsigned integer in the range (0..255), and pushes them onto the stack. n itself is not pushed onto the stack.

PUSH N Words

NPUSHW[ ]

Code Range	0x41

From IS	n: number of words to push (one byte interpreted as an integer)
w1, w2,..wn: sequence of n words formed from pairs of bytes,
the high byte appearing first

Pushes	w1, w2,...wn: sequence of n words each sign extended to 32 bits (LONG)

Takes n 16-bit signed words from the instruction stream, where n is an unsigned integer in the range (0..255), and pushes them onto the stack. n itself is not pushed onto the stack.

PUSH Bytes

PUSHB[abc]

Code Range	0xB0 - 0xB7

abc	number of bytes to be pushed - 1

From IS	b0, b1,..bn: sequence of n + 1 bytes

Pushes	b0, b1, ...,bn: sequence of n + 1 bytes each padded to 32 bits (ULONG)

Takes the specified number of bytes from the instruction stream and pushes them onto the interpreter stack.

The variables a, b, and c are binary digits representing numbers from 000 to 111 (0-7 in binary). Because the actual number of bytes (n) is from 1 to 8, 1 is automatically added to the abc figure to obtain the actual number of bytes pushed.

Example:

PUSH Words

PUSHW[abc]

Code Range	0xB8 - 0xBF

abc	number of words to be pushed - 1.

From IS	w0,w1,..wn: sequence of n+1 words formed from pairs of bytes,
the high byte appearing first

Pushes	w0 ,w1,...wn: sequence of n+1 words each sign extended to 32 bits
(LONG)

Takes the specified number of words from the instruction stream and pushes them onto the interpreter stack.

The variables a, b, and c are binary digits representing numbers from 000 to 111 (0-7 binary). Because the actual number of bytes (n) is from 1 to 8, 1 is automatically added to the abc figure to obtain the actual number of bytes pushed.

Example:


Managing the Storage Area

The interpreter Storage Area is a block of memory that can be used to store and later access 32-bit values. Instructions exist for writing values to the Storage Area and retrieving values from the Storage Area. Attempting to read a value from a storage location that has not previously had a value written to it will yield unpredictable results.

Read Store

RS[ ]

Code Range	0x43

Pops	location: Storage Area location (ULONG)

Pushes	value: Storage Area value (ULONG)

Gets	Storage Area value

This instruction reads a 32-bit value from the Storage Area location popped from the stack and pushes the value read onto the stack. It pops an address from the stack and pushes the value found in that Storage Area location to the top of the stack. The number of available storage locations is specified in the maxProfile table in the font file.

Example:

The effect of the RS instruction is to push the value 0x1B of the Storage Area onto the Stack.

Write Store

WS[ ]

Code Range	0x42

Pops	value: Storage Area location (ULONG)

location: Storage Area value (ULONG)

Pushes	-

Sets	Storage Area value

This instruction writes a 32-bit value into the storage location indexed by locations. It works by popping a value and then a location from the stack. The value is placed in the Storage Area location specified by that address. The number of storage locations is specified in the maxProfile table in the font file.

Example:

Write the value 0x0000 0118 to location 3A in the Storage Area.

Managing the Control Value Table

The Control Value Table stores information that is accessed by the indirect instructions. Values can be written to the CVT in FUnits or pixel units as proves convenient. Values read from the CVT are always in pixels (F26Dot6 ). This table, unlike the Storage Area, is initialized by the font and is automatically scaled.

Write Control Value Table in Pixel units

WCVTP[ ]

Code Range	0x44

Pops	value: number in pixels (F26Dot6 fixed point number)

location: Control Value Table location (ULONG)

Pushes	-

Sets	Control Value Table entry

Pops a location and a value from the stack and puts that value in the specified location in the Control Value Table. This instruction assumes the value is in pixels and not in FUnits.

Write Control Value Table in FUnits

WCVTF[ ]

Code Range	0x70

Pops	location: Control Value Table location (ULONG)

value: number in FUnits (ULONG)

Pushes	-

Sets	Control Value Table entry

Pops a location and a value from the stack and puts the specified value in the specified address in the Control Value Table. This instruction assumes the value is expressed in FUnits and not pixels. The value is scaled before being written to the table.

Read Control Value Table

RCVT[ ]

Code Range	0x45

Pops	location: CVT entry number (ULONG)

Pushes	value: CVT value (F26Dot6)

Gets	Control Value Table entry

Pops a location from the stack and pushes the value in the location specified in the Control Value Table onto the stack.

Managing the Graphics State

Instructions can be used to set the value of Graphics State variables and, in some cases, to retrieve their current value.

Getting a value

Instructions that retrieve the value of a state variable have names that begin with the word get. Get instructions will return the value of the state variable in question by placing that value on the top of the stack.

The illustration shows the effect of a GPV or get projection_vector instruction. It takes the x and y components of the projection_vector from the Graphics State and places them on the stack.

Setting a value

Instructions that change the value of a Graphics State variable have a name that begins with the word set. Set instructions expect their arguments to be at the top of the interpreter stack.

Figure 3-4	Setting the value of the Graphics State variable projection_vector

In addition to simple sets and gets, some instructions exist to simplify management of the values of state variables. For example, a number of instructions exist to set the direction of the freedom_vector and the projection_vector. In setting a vector, it is possible to set it to either of the coordinate axes, to the direction specified by a line, or to a direction specified by values taken from the stack. An instruction exists that directly sets the freedom_vector to the same value as the projection_vector.

Set freedom and projection Vectors To Coordinate Axis

SVTCA[a]

Code range	0x00 - 0x01

a 	0: set vectors to the y-axis
1: set vectors to the x-axis

Pops	-

Pushes	-

Sets	projection_vector
freedom_vector

Sets both the projection_vector and freedom_vector to the same one of the coordinate axes.

The SVTCA is a shortcut for using both the SFVTCA and SPVTCA instructions. SVTCA[1] is equivalent to SFVTCA[1] followed by SPVTCA[1]. This instruction ensures that both movement and measurement are along the same coordinate axis.

Example:

SVTCA[1]

P [image] F

Sets both measurement and movement to the x-direction.

SVTCA[0]

P [image] F

Sets both measurement and movement to the y-direction.

Set Projection_Vector To Coordinate Axis

SPVTCA[a]

Code range	0x02 - 0x03

a	0: set the projection_vector to the y-axis
1: set the projection_vector to the x-axis

Pops	-

Pushes	-

Sets	projection_vector

Sets the projection_vector to one of the coordinate axes depending on the value of the flag a.

Example:

SPVTCA[0]

P

Sets the projection_vector to the y-axis assuring the measurement will be in that direction.

Set Freedom_Vector to Coordinate Axis

SFVTCA[a]

Code range	0x04 - 0x05

a 	0: set the freedom_vector to the y-axis
1: set the freedom_vector to the x-axis

Pops	-

Pushes	-

Sets	freedom_vector

Sets the freedom_vector to one of the coordinate axes depending upon the value of the flag a.

Example:

SFVTCA[0]

F

Sets the freedom_vector to the y-axis ensuring that movement will be along that axis.

Set Projection_Vector To Line

SPVTL[a]

Code Range	0x06 - 0x07

a	0: sets projection_vector to be parallel to line segment from p1 to p2
1:sets projection_vector to be perpendicular to line segment from p1 to p2;
the vector is rotated counter clockwise 90 degrees

Pops	p1: point number (ULONG)

p2: point number (ULONG)

Pushes	-

Uses	point p1 in the zone pointed at by zp1
point p2 in the zone pointed at by zp2

Sets 	projection_vector

Sets the projection_vector to a unit vector parallel or perpendicular to the line segment from point p1 to point p2.

  P

If parallel, the projection_vector points from p1 toward p2 as shown.

If perpendicular the projection_vector is obtained by rotating the parallel vector in a counter clockwise manner as shown.

 P

case 1:

SPVTL[0]

 P

Sets the projection_vector to be parallel to the line from point 7 to point 14.

case 2:

SPVTL[1]

P

Sets the projection_vector to be perpendicular to the line from point 7  to point 14.

case 3:

SPVTL[1]

P

The order in which the points are specified matters.  This instruction sets the projection_vector to be perpendicular to the line from point 14 to point 7.

Set Freedom_Vector To Line

SFVTL[a]

Code Range	0x08 - 0x09

a	0:set freedom_vector to be parallel to the line segment defined by points
p1 and p2

1:set freedom_vector  perpendicular to the line segment defined by points p1
and p2; the vector is rotated counter clockwise 90 degrees

Pops	p1: point number (ULONG)

p2: point number (ULONG)

Pushes	-

Sets	freedom_vector

Uses	zp1 points to the zone containing point p1
zp2 points to the zone containing point p2

Sets the freedom_vector to a unit vector parallel or perpendicular to the line segment defined by points p1 and p2.

If parallel the freedom_vector points from p1 toward p2 as shown.

F

If perpendicular the freedom_vector is obtained by rotating the parallel vector in a counter clockwise manner as shown.

 F

Set Freedom_Vector To Projection Vector

SFVTPV[ ]

Code	0x0E

Pops	-

Pushes	-

Sets	freedom_vector

Sets the freedom_vector to be the same as the projection_vector.

Before

P 	F

After

P 	F

Set Dual Projection_Vector To Line

SDPVTL[a]

Code Range	0x86 - 0x87

a	0: Vector is parallel to line
1: Vector is perpendicular to line

Pops	p1: first point number (ULONG)

p2: second point number (ULONG)

Pushes	-

Sets	dual_projection_vector

Pops two point numbers from the stack and uses them to specify a line that defines a second, dual_projection_vector. This dual_projection_vector uses coordinates from the scaled outline before any grid-fitting took place. It is used only with the IP, GC, MD, MDRP and MIRP instructions. Those instructions will use the dual_projection_vector when they measure distances between ungrid-fitted points. The dual_projection_vector will disappear when any other instruction that sets the projection_vector is used.

D	P

NOTE: The dual_projection_vector is set parallel to the points as they appeared in the original outline before any grid-fitting took place.

Set Projection_Vector From Stack

SPVFS[ ]

Code Range	0x0A

Pops	y: y component of projection_vector (2.14 fixed point number padded
with zeroes)

x: x component of projection_vector (2.14 fixed point number padded
with zeroes)

Pushes	-

Sets	projection_vector

Sets the direction of the projection_vector, using values x and y taken from the stack, so that its projections onto the x and y-axes are x and y, which are specified as signed (two's complement) fixed-point (2.14) numbers.

The square root of [image] must be equal to 0x4000 (hex).

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

SPVFS[ ]

Sets the projection_vector to a unit vector that points in the direction of the x-axis

Set Freedom_Vector From Stack

SFVFS[ ]

Code	0x0B

Pops	y: y component of freedom_vector (2.14 fixed point number padded
with zeroes)

x: x component of freedom_vector (2.14 fixed point number padded
with zeroes)

Pushes	-

Sets	freedom_vector

Sets the direction of the freedom_vector using the values x and y taken from the stack. The vector is set so that its projections onto the x  and y -axes are x and y, which are specified as signed (two's complement) fixed-point (2.14) numbers.

The square root of [image] must be equal to 0x4000 (hex).

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

 F

Sets the freedom_vector to a unit vector that points in the direction of the y-axis.

Get Projection_Vector

GPV[ ]

Code Range	0x0C

Pops	-

Pushes	x: x component of projection_vector  (2.14 fixed point number padded
with zeroes)

y : y component of projection_vector  (2.14 fixed point number padded
with zeroes)

Gets	projection_vector

Pushes the x and y components of the projection_vector onto the stack as two 2.14 numbers.

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

case 1:

P

The stack entry 0x4000 which when interpreted as a 2.14 number is simply 1. This command reveals that, in this case, the projection_vector is a unit vector that points in the x-direction.

case 2:

P

Here the projection_vector is a unit vector that point in the direction of the y-axis.

case 3:

P

 NOTE:  0x2D41 is the hex equivalent of  [image] . As a result of this instruction, the projection_vector is set to a 45 degree angle relative to the x-axis.

Get Freedom_Vector

GFV[ ]

Code Range	0x0D

Pops	-

Pushes	x: x-component of freedom_vector (2.14 number padded with zeroes)

y: y component of freedom_vector (2.14 number padded with zeroes)

Gets	freedom_vector

Puts the x and y  components of the freedom_vector on the stack. The freedom_vector is put onto the stack as two 2.14 coordinates.

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example

GFV[ ]

Set Reference Point 0

SRP0[ ]

Code Range	0x10

Pops	p: point number (ULONG)

Pushes	-

Sets	rp0

Affects	IP, MDAP, MIAP, MIRP, MSIRP, SHC, SHE, SHP

Pops a point number from the stack and sets rp0 to that point number.

Set Reference Point 1

SRP1[ ]

Code Range	0x11

Pops	p: point number (ULONG)

Pushes	-

Sets	rp1

Affects	IP, MDAP, MDRP, MIAP, MSIRP, SHC, SHE, SHP

Pops a point number from the stack and sets rp1 to that point number.

Set Reference Point 2

SRP2[ ]

Code Range	0x12

Pops	p:point number (ULONG)

Pushes	-

Sets	rp2

Pops a point number from the stack and sets rp2 to that point number.

Set Zone Pointer 0

SZP0[ ]

Code Range	0x13

Pops	n:zone number (ULONG)

Pushes	-

Sets 	zp0

Affects	ALIGNPTS, ALIGNRP, DELTAP1, DELTAP2, DELTAP3, IP,
ISECT, MD, MDAP, MIAP, MIRP, MSIRP, SHC, SHE, SHP, UTP

Pops a zone number, n, from the stack and sets zp0 to the zone with that number. If n is 0, zp0 points to zone 0. If n is 1, zp0 points to zone 1. Any other value for n is an error.

Example:

Set Zone Pointer 1

SZP1[ ]

Code Range 	0x14

Pops	n:zone number (ULONG)

Pushes	-

Sets	zp1

Affects	ALIGNRPTS, ALIGNRP, IP, MD, MDRP, MSIRP, SHC, SHE, SHP,
SFVTL, SPVTL

Pops a zone number, n, from the stack and sets zp1 to the zone with that number. If n is 0, zp1 points to zone 0. If n is 1, zp1 points to zone 1. Any other value for n is an error.

Example

Set Zone Pointer 2

SZP2[ ]

Code Range 	0x15

Pops	n:zone number (ULONG)

Pushes	-

Sets	zp2

Affects	ISECT, IUP, GC, SHC, SHP, SFVTL, SHPIX, SPVTL, SC

Pops a zone number, n, from the stack and sets zp2 to the zone with that number. If n is 0, zp2 points to zone 0. If n is 1, zp2 points to zone 1. Any other value for n is an error.

Set Zone PointerS

SZPS[ ]

Code Range	0x16

Pops	n:zone number (ULONG)

Pushes 	-

Sets	zp0, zp1, zp2

Affects	ALIGNPTS, ALIGNRP, DELTAP1, DELTAP2, DELTAP3, GC, IP,
ISECT, IUP, MD, MDAP, MDRP, MIAP, MIRP, MSIRP, SC, SFVTL,
SHPIX, SPVTL, SHC, SHE, SHP, SPVTL, UTP

Pops a zone number from the stack and sets all of the zone pointers to point to the zone with that number. If n is 0, all three zone pointers will point to zone 0. If n is 1, all three zone pointers will point to zone 1. Any other value for n is an error

Round To Half Grid

RTHG[ ]

Code Range 	0x19

Pops	-

Pushes 	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 0 (hg). In this state, the coordinates of a point are rounded to the nearest half grid line.

Example:

Round To Grid

RTG[ ]

Code Range 	0x18

Pops	-

Pushes 	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 1 (g). In this state, distances are rounded to the closest grid line.

Example:

Round To Double Grid

RTDG[ ]

Code Range	0x3D

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 2 (dg). In this state, distances are rounded to the closest half or integer pixel.

Example:

Round Down To Grid

RDTG[ ]

Code Range	0x7D

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 3 (dtg). In this state, distances are rounded down to the closest integer grid line.

Example:

Round Up To Grid

RUTG[ ]

Code Range	0x7C

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 4 (utg). In this state distances are rounded up to the closest integer pixel boundary.

Example:

Round OFF

ROFF[ ]

Code Range	0x7A

Pop	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 5 (off). In this state rounding is turned off.

Example:

Super ROUND

SROUND[ ]

Code Range	0x76

Pops	n: number decomposed to obtain period, phase, threshold

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

SROUND allows you fine control over the effects of the round_state variable by allowing you to set the values of three components of the round_state: period, phase, and threshold.

More formally, SROUND maps the domain of 26.6 fixed point numbers into a set of discrete values that are separated by equal distances. SROUND takes one argument from the stack, n, which is decomposed into a period, phase and threshold.

The period specifies the length of the separation or space between rounded values in terms of grid spacing.

The phase specifies the offset of the values from multiples of the period.

The threshold specifies the part of the domain that is mapped onto each value. More intuitively, the threshold tells a value when to fall forward to the next largest integer.

Only the lower 8 bits of the argument n are used. For SROUND gridPeriod is equal to 1.0 pixels. The byte is encode as follows: bits 7 and 6 encode the period, bits 5 and 4 encode the phase and bits 3, 2, 1 and 0 encode the threshold as shown here.

period

0	period = gridPeriod/2

1	period = gridPeriod

2	period = gridPeriod*2

3	Reserved

phase

0	phase = 0

1	phase= period/4

2	phase = period/2

3	phase = gridPeriod*3/4

threshold

0	threshold = period -1

1	threshold = -3/8 * period

2	threshold = -2/8 * period

3	threshold = -1/8 * period

4	threshold = 0/8 * period

5	threshold = 1/8 * period

6	threshold = 2/8 * period

7	threshold =3/8 * period

8	threshold = 4/8 * period

9	threshold = 5/8 * period

10	threshold = 6/8 period

11	threshold = 7/8 * period

12	threshold = 8/8 * period

13	threshold = 9/8 * period

14	threshold = 10/8 * period

15	threshold = 11/8 * period

For example, SROUND(01:01:1000) maps numbers into the values 0.25, 1.25, 2.25, .... The numbers from -0.25 to 0.75 are mapped into 0.25.  The range of numbers [0.75, 1.75) map into 1.25.  Similarly, the numbers from [1.75, 2.75) map into the number 2.25 and so on.

Rounding occurs after compensation for engine characteristics, so the steps in the rounding of a number n are:

add engine compensation to n.

subtract the phase from n.

add the threshold to n.

truncate n to the next lowest periodic value (ignore the phase).

add the phase back to n.

if rounding caused a positive number to become negative, set n to the positive round value closest to 0.

if rounding caused a negative number of become positive, set n to the negative round value closest to 0.

the period parameters can have values of 1/2 pixel, 1 pixel, or 2 pixels.

the phase parameters can have values of 0 pixels, 1/4 pixel, 1/2 pixel, or 3/4 pixel.

the threshold parameters can have values of -3/8 period, -2/8 period,... 11/8 period.  It can also have the special value largest-number-smaller-than-period which causes rounding equivalent to CEILING.

Super ROUND 45 degrees

S45ROUND[ ]

Code Range	0x77

Pops	n: ULONG decomposed to obtain period, phase, threshold (ULONG)

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

S45ROUND is analogous to SROUND. The gridPeriod is SQRT(2)/2 pixels rather than 1 pixel. It is useful for measuring at a 45 degree angle with the coordinate axes.

Set LOOP variable

SLOOP[ ]

Code Range	0x17

Pops	n: value for loop Graphics State variable (integer)

Pushes	 -

Sets	loop

Affects	ALIGNRP, FLIPPT, IP, SHP, SHPIX

Pops a value, n, from the stack and sets the loop variable count to that value. The loop variable works with the SHP[a], SHPIX[a], IP[ ], and ALIGNRP[ ]. The value n indicates the number of times the instruction is to be repeated. After the instruction executes, the loop variable and LOOPCALL[ ] are reset to 1.

Set Minimum_ Distance

SMD[ ]

Code Range 	0x1A

Pops	distance: value for minimum_distance (F26Dot6)

Pushes 	 -

Sets 	minimum_distance

Pops a value from the stack and sets the minimum_distance variable to that value.  The distance is assumed to be expressed in sixty-fourths of a pixel.

INSTRuction execution ConTRoL

INSTCTRL[]

Code Range	0x8E

Pops	s:	selector (int32)
value: USHORT (padded to 32 bits) used to set value of
instruction_control

Pushes	-

Sets	instruction_control

Sets the instruction control state variable making it possible to turn on or off the execution of instructions and to regulate use of parameters set in the CVT program.

This instruction clears and sets various control flags. The selector is used to choose the relevant flag. The value determines the new setting of that flag. In version 1.0 there are only two flags in use:

Flag 1 is used to inhibit grid-fitting. It is chosen with a selector value of 1. If this flag is set to TRUE (v=1), any instructions associated with glyphs will not be executed. For example, to inhibit grid-fitting when a glyph is being rotated or stretched, use the following sequence on the preprogram:

PUSHB[000] 6	/* ask GETINFO to check for stretching or rotation */
GETINFO[]	/* will push TRUE if glyph is stretched or ratated */
IF[]	/* tests value at top of stack */
PUSHB[000] 1	/* value for INSTCTRL */
PUSHB[000] 1	/* selector for INSTCTRL */
INSTRCTRL[]	/* based on selector and value will turn grid-fitting off */
EIF[]

Flag 2 is used to establish that any parameters set in the CVT program should be ignored when instructions associated with glyphs are executed. These include, for example, the values for scantype and the CVT cut-in. When flag2 is set to TRUE, the default values of those parameters will be used regardless of any changes that may have been made in those values by the preprogram. When flag2 is set to FALSE, parameter values changed by the CVT program will be used in glyph instructions.

INSTCTRL[] can only be executed in the CVT program.

SCAN conversion ConTRoL

SCANCTRL[ ]

Code Range	0x85

Pops	n: flags indicating when to turn on dropout control mode
(16-bit word padded to 32 bits)

Pushes	-

Sets	scan_control

SCANCTRL is used to set the value of the Graphics State variable scan_control which in turn determines whether the scan converter will activate dropout control for this glyph. Use of the dropout control mode is determined by three conditions:

1. Is the glyph rotated?

2. Is the glyph stretched?

3. Is the current setting for ppem less than a specified threshold?

The interpreter pops a word from the stack and looks at the lower 13 bits.

Bits 0-7 represent the threshold value for ppem. A value of FF in bits 0-7 means invoke dropout_control for all sizes. A value of 0 in bits 0-7 means never invoke dropout_control.

Bits 8-13 are used to turn on dropout_control in cases where the specified conditions are met. Bits 8, 9 and 10 are used to turn on the dropout_control mode (assuming other conditions do not block it). Bits 11, 12, and 13 are used to turn off the dropout mode unless other conditions force it.

Bit 	Meaning if set

8	Set dropout_control to TRUE if other conditions do not block and ppem is
less than or equal to the threshold value.

9	Set dropout_control to TRUE if other conditions do not block and the glyph
is rotated.

10 	Set dropout_control to TRUE if other conditions do not block and the glyph
is stretched.

11	Set dropout_control to FALSE unless ppem is less than or equal to the
threshold value.

12	Set dropout_control to FALSE unless the glyph is rotated.

13	Set dropout_control to FALSE unless the glyph is stretched.

For example

0x0000	No dropout control is invoked

0x01FF	Always do dropout control

0x0A10	Do dropout control if the glyph is rotated and has less than 16 pixels per em

The scan converter can operate in either a "normal" mode or in a "fix dropout" mode depending on the value of a set of enabling and disabling flags.

SCANTYPE

SCANTYPE[ ]

Code Range	0x8D

Pops	n: 16-bit integer

Pushes	-

Sets	scan_control

Pops a 16-bit integer whose value is used to determine which rules the scan converter will use. If the value of the argument is 0, the fast scan converter will be used. If the value of the integer is 1 or 2, the dropout control mode will be set. More specifically,

if n=0  rules 1, 2, and 3 are invoked (dropout control scan conversion including stubs)

if n=1  rules 1, 2, and 4 are invoked (dropout control scan conversion excluding stubs)

if n=2  rules 1 and 2 are invoked (fast scan conversion)

The scan conversion rules are shown here:

Rule 1

If a pixel's center falls within the glyph outline, that pixel is turned on and becomes part of that glyph.

Rule 2

If a contour falls exactly on a pixel's center, that pixel is turned on.

Rule 3

If a scan line between two adjacent pixel centers (either vertical or horizontal) is intersected by both an on-Transition contour and an off-Transition contour and neither of the pixels was already turned on by rules 1 and 2, turn on the left-most pixel (horizontal scan line) or the bottom-most pixel (vertical scan line)

Rule 4

Apply Rule 3 only if the two contours continue to intersect other scan lines in both directions. That is, do not turn on pixels for 'stubs'. The scanline segments that form a square with the intersected scan line segment are examined to verify that they are intersected by two contours.  It is possible that these could be different contours than the ones intersecting the dropout scan line segment.  This is very unlikely but may have to be controlled with grid-fitting in some exotic glyphs.

Set Control Value Table Cut In

SCVTCI[ ]

Code Range 	0x1D

Pops	n: value for cut_in (F26Dot6)

Pushes 	-

Sets 	control_value_cut_in

Affects	MIAP, MIRP

Sets the control_value_cut_in in the Graphics State. The value n is expressed in sixty-fourths of a pixel.

Increasing the value of the cut_in will increase the range of sizes for which CVT values will be used instead of the original outline value.

Set Single_Width_Cut_In

SSWCI[ ]

Code Range 	0x1E

Pops	n: value for single_width_cut_in (F26dot6)

Pushes 	-

Sets	single_width_cut_in

Affects	MIAP, MIRP

Sets the single_width_cut_in in the Graphics State. The value n is expressed in sixty-fourths of a pixel.

Set Single-width

SSW[ ]

Code Range	0x1F

Pops	n: value for single_width_value (F26dot6)

Pushes 	-

Sets	single_width_value

Sets the single_width_value in the Graphics State. The single_width_value is expressed in sixty-fourths of a pixel.

Set the auto_flip Boolean to ON

FLIPON[ ]

Code Range 	0x4D

Pops	-

Pushes 	-

Sets	auto_flip

Affects	MIRP, MIAP

Sets the auto_flip Boolean in the Graphics State to TRUE causing the MIRP and MIAP instructions to ignore the sign of Control Value Table entries.The default auto_flip Boolean value is TRUE.

Set the auto_flip Boolean to OFF

FLIPOFF[ ]

Code Range	0x4E

Pops	-

Pushes	-

Sets	auto_flip

Affects	MIRP, MIAP

Set the auto_flip Boolean in the Graphics State to FALSE causing the MIRP and MIAP instructions to use the sign of Control Value Table entries.  The default auto_flip Boolean value is TRUE.

Set Angle _Weight

SANGW[ ]

Code Range	0x7E

Pops	weight: value for angle_weight

Pushes	-

Sets	angle_weight

SANGW is no longer needed because of dropped support to the AA (Adjust Angle) instruction. AA was the only instruction that used angle_weight in the global graphics state.

Pops a weight value from the stack and sets the value of the angle_weight state variable accordingly.

Set Delta_Base in the graphics state

SDB[ ]

Code Range	0x5E

Pops	n: value for the delta_base (ULONG)

Pushes	-

Sets	delta_base

Affects	DELTAP1, DELTAP2, DELTAP3, DELTAC1, DELTAC2, DELTAC3

Pops a number, n, and sets delta_base to the value n. The default for delta_base is 9.

Set Delta_Shift in the graphics state

SDS[ ]

Code Range	0x5F

Pops	n: value for the delta_shift (ULONG)

Pushes	-

Sets	delta_shift

Affects	DELTAP1, DELTAP2, DELTAP3, DELTAC1, DELTAC2, DELTAC3

Sets delta_shift to the value n. The default for delta_shift is 3.

Reading and writing data

The following instructions make it possible to get and to set a point coordinate, to measure the distance between two points, and to determine the current settings for pixels per em and point size.

Get Coordinate projected onto the projection_vector

GC[a]

Code Range	0x46 - 0x47

a	0: use current position of point p

1: use the position of point p in the original outline

Pops	p: point number (ULONG)

Pushes	value: coordinate location (F26Dot6)

Uses	zp2

Measures the coordinate value of point p on the current projection_vector and pushes the value onto the stack.

Example

The following example shows that the value returned by GC is dependent upon the current position of the projection_vector. Note that point p is at the position (300,420) in the coordinate grid.

GC[1] 9

P

P

P

The projection_vector is parallel to the line from (0,0) to (300,420)

Sets Coordinate From the Stack using projection_vector and freedom_vector

SCFS[ ]

Code Range	0x48

Pops	value: distance from origin to move point (F26Dot6)

p: point number (ULONG)

Pushes	-

Uses	zp2

Moves point p from its current position along the freedom_vector so that its component along the projection_vector becomes the value popped off the stack.

Measure Distance

MD[ ]

Code Range	0x49 - 0x4A

a	0: measure distance in grid-fitted outline

1: measure distance in original outline

Pops	p1: point number (ULONG)
p2: point number (ULONG)

Pushes	distance (F26Dot6)

Uses	zp0 with point p1, zp1 with point p2

Measures the distance between outline point p1 and outline point p2. The value returned is in  pixels (F26Dot6) If distance is negative, it was measured against the projection vector. Reversing the order in which the points are listed will change the sign of the result.

Example:

In the illustration below MD[1] between points 25 and 31 will return a smaller value that MD[0] at 10 pixels per em on a 72 dpi device. The difference is due to the effects of grid-fitting which, at this size, stretches out the counter.

P

Measure Pixels Per EM

MPPEM[ ]

Code Range	0x4B

Pops	-

Pushes	ppem: pixels per em (ULONG)

This instruction pushes the number of pixels per em onto the stack. Pixels per em is a function of the resolution of the rendering device and the current point size and the current transformation matrix. This instruction looks at the projection_vector and returns the number of pixels per em in that direction.

Measure Point Size

MPS[ ]

Code Range	0x4C

Pops	-

Pushes	pointSize: the size in points of the current glyph (F26Dot6)

Pushes the current point size onto the stack.

Measure point size can be used to obtain a value which serves as the basis for choosing whether to branch to an alternative path through the instruction stream. It makes it possible to treat point sizes below or above a certain threshold differently.

12, 18, and 36 point Helvetica g at 72 dpi


Managing outlines

The following set of instructions make it possible to move the points that make up a glyph outline. They are the instructions that accomplish the actual work of grid-fitting. They include instructions to move points, shift points or groups of points, flip points from off to on the curve or vice versa, and to interpolate points.

FLIP PoinT

FLIPPT[ ]

Code Range	0x80

Pops	p: point number (ULONG)

Pushes	-

Uses	loop

Flips points that are off the curve so that they are on the curve and points that are on the curve so that they are off the curve. The point is not marked as touched. The result of a FLIPPT instruction is that the contour describing part of a glyph outline is redefined.

Before:

After

FLIP  RanGe ON

FLIPRGON[ ]

Code Range	0x81

Pops	highpoint: highest point number in range of points to be flipped (ULONG)

lowpoint: lowest point number in range of points to be flipped (ULONG)

Pushes	-

Flips a range of points beginning with lowpoint and ending with highpoint so that any off the curve points become on the curve points. The points are not marked as touched.

Example:

FLIPRGON[ ] 1 5

Before:

After:

Will make all off curve points between point 0 and point 5 into on curve points as shown

FLIP RanGe OFF

FLIPRGOFF[ ]

Code Range	0x82

Pops	highpoint: highest point number in range of points to be flipped (ULONG)

lowpoint: lowest point number in range of points to be flipped (ULONG)

Pushes	-

Flips a range of points beginning with lowpoint and ending with highpoint so that any on curve points become off the curve points.

NOTE: This instruction changes the curve but the position of the points is unaffected.  Accordingly, points affected by this instruction are not marked as touched.

Example:

FLIPRGOFF[ ] 8 6

Before :

After:

SHift Point by the last point

SHP[a]

Code Range	0x32 - 0x33

a	0: uses rp2 in the zone pointed to by zp1

1: uses rp1 in the zone pointed to by zp0

Pops	p: point to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with point p
loop, freedom_vector, projection_vector

Shift point p by the same amount that the reference point has been shifted. Point p is shifted along the freedom_vector so that the distance between the new position of point p and the current position of point p is the same as the distance between the current position of the reference point and the original position of the reference point.

NOTE: Point p is shifted from its current position, not its original position. The distance that the reference point has shifted is measured between its current position and the original position.

In the illustration below rp is the original position of the reference point, rp' is the current position of the reference point, p is the original position of point p, p' is the current position, p" the position after it is shifted by the SHP instruction.  (White indicates original position, grey is current position, black is position to which this instruction moves a point).

SHift Contour by the last point

SHC[a]

Code Range	0x34 - 0x35

a	0: uses rp2 in the zone pointed to by zp1

1: uses rp1 in the zone pointed to by zp0

Pops	c: contour to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with contour c
freedom_vector, projection_vector

Shifts every point on contour c by the same amount that the reference point has been shifted. Each point is shifted along the freedom_vector so that the distance between the new position of the point and the old position of that point is the same as the distance between the current position of the reference point and the original position of the reference point. The distance is measured along the projection_vector. If the reference point is one of the points defining the contour, the reference point is not moved by this instruction.

This instruction is similar to SHP, but every point on the contour is shifted.

SHift Zone by the last pt

SHZ[a]

Code Range	0x36 - 0x37

a 	0:  the reference point rp2 is in the zone pointed to by zp1

1: the reference point rp1 is in the zone pointed to by zp0

Pops	e: zone to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with e
freedom_vector, projection_vector

Shift the points in the specified zone (Z1 or Z0) by the same amount that the reference point has been shifted. The points in the zone are shifted along the freedom_vector so that the distance between the new position of the shifted points and their old position is the same as the distance between the current position of the reference point and the original position of the reference point.

SHZ[a] uses zp0 with rp1 or zp1 with rp2. This instruction always uses zp2 with e. This instruction is similar to SHC, but all points in the zone are shifted, not just the points on a single contour.

SHift point by a PIXel amount

SHPIX[ ]

Code Range	0x38

Pops	amount: magnitude of the shift (F26Dot6)

p1, p2,...pn: points to be shifted (ULONG)

Pushes	-

Uses	zp2, loop

Shifts the points specified by the amount stated. When the loop variable is used, the amount to be shifted is put onto the stack only once. That is, if loop = 3, then the contents of the top of the stack should be point p1, point p2, point p3, amount. The value amount is expressed in sixty-fourths of a pixel.

SHPIX is unique in relying solely on the direction of the freedom_vector. It makes no use of the projection_vector. Measurement is made in the direction of the freedom_vector.

Example

The instruction shifts points 27, 28, and 29 by 80/64  or 1.25 pixels in the direction of the freedom vector. The distance is measured in the direction of the freedom_vector; the projection vector is ignored.

SHPIX[]

Move Stack Indirect Relative Point

MSIRP[a]

Code Range	0x3A - 0x3B

a	0: don't set reference point to point p after move

1: do set reference point to point p after move

Pops	d: distance (F26Dot6)

p: point number (ULONG)

Pushes	-

Uses	zp1 with point p and zp0 with rp0.

Makes the distance between a point p and rp0 equal to the value specified on the stack. The distance on the stack is in fractional pixels (F26Dot6). An MSIRP has the same effect as a MIRP instruction except that it takes its value from the stack rather than the Control Value Table. As a result, the cut_in does not affect the results of a MSIRP. Additionally, MSIRP is unaffected by the round_state.

Move Direct Absolute Point

MDAP[ a ]

Code Range	0x2E - 0x2F

a:	0: do not round the value

1: round the value

Pops	p: point number (ULONG)

Pushes 	-

Sets 	rp0 = rp1 = point p

Uses 	zp0

Sets the reference points rp0 and rp1 equal to point p. If a=1, this instruction rounds point p to the grid point specified by the state variable round_state. If a=0, it simply marks the point as touched in the direction(s) specified by the current freedom_vector.

Example:

MDAP[0]

When a=0, the point is simply marked as touched and the values of rp0 and rp1 set to point p.

F [image] P

MDAP[1] assuming that the round_state is round to grid and the freedom_vector is a shown.

F [image]  P

Move Indirect Absolute Point

MIAP[a]

Code Range 	0x3E - 0x3F

a	0: don't round the distance and don't look at
    the control_value_cut_in

1: round the distance and look at the
    control_value_cut_in

Pops	n: CVT entry number (F26Dot6)

p: point number (ULONG)

Pushes 	-

Sets	rp0 = rp1 = point p

Uses	zp0, round_state, control_value_cut_in

Moves point p to the absolute coordinate position specified by the nth Control Value Table entry . The coordinate is measured along the current projection_vector. If a=1, the position will be rounded as specified by round_state. If a=1, and if the device space difference between the CVT value and the original position is greater than the control_value_cut_in, then the original position will be rounded (instead of the CVT value.)

Rounding is done as if the entire coordinate system has been rotated to be consistent with the projection_vector. That is, if round_state is set to 1, and the projection_vector and freedom_vector are at a 45_ angle to the x-axis, then a MIAP[1] of a point to 2.9 pixels will round to 3.0 pixels along the projection_vector.

The a Boolean above controls both rounding and the use of the control_value_cut_in.  If you would like the meaning of this Boolean to specify only whether or not the MIAP[ ] instruction should look at the control_value_cut_in value, use the ROFF[ ] instruction to turn off rounding.

This instruction can be used to create Twilight Zone points.

Example:

MIAP[1] 4 7

case 1:

rounding is OFF

The point is moved to the position specified in the CVT

case 2:

the cut_in test succeeds and rounding is RTG

The value in the CVT is subjected to the rounding rule and then the point is moved to the rounded position.

case 3:

the cut_in test fails and rounding is OFF

Here the point is not moved.

case 4:

the cut_in test fails and rounding is RTG

In this case the point is moved to the nearest grid position.

Move Direct Relative Point

MDRP[abcde]

Code Range	0xC0 - 0xDF

a	0: do not set rp0 to point p after move

1: do set rp0 to point p after move

b	0: do not keep distance greater than or equal
to minimum_distance

1: keep distance greater than or equal to
minimum_distance

c	0: do not round distance

1: round the distance

de	distance type for engine characteristic compensation

Pops	p: point number (ULONG)

Pushes	-

Sets	after point p is moved, rp1 is set equal to rp0, rp2 is set equal to point p;
if the a flag is set to TRUE, rp0 is set equal to point p

Uses	zp0 with rp0 and zp1 with point p, round_state, single_width_value,
single_width_cut_in

MDRP moves point p along the freedom_vector so that the distance from its new position to the current position of rp0 is the same as the distance between the two points in the original uninstructed outline, and then adjusts it to be consistent with the Boolean settings. Note that it is only the original positions of rp0 and point p and the current position of rp0 that determine the new position of point p along the freedom_vector.

MDRP is typically used to control the width or height of a glyph feature using a value which comes from the original outline. Since MDRP uses a direct measurement and does not reference the control_value_cut_in, it is used to control measurements that are unique to the glyph being instructed. Where there is a need to coordinate the control of a point with the treatment of points in other glyphs in the font, a MIRP instruction is needed.

Though MDRP does not refer to the CVT, its effect does depend upon the single-width cut-in value. If the device space distance between the measured value taken from the uninstructed outline and the single_width_value is less than the single_width_cut_in, the single_width_value will be used in preference to the outline distance. In other words, if the two distances are sufficiently close (differ by less than the single_width_cut_in), the single_width_value will be used.

The setting of the round_state Graphics State variable will determine whether and how the distance of point p from point q is rounded. If the round bit is not set, the value will be unrounded. If the round bit is set, the effect will depend upon the choice of rounding state. The value of the minimum distance variable is the smallest possible value the distance between two points can be rounded to.

Distances measured with the MDRP instruction must be either black, white or grey. Indicating this value in Booleans de allows the interpreter to compensate for engine characteristics as needed. The value de specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

Example 1:

Graphics State Settings

Before MDRP
F [image] P

rp0	7
rp1	?
rp2	?

Case 1:

After MDRP[00001] 8

F [image] P
rp0	7
rp1	7
rp2	8

Case 2:

After MDRP[10001] 8

F [image] P
rp0	8
rp1	7
rp2	8

Example 2:

Point p is moved so that its distance from rp1 is the same as it was in the original outline.

F [image] P

Move Indirect Relative Point

MIRP[abcde]

Code Range	0xE0 - 0xFF

a	0: Do not set RP0 to p

1: Set rp0 to p

b	0: Do not keep distance greater than or equal to
minimum_distance

1: Keep distance greater than or equal to
minimum_distance

c	0: Do not round the distance and do not look at the
control_value_cut_in

1: Round the distance and look at the
control_value_cut_in value

de: 	distance type for engine characteristic compensation

Pops	n: CVT entry number (F26Dot6)
p: point number (ULONG)

Pushes	-

Uses	zp0 with rp0 and zp1 with point p.
round_state, control_value_cut_in, single_width_value,
single_width_cut_in

Sets 	After it has moved the point this instruction sets rp1 = rp0,
rp2 = point p, and if a has the value TRUE,  rp0  is set to point p.

A MIRP instruction makes it possible to preserve the distance between two points subject to a number of qualifications. Depending upon the setting of Boolean flag b, the distance can be kept greater than or equal to the value established by the minimum_distance state variable. Similarly, the instruction can be set to round the distance according to the round_state graphics state variable. The value of the minimum distance variable is the smallest possible value the distance between two points can be rounded to. Additionally, if the c Boolean is set, the MIRP instruction acts subject to the control_value_cut_in. If the difference between the actual measurement and the value in the CVT is sufficiently small (less than the cut_in_value), the CVT value will be used and not the actual value. If the device space difference between this distance from the CVT and the single_width_value is smaller than the single_width_cut_in, then use the single_width_value rather than the outline or Control Value Table distance.

MIRP measures distance relative  to point rp0. More formally, MIRP moves point p along the freedom_vector so that the distance from p to rp0 is equal to the distance stated in the reference CVT entry (assuming that the cut_in test succeeds)

The c Boolean above controls both rounding and the use of Control Value Table entries. If you would like the meaning of this Boolean to specify only whether or not the MIRP[ ] instruction should look at the control_value_cut_in, use the ROFF[ ] instruction to turn off rounding. In this manner, it is possible to specify rounding off and no cut_in.

The value de specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

Example 1

MIRP[00110] 3 17

case 1:

the cut_in test succeeds and rounding is off

The point is moved so that the distance from RP0 is equal to that given in CVT entry 17.

case 2:

the cut_in test succeeds and rounding is set to RTG

The distance in the CVT is rounded and the point is moved by the rounded distance.

case 3:

the cut_in test fails and the round_state is OFF

The point is not moved.

case 4:

the cut_in test fails and the round_state is RTG

The current position of the point is rounded to the grid.

ALIGN Relative Point

ALIGNRP[ ]

Code Range 	0x3C

Pops	p: point number (ULONG)

Pushes 	-

Uses	zp1 with point p and zp0 with rp0 loop

Reduces the distance between rp0 and point p to zero. Since distance is measured along the projection_vector and movement is along the freedom_vector, the effect of the instruction is to align points.

case 1:

P  	F

case 2:

P  	F

Adjust Angle(No Longer Supported)

AA[ ]

Code Range 	0x7F

Pops	p: point number (ULONG)

Pushes	 -

Uses	zp1 with point p, zp0 with rp0

AA was a prototype instruction from an earlier version of the rasterizer which is no longer supported.  It is now a no-op which pops its arguments from the stack and may be deleted entirely from later versions of the rasterizer.

AA attempts to find the best angle for the line. A good angle,  for TrueType fonts, is defined as an angle with a small pixel pattern repetition period. If AA can move point p along the freedom_vector so that the line from rp0 to point p is at a good angle, it will do so.

The instruction considers 152 different distinct angles. These are all the angles that have a repetition period of less than 9 pixels. The instruction does not change an angle of more than about ± 10-12 degrees. Within this range it will search for an angle that has the smallest penalty. The penalty must be less than 10 pixels. The penalty is defined as (in pixels):

R + l * a

where

R:	repetition period

l:	line rp0 to point p projected into a unit vector at an angle orthogonal to the angle being examined

a:	angle_weight/64

When acting on small point sizes, the instruction is likely to make a large adjustment to the angle. When acting on sufficiently large point sizes, the instruction does not change the angle at all. If high values are used for angle_weight, the angle does not change much. If low values are used for angle_weight, the angle changes significantly.

moves point p to the InterSECTion of two lines

ISECT[ ]

Code Range	0x0F

Pops	b1: end point of line 2  (ULONG)
b0: start point of line 2  (ULONG)
a1: end point of line 1  (ULONG)
a0: start point of line 1  (ULONG)
p: point to move (ULONG)

Pushes	 -

Uses	zp2 with point p, zp1 with line A, zp0 with line B

Puts point p at the intersection of the lines A and B. The points a0 and a1 define line A. Similarly, b0 and b1 define line B. ISECT ignores the freedom_vector in moving point p.

Example:

ISECT[ ] 21 9 5 4 7

ALIGN Points

ALIGNPTS[ ]

Code Range	0x27

Pops	p1: point number (ULONG)
p2: point number (ULONG)

Pushes	-

Uses	zp0 with point p1 and zp1 with point p2

Makes the distance between point 1 and point 2 zero by moving both along the freedom_vector to the average of both their projections along the projection_vector.

Example:

ALIGNPTS[] 3 7

Interpolate Point by the last relative stretch

IP[ ]

Code Range	0x39

Pops	p: point number (ULONG)

Pushes	-

Uses	zp0 with rp1, zp1 with rp2, zp2 with point p, loop

Moves point p so that its relationship to rp1 and rp2 is the same as it was in the original uninstructed outline. Measurements are made along the projection_vector, and movement to satisfy the interpolation relationship is constrained to be along the freedom_vector. This instruction is illegal if rp1 and rp2 have the same position on the projection_vector.

F [image] P

In the example shown, assume that the points referenced by rp1 and rp2 are moved as shown. An IP instruction is then used to preserve their relative relationship with point p. After the IP the following should be true

D(p, rp1)/D(p',rp1') = D(p,rp2)/D(p', rp2')

In other words, the relative distance is preserved.

UnTouch Point

UTP[ ]

Code Range	0x29

Pops	p: point number (ULONG)

Pushes	-

Uses	zp0 with point p

Marks point p as untouched. A point may be touched in the x-direction, the y-direction, both, or neither. This instruction uses the current freedom_vector to determine whether to untouch the point in the x-direction, the y-direction, or both. Points that are marked as untouched will be moved by an IUP (interpolate untouched points) instruction. Using UTP you can ensure that a point will be affected by IUP even if it was previously touched.

Interpolate Untouched Points through the outline

IUP[a]

Code Range	0x30 - 0x31

a	0: interpolate in the y-direction

1: interpolate in the x-direction

Pops	-

Pushes	-

Uses	zp2

Considers a glyph contour by contour, moving any untouched points in each contour that are between a pair of touched points. If the coordinates of an untouched point were originally between those of the touched pair, it is linearly interpolated between the new coordinates, otherwise the untouched point is shifted by the amount the nearest touched point is shifted.

This instruction operates on points in the glyph zone pointed to by zp2. This zone should almost always be zone 1. Applying IUP to zone 0 is an error.

Consider three consecutive points all on the same contour. Two of the three points, p1 and p3 have been touched. Point p2 is untouched. The effect of an IUP in the x-direction is to move point p2 so that is in the same relative position to points p1 and p3 before they were moved.

The IUP instruction does not touch the points it moves. Thus the untouched points affected by an IUP instruction will be affected by subsequent IUP instructions unless they are touched by an intervening instruction. In this case, the first interpolation is ignored and the point is moved based on its original position.

Managing exceptions

DELTA instructions can be used to alter the outline of a glyph at a particular size. They are generally used to turn on or off specific pixels. Delta instructions work by moving points (DELTAP's) or by changing a value in the Control Value Table (DELTAC's).

More formally, the DELTA instructions take a variable number of arguments from the stack and allow the use of an exception of the form: at size x apply the movement d to point p (or at size x add or subtract an amount less than or equal to the Control Value Table entry c). DELTAs take a list of exceptions of the form: relative ppem value, the magnitude of the exception and the point number to which the exception is to be applied.

Each DELTA instruction works on a range of sizes as specified below. As a result, sizes are specified in relative pixels per em (ppem), that is relative to the delta_base. The default value for delta_base is 9 ppem.  To set delta_base to another value, use the SDB  instruction.

The DELTAP1 and DELTAC1 instructions allow values to be changed for glyphs at 9 through 24 ppem, assuming the default value for delta_base. Lowering the value for delta_base allows you to invoke exceptions at a smaller number of ppem.

DELTAP2 and DELTAC2 are triggered at 16 ppem higher than the value set for DELTAP1 and DELTAC1, and consequently the formula for the relative ppem is

ppem - 16 - delta_base.

DELTAP3 and DELTAC3 are triggered at 16 ppem higher than the value set for DELTAP2 and DELTAC2, or 32 ppem higher than the value set for DELTAP1 and DELTAC1, and consequently the formula for the relative ppem is:

ppem - 32 - delta_base.

DELTA*1	delta_base through delta_base + 15 ppem

DELTA*2	delta_base + 16 ppem through delta_base + 31 ppem

DELTA*3	delta_base + 32 ppem through delta_base + 47 ppem

In specifying a DELTA instruction, the high 4 bits of arg1 describe the relative ppem value that will activate the exception.

The low 4 bits of arg1 describe the magnitude of the exception. The amount the point moves is a function of the exception stated and the Graphics State variable delta_shift.  To set delta_shift, use the SDS instruction.

NOTE:  Always observe that DELTA instructions expect the argument list to be sorted according to ppem. The lowest ppem should be deepest on the stack, and the highest ppem should be topmost on the stack.

In the descriptions of the instructions that follow, pi is a point number, ci is a Control Value Table entry number and argi is a byte composed of two parts: the relative ppem (ppem - delta_base) and the magnitude of the exception.

Increasing the delta_shift will allow for more fine control over pixel movement at the sacrifice of total range of movement. A step is the minimal amount that a delta instruction can move a point. Points can be moved in integral multiples of steps.

The size of a step is 1 divided by 2 to the power delta_shift. The range of movement produced by a given delta_shift can be calculated by taking the number of steps allowed (16) and dividing it by 2 to the power delta_shift. For example, a delta_shift equal to 2 allows the smallest movement to be ± 1/4 pixel (because 22 equals 4) and the largest movement to be ± 2 pixels (16/4 = 4 pixels of movement). A delta_shift of 5 allows the smallest movement to be ± 1/32 pixel (because 25 equals 32), but the largest movement is limited to ± 1/4 pixel. (16/32  = 1/2 a pixel of movement).

Internally, the value obtained for the exception is stored as a 4 bit binary number. As a result, the desired output range must be converted to a number between 0 and 15 before being converted to binary. Here is the internal remapping table for the DELTA instructions.

NOTE: that zero is lacking in the output range.

Number of Steps [image] Exception

-8	0

-7	1

-6	2

-5	3

-4	4

-3	5

-2	6

-1	7

1	8

2	9

3	10

4	11

5	12

6	13

7	14

8	15

DELTA exception P1

DELTAP1[ ]

Code Range	0x5D

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2, ..., pn, argn: n pairs of exception specifications and
points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_base, delta_shift

DELTAP1 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of points and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi may vary between iterations.

DELTA exception P2

DELTAP2[ ]

Code Range	0x71

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2,  ..., pn, argn: n pairs of exception specifications and points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_shift, delta_base

DELTAP2 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of points and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi may vary between iterations.

DELTA exception P3

DELTAP3[ ]

Code Range	0x72

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2, ..., pn, argn: n pairs of exception specifications and
points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_base, delta_shift

DELTAP3 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of point and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi  may vary between iterations.

DELTA exception C1

DELTAC1[ ]

Code Range	0x73

Pops	n: number of pairs of exception specifications and CVT entry
numbers  (ULONG)

c1, arg1, c2, arg2,..., cn, argn: (pairs of ULONGs)

Pushes	-

DELTAC1 changes the value in each CVT entry specified at the size and by the amount specified in its paired argument.

The grouping [argi, ci ] can be executed n times. The value of argi may vary between iterations.

DELTA exception C2

DELTAC2[ ]

Code Range	0x74

Pops	n:	number of pairs of exception specifications and CVT entry numbers
(ULONG)

c1, arg1, c2, arg2,..., cn, argn: (pairs of ULONGs)

Pushes 	-

DELTAC2 changes the value in each CVT entry specified at the size and by the amount 	 specified in its paired argument.

The grouping [argi, ci] can be executed n times. The value of argi may vary between iterations.

DELTA exception C3

DELTAC3[ ]

Code Range	0x75

Pops	n:	number of pairs of  CVT entry numbers and exception
specifications (ULONG)

c1, arg1, c2 arg2,..., cn, argn:	pairs of CVT entry number and exception
specifications (pairs of ULONGs)

Pushes	-

DELTAC3 changes the value in each CVT entry specified at the size and by the amount specified in its paired argument.

The grouping [argi, ci] can be executed n times. The value of argi may vary between iterations.

Example of DELTA exceptions

Assume that you want to move point 15 of your glyph 1/8 of a pixel along the freedom_vector at 12 pixels per em. Assume that delta_base has the default value 9 and delta_shift the default value 3.

To specify that the exception should be made at 12 ppem, you subtract the delta_base, which is 9, from 12 and store the result, which is 3, in the high nibble of argi.

To specify that the point is to be moved 1/8 of a pixel, multiply 1/8 by 2 raised to the power delta_shift. In other words, you multiply 1/8 by 2 raised to the third power (or 8)yielding 1. This value must be mapped to an internal value which using the table shown is 8.

Putting these two results together yields a 3 in the high nibble and an 8 in the low nibble or 56 (00111000, in binary).

To obtain this single exception, the top of the stack is: 56, 15, 1.

(iteration)

(point number)

(arg1: ppem and magnitude)

Now if the interpreter executes

DELTAP1[ ]

then this instruction will move point 15 of the glyph (at 12 ppem) 1/8 of a pixel along the freedom_vector.


Managing the stack

The following set of instructions make it possible to manage elements on the stack. They make it possible to duplicate the element at the top of the stack, remove the top element from the stack, clear the stack, swap the top two stack elements, determine the number of elements currently on the stack, copy a specified element to the top of the stack, move a specified element to the top of the stack, and rearrange the order of the top three elements on the stack.

Duplicate top stack element

DUP[ ]

Code Range	0x20

Pops	e: stack element (ULONG)

Pushes	e, e (two ULONGs)

Duplicates the element at the top of the stack.

POP top stack element

POP[ ]

Code Range	0x21

Pops	e: stack element (ULONG)

Pushes	-

Pops the top element of the stack.

Clear the entire stack

CLEAR[ ]

Code Range	0x22

Pops	all the items on the stack (ULONGs)

Pushes	 -

Clears all elements from the stack.

SWAP the top two elements on the stack

SWAP[ ]

Code Range	0x23

Pops	e2: stack element (ULONG)
e1: stack element (ULONG)

Pushes	e1, e2 (pair of ULONGs)

Swaps the top two elements of the stack making the old top element the second from the top and the old second element the top element.

Returns the DEPTH of the stack

DEPTH[ ]

Code Range	 0x24

Pops	-

Pushes	n: number of elements (ULONG)

Pushes n, the number of elements currently in the stack onto the stack.

Example:

Copy the INDEXed element to the top of the stack

CINDEX[ ]

Code Range	0x25

Pops	k : stack element number

Pushes	ek: indexed element (ULONG)

Puts a copy of the kth stack element on the top of the stack.

Example:

CINDEX[ ]

Move the INDEXed element to the top of the stack

MINDEX[ ]

Code Range	0x26

Pops	k: stack element number

Pushes

Moves the indexed element to the top of the stack.

MINDEX[ ]

ROLL the top three stack elements

ROLL[ ]

Code Range 	0x8a

Pops	a, b, c (top three stack elements)

Pushes	b, a, c (elements reordered)

Performs a circular shift of the top three objects on the stack with the effect being to move the third element to the top of the stack and to move the first two elements down one position. ROLL is equivalent to MINDEX[ ] 3.


Managing the flow of control

This section describes those instruction that make it possible to alter the sequence in which items in the instruction steam are executed. The IF and JMP instructions and their variants work by testing the value of an element on the stack and changing the value of the instruction pointer accordingly.

IF test

IF[ ]

Code Range	0x58

Pops	e: stack element (ULONG)

Pushes	-

Tests the element popped off the stack: if it is zero (FALSE), the instruction pointer is jumped to the next ELSE or EIF instruction in the instruction stream. If the element at the top of the stack is nonzero (TRUE),  the next instruction in the instruction stream is executed. Execution continues until an ELSE instruction is encountered or an EIF instruction ends the IF. If an else statement is found before the EIF, the instruction pointer is moved to the EIF statement.

case 1:

Element at top of stack is TRUE; instruction pointer is unaffected. IF terminates with EIF.

case 2:

Element at top of stack is TRUE. The instruction stream is sequentially executed until ELSE is encountered whereupon the instruction pointer jumps to the EIF statement that terminates the IF.

case 3:

Element at the top of the stack is FALSE; instruction pointer is moved to the ELSE statement; instructions are then executed sequentially; EIF ends the IF statement.

ELSE

ELSE[ ]

Code Range	0x1B

Pops	-

Pushes	-

Marks the start of the sequence of instructions that are to be executed if an IF instruction encounters a FALSE value on the stack. This sequence of instructions is terminated with an EIF instruction.

End IF

EIF[ ]

Code Range	0x59

Pops	-

Pushes	-

Marks the end of an IF[ ] instruction.

Jump Relative On True

JROT[ ]

Code Range	0x78

Pops	e:stack element (ULONG)
offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

Obtains an offset and tests a Boolean value. If the Boolean is TRUE, the signed offset will be added to the instruction pointer and execution will be resumed at the address obtained. Otherwise, the jump is not taken. The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.

Example:

case 1:

element is FALSE.

case 2:

element is TRUE.

JuMP

JMPR[ ]

Code Range	0x1C

Pops	offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

The signed offset is added to the instruction pointer and execution is resumed at the new location in the instruction steam. The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.

Jump Relative On False

JROF[ ]

Code Range	0x79

Pops	e: stack element (ULONG)
offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

In the case where the Boolean is FALSE, the signed offset will be added to the instruction pointer and execution will be resumed there; otherwise, the jump is not taken.  The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.

case 1:

element is FALSE.

case 2:

element is TRUE.

Logical functions

The TrueType instruction set includes a set of logical functions that can be used to test the value of a stack element or to compare the values of two stack elements. The logical functions compare 32 bit values (ULONG) and return a Boolean value to the top of the stack.

Less Than

LT[ ]

Code Range	0x50

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e2 and e1 off the stack and compares them: if e2 is less than e1, 1, signifying TRUE, is pushed onto the stack if e2 is not less than e1, 0, signifying FALSE, is placed onto the stack.

Example:

LT[ ]

Less Than or Equal

LTEQ[ ]

Code Range	0x51

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e2 and e1 off the stack and compares them. If e2 is less than or equal to e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not less than or equal to e1, 0, signifying FALSE, is placed onto the stack.

Example:

LTEQ[ ]

Greater Than

GT[ ]

Code Range	0x52

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If e2 is greater than e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not greater than e1, 0, signifying FALSE, is placed onto the stack.

Example:

GT[ ]

Greater Than or Equal

GTEQ[ ]

Code Range	0x53

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If e2 is greater than or equal to e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not greater than or equal to e1, 0, signifying FALSE, is placed onto the stack.

Example:

GTEQ[ ]

EQual

EQ[ ]

Code Range	0x54

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If they are equal, one signifying TRUE is pushed onto the stack. If they are not equal, 0, signifying FALSE is placed onto the stack.

Example:

EQ[ ]

Not EQual

NEQ[ ]

Code Range	0x55

Pops	e1:stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 from the stack and compared them. If they are different, one, signifying TRUE is pushed onto the stack. If they are equal, zero, signifying FALSE is placed on the stack.

Example:

ODD

ODD[ ]

Code Range	0x56

Pops	e1: stack element (F26Dot6)

Pushes	Boolean value

Tests whether the number at the top of the stack is odd. Pops e1 from the stack and rounds it before testing it. If the rounded number is odd, one, signifying TRUE, is pushed onto the stack if it is even, zero, signifying FALSE is placed onto the stack.

Example:

ODD[ ]

This example assume that round_state is RTG.

EVEN

EVEN[ ]

Code Range	0x57

Pops	e1: stack element (F26Dot6)

Pushes	Boolean value (ULONG in the range [0,1])

Tests whether the number at the top of the stack is even. Pops e1 off the stack and rounds it before testing it.  If the rounded number is even, one, signifying TRUE, is pushed onto the stack if it is odd, zero, signifying FALSE, is placed onto the stack.

Example:

EVEN[ ]

This example assume that round_state is RTG.

logical AND

AND[ ]

Code Range	0x5A

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	( e1 and e2 ): logical and of e1 and e2 (ULONG)

Pops e1 and e2 off the stack and pushes onto the stack the result of a logical and of the two elements. Zero is returned if either or both of the elements are FALSE (have the value zero). One is returned if both elements are TRUE (have a non zero value).

case 1:

AND[ ]

case 2:

AND[ ]

logical OR

OR[ ]

Code Range	0x5B

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	(e1 or e2): logical or of e1 and e2 (ULONG)

Pops e1 and e2 off the stack and pushes onto the stack the result of a logical or operation between the two elements. Zero is returned if both of the elements are FALSE. One is returned if either both of the elements are TRUE.

Example:

case 1:

OR[ ]

case 2:

OR[ ]

logical NOT

NOT[ ]

Code Range	0x5C

Pops	e: stack element (ULONG)

Pushes	(not e): logical negation of e (ULONG)

Pops e off the stack and returns the result of a logical NOT operation performed on e. If originally zero, one is pushed onto the stack if originally nonzero, zero is pushed onto the stack.

Example:

case 1:

case 2:

Arithmetic and math instructions

These instructions perform arithmetic on stack values. Values are treated as signed (two's complement) 26.6 fixed-point numbers (F26Dot6) and give results in the same form. There is no overflow or underflow protection for these instructions.

In general, the arithmetic operators should be understood to mean e2 op e1 where e1 is the first element popped from the stack and e2 is the second element popped from the stack and op stands for an arithmetic operator.

ADD

ADD[ ]

Code Range	0x60

Pops	n1, n2 (F26Dot6)

Pushes	(n2 + n1)

Pops n1 and n2 off the stack and pushes the sum of the two elements onto the stack.

SUBtract

SUB[ ]

Code Range	0x61

Pops	n1, n2 (F26Dot6)

Pushes	(n2 - n1): difference

Pops n1 and n2 off the stack and pushes the difference between the two elements onto the stack.

DIVide

DIV[ ]

Code Range	0x62

Pops	n1: divisor (F26Dot6)

n2: dividend (F26Dot6)

Pushes

Pops n1 and n2 off the stack and pushes onto the stack the quotient obtained by dividing n2 by n1. Note that this truncates rather than rounds the value.

MULtiply

MUL[ ]

Code Range	0x63

Pops	n1, n2: multiplier and multiplicand (F26Dot6)

Pushes	n1 * n2

Pops n1 and n2 off the stack and pushes onto the stack the product of the two elements.

ABSolute value

ABS[ ]

Code Range	0x64

Pops	n

Pushes	|n|: absolute value of n (F26Dot6)

Pops n off the stack and pushes onto the stack the absolute value of n.

Example:

case 1:

case 2:

NEGate

NEG[ ]

Code Range	0x65

Pops	n1

Pushes	-n1: negation of n1 (F26Dot6)

This instruction pops n1 off the stack and pushes onto the stack the negated value of n1.

NEG[ ]

FLOOR

FLOOR[ ]

Code Range	0x66

Pops	n1: number whose floor is desired (F26Dot6)

Pushes	n : floor of n1 (F26Dot6)

Pops n1 and returns n, the greatest integer value less than or equal to n1.

Example:

FLOOR[ ]

case 1:

case 2:

case 3:

CEILING

CEILING[ ]

Code Range 	0x67

Pops	n1: number whose ceiling is desired (F26Dot6)

Pushes 	n: ceiling of n1 (F26Dot6)

Pops n1 and returns n, the least integer value greater than or equal to n1. For instance, the ceiling of 15 is 15, but the ceiling of 15.3 is 16. The ceiling of  -0.8 is 0. (n is the least integer value greater than or equal to n1)

Example:

CEILING[ ]

case 1:

case 2:

MAXimum of top two stack elements

MAX[ ]

Code Range	0x8B

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	maximum of e1 and e2

Pops two elements, e1 and e2, from the stack and pushes the larger of these two quantities onto the stack.

MINimum of top two stack elements

MIN[ ]

Code Range	0x8C

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	minimum of e1 and e2

Pops two elements, e1 and e2, from the stack and pushes the smaller of these two quantities onto the stack.

Compensating for the engine characteristics

The following two functions make it possible to compensate for the engine characteristic. Each takes value and make the compensation. In addition to the engine compensation, ROUND, rounds the value according to the round_state. NROUND only compensates for the engine.

ROUND value

ROUND[ab]

Flags	ab: distance type for engine characteristic compensation

Pops	n1

Pushes	n2

Code	0x68 - 0x6B

Rounds a value according to the state variable round_state while compensating for the engine. n1 is popped off the stack and, depending on the engine characteristics, is increased or decreased by a set amount. The number obtained is then rounded and pushed back onto the stack as n2.

The value ab specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

No ROUNDing of value

NROUND[ab]

Flags	ab: distance type for engine characteristic compensation

Pops	n1

Pushes	n2

Code	0x6C - 0x6F

NROUND[ab] does the same operation as ROUND[ab] (above), except that it does not round the result obtained after compensating for the engine characteristics. n1 is popped off the stack and, depending on the engine characteristics, increases or decreases by a set amount. This figure is then pushed back onto the stack as n2.

The value ab specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

Defining and using functions and instructions

The following instruction make it possible to define and use both functions and new instructions.

 In addition to a simple call function, there is a loop and call function.

An IDEF or instruction definition call makes it possible to patch old scalers in order to add newly defined instructions.

Function DEFinition

FDEF[ ]

Code Range	0x2C

Pops	f: function identifier number (integer in the range 0 to n-1 where n is specified
in the 'maxp' table )

Pushes	-

Marks the start of a function definition.  The argument f is a number that uniquely identifies this function. A function definition can appear only in the Font Program or the CVT program.

END Function definition

ENDF[ ]

Code Range	0x2D

Pops	-

Pushes	-

Marks the end of a function definition or an instruction definition.

CALL function

CALL[ ]

Code Range	0x2B

Pops	f: function identifier number (integer in the range 0 to n-1 where n is specified
in the 'maxp' table )

Pushes	-

Calls the function identified by the number f.

LOOP and CALL function

LOOPCALL[ ]

Code Range	0x2A

Pops	count: 	number of times to call the function (signed word) the
'maxp' table
f: function number integer in the range 0 to n-1 where n
is specified in
Pushes	-

Calls the function f, count number of times.

Example:

Assume the Font Program contains this:

PUSHB(000), 17 	push 17 onto the stack

FDEF[ ]	start defining function 17
    ...	contents of function

    ...

ENDF[ ]	end the definition

PUSHB(000),5	push count

PUSHB(000),17	push function number

LOOPCALL[ ]	call function17, 5 times

Instruction DEFinition

IDEF[ ]

Code Range	0x89

Pops	opcode (8 bit code padded with zeroes to ULONG)

Pushes	-

Begins the definition of an instruction. The instruction definition terminates when at ENDF, which is encountered in the instruction stream. Subsequent executions of the opcode popped will be directed to the contents of this instruction definition (IDEF). IDEFs should be defined in the Font Program or the CVT Program. An IDEF affects only undefined opcodes. If the opcode in question is already defined, the interpreter will ignore the IDEF. This is to be used as a patching mechanism for future instructions.


Debugging

The TrueType instruction set provides the following instruction as an aid to debugging.

DEBUG call

DEBUG[ ]

Code Range	0x4F

Pops	number (ULONG)

Pushes	-

This instruction is only for debugging purposes and should not be a part of a finished font. Some implementations may not support this instruction.

On Microsoft platforms, this instruction will issue an interrupt 3 (INT 3); if a debugger is loaded, this will result in a debug trap. On entry to the debugger, DS:BX (or EBX if running in 386 mode) will point at the local graphics state structure (documented elsewhere).  To resume, execution must be restarted at the instruction  following the INT 3.

On a Macintosh, this instruction will go to MacsBug and print the number taken from the stack. Typing "g" will cause execution to resume.


Miscellaneous instructions

The following instruction obtains information about the current glyph and the scaler version.

GET INFOrmation

GETINFO[ ]

Code Range	0x88

Pops	selector (integer)

Pushes	result (integer)

GETINFO is used to obtain data about the font scaler version and the characteristics of the current glyph. The instruction pops a selector used to determine the type of information desired and pushes a result onto the stack.

A selector value of 1 indicates that the scaler version number is the desired information, a value of 2 is a request for glyph rotation status, a value of 4 asks whether the glyph has been stretched.  (Looking at this another way, setting bit 0 asks for the scaler version number, setting bit 1 asks for the rotation information, setting bit 2 ask for stretching information. To request information on two or more of these set the appropriate bits.)

The result pushed onto the stack contains the requested information.  More precisely, bits 0 through 7 comprise the Scaler version number. Version 1 is Macintosh System 6 INIT, version 2 is Macintosh System 7, and version 3 is Windows 3.1. Version Version numbers 0 and 4 through 255 are reserved.

Bit 8 is set to 1 if the current glyph has been rotated. It is 0 otherwise. Setting bit 9 to 1 indicates that the glyph has been stretched. It is 0 otherwise.

When the selector is set to request more than one piece of information, that information is OR'd together and pushed onto the stack. For example, a selector value of 6 requests both information on rotation and stretching and will result in the setting of both bits 8 and 9.


Data Types
The TrueType Font File

The TrueType font file holds the tables that make up an outline font. All tables should be long aligned and padded with zeroes.

Data Types

The following data types are used in the TrueType font file. All TrueType fonts use Motorola-style byte ordering (Big Endian):

Data type	Description

BYTE	8-bit unsigned integer.

CHAR	8-bit signed integer.

USHORT	16-bit unsigned integer.

SHORT	16-bit signed integer.

ULONG	32-bit unsigned integer.

LONG	32-bit signed integer.

Fixed	16.16-bit signed fixed-point number.

FUnit	Smallest measurable distance in the em space.

FWord	16-bit signed integer (SHORT) that describes a quantity in FUnits.

uFWord	Unsigned 16-bit integer (USHORT) that describes a quantity in FUnits.

F2Dot14	16-bit signed fixed number with the low 14 bits of fraction.

Most tables have version numbers, and the version number for the entire font is contained in the Table Directory (see below). Note that there are two different version number types, each with its own numbering scheme. USHORT version numbers always start at zero (0).  Fixed version numbers always start at one (1.0 or 0x00010000).

The Fixed point format consists of a signed, 2's complement mantissa and an unsigned fraction. To compute the actual value, take the mantissa and add the fraction.  Examples of 2.14 values are:

Decimal Value	Hex Value	Mantissa	Fraction

1.999939	0x7fff	1	16383/16384

1.0	0x7000	1	0/16384

0.000061	0x0001	0	1/16384

0.0	0x0000	0	0/16384

-0.000061	0xffff	-1	16383/16384

-1.0	0x8000	-2	0/16384


The Table Directory
.The Table Directory

The TrueType font file begins at byte 0 with the Offset Table.

Type	Name	Description
Fixed	sfnt version	0x00010000 for version 1.0.
USHORT	numTables	Number of tables.
USHORT	searchRange	(Maximum power of 2 ≤ numTables) x 16.
USHORT	entrySelector	Log2(maximum power of 2 ≤ numTables).
USHORT	rangeShift	NumTables x 16-searchRange.
This is followed at byte 12 by the Table Directory entries. Entries in the Table Directory must be sorted in ascending order by tag.

Type	Name	Description
ULONG	tag	4 -byte identifier.
ULONG	checkSum	CheckSum for this table.
ULONG	offset	Offset from beginning of TrueType font file.
ULONG	length	Length of this table.
Tags are the names given to tables in the TrueType font file. At present, all tag names consist of four characters, though this need not be the case. Names with less than four letters are allowed if followed by the necessary trailing spaces. A list of the currently defined tags follows. Other tables may be defined for other platforms and for future expansion. Note that these tables will not have any effect on the scan converter. Tags for these tables must be registered with Apple Developer Technical Support. Tag names consisting of all lower case letters are reserved for Apple's use. The number 0 is never a valid tag name. Note that the offset in the Table Directory is measured from the start of the TrueType font file.

The tag directory makes it possible for a given font to contain only those tables it actually needs. As a result there is no standard value for numTables.

Table checksums are the unsigned sum of the longs of a given table. In C, the following function can be used to determine a checksum:

ULONG

CalcTableChecksum(ULONG *Table, ULONG Length)

{

ULONG Sum = 0L;

ULONG *Endptr = Table+((Length+3) & ~3) / sizeof(ULONG);

while (Table < EndPtr)

Sum += *Table++;

return Sum;

}

Note: This function implies that the length of a table must be a multiple of four bytes. While this is not a requirement for the TrueType scaler itself, it is suggested that all tables begin on four byte boundries, and pad any remaining space between tables with zeros. The length of all tables should be recorded in the table directory with their actual length.

Required Tables

Tag	Name
'cmap'	character to glyph mapping
'glyf'	glyph data
'head'	font header
'hhea'	horizontal header
'hmtx'	horizontal metrics
'loca'	index to location
'maxp'	maximum profile
'name'	naming table
'post'	PostScript information
'OS/2'	OS/2 and Windows specific metrics
Optional  Tables

Tag	Name
'cvt '	Control Value Table
'fpgm'	font program
'hdmx'	horizontal device metrics
'kern'	kerning
'LTSH'	Linear threshold table
'prep'	CVT Program
'WIN '	(Reserved for future use)
'VDMX'	Vertical Device Metrics table
'FOCA'	Reserved for IBM Font Object Content Architecture data


'cmap'-Character o Glyph Index Mapping Table
'cmap' - Character To Glyph Index Mapping Table

This table defines the mapping of character codes to the glyph index values used in the font. It may contain more than one subtable, in order to support more than one character encoding scheme. Character codes that do not correspond to any glyph in the font should be mapped to glyph index 0. The glyph at this location must be a special glyph representing a missing character.

The table header indicates the character encodings for which subtables are present. Each subtable is in one of four possible formats and begins with a format code indicating the format used.

The platform id and platform-specific encoding id are used to specify the subtable; this means that each platform id/platform-specific encoding id pair may only appear once in the cmap table. Each subtable can specify a different character encoding. (See the Naming Table section  for a description of these ids.)  The entries must be sorted first by platform id and then by platform-specific encoding id.

All Microsoft UGL encodings (Platform ID = 3, Encoding ID = 1) must use Format 4 for their 'cmap' subtable.

The Character To Glyph Index Mapping Table is organized as follows:

Type	Description
USHORT	Table version number (0).
USHORT	Number of encoding tables, n.
This is followed by an entry for each of the n encoding table specifying the particular encoding, and the offset to the actual subtable:

Type	Description
USHORT	Platform id.
USHORT	Platform-specific encoding id.
ULONG	Byte offset from beginning of table to the subtable for this encoding.
Format 0: Byte encoding table

This is the Apple standard character to glyph index mapping table.

Type	Name	Description
USHORT	format	Format number is set to 0.
USHORT	length	This is the length in bytes of the subtable.
USHORT	version	Version number (starts at 0).
BYTE	glyphIdArray[256]	An array that maps character codes to glyph index values.
This is a simple 1 to 1 mapping of character codes to glyph idices. The glyph set is limited to 256. Note that if this format is used to index into a larger glyph set, on the the first 256 glyphs will be accessible.

Format 2: High-byte mapping through table

This subtable is useful for the national character code standards used for Japanese, Chinese, and Korean characters. These code standards use a mixed 8/16-bit encoding, in which certain byte values signal the first byte of a 2-byte character (but these values are also legal as the second byte of a 2-byte character).  Character codes are always 1-byte. The glyph set is limited to 256.

In addition, even for the 2-byte characters, the mapping of character codes to glyph index values depends heavily on the first byte. Consequently, the table begins with an array that maps the first byte to a 4-word subHeader. For 2-byte character codes, the subHeader is used to map the second byte's value through a subArray, as described below. When processing mixed 8/16-bit text, subHeader 0 is special: it is used for single-byte character codes. When subHeader zero is used, a second byte is not needed; the single byte value is mapped through the subArray.

Type	Name	Description
USHORT	format	Format number is set to 2.
USHORT	length	Length in bytes.
USHORT	version	Version number (starts at 0)
USHORT	subHeaderKeys[256]	Array that maps high bytes to subHeaders: value is subHeader index * 8.
4 words-struct	subHeaders[ ]	Variable-length array of subHeader structures.
4 words-struct	subHeaders[ ]
USHORT	glyphIndexArray[ ]	Variable-length array containing subarrays used for mapping the low byte of 2-byte characters.
A subHeader is structured as follows:

Type	Name	Description
USHORT	firstCode	First valid low byte for this subHeader.
USHORT	entryCount	Number of valid low bytes for this subHeader.
SHORT	idDelta	See text below.
USHORT	idRangeOffset	See text below.
The firstCode and entryCount values specify a subrange that begins at firstCode and has a length equal to the value of entryCount. This subrange stays within the 0-255 range of the byte being mapped. Bytes outside of this subrange are mapped to glyph index 0 (missing glyph).The offset of the byte within this subrange is then used as index into a corresponding subarray of glyphIndexArray. This subarray is also of length entryCount, and begins at an address formed by adding the value of idRangeOffset to the address of that idRangeOffset.

Finally, if the value obtained from the subarray is not 0 (which indicates the missing glyph), you should add idDelta to it in order to get the glyphIndex. The value idDelta permits the same subarray to be used for several different subheaders. The idDelta arithmetic is modulo 65536.

Format 4: Segment mapping to delta values

This is the Microsoft standard character to glyph index mapping table.

This format is used when the character codes for the characters represented by a font fall into several contiguous ranges, possibly with holes in some or all of the ranges (that is, some of the codes in a range may not have a representation in the font). The format-dependent data is divided into three parts, which must occur in the following order:

1.	A four-word header gives parameters for an optimized search of the segment list;

2.	Four parallel arrays describe the segments (one segment for each contiguous range of codes);

3.	A variable-length array of glyph IDs (unsigned words).

Type	Name	Description
USHORT	format	Format number is set to 4.
USHORT	length	Length in bytes.
USHORT	version	Version number (starts at 0).
USHORT	segCountX2	2 x segCount .
USHORT	searchRange	2 x (2**floor(log2(segCount)))
USHORT	entrySelector	log2(searchRange/2)
USHORT	rangeShift	2 x segCount - searchRange
USHORT	endCount[segCount]	End characterCode for each segment, last =0xFFFF.
USHORT	reservedPad	Set to 0.
USHORT	startCount[segCount]	Start character code for each segment.
USHORT	idDelta[segCount]	Delta for all character codes in segment.
USHORT	idRangeOffset[segCount]	Offsets into glyphIdArray or 0
USHORT	glyphIdArray[ ]	Glyph index array (arbitrary length)
The number of segments is specified by segCount, which is not explicitly in the header; however, all of the header parameters are derived from it. The searchRange value is twice the largest power of 2 that is less than or equal to  segCount. For example, if segCount=39, we have the following:

segCountX2	78

searchRange	64	(2 * largest power of 2 ≤ 39)

entrySelector	5	log2(32)

rangeShift	46	2 x 39 - 32

Each segment is described by a startCode and endCode, along with an idDelta and an idRangeOffset, which are used for mapping the character codes in the segment. The segments are sorted in order of increasing endCode values, and the segment values are specified in four parallel arrays. You search for the first endCode that is greater than or equal to the character code you want to map. If the corresponding startCode is less than or equal to the character code, then you use the corresponding idDelta and idRangeOffset to map the character code to a glyph index (otherwise, the missingGlyph is returned). For the search to terminate, the final endCode value must be 0xFFFF. This segment need not contain any valid mappings. (It can just map the single character code 0xFFFF to missingGlyph). However, the segment must be present.

If the idRangeOffset value for the segment is not 0, the mapping of character codes relies on glyphIdArray. The character code offset from startCode is added to the idRangeOffset value. This sum is used as an offset from the current location within idRangeOffset itself to index out the correct glyphIdArray value. This obscure indexing trick works because glyphIdArray immediately follows idRangeOffset in the font file. The C expression that yields the glyph index is:

*(idRangeOffset[i]/2 + (c - startCount[i]) + &idRangeOffset[i])

The value c  is the character code in question, and i  is the segment index in which c  appears. If the value obtained from the indexing operation is not 0 (which indicates missingGlyph), idDelta[i] is added to it to get the glyph index. The idDelta arithmetic is modulo 65536.

If the idRangeOffset is 0, the idDelta value is added directly to the character code offset (i.e. idDelta[i] + c) to get the corresponding glyph index. Again, the idDelta arithmetic is modulo 65536.

As an example, the variant part of the table to map characters 10-20, 30-90, and 100-153 onto a contiguous range of glyph indices may look like this:

segCountX2:	8

searchRange:	8

entrySelector:	4

rangeShift:	0

endCode:	20	90	153	0xFFFF

reservedPad:	0

startCode:	10	30	100	0xFFFF

idDelta:	-9	-18	-27	1

idRangeOffset:	0	0	0	0

This table performs the following mappings:

10 -> 10 - 9 = 1

20 -> 20 - 9 = 11

30 -> 30 - 18 = 12

90 -> 90 - 18 = 72

...and so on.

Note that the delta values could be reworked so as to reorder the segments.

Format 6: Trimmed table mapping

Type	Name	Description
USHORT	format	Format number is set to 6.
USHORT	length	Length in bytes.
USHORT	version	Version number (starts at 0)
USHORT	firstCode	First character code of subrange.
USHORT	entryCount	Number of character codes in subrange.
USHORT	glyphIdArray [entryCount]	Array of glyph index values for character codes in the range.
The firstCode and entryCount values specify a subrange (beginning at firstCode,length = entryCount) within the range of possible character codes. Codes outside of this subrange are mapped to glyph index 0. The offset of the code (from the first code) within this subrange is used as index to the glyphIdArray, which provides the glyph index value.


'glyf' - Glyph Data

This table contains information that describes the glyphs in the font. Each glyph begins with the following header:

Type	Name	Description
SHORT	numberOfContours	If  the number of contours is greater than or equal to zero, this is a single glyph; if negative, this is a composite glyph.
FWord	xMin	Minimum x for coordinate data.
FWord	yMin	Minimum y for coordinate data.
FWord	xMax	Maximum x for coordinate data.
FWord	yMax	Maximum y for coordinate data.
Note that the bounding rectangle from each character is defined as the rectangle with a lower left corner of (xMin, yMin) and an upper right corner of (xMax, yMax).

Note: The scaler will perform better if the glyph coordinates have been created such that the xMin is equal to the lsb. For example, if the lsb is 123, then xMin for the glyph should be 123. If the lsb is -12 then the xMin should be -12. If the lsb is 0 then xMin is 0. If all glyphs are done like this, set bit 1 of flags field in the 'head' table.

Simple Glyph Description

This is the table information needed if numberOfContours is greater than zero, that is, a glyph is not a composite.

Type	Name	Description
USHORT	endPtsOfContours[n]	Array of last points of each contour; n is the number of contours.
USHORT	instructionLength	Total number of bytes for instructions.
BYTE	instructions[n]	Array of instructions for each glyph; n is the number of instructions.
BYTE	flags[n]	Array of flags for each coordinate in outline; n  is the number of flags.
BYTE or SHORT	xCoordinates[ ]	First coordinates relative to (0,0); others are relative to previous point.
BYTE or SHORT	yCoordinates[ ]	First coordinates relative to (0,0); others are relative to previous point.
Each flag is a single byte. Their meanings are shown below.

Flags	Bit	Description
On Curve	0	If set, the point is on the curve; otherwise, it is off the curve.
x-Short Vector	1	If set, the corresponding x-coordinate is 1 byte long, not 2.
y-Short Vector	2	If set, the corresponding y-coordinate is 1 byte long, not 2.
Repeat	3	If set, the next byte specifies the number of additional times this set of flags is to be repeated. In this way, the number of flags listed can be smaller than the number of points in a character.
This x is same (Positive x-Short vector)	4	This flag has two meanings, depending on how the x-Short Vector flag is set. If x-Short Vector is set, this bit describes the sign of the value, with 1 equalling positive and 0 negative. If the x-short Vector bit is not set and this bit is set, then the current x-coordinate is the same as the previous x-coordinate. If the x-short Vector bit is not set and this bit is also not set, the current x-coordinate is a signed 16-bit delta vector.
This y is same (Positive y-Short vector)	5	This flag has two meanings, depending on how the y-Short Vector flag is set. If y-Short Vector is set, this bit describes the sign of the value, with 1 equalling positive and 0 negative. If the x-short Vector bit is not set and this bit is set, then the current y-coordinate is the same as the previous y-coordinate. If the x-short Vector bit is not set and this bit is also not set, the current y-coordinate is a signed 16-bit delta vector.
Reserved	6	This bit is reserved. Set it to zero.
Reserved	7	This bit is reserved. Set it to zero.
Composite Glyph Description

This is the table information needed for composite glyphs (numberOfContours is -1). A composite glyph starts with two USHORT values ("flags" and "glyphIndex", i.e. the index of the first contour in this composite glyph); the data then varies according to "flags). The C pseudo-code fragment below shows how the composite glyph information is stored and parsed; definitions for "flags" bits follow this fragment:

do {

USHORT flags;

USHORT glyphIndex;

if ( flags & ARG_1_AND_2_ARE_WORDS) {

(SHORT or FWord) argument1;

(SHORT or FWord) argument2;

} else {

USHORT arg1and2; /* (arg1 << 8) | arg2 */

}

if ( flags & WE_HAVE_A_SCALE ) {

F2Dot14  scale;    /* Format 2.14 */

} else if ( flags & WE_HAVE_AN_X_AND_Y_SCALE ) {

F2Dot14  xscale;    /* Format 2.14 */

F2Dot14  yscale;    /* Format 2.14 */

} else if ( flags & WE_HAVE_A_TWO_BY_TWO ) {

F2Dot14  xscale;    /* Format 2.14 */

F2Dot14  scale01;   /* Format 2.14 */

F2Dot14  scale10;   /* Format 2.14 */

F2Dot14  yscale;    /* Format 2.14 */

}

} while ( flags & MORE_COMPONENTS )

if (flags & WE_HAVE_INSTR){

USHORT numInstr

BYTE instr[ ]

Argument1 and argument2 can be either x and y offsets to be added to the glyph or two point numbers. In the latter case, the first point number indicates the point that is to be matched to the new glyph. The second number indicates the new glyph's matched point. Once a glyph is added, its point numbers begin directly after the last glyphs (endpoint of first glyph + 1).

When arguments 1 and 2 are an x and a y offset instead of points and the bit ROUND_XY_TO_GRID is set to 1, the values are rounded to those of the closest grid lines before they are added to the glyph. X and Y offsets are described in FUnits.

If the bit WE_HAVE_A_SCALE is set, the scale value is read in 2.14 format--the value can be between -2 to almost +2. The glyph will be scaled by this value before grid-fitting.

The bit WE_HAVE_A_TWO_BY_TWO allows for an interrelationship between the x and y coordinates. This could be used for 90-degree rotations, for example.

These are the constants for the flags field:

Flags	Bit	Description
ARG_/1_AND_2_ARE_WORDS	0	If this is set, the arguments are words; otherwise, they are bytes.
ARGS_ARE_XY_VALUES	1	If this is set, the arguments are xy values; otherwise, they are points.
ROUND_XY_TO_GRID	2	For the xy values if the preceding is true.
WE_HAVE_A_SCALE	3	This indicates that there is a simple scale for the component. Otherwise, scale = 1.0.
RESERVED	4	This bit is reserved.  Set it to 0.
MORE_COMPONENTS	5	Indicates at least one more glyph after this one.
WE_HAVE_AN_X_AND_Y_SCALE	6	The x direction will use a different scale from the y direction.
WE_HAVE_A_TWO_BY_TWO	7	There is a 2 by 2 transformation that will be used to scale the component.
WE_HAVE_INSTRUCTIONS	8	Following the last component are instructions for the composite character.
USE_MY_METRICS	9	If set, this forces the aw and lsb (and rsb) for the composite to be equal to those from this original glyph. This works for hinted and unhinted characters.
The purpose of USE_MY_METRICS is to force the lsb and rsb to take on a desired value. For example, an i-circumflex (Unicode 00ef) is often composed of the circumflex and a dotless-i. In order to force the composite to have the same metrics as the dotless-i, set USE_MY_METRICS for the dotless-i component of the composite. Without this bit, the rsb and lsb would take on the characteristics of the wider circumflex (or would need to be explicitly set with TrueType instructions).

Note that the behavior of the USE_MY_METRICS operation is undefined for rotated composite components.


'head' - Font Header

This table gives global information about the font. The bounding box values should be computed using only glyphs that have contours. Glyphs with no contours should be ignored for the purposes of these calculations.

Type	Name	Description
Fixed	Table version number	0x00010000 for version 1.0.
Fixed	fontRevision	Set by font manufacturer.
ULONG	checkSumAdjustment	To compute:  set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
ULONG	magicNumber	Set to 0x5F0F3CF5.
USHORT	flags	Bit 0 - baseline for font at y=0; Bit 1 - left sidebearing at x=0; Bit 2 - instructions may be dependant on point size; Bit 3 - force ppem to integer values for all internal scaler math; may use fractional ppem sizes if this bit is clear; Bit 4 - instructions may alter advance width (i.e., the advance widths might not scale linearly); Note: All other bits must be zero.
USHORT	unitsPerEm	Valid range is from 16 to 16384
longDateTime	created	International date (8-byte field).
longDateTime	modified	International date (8-byte field).
FWord	xMin	For all glyph bounding boxes.
FWord	yMin	For all glyph bounding boxes.
FWord	xMax	For all glyph bounding boxes.
FWord	yMax	For all glyph bounding boxes.
USHORT	macStyle	Bit 0 bold (if set to 1) Bit 1 italic (if set to 1) Bits 2-15 reserved (set to 0).
USHORT	lowestRecPPEM	Smallest readable size in pixels.
SHORT	fontDirectionHint	0   Fully mixed directional glyphs;  1   Only strongly left to right;  2   Like 1 but also contains neutrals -1   Only strongly right to left; -2   Like -1 but also contains neutrals.
SHORT	indexToLocFormat	0 for short offsets, 1 for long.
SHORT	glyphDataFormat	0 for current format.
macStyle bits must agree with the 'OS/2' table fsSelection bits. The fsSelection bits are used over the macStyle bits in Microsoft Windows. The PANOSE values and 'post' table values are ignored for determining bold or italic fonts.

A neutral character has no inherent directionality; it is not a character with zero (0) width. Spaces and punctuation are examples of neutral characters. Non-neutral characters are those with inherent directionality. For example, Roman letters (left-to-right) and Arabic letters (right-to-left) have directionality. In a "normal" Roman font where spaces and punctuation are present, the font direction hints should be set to two (2).


'hhea' - Horizontal Header

This table contains information for horizontal layout. The values in the minRightSidebearing, minLeftSideBearing and xMaxExtent should be computed using only glyphs that have contours. Glyphs with no contours should be ignored for the purposes of these calculations.

Type	Name	Description
Fixed	Table version number	0x00010000 for version 1.0.
FWord	Ascender	Typographic ascent.
FWord	Descender	Typographic descent.
FWord	LineGap	Typographic line gap. Negative LineGap values are treated as zero  in Windows 3.1, System 6, and  System 7.
uFWord	advanceWidthMax	Maximum advance width value in 'hmtx' table.
FWord	minLeftSideBearing	Minimum left sidebearing value in 'hmtx' table.
FWord	minRightSideBearing	Minimum right sidebearing value; calculated as Min(aw - lsb - (xMax - xMin)).
FWord	xMaxExtent	Max(lsb + (xMax - xMin)).
SHORT	caretSlopeRise	Used to calculate the slope of the cursor (rise/run); 1 for vertical.
SHORT	caretSlopeRun	0 for vertical.
SHORT	(reserved)	set to 0
SHORT	(reserved)	set to 0
SHORT	(reserved)	set to 0
SHORT	(reserved)	set to 0
SHORT	(reserved)	set to 0
SHORT	metricDataFormat	0 for current format.
USHORT	numberOfHMetrics	Number of hMetrtic entries in  'hmtx' table; may be smaller than the total number of glyphs in the font.


'hmtx' - Horizontal Metrics

The type longHorMetric is defined as an array where each element has two parts: the advance width, which is of type uFWord, and the left side bearing, which is of type FWord. Or, more formally:

typedef struct 	_longHorMertric {

uFWord	advanceWidth;

FWord	lsb;

}  longHorMetric;

Field	Type	Description
hMetrics	longHorMetric [numberOfHMetrics]	Paired advance width and left side bearing values for each glyph. The value numOfHMetrics comes from the 'hhea' table. If the font is monospaced, only one entry need be in the array, but that entry is required. The last entry applies to all subsequent glyphs.
leftSideBearing	FWord[ ]	Here the advanceWidth is assumed to be the same as the advanceWidth for the last entry above. The number of entries in this array is derived from numGlyphs (from 'maxp' table) minus numberOfHMetrics. This generally is used with a run of monospaced glyphs (e.g., Kanji fonts or Courier fonts). Only one run is allowed and it must be at the end. This allows a monospaced font to vary the left side bearing values for each glyph.
For any glyph, xmax and xmin are given in 'glyf' table, lsb and aw are given in 'hmtx' table. rsb is calculated as follows:

rsb = aw - (lsb + xmax).

If pp1 and pp2 are phantom points used to control lsb and rsb, their initial position in x is calculated as follows:

pp1 = xmin - lsb             pp2 = pp1 + aw


'loca' - Index to Location

The indexToLoc table stores the offsets to the locations of the glyphs in the font, relative to the beginning of the glyphData table. In order to compute the length of the last glyph element, there is an extra entry after the last valid index.

By definition, index zero points to the missing character, which is the character that appears if a character is not found in the font. The missing character is commonly represented by a blank box (such as [image]) or a space. If the font does not contain an outline for the missing character, then the first and second offsets should have the same value. This also applies to any other character without an outline, such as the space character.

There are two versions of this table, the short and the long. The version is specified in the indexToLocFormat entry in the 'head' table.

Short version

Type	Name	Description
USHORT	offsets[n]	The actual local offset divided by 2 is stored. The value of n  is numGlyphs + 1. The value for numGlyphs is found in the 'maxp' table.
Long version

Type	Name	Description
ULONG	offsets[n]	The actual local offset is stored. The value of n  is numGlyphs + 1. The value for numGlyphs is found in the 'maxp' table.


'maxp' - Maximum Profile

This table establishes the memory requirements for this font.

Type	Name	Description
Fixed	Table version number	0x00010000 for version 1.0.
USHORT	numGlyphs	The number of glyphs in the font.
USHORT	maxPoints	Maximum points in a component glyph.
USHORT	maxContours	Maximum contours in a component glyph.
USHORT	maxCompositePoints	Maximum points in a composite glyph.
USHORT	maxCompositeContours	Maximum contours in a composite glyph.
USHORT	maxZones	1 if instructions do not use the twilight zone (Z0), or 2 if instructions do use Z0; should be set to 2 in most cases.
USHORT	maxTwilightPoints	Maximum points used in Z0.
USHORT	maxStorage	Number of Storage Area locations.
USHORT	maxFunctionDefs	Number of FDEFs.
USHORT	maxInstructionDefs	Number of IDEFs.
USHORT	maxStackElements	Maximum stack depth
This includes Font and CVT Programs, as well as the instructions for each glyph.

USHORT	maxSizeOfInstructions	Maximum byte count for glyph instructions.
USHORT	maxComponentElements	Maximum number of glyphs referenced at "top level" for any component glyph.
USHORT	maxComponentDepth	Maximum levels of recursion; 1 for simple components.


'name' - Naming Table

The naming table allows multilingual strings to be associated with the TrueType font file. These strings can represent copyright notices, font names, family names, style names, and so on. To keep this table short, the font manufacturer may wish to make a limited set of entries in some small set of languages; later, the font can be localized and the strings translated or added. Other parts of the TrueType font file that require these strings can then refer to them simply by their index number. Clients that need a particular string can look it up by its platform id, character encoding id, language id and name id.  Note that some platforms may require single byte character strings, while others may require double byte strings.

The Naming Table is organized as follows:

Type	Description
USHORT	Format selector (=0).
USHORT	Number of NameRecords that follow n.
USHORT	Offset to start of string storage (from start of table).
n  NameRecords	The NameRecords.
(Variable)	Storage for the actual string data .
Each NameRecord looks like this:

Type	Description
USHORT	Platform ID.
USHORT	Platform-specific encoding ID.
USHORT	Language ID.
USHORT	Name ID.
USHORT	String length (in bytes).
USHORT	String offset from start of storage area (in bytes).
Following are the descriptions of the four kinds of ID. Note that the specific values listed here are the only ones that are predefined; new ones may be added by registry with Apple Developer Technical Support. Similar to the character encoding table, the NameRecords is sorted by platform ID, then platform-specific ID, then language ID, and then by name ID.

Platform ID:

ID	Platform	Specific encoding
0	Apple Unicode	none
1	Macintosh	Script manager code
2	ISO	ISO encoding
3	Microsoft	Microsoft encoding
The values 240 through 255 are reserved for user-defined platforms. The DTS registry will never assign these values to a registered platform.

Microsoft platform-specific encoding id's (platform ID = 3):

Code	Description
0	Undefined character set or indexing scheme
1	UGL character set  with Unicode indexing scheme (as defined in Chapter 5, Section 5)
The language id refers to a value which identifies the language in which a particular string is written; Microsoft language id's are defined as follows (the values in the first column are the language id values):

Language	Language Name	Principal Country	Microsoft Language Code	Language Number	Sub Language Number
0x0401	Arabic	Arab Countries	ARA	1	1
0x0402	Bulgarian	Bulgaria	BGR	2	1
0x0403	Catalan	Spain	CAT	3	1
0x0404	Traditional Chinese	R.O.C.	CHT	4	1
0x0804	Simplified Chinese	People's Republic of China	CHS	4	2
0x0405	Czech	Czechoslovakia	CSY	5	1
0x0406	Danish	Denmark	DAN	6	1
0x0407	German	Germany	DEU	7	1
0x0807	Swiss German	Switzerland	DES	7	2
0x0408	Greek	Greece	ELL	8	1
0x0409	US English	United States	ENU	9	1
0x0809	UK English	United Kingdom	ENG	9	2
0x040a	Castilian Spanish	Spain	ESP	10	1
0x080a	Mexican Spanish	Mexico	ESM	10	2
0x0c0a	Modern Spanish	Spain	ESN	10	3
0x040b	Finnish	Finland	FIN	11	1
0x040c	French	France	FRA	12	1
0x080c	Belgian French	Belgium	FRB	12	2
0x0c0c	Canadian French	Canada	FRC	12	3
0x100c	Swiss French	Switzerland	FRS	12	4
0x040d	Hebrew	Israel	HEB	13	1
0x040e	Hungarian	Hungary	HUN	14	1
0x040f	Icelandic	Iceland	ISL	15	1
0x0410	Italian	Italy	ITA	16	1
0x0810	Swiss Italian	Switzerland	ITS	16	2
0x0411	Japanese	Japan	JPN	17	1
0x0412	Korean	Korea	KOR	18	1
0x0413	Dutch	Netherlands	NLD	19	1
0x0813	Belgian Dutch	Belgium	NLB	19	2
0x0414	Norwegian - Bokmal	Norway	NOR	20	1
0x0814	Norwegian - Nynorsk	Norway	NON	20	2
0x0415	Polish	Poland	PLK	21	1
0x0416	Brazilian Portuguese	Brazil	PTB	22	1
0x0816	Portuguese	Portugal	PTG	22	2
0x0417	Rhaeto-Romanic	Switzerland	RMS	23	1
0x0418	Romanian	Romania	ROM	24	1
0x0419	Russian	U.S.S.R	RUS	25	1
0x041a	Croato-Serbian (Lat)	Yugoslavia	SHL	26	1
0x081a	Serbo-Croatian (Cyr)	Yugoslavia	SHC	26	2
0x041b	Slovakian	Czechoslovakia	SKY	27	1
0x041c	Albanian	Albania	SQI	28	1
0x041d	Swedish	Sweden	SVE	29	1
0x041e	Thai	Thailand	THA	30	1
0x041f	Turkish	Turkey	TRK	31	1
0x0420	Urdu	Pakistan	URD	32	1
0x0421	Bahasa	Indonesia	BAH	33	1
Macintosh  platform-specific encoding id's (script manager codes)

(platform ID = 1):

Code	Script	Code	Script
0	Roman	17	Malayalam
1	Japanese	18	Sinhalese
2	Chinese	19	Burmese
3	Korean	20	Khmer
4	Arabic	21	Thai
5	Hebrew	22	Laotian
6	Greek	23	Georgian
7	Russian	24	Armenian
8	RSymbol	25	Maldivian
9	Devanagari	26	Tibetan
10	Gurmukhi	27	Mongolian
11	Gujarati	28	Geez
12	Oriya	29	Slavic
13	Bengali	30	Vietnamese
14	Tamil	31	Sindhi
15	Telugu	32	Uninterp
16	Kannada
Macintosh language id's are defined as follows:

Code	Language	Code	Language
0	English	12	Arabic
1	French	13	Finnish
2	German	14	Greek
3	Italian	15	Icelandic
4	Dutch	16	Maltese
5	Swedish	17	Turkish
6	Spanish	18	Yugoslavian
7	Danish	19	Chinese
8	Portuguese	20	Urdu
9	Norwegian	21	Hindi
10	Hebrew	22	Thai
11	Japanese
ISO specific encodings (platform ID = 2):

Code	ISO encoding
0	7-bit ASCII
1	ISO 10646
2	ISO 8859-1
There are not any ISO-specific language id's.

The following name ids are defined, and they apply to all platforms. Extensions to this table will be registered with Apple DTS.

Code	Meaning
0	Copyright notice.
1	Font Family name
2	Font Subfamily name; for purposes of definition, this is assumed to address style (italic, oblique) and weight (light, bold, black, etc.) only. A font with no particular differences in weight or style (e.g. medium weight, not italic and fsSelection bit 6 set) should have the string Regular stored in this position.
3	Unique font identifier
4	Full font name; this should simply be a combination of strings 1 and 2. Exception: if string 2 is Regular, then use only string 1. This is the font name that Windows will expose to users.
5	Version string.
6	Postscript name for the font.
7	Trademark; this is used to save any trademark notice/information for this font. This is distinctly separate from the copyright.
Note that while both Apple and Microsoft support the same set of name strings, the interpretations may be somewhat different. But since name strings are stored by platform, encoding and language (placing separate strings in for both Apple and MS platforms), this should not present a problem.

The key information for this table for MS fonts relates to the use of strings 1, 2 and 4. Some examples:

Helvetica Narrow Oblique	1 = Helvetica Narrow

2 = Oblique

4 = Helvetica Narrow Oblique

Helvetia Narrow	1 = Helvetica Narrow

2 = Regular

4 = Helvetica Narrow

Helvetica Narrow Light Italic	1 = Helvetica Narrow

2 = Light Italic

4 = Helvetica Narrow Light Italic

Note that OS/2 and Windows both require that all name strings be defined in Unicode.  Thus all 'name' table strings for platform ID = 3 (Microsoft) will require two bytes per character.  See Chapter 5 for a list of the current Unicode character codes supported by Microsoft. Macintosh fonts require single byte strings.

Examples of how these strings might be defined:

0	The copyright string from the font vendor.

© Copyright the Monotype Corporation plc, 1990

1	The name the user sees.

Times New Roman

2	The name of the style.

Bold

3	A unique identifier that applications can store to identify the font being used.

Monotype: Times New Roman Bold:1990

4	The complete, hopefully unique, human readable name of the font. This name is used by Windows.

Times New Roman Bold

5	Release and version information from the font vendor.

June 1, 1990; 1.00, initial release

6	The name the font will be known by on a PostScript printer.

TimesNewRoman-Bold

7	Trademark string,

Times New Roman is a registered trademark of the Monotype Corporation.


'OS/2' - OS/2 and Windows Metrics

The OS/2 table consists of a set of metrics that are required by OS/2 and Windows.  The layout of this table is as follows:

Type	Name of Entry
USHORT	version
SHORT	xAvgCharWidth;
USHORT	usWeightClass;
USHORT	usWidthClass;
SHORT	fsType;
SHORT	ySubscriptXSize;
SHORT	ySubscriptYSize;
SHORT	ySubscriptXOffset;
SHORT	ySubscriptYOffset;
SHORT	ySuperscriptXSize;
SHORT	ySuperscriptYSize;
SHORT	ySuperscriptXOffset;
SHORT	ySuperscriptYOffset;
SHORT	yStrikeoutSize;
SHORT	yStrikeoutPosition;
SHORT	sFamilyClass;
PANOSE	panose;
ULONG	ulCharRange[4];
CHAR	achVendID[4];
USHORT	fsSelection;
USHORT	usFirstCharIndex
USHORT	usLastCharIndex
USHORT	sTypoAscender
USHORT	sTypoDescender
USHORT	sTypoLineGap
USHORT	usWinAscent
USHORT	usWinDescent
version

Format:	2-byte unsigned short

Units:	n/a

Title:	OS/2 table version number.

Description:	The version number for this OS/2 table.

Comments:	The version number allows for identification of the precise contents and layout for the OS/2 table. The version number for this layout is zero (0); the next version number would be one (1).

xAvgCharWidth

Format:	2-byte signed short

Units:	Pels / em units

Title:	Average weighted escapement.

Description:	The Average Character Width parameter specifies the arithmetic average of the escapement (width) of all of the 26 lowercase letters a through z of the Latin alphabet and the space character. If any of the 26 lowercase letters are not present, this parameter should equal the weighted average of all glyphs in the font. For non-UGL (platform 3, encoding 0) fonts, use the unweighted average.

Comments:	This parameter is a descriptive attribute of the font that specifies the spacing of characters for comparing one font to another for selection or substitution. For proportionally spaced fonts, this value is useful in estimating the length for lines of text.  The weighting factors provided with this example are only valid for Latin lowercase letters.  If other character sets, or capital letters are used, different frequency of use values should be used.  One needs to be careful when comparing fonts that use different frequency of use values for font mapping. The average character width is calculated according to this formula:  For the lowercase letters only, sum the individual character widths multiplied by the following weighting factors and then divide by 1000. For example:

Letter	Weight Factor		Letter	Weight Factor
a	64		o	56
b	14		p	17
c	27		q	4
d	35		r	49
e	100		s	56
f	20		t	71
g	14		u	31
h	42		v	10
i	63		w	18
j	3		x	3
k	6		y	18
l	35		z	2
m	20		space	166
n	56
usWeightClass

Format:	2-byte unsigned short

Title:	Weight class.

Description:	Indicates the visual weight (degree of blackness or thickness of strokes) of the characters in the font.

Comments:

Value	Description	C Definition (from windows.h)
100	Thin	FW_THIN
200	Extra-light (Ultra-light)	FW_EXTRALIGHT
300	Light	FW_LIGHT
400	Normal (Regular)	FW_NORMAL
500	Medium	FW_MEDIUM
600	Semi-bold (Demi-bold)	FW_SEMIBOLD
700	Bold	FW_BOLD
800	Extra-Bold (Ultra-bold)	FW_EXTRABOLD
900	Black (Heavy)	FW_BLACK
usWidthClass

Format:	2-byte unsigned short

Title:	Width class.

Description:	Indicates a relative change from the normal aspect ratio (width to height ratio) as specified by a font designer for the glyphs in a font.

Comments:

Value	Description	C Definition	% of normal
1	Ultra-condensed	FWIDTH_ULTRA_CONDENSED	50
2	Extra-condensed	FWIDTH_EXTRA_CONDENSED	62.5
3	Condensed	FWIDTH_CONDENSED	75
4	Semi-condensed	FWIDTH_SEMI_CONDENSED	87.5
5	Medium (normal)	FWIDTH_NORMAL	100
6	Semi-expanded	FWIDTH_SEMI_EXPANDED	112.5
7	Expanded	FWIDTH_EXPANDED	125
8	Extra-expanded	FWIDTH_EXTRA_EXPANDED	150
9	Ultra-expanded	FWIDTH_ULTRA_EXPANDED	200
Although every character in a font may have a different numeric aspect ratio, each character in a font of normal width has a relative aspect ratio of one.  When a new type style is created of a different width class (either by a font designer or by some automated means) the relative aspect ratio of the characters in the new font is some percentage greater or less than those same characters in the normal font -- it is this difference that this parameter specifies.

fsType

Format:	2-byte bit field

Title:	Type flags.

Description:	Indicates characteristics and properties for the font.

Bit	C Definition	Description
1	FM_TYPE_LICENSED	Licensed (protected) font.
2	FM_READONLY_EMBED	Read-write embedding is not permitted; only read-only encapsulation is allowed.
Comments:	All undefined bits must be zero.

FM_TYPE_LICENSED  Fonts that do not have this bit set may be embedded within a document and shipped freely to other users. When that font is unbundled from the document and installed on the target machine, the user of that machine acquires the identical rights, obligations and licenses for that font. A font with this bit unset is also subject to an end-user license agreement, copyright, design patent, and/or trademark. Additional information concerning the legal protection of a font can be found in its 'name' table.

Fonts that do have this bit set are also subject to a license agreement and must 	not be modified, embedded or exchanged in any manner without first obtaining 	permission of the legal owner.

FM_READONLY_EMBED  Fonts with this bit set indicate that they may be embedded within documents but cannot be installed permanently on the target machine. Windows v3.1 provides API support for read-only embedding. See the Windows v3.1 SDK for more information. Applications who make use of FM_READONLY_EMBED may not embed fonts which are not licensed and must de-install any read-only embedded fonts when the document that uses the fonts is closed. Any document which includes a read-only embedded font must not allow the user to edit the document; it can only be viewed and/or printed.

ySubscriptXSize

Format:	2-byte signed short

Units:	Font design units

Title:	Subscript horizontal font size.

Description:	The recommended horizontal size in font design units for subscripts for this font.

Comments:	If a font has two recommended sizes for subscripts, e.g., numerics and other, the numeric sizes should be stressed. This size field maps to the em square size of the font being used for a subscript.  The horizontal font size specifies a font designer's recommended horizontal font size for subscript characters associated with this font.  If a font does not include all of the required subscript characters for an application, and the application can substitute characters by scaling the character of a font or by substituting characters from another font, this parameter specifies the recommended em square for those subscript characters.

For example, if the em square for a font is 2048 and ySubScriptXSize is set to 205, then the horizontal size for a simulated subscript character would be 1/10th the size of the normal character.

ySubscriptYSize

Format:	2-byte signed short

Units:	Font design units

Title:	Subscript vertical font size.

Description:	The recommended vertical size in font design units for subscripts for this font.

Comments:	If a font has two recommended sizes for subscripts, e.g. numerics and other, the numeric sizes should be stressed. This size field maps to the emHeight of the font being used for a subscript.  The horizontal font size specifies a font designer's recommendation for horizontal font size of subscript characters associated with this font.  If a font does not include all of the required subscript characters for an application, and the application can substitute characters by scaling the characters in a font or by substituting characters from another font, this parameter specifies the recommended horizontal EmInc for those subscript characters.

For example, if the em square for a font is 2048 and ySubScriptYSize is set to 205, then the vertical size for a simulated subscript character would be 1/10th the size of the normal character.

ySubscriptXOffset

Format:	2-byte signed short

Units:	Font design units

Title:	Subscript x offset.

Description:	The recommended horizontal offset in font design untis for subscripts for this font.

Comments:	The Subscript X Offset parameter specifies a font designer's recommended horizontal offset -- from the character origin of the font to the character origin of the subscript's character -- for subscript characters associated with this font.  If a font does not include all of the required subscript characters for an application, and the application can substitute characters, this parameter specifies the recommended horizontal position from the character escapement point of the last character before the first subscript character.  For upright characters, this value is usually zero; however, if the characters of a font have an incline (italic characters) the reference point for subscript characters is usually adjusted to compensate for the angle of incline.

ySubscriptYOffset

Format:	2-byte signed short

Units:	Font design units

Title:	Subscript y offset.

Description:	The recommended vertical offset in font design units from the baseline for subscripts for this font.

Comments:	The Subscript Y Offset parameter specifies a font designer's recommended vertical offset from the character baseline to the character baseline for subscript characters associated with this font.  Values are expressed as a positive offset below the character baseline.  If a font does not include all of the required subscript for an application, this parameter specifies the recommended vertical distance below the character baseline for those subscript characters.

ySuperscriptXSize

Format:	2-byte signed short

Units:	Font design units

Title:	Superscript horizontal font size.

Description:	The recommended horizontal size in font design units for superscripts for this font.

Comments:	If a font has two recommended sizes for subscripts, e.g., numerics and other, the numeric sizes should be stressed. This size field maps to the em square size of the font being used for a subscript.  The horizontal font size specifies a font designer's recommended horizontal font size for superscript characters associated with this font.  If a font does not include all of the required superscript characters for an application, and the application can substitute characters by scaling the character of a font or by substituting characters from another font, this parameter specifies the recommended em square for those superscript characters.

For example, if the em square for a font is 2048 and ySuperScriptXSize is set to 205, then the horizontal size for a simulated superscript character would be 1/10th the size of the normal character.

ySuperscriptYSize

Format:	2-byte signed short

Units:	Font design units

Title:	Superscript vertical font size.

Description:	The recommended vertical size in font design units for superscripts for this font.

Comments:	If a font has two recommended sizes for subscripts, e.g., numerics and other, the numeric sizes should be stressed. This size field maps to the emHeight of the font being used for a subscript.  The vertical font size specifies a font designer's recommended vertical font size for superscript characters associated with this font.  If a font does not include all of the required superscript characters for an application, and the application can substitute characters by scaling the character of a font or by substituting characters from another font, this parameter specifies the recommended EmHeight for those superscript characters.

For example, if the em square for a font is 2048 and ySuperScriptYSize is set to 205, then the vertical size for a simulated superscript character would be 1/10th the size of the normal character.

ySuperscriptXOffset

Format:	2-byte signed short

Units:	Font design units

Title:	Superscript x offset.

Description:	The recommended horizontal offset in font design units for superscripts for this font.

Comments:	The Superscript X Offset parameter specifies a font designer's recommended horizontal offset -- from the character origin to the superscript  character's origin for the superscript characters associated with this font.  If a font does not include all of the required superscript characters for an application, this parameter specifies the recommended horizontal position from the escapement point of the character before the first superscript character.  For upright characters, this value is usually zero; however, if the characters of a font have an incline (italic characters) the reference point for superscript characters is usually adjusted to compensate for the angle of incline.

ySuperscriptYOffset

Format:	2-byte signed short

Units:	Font design units

Title:	Superscript y offset.

Description:	The recommended vertical offset in font design units from the baseline for superscripts for this font.

Comments:	The Superscript Y Offset parameter specifies a font designer's recommended vertical offset -- from the character baseline to the superscript character's baseline associated with this font.  Values for this parameter are expressed as a positive offset above the character baseline.  If a font does not include all of the required superscript characters for an application, this parameter specifies the recommended vertical distance above the character baseline for those superscript characters.

yStrikeoutSize

Format:	2-byte signed short

Units:	Font design units

Title:	Strikeout size.

Description:	Width of the strikeout stroke in font design units.

Comments:	This field should normally be the width of the em-dash for the current font. If the size is one, the strikeout line will be the line represented by the strikeout position field. If the value is two, the strikeout line will be the line represented by the strikeout position and the line immediately above the strikeout position. For a Roman font with a 2048 em square, 102 is suggested.

yStrikeoutPosition

Format:	2-byte signed short

Units:	Font design units

Title:	Strikeout position.

Description:	The position of the strikeout stroke relative to the baseline in font design units.

Comments:	Positive values represent distances above the baseline, while negative values represent distances below the baseline.  A value of zero falls directly on the baseline, while a value of one falls one pel above the baseline. The value of strikeout position should not interfere with the recognition of standard characters, and therefore should not line up with crossbars in the font.  For a Roman font with a 2048 em square, 530 is suggested.

sFamilyClass

Format:	2-byte signed short

Title:	Font-family class and subclass.  Aslo see section 3.4.

Description:	This parameter is a classification of font- family design.

Comments:	The font class and font subclass are registered values assigned by IBM to each font family.  This parameter is intended for use in selecting an alternate font when the requested font is not available. The font class is the most general and the font subclass is the most specific. The high byte of this field contains the family class, while the low byte contains the family subclass.

This section defines the IBM Font Class and the IBM Font Subclass parameter values to be used in the classification of font designs by the font designer or supplier.  These values classify a font design as to its appearance, but do not identify the specific font family, typeface variation, designer, supplier, size, or metric table differences.  It should be noted that some font designs may be classified equally well into more than IBM Font Class or Subclass. Such designs should be matched to a classification for which substitution of another font design from the same class or subclass would generally result in a similar appearance of the presented document.

Class ID = 0  No Classification

This class ID is used to indicate that the associated font has no design classification or that the design classification is not of significance to the creator or user of the font resource.

Class ID = 1  Oldstyle Serifs

This style is generally based upon the Latin printing style of the 15th to 17th century, with a mild diagonal contrast in stroke emphasis (lighter in upper left to lower right, heavier in upper right to lower left) and bracketed serifs. This IBM Class reflects the ISO Serif Class, Oldstyle and Legibility Subclasses as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design subclassification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : IBM Rounded Legibility

This style is generally characterized by a large x-height, with short ascenders and descenders.  Specifically, it is distinguished by a medium resolution, hand tuned, bitmap rendition of the more general rounded legibility subclass.  An example of this font style is the IBM Sonoran Serif family.  This IBM Subclass reflects the ISO Serif Class, Legibility Subclass, and Rounded Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Garalde

This style is generally characterized by a medium x-height, with tall ascenders.  An example of this font style is the ITC Garamond family.  This IBM Subclass reflects the ISO Serif Class, Oldstyle Subclass, and Garalde Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Venetian

This style is generally characterized by a medium x-height, with a relatively monotone appearance and sweeping tails based on the designs of the early Venetian printers. An example of this font style is the Goudy family.  This IBM Subclass reflects the ISO Serif Class, Oldstyle Subclass, and Venetian Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : Modified Venetian

This style is generally characterized by a large x-height, with a relatively monotone appearance and sweeping tails based on the designs of the early Venetian printers. An example of this font style is the Allied Linotype Palatino family.  This IBM Subclass reflects the ISO Serif Class, Transitional Subclass, and Modified Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5 : Dutch Modern

This style is generally characterized by a large x-height, with wedge shaped serifs and a circular appearance to the bowls similar to the Dutch Traditional Subclass below, but with lighter stokes.  An example of this font style is the Monotype Times New Roman family.  This IBM Subclass reflects the ISO Serif Class, Oldstyle Subclass, and Dutch Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 6 : Dutch Traditional

This style is generally characterized by a large x-height, with wedge shaped serifs and a circular appearance of the bowls.  An example of this font style is the IBM Press Roman family.  This IBM Subclass reflects the ISO Serif Class and Legibility Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 7 : Contemporary

This style is generally characterized by a small x-height, with light stokes and serifs.  An example of this font style is the University family.  This IBM Subclass reflects the ISO Serif Class and Contemporary Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 8 : Calligraphic

This style is generally characterized by the fine hand writing style of calligraphy, while retaining the characteristic Oldstyle appearance.  This IBM Subclass is not reflected in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 9-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 2  Transitional Serifs

This style is generally based upon the Latin printing style of the 18th to 19th century, with a pronounced vertical contrast in stroke emphasis (vertical strokes being heavier than the horizontal strokes) and bracketed serifs.  This IBM Class reflects the ISO Serif Class, Transitional Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Direct Line

This style is generally characterized by a medium x-height, with fine serifs, noticeable contrast, and capitol letters of approximately the same width.  An example of this font style is the Monotype Baskerville family.  This IBM Subclass reflects the ISO Serif Class, Transitional Subclass, and Direct Line Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Script

This style is generally characterized by a hand written script appearance while retaining the Transitional Direct Line style.  An example of this font style is the IBM Nasseem (Arabic) family.  This IBM Subclass is not specifically reflected in the 12/87 ISO/IEC 9541-5 draft standard, though the ISO Serif Class, Transitional Subclass, and Direct Line Specific Group would be a close approximation.

Subclass ID = 3-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 3  Modern Serifs

This style is generally based upon the Latin printing style of the 20th century, with an extreme contrast between the thick and thin portion of the strokes.  This IBM Class reflects the ISO Serif Class, Modern Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Italian

This style is generally characterized by a medium x-height, with thin hairline serifs.  An example of this font style is the Monotype Bodoni family.  This IBM Subclass reflects the ISO Serif Class, Modern Subclass, and Italian Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Script

This style is generally characterized by a hand written script appearance while retaining the Modern Italian style. An example of this font style is the IBM Narkissim (Hebrew) family.  This IBM Subclass is not specifically reflected in the 12/87 ISO/IEC 9541-5 draft standard, though the ISO Serif Class, Modern Subclass, and Italian Specific Group would be a close approximation.

Subclass ID = 3-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 4  Clarendon Serifs

This style is a variation of the Oldstyle Serifs and the Transitional Serifs, with a mild vertical stroke contrast and bracketed serifs.  This IBM Class reflects the ISO Serif Class, Square Serif Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Clarendon

This style is generally characterized by a large x-height, with serifs and strokes of equal weight.  An example of this font style is the Allied Linotype Clarendon family. This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Clarendon Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Modern

This style is generally characterized by a large x-height, with serifs of a lighter weight than the strokes and the strokes of a lighter weight than the Traditional.  An example of this font style is the Monotype Century Schoolbook family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Clarendon Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Traditional

This style is generally characterized by a large x-height, with serifs of a lighter weight than the strokes. An example of this font style is the Monotype Century family.This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Clarendon Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : Newspaper

This style is generally characterized by a large x-height, with a simpler style of design and serifs of a lighter weight than the strokes.  An example of this font style is the Allied Linotype Excelsior Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Clarendon Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5 : Stub Serif

This style is generally characterized by a large x-height, with short stub serifs and relatively bold stems. An example of this font style is the Cheltenham Family. This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Short Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 6 : Monotone

This style is generally characterized by a large x-height, with monotone stems.  An example of this font style is the ITC Korinna Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 7 : Typewriter

This style is generally characterized by a large x-height, with moderate stroke thickness characteristic of a typewriter.  An example of this font style is the Prestige Elite Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Typewriter Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 8-14: (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 5  Slab Serifs

This style is characterized by serifs with a square transition between the strokes and the serifs (no brackets). This IBM Class reflects the ISO Serif Class, Square Serif Subclass (except the Clarendon Specific Group) as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Monotone

This style is generally characterized by a large x-height, with serifs and strokes of equal weight.  An example of this font style is the ITC Lubalin Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Humanist

This style is generally characterized by a medium x-height, with serifs of lighter weight that the strokes.  An example of this font style is the Candida Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Geometric

This style is generally characterized by a large x-height, with serifs and strokes of equal weight and a geometric (circles and lines) design.  An example of this font style is the Monotype Rockwell Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : Swiss

This style is generally characterized by a large x-height, with serifs and strokes of equal weight and an emphasis on the white space of the characters.  An example of this font style is the Allied Linotype Serifa Family. This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5 : Typewriter

This style is generally characterized by a large x-height, with serifs and strokes of equal but moderate thickness, and a geometric design.  An example of this font style is the IBM Courier Family.  This IBM Subclass reflects the ISO Serif Class, Square Serif Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 6-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 6  (reserved for future use)

This class ID is reserved for future assignment, and shall not be used without formal assignment by IBM.

Class ID = 7  Freeform Serifs

This style includes serifs, but which expresses a design freedom that does not generally fit within the other serif design classifications.  This IBM Class reflects the remaining ISO Serif Class subclasses as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Modern

This style is generally characterized by a medium x-height, with light contrast in the strokes and a round full design.  An example of this font style is the ITC Souvenir Family.  This IBM Subclass is not reflected in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 8  Sans Serif

This style includes most basic letter forms (excluding Scripts and Ornamentals) that do not have serifs on the strokes.  This IBM Class reflects the ISO Sans Serif Class as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : IBM Neo-grotesque Gothic

This style is generally characterized by a large x-height, with uniform stroke width and a simple one story design distinguished by a medium resolution, hand tuned, bitmap rendition of the more general Neo-grotesque Gothic Subclass.  An example of this font style is the IBM Sonoran Sans Serif family.  This IBM Subclass reflects the ISO Sans Serif Class, Gothic Subclass, and Neo-grotesque Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Humanist

This style is generally characterized by a medium x-height, with light contrast in the strokes and a classic Roman letterform.  An example of this font style is the Allied Linotype Optima family.  This IBM Subclass reflects the ISO Sans Serif Class, Humanist Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Low-x Round Geometric

This style is generally characterized by a low x-height, with monotone stroke weight and a round geometric design. An example of this font style is the Fundicion Tipograficia Neufville Futura family.  This IBM Subclass reflects the ISO Sans Serif Class, Geometric Subclass, Round Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : High-x Round Geometric

This style is generally characterized by a high x-height, with uniform stroke weight and a round geometric design.  An example of this font style is the ITC Avant Garde Gothic family.  This IBM Subclass reflects the ISO Sans Serif Class, Geometric Subclass, Round Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5 : Neo-grotesque Gothic

This style is generally characterized by a high x-height, with uniform stroke width and a simple one story design.  An example of this font style is the Allied Linotype Helvetica family.  This IBM Subclass reflects the ISO Sans Serif Class, Gothic Subclass, Neo-grotesque Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 6 : Modified Neo-grotesque Gothic

This style is similar to the Neo-grotesque Gothic style, with design variations to the G and Q.  An example of this font style is the Allied Linotype Univers family.  This IBM Subclass reflects the ISO Sans Serif Class, Gothic Subclass, Neo-grotesque Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 7-8 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 9 : Typewriter Gothic

This style is similar to the Neo-grotesque Gothic style, with moderate stroke thickness characteristic of a typewriter.  An example of this font style is the IBM Letter Gothic family.  This IBM Subclass reflects the ISO Sans Serif Class, Gothic Subclass, Typewriter Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 10 : Matrix

This style is generally a simple design characteristic of a dot matrix printer.  An example of this font style is the IBM Matrix Gothic family.  This IBM Subclass is not reflected in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 11-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 9  Ornamentals

This style includes highly decorated or stylized character shapes that are typically used in headlines.  This IBM Class reflects the ISO Ornamental Class and the ISO Blackletter Class as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Engraver

This style is characterized by fine lines or lines engraved on the stems.  An example of this font style is the Copperplate family.  This IBM Subclass reflects the ISO Ornamental Class and Inline Subclass, or the Serif Class and Engraving Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Black Letter

This style is generally based upon the printing style of the German monasteries and printers of the 12th to 15th centuries.  An example of this font style is the Old English family.  This IBM Subclass reflects the ISO Blackletters Class as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Decorative

This style is characterized by ornamental designs (typically from nature, such as leaves, flowers, animals, etc.) incorporated into the stems and strokes of the characters.  An example of this font style is the Saphire family.  This IBM Subclass reflects the ISO Ornamental Class and Decorative Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : Three Dimensional

This style is characterized by a three dimensional (raised) appearance of the characters created by shading or geometric effects.  An example of this font style is the Thorne Shaded family.  This IBM Subclass reflects the ISO Ornamental Class and Three Dimensional Subclass as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 10  Scripts

This style includes those typefaces that are designed to simulate handwriting.  This IBM Class reflects the ISO Script Class and Uncial Class as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1 : Uncial

This style is characterized by unjoined (nonconnecting) characters that are generally based on the hand writing style of Europe in the 6th to 9th centuries.  An example of this font style is the Libra family.  This IBM Subclass reflects the ISO Uncial Class as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 2 : Brush Joined

This style is characterized by joined (connecting) characters that have the appearance of being painted with a brush, with moderate contrast between thick and thin strokes.  An example of this font style is the Mistral family.  This IBM Subclass reflects the ISO Script Class, Joined Subclass, and Informal Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 3 : Formal Joined

This style is characterized by joined (connecting) characters that have a printed (or drawn with a stiff brush) appearance with extreme contrast between the thick and thin strokes.  An example of this font style is the Coronet family.  This IBM Subclass reflects the ISO Script Class, Joined Subclass, and Formal Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4 : Monotone Joined

This style is characterized by joined (connecting) characters that have a uniform appearance with little or no contrast in the strokes.  An example of this font style is the Kaufmann family.  This IBM Subclass reflects the ISO Script Class, Joined Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 5 : Calligraphic

This style is characterized by beautifully hand drawn, unjoined (non-connecting) characters that have an appearance of being drawn with a broad edge pen.  An example of this font style is the Thompson Quillscript family.  This IBM Subclass reflects the ISO Script Class, Unjoined Subclass, and Calligraphic Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 6 : Brush Unjoined

This style is characterized by unjoined (non-connecting) characters that have the appearance of being painted with a brush, with moderate contrast between thick and thin strokes.  An example of this font style is the Saltino family.  This IBM Subclass reflects the ISO Script Class, Unjoined Subclass, and Brush Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 7 : Formal Unjoined

This style is characterized by unjoined (non-connecting) characters that have a printed (or drawn with a stiff brush) appearance with extreme contrast between the thick and thin strokes.  An example of this font style is the Virtuosa family.  This IBM Subclass reflects the ISO Script Class, Unjoined Subclass, and Formal Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 8 : Monotone Unjoined

This style is characterized by unjoined (non-connecting) characters that have a uniform appearance with little or no contrast in the strokes.  An example of this font style is the Gilles Gothic family.  This IBM Subclass reflects the ISO Script Class, Unjoined Subclass, and Monotone Specific Group as documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 9-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 11  (reserved for future use)

This class ID is reserved for future assignment, and shall not be used without formal assignment by IBM.

Class ID = 12  Symbolic

This style is generally design independent, making it suitable for Pi and special characters (icons, dingbats, technical symbols, etc.) that may be used equally well with any font.  This IBM Class reflects various ISO Specific Groups, as noted below and documented in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 0 : No Classification

This subclass ID is used to indicate that the associated font has no design sub-classification or that the design sub-classification is not of significance to the creator or user of the font resource.

Subclass ID = 1-2 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 3 : Mixed Serif

This style is characterized by either both or a combination of serif and sans serif designs on those characters of the font for which design is important (e.g., superscript and subscript characters, numbers, copyright or trademark symbols, etc.).  An example of this font style is found in the IBM Symbol family.  This IBM Subclass is not reflected in the 12/87 ISO/IEC 9541-5 draft standard.

Subclass ID = 4-5 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 6 : Oldstyle Serif

This style is characterized by a Oldstyle Serif IBM Class design on those characters of the font for which design is important (e.g., superscript and subscript characters, numbers, copyright or trademark symbols, etc.). An example of this font style is found in the IBM Sonoran Pi Serif family.  This IBM Subclass is not directly reflected in the 12/87 ISO/IEC 9541-5 draft standard, though it is indirectly by the ISO Serif Class and Legibility Subclass (implies that all characters of the font exhibit the design appearance, while only a subset of the characters actually exhibit the design).

Subclass ID = 7 : Neo-grotesque Sans Serif

This style is characterized by a Neo-grotesque Sans Serif IBM Font Class and Subclass design on those characters of the font for which design is important (e.g., superscript and subscript characters, numbers, copyright or trademark symbols, etc.).  An example of this font style is found in the IBM Sonoran Pi Sans Serif family.  This IBM Subclass is not directly reflected in the 12/87 ISO/IEC 9541-5 draft standard, though it is indirectly by the ISO Sans Serif Class and Gothic Subclass (implies that  all characters of the font exhibit the design appearance, while only a subset of the characters actually exhibit the design).

Subclass ID = 8-14 : (reserved for future use)

These subclass IDs are reserved for future assignment, and shall not be used without formal assignment by IBM.

Subclass ID = 15 : Miscellaneous

This subclass ID is used for miscellaneous designs of the associated design class that are not covered by another Subclass.

Class ID = 13  Reserved

Class ID = 14  Reserved

Panose

Format:	10 byte array

Title:	PANOSE classification number

International:	Additional specifications are required for PANOSE to classify non Latin character sets.

Description:	This 10 byte series of numbers are used to describe the visual characteristics of a given typeface.  These characteristics are then used to associate the font with other fonts of similar appearance having different names.  The variables for each digit are listed below.  The specifications for each variable can be obtained in the specification PANOSE v2.0 Numerical Evaluation from Microsoft or Elseware Corporation.

Comments:	The PANOSE definition contains ten digits each of which currently describes up to sixteen variations. Windows v3.1 uses bFamilyType, bSerifStyle and bProportion in the font mapper to determine family type.  It also uses bProportion to determine if the font is monospaced.

Type	Name
BYTE	bFamilyType;
BYTE	bSerifStyle;
BYTE	bWeight;
BYTE	bProportion;
BYTE	bContrast;
BYTE	bStrokeVariation;
BYTE	bArmStyle;
BYTE	bLetterform;
BYTE	bMidline;
BYTE	bXHeight;
1.  Family Kind (6 variations)

0 	= Any

1 	= No Fit

2 	= Text and Display

3 	= Script

4 	= Decorative

5 	= Pictorial

2.  Serif Style (16 variations)

0	= Any

1	= No Fit

2	= Cove

3	= Obtuse Cove

4	= Square Cove

5	= Obtuse Square Cove

6	= Square

7	= Thin

8	= Bone

9	= Exaggerated

10	= Triangle

11	= Normal Sans

12	= Obtuse Sans

13	= Perp Sans

14	= Flared

15	= Rounded

3. Weight (12 variations)

0	= Any

1	= No Fit

2	= Very Light

3	= Light

4	= Thin

5	= Book

6	= Medium

7	= Demi

8	= Bold

9	= Heavy

10	= Black

11	= Nord

4.  Proportion (10 variations)

0	= Any

1	= No Fit

2	= Old Style

3	= Modern

4	= Even Width

5	= Expanded

6	= Condensed

7	= Very Expanded

8	= Very Condensed

9	= Monospaced

5.  Contrast (10 variations)

0	= Any

1	= No Fit

2	= None

3	= Very Low

4	= Low

5	= Medium Low

6	= Medium

7	= Medium High

8	= High

9	= Very High

6.  Stroke Variation (9 variations)

0	= Any

1	= No Fit

2	= Gradual/Diagonal

3	= Gradual/Transitional

4	= Gradual/Vertical

5	= Gradual/Horizontal

6	= Rapid/Vertical

7	= Rapid/Horizontal

8	= Instant/Vertical

7.  Arm Style (12 variations)

0	= Any

1	= No Fit

2	= Straight Arms/Horizontal

3	= Straight Arms/Wedge

4	= Straight Arms/Vertical

5	= Straight Arms/Single Serif

6	= Straight Arms/Double Serif

7	= Non-Straight Arms/Horizontal

8	= Non-Straight Arms/Wedge

9	= Non-Straight Arms/Vertical

10	= Non-Straight Arms/Single Serif

11	= Non-Straight Arms/Double Serif

8.  Letterform (16 variations)

0	= Any

1	= No Fit

2	= Normal/Contact

3	= Normal/Weighted

4	= Normal/Boxed

5	= Normal/Flattened

6	= Normal/Rounded

7	= Normal/Off Center

8	= Normal/Square

9	= Oblique/Contact

10	= Oblique/Weighted

11	= Oblique/Boxed

12	= Oblique/Flattened

13	= Oblique/Rounded

14	= Oblique/Off Center

15	= Oblique/Square

9.  Midline (14 variations)

0	= Any

1	= No Fit

2	= Standard/Trimmed

3	= Standard/Pointed

4	= Standard/Serifed

5	= High/Trimmed

6	= High/Pointed

7	= High/Serifed

8	= Constant/Trimmed

9	= Constant/Pointed

10	= Constant/Serifed

11	= Low/Trimmed

12	= Low/Pointed

13	= Low/Serifed

10. X-height (8 variations)

0	= Any

1	= No Fit

2	= Constant/Small

3	= Constant/Standard

4	= Constant/Large

5	= Ducking/Small

6	= Ducking/Standard

7	= Ducking/Large

ulCharRange

Format:	16-byte unsigned long array (4 elements)

Title:	Character Range

Description:	This field is split conceptually into two bit fields of 96 and 32 bits each. The low 96 bits are used to specify the Unicode blocks encompassed by the font file.  The high 32 bits are used to specify the character or script sets that are covered by the font file. The actual bit assignments are not yet completed; presently, all bits must be set to zero (0).

achVendID

Format	4-byte character array

Title:	Font Vendor Identification

Description:	The four character identifier for the vendor of the given type face.

Comments:	This is not the royalty owner of the original artwork. This is the company responsible for the marketing and distribution of the typeface that is being classified. It is reasonable to assume that there will be 6 vendors of ITC Zapf Dingbats for use on desktop platforms in the near future (if not already).  It is also likely that the vendors will have other inherent benefits in their fonts (more kern pairs, unregularized data, hand hinted, etc.). This identifier will allow for the correct vendors type to be used over another, possibly inferior, font file. These id's are assigned by Microsoft; the currently assigned vendor id's are:

Vendor ID	Vendor Name
'AGFA'	AGFA Compugraphic
'Adbe'	Adobe
'Appl'	Apple
'Alts'	Altsys
'B&H '	Bigelow & Holmes
'Bert'	Berthold
'Bits'	Bitstream
'DTC '	Digital Typeface Corp.
'HP  '	Hewlett-Packard
'IBM '	IBM
'KATF'	Kingsley/ATF
'Lans'	Lanston Type Co., Ltd.
'LETR'	Letraset
'Lino'	Linotype
'Mono'	Monotype
'Mlgc'	Micrologic Software
'MS  '	Microsoft
'QMSI'	QMS/Imagen
'SWFT'	Swfte International
'URW '	URW
'ZSFT'	ZSoft
fsSelection

Format:	2-byte bit field.

Title:	Font selection flags.

Description:	Contains information concerning the nature of the font patterns, as follows:

Bit #	macStyle bit	C definition	Description
0	bit 1	ITALIC	Font contains Italic characters, otherwise they are upright.
1		UNDERSCORE	Characters are underscored.
2		NEGATIVE	Characters have their foreground and  background reversed.
3		OUTLINED	Outline (hollow) characters, otherwise they are solid.
4		STRIKEOUT	Characters are overstruck.
5	bit 0	BOLD	Characters are emboldened.
6		REGULAR	Characters are in the standard weight/style for the font.
Comments:	All undefined bits must be zero.

This field contains information on the original design of the font.  Bits 0 & 5 can be used to determine if the font was designed with these features or whether some type of machine simulation was performed on the font to achieve this appearance. Bits 1-4 are rarely used bits that indicate the font is primarily a decorative or special purpose font.

If bit 6 is set, then bits 0 and 5 must be clear, else the behavior is undefined. As noted above, the settings of bits 0 and 1 must be reflected in the macStyle bits in the 'head' table. While bit 6 on implies that bits 0 and 1 of macStyle are clear (along with bits 0 and 5 of fsSelection), the reverse is not true. Bits 0 and 1 of macStyle (and 0 and 5 of fsSelection) may be clear and that does not give any indication of whether or not bit 6 of fsSelection is clear (e.g., Arial Light would have all bits cleared; it is not the regular version of Arial).

usFirstCharIndex

Format:	2-byte USHORT

Description:	The minimum Unicode index in this font. This assumes there is only one platform id 3 cmap subtable (either encoding id 0 or 1); for a platform id 3, encoding id 1 font this value should be 0x0020.

usLastCharIndex

Format:	2-byte USHORT

Description:	The maximum Unicode index in this font. This assumes there is only one platform id 3 cmap subtable (either encoding id 0 or 1); for a platform id 3, encoding id 3 font this value should be 0xf002.

sTypoAscender

Format:	2-byte SHORT

Description:	The typographic ascender for this font. Remember that this is not the same as the Ascender value in the 'hhea' table, which Apple defines in a far different manner. One good source for usTypoAscender is the Ascender value from an AFM file.

The suggested useage for usTypoAscender is that it be used in conjunction with unitsPerEm to compute a typographically correct default line spacing. The goal is to free applications from Macintosh or Windows-specific metrics which are constrained by backward compatability requirements. These new metrics, when combined with the character design widths, will allow applications to lay out documents in a typographically correct and portable fashion. These metrics will be exposed through Windows APIs. Macintosh applications will need to access the 'sfnt' resource and parse it to extract this data from the 'OS/2 table (unless Apple exposes the 'OS/2' table through a new API).

sTypoDescender

Format:	2-byte SHORT

Description:	The typographic descender for this font. Remember that this is not the same as the Descender value in the 'hhea' table, which Apple defines in a far different manner. One good source for usTypoDescender is the Descender value from an AFM file.

The suggested useage for usTypoDescender is that it be used in conjunction with unitsPerEm to compute a typographically correct default line spacing. The goal is to free applications from Macintosh or Windows-specific metrics which are constrained by backward compatability requirements. These new metrics, when combined with the character design widths, will allow applications to lay out documents in a typographically correct and portable fashion. These metrics will be exposed through Windows APIs. Macintosh applications will need to access the 'sfnt' resource and parse it to extract this data from the 'OS/2 table (unless Apple exposes the 'OS/2' table through a new API).

sTypoLineGap

Format:	2-byte SHORT

Description:	The typographic line gap for this font. Remember that this is not the same as the LineGap value in the 'hhea' table, which Apple defines in a far different manner.

The suggested useage for usTypoLineGap is that it be used in conjunction with unitsPerEm to compute a typographically correct default line spacing. Typical values average 7-10% of units per em. The goal is to free applications from Macintosh or Windows-specific metrics which are constrained by backward compatability requirements (see Appendix D). These new metrics, when combined with the character design widths, will allow applications to lay out documents in a typographically correct and portable fashion. These metrics will be exposed through Windows APIs. Macintosh applications will need to access the 'sfnt' resource and parse it to extract this data from the 'OS/2 table (unless Apple exposes the 'OS/2' table through a new API).

usWinAscent

Format:	2-byte USHORT

Description:	The ascender metric for Windows. This, too, is distinct from Apple's Ascender value and from the usTypoAscender values. usWinAscent is computed as the yMax for all characters in the Windows ANSI character set. usTypoAscent is used to compute the Windows font height and default line spacing. For platform 3 encoding 0 fonts, it is the same as yMax.

usWinDescent

Format:	2-byte USHORT

Description:	The descender metric for Windows. This, too, is distinct from Apple's Descender value and from the usTypoDescender values. usWinDescent is computed as the -yMin for all characters in the Windows ANSI character set. usTypoAscent is used to compute the Windows font height and default line spacing. For platform 3 encoding 0 fonts, it is the same as -yMin.


'post' - PostScript

This table contains additional information needed to use TrueType fonts on PostScript printers. This includes data for the FontInfo dictionary entry and the PostScript names of all the glyphs.

The table begins as follows:

Type	Name	Description
Fixed	Format Type	0x00010000 for format 1.0, 0x00020000 for format 2.0, and so on...
Fixed	italicAngle	Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward)
FWord	underlinePosition	Suggested values for the underline position.
FWord	underlineThickness	Suggested values for the underline thickness.
ULONG	isFixedPitch	Set to 0 if the font is proportionally spaced, non-zero if the font is not proportionally spaced (i.e. monospaced).
ULONG	minMemType42	Minimum memory usage when a TrueType font is downloaded.
ULONG	maxMemType42	Maximum memory usage when a TrueType font is downloaded.
ULONG	minMemType1	Minimum memory usage when a TrueType font is downloaded as a Type 1 font.
ULONG	maxMemType1	Maximum memory usage when a TrueType font is downloaded as a Type 1 font.

The last four entries in the table are present because PostScript drivers can do better memory management if the virtual memory (VM) requirements of a downloadable TrueType font are known before the font is downloaded. This information should be supplied if known. If it is not known, set the value to zero. The driver will still work but will be less efficient.

Maximum memory usage is minimum memory usage plus maximum runtime memory use. Maximum runtime memory use depends on the maximum band size of any bitmap potentially rasterized by the TrueType font scaler. Runtime memory usage could be calculated by rendering characters at different point sizes and comparing memory use.

How to calculate VM usage

The memory usage of a downloaded TrueType font will vary with whether it is defined as a TrueType or Type 1 font on the printer. Minimum memory usage can be calculated by calling VMStatus, downloading the font, and calling VMStatus a second time.

If the format is 1.0 or 3.0, the table ends here. The additional entries for formats 2.0 and 2.5 are shown below.

Format 1.0

This TrueType font file contains exactly the 258 glyphs in the standard Macintosh TrueType font file in the order specified in Appendix C, Standard Macintosh Character Set to UGL. As a result, the glyph names are taken from the system with no storage required by the font.

Format 2.0

This is the format required by Microsoft fonts.

Type	Description
USHORT	Number of glyphs (this is the same as numGlyphs in 'maxp' table).
USHORT	glyphNameIndex[numGlyphs].
CHAR	Glyph names with length bytes [variable] (a Pascal string).
This TrueType font file contains glyphs not in the standard Macintosh set or the ordering of the glyphs in the TrueType font file is non-standard (again, for the Macintosh). The glyph name array maps the glyphs in this font to name index. If the name index is between 0 and 257, treat the name index as a glyph index in the Macintosh standard order. If the name index is between 258 and 32767, then subtract 258 and use that to index into the list of Pascal strings at the end of the table. Thus a given font may map some of its glyphs to the standard glyph names, and some to its own names.

Index numbers 32768 through 65535 are reserved for future use.  If you do not want to associate a PostScript name with a particular glyph, use index number 0 which points the name .notdef.

Format 2.5

This format provides a space saving table for fonts which contain a pure subset of, or a simple reordering of, the standard Macintosh glyph set.

Type	Description
CHAR	offset[numGlyphs]
This format is useful for font files that contain only glyphs in the standard Macintosh glyph set but which have those glyphs arranged in a non-standard order or which are missing some glyphs. The table contains one byte for each glyph in the font file. The byte is treated as a signed offset that maps the glyph index used in this font into the standard glyph index. In other words, assuming that the 'sfnt' contains the three glyphs A, B, and C which are the 37th, 38th, and 39th glyphs in the standard ordering, the 'post' table would contain the bytes +36, +36, +36.

Format 3.0

This format makes it possible to create a special font that is not burdened with a large 'post' table set of glyph names.

This format specifies that no PostScript name information is provided for the glyphs in this 'font file. The printing behavior this format on PostScript printers is unspecified, except that it should not result in a fatal or unrecoverable error. Some drivers may print nothing, other drivers may attempt to print using a default naming scheme.

Windows v3.1 makes use of the italic angle value in the 'post' table but does not actually require any glyph names to be stored as Pascal strings .


'cvt ' - Control Value Table

This table contains a list of values that can be referenced by instructions. They can be used, among other things, to control characteristics for different glyphs.

Type	Description
FWord[ n ]	List of n values referenceable by instructions.


'fpgm' - Font Program

This table is similar to the CVT Program, except that it is only run once, when the font is first used. It is used only for FDEFs and IDEFs.  Thus the CVT Program need not contain function definitions.  However, the CVT Program may redefine existing FDEFs or IDEFs.

This table is optional.

Type	Description
BYTE[ n ]	Instructions


'hdmx' - Horizontal Device Metrics

The Horizontal Device Metrics table stores integer advance widths scaled to particular pixel sizes.  This allows the font manager to build integer width tables without calling the scaler for each glyph.  Typically this table contains only selected screen sizes. This table is sorted by pixel size. The checksum for this table applies to both subtables listed.

Note that for non-square pixel grids (for example, on an EGA), the character width (in pixels) will be used to determine which device record to use. For example, a 12 point character on an EGA (resolution of 72x96) would be 12 pixels high, and 16 pels wide, and the hdmx device record for 16 pixel characters would be used.

If bit 2 of the flag field in the 'head' table is not set, then it is assumed that the font scales linearly; in this case an 'hdmx' table is not necessary and should be not be built. If bit 2 of the flag field is set, then one or more glyphs in the font are assumed to scale nonlinearly. In this case, performance can be improved by including the 'hdmx' table with one or more important DeviceRecord's for important sizes. Please see Appendix D for more detailed recommendations.

The table begins as follows:

Type	Description
USHORT	Table version number (starts at 0)
SHORT	Number of device records.
LONG	Size of a device record, long aligned.
DeviceRecord	Records[number of device records].

Each DeviceRecord for format 0 looks like this.

Type	Description
BYTE	Pixel size for following widths (as ppem).
BYTE	Maximum width.
BYTE	Widths[numGlyphs] (numGlyphs is from the 'maxp' table).
Each DeviceRecord is padded with 0's to make it long word aligned.

Each Width value is the width of the particular glyph, in pixels, at the pixels per em (ppem) size listed at the start of the DeviceRecord.

The ppem sizes are measured along the y axis.


'kern'- Kerning

The kerning table contains the values that control the intercharacter spacing for the glyphs in a font. There is currently no system level support for kerning (other than returning the kern pairs and kern values).

Each subtable varies in format, and can contain information for vertical or horizontal text, and can contain kerning values or minimum values. Kerning values are used to adjust inter-character spacing, and minimum values are used to limit the amount of adjustment that the scaler applies by the combination of kerning and tracking. Because the adjustments are additive, the order of the subtables containing kerning values is not important. However, tables containing minimum values should usually be placed last, so that they can be used to limit the total effect of other subtables.

The kerning table in the TrueType font file has a header, which contains the format number and the number of subtables present, and the subtables themselves.

Type	Field	Description
USHORT	version	Table version number (starts at 0)
USHORT	nTables	Number of subtables in the kerning table.
Kerning subtables will share the same header format. This header is used to identify the format of the subtable and the kind of information it contains:

Type	Field	Description
USHORT	version	Kern subtable version number
USHORT	length	Length of the subtable, in bytes (including this header).
USHORT	coverage	What type of information is contained in this table.
The coverage field is divided into the following sub-fields, with sizes given in bits:

Sub-field	Bits #'s	Size	Description
horizontal	0	1	1 if table has horizontal data, 0 if vertical.
minimum	1	1	If this bit is set to 1, the table has minimum values. If set to 0, the table has kerning values.
cross-stream	2	1	If set to 1, kerning is perpendicular to the flow of the text.  If the text is normally written horizontally, kerning will be done in the up and down directions. If kerning values are positive, the text will be kerned upwards; if they are negative, the text will be kerned downwards. If the text is normally written vertically, kerning will be done in the left and right directions. If kerning values are positive, the text will be kerned to the right; if they are negative, the text will be kerned to the left. The value 0x8000 in the kerning data resets the cross-stream kerning back to 0.
override	3	1	If this bit is set to 1 the value in this table should replace the value currently being accumulated.
reserved1	4-7	4	Reserved. This should be set to zero.
format	8-15	8	Format of the subtable. Only formats 0 and 2 have been defined. Formats 1 and 3 through 255 are reserved for future use.
Format 0

This is the only format that will be properly interpreted by Windows and OS/2.

This subtable is a sorted list of kerning pairs and values. The list is preceded by information which makes it possible to make an efficient binary search of the list:

Type	Field	Description
USHORT	nPairs	This gives the number of kerning pairs in the table.
USHORT	searchRange	The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the table.
USHORT	entrySelector	This is calculated as log2 of the largest power of two less than or equal to the value of nPairs. This value indicates how many iterations of the search loop will have to be made. (For example, in a list of eight items, there would have to be three iterations of the loop).
USHORT	rangeShift	The value of nPairs minus the largest power of two less than or equal to nPairs, and then multiplied by the size in bytes of an entry in the table.
This is followed by the list of kerning pairs and values. Each has the following format:

Type	Field	Description
USHORT	left	The glyph index for the left-hand glyph in the kerning pair.
USHORT	right	The glyph index for the right-hand glyph in the kerning pair.
FWord	value	The kerning value for the above pair, in FUnits. If this value is greater than zero, the characters will be moved apart. If this value is less than zero, the character will be moved closer together.
The left and right halves of the kerning pair make an unsigned 32-bit number, which is then used to order the kerning pairs numerically.

A binary search is most efficiently coded if the search range is a power of two. The search range can be reduced by half by shifting instead of dividing. In general, the number of kerning pairs, nPairs, will not be a power of two. The value of the search range, searchRange, should be the largest power of two less than or equal to nPairs. The number of pairs not covered by searchRange (that is, nPairs - searchRange) is the value rangeShift.

Windows v3.1 does not make use of the 'kern' data other than to expose it to applications through the GetFontData() API.

Format 2

This subtable is a two-dimensional array of kerning values. The glyphs are mapped to classes, using a different mapping for left- and right-hand glyphs. This allows glyphs that have similar right- or left-side shapes to be handled together. Each similar right- or left-hand shape is said to be single class.

Each row in the kerning array represents one left-hand glyph class, each column represents one right-hand glyph class, and each cell contains a kerning value. Row and column 0 always represent glyphs that do not kern and contain all zeros.

The values in the right class table are stored pre-multiplied by the number of bytes in a single kerning value, and the values in the left class table are stored pre-multiplied by the number of bytes in one row. This eliminates needing to multiply the row and column values together to determine the location of the kerning value. The array can be indexed by doing the right- and left-hand class mappings, adding the class values to the address of the array, and fetching the kerning value to which the new address points.

The header for the simple array has the following format:

Type	Field	Description
USHORT	rowWidth	The width, in bytes, of a row in the table.
USHORT	leftClassTable	Offset from beginning of this subtable to left-hand class table.
USHORT	rightClassTable	Offset from beginning of this subtable to right-hand class table.
USHORT	array	Offset from beginning of this subtable to the start of the kerning array.
Each class table has the following header:

Type	Field	Description
USHORT	firstGlyph	First glyph in class range.
USHORT	nGlyphs	Number of glyph in class range.
This header is followed by nGlyphs number of class values, which are in USHORT format. Entries for glyphs that don't participate in kerning should point to the row or column at position zero.

The array itself is a left by right array of kerning values, which are FWords, where left is the number of left-hand classes and R is the number of right-hand classes. The array is stored by row.

Note that this format is the quickest to process since each lookup requires only a few index operations. The table can be quite large since it will contain the number of cells equal to the product of the number of right-hand classes and the number of left-hand classes, even though many of these classes do not kern with each other.


'LTSH' - Linear Threshold

There are noticeable improvements to fonts on the screen when instructions are carefully applied to the sidebearings. The gain in readability is offset by the necessity for the OS to grid fit the glyphs in order to find the actual advance width for the glyphs (since instructions may be moving the sidebearing points). TrueType already has one mechanism to side step the speed issues: the 'hdmx' table, where precomputed advance widths may be saved for selected ppem sizes. The 'LTSH' table (Linear ThreSHold) is a second, complementary method.

The LTSH table defines the point at which it is reasonable to assume linearly scaled advance widths on a glyph-by-glyph basis. This table should not be included unless bit 4 of the flags field in the 'head' table is set. The criteria for linear scaling is:

a. (ppem size is ≥ 50) AND (difference between the rounded linear width and the rounded instructed width ≤ 2% of the rounded linear width)

or b. Linear width == Instructed width

The LTSH table records the ppem for each glyph at which the scaling becomes linear again, despite instructions effecting the advance width. It is a requirement that, at and above the recorded threshold size, the glyph remain linear in its scaling (i.e., not legal to set threshold at 55 ppem if glyph becomes non-linear again at 90 ppem). The format for the table is:

Type	Name	Description
USHORT	version	Version number (starts at 0).
USHORT	numGlyphs	Number of glyphs (from numGlyphs in 'maxp' table).
UINT8	yPels[numGlyphs]	The vertical pel height at which the glyph can be assumed to scale linearly. On a per glyph basis.
Note that glyphs which do not have instructions on their sidebearings should have yPels = 1; i.e., always scales linearly.


'prep' - Control Value Program

The Control Value Program consists of a set of TrueType instructions that will be executed whenever the font or point size or transformation matrix change and before each glyph is interpreted. Any instruction is legal in the CVT Program but since no glyph is associated with it, instructions intended to move points within a particular glyph outline cannot be used in the CVT Program. The name 'prep' is anachronistic.

Type	Description
BYTE[ ]	Set of instructions executed whenever point size or font or transformation change


'VDMX' - Vertical Device Metrics

Under Windows, the usWinAscent and usWinDescent values from the 'OS/2' table will be used to determine the maximum black height for a font at any given size. Windows calls this distance the Font Height. Because TrueType instructions can lead to Font Heights that differ from the actual scaled and rounded values, basing the Font Height strictly on the yMax and yMin can result in "lost pixels". Windows will clip any pixels that extend above the yMax or below the yMin. In order to avoid grid fitting the entire font to determine the correct height, the VDMX table has been defined.

The VDMX table consists of a header followed by groupings of VDMX records:

Type	Name	Description
USHORT	version	Version number (starts at 0).
USHORT	numRecs	Number of VDMX groups present
USHORT	numRatios	Number of aspect ratio groupings
Ratios	ratRange[numRatios]	Ratio ranges (see below for more info)
USHORT	offset[numRatios]	Offset from start of this table to the VDMX group for this ratio range.
Vdmx	groups	The actual VDMX groupings (documented below)
struct	Ratios {

BYTE bCharSet;	/* Character set (see below) */

BYTE xRatio;	/* Value to use for x-Ratio */

BYTE yStartRatio;	/* Starting y-Ratio value */

BYTE yEndRatio	/* Ending y-ratio value */

}

Ratios are set up as follows:

For a 1:1 aspect ratio	Ratios.xRatio = 1; Ratios.yStartRatio = 1; Ratios.yEndRatio = 1;
For 1:1 through 2:1 ratio	Ratios.xRatio = 2; Ratios.yStartRatio = 1; Ratios.yEndRatio = 2;
For 1.33:1 ratio	Ratios.xRatio = 4; Ratios.yStartRatio = 3; Ratios.yEndRatio = 3;
For all aspect ratios	Ratio.xRatio = 0; Ratio.yStartRatio = 0; Ratio.yEndRatio = 0;
All values set to zero signals the default grouping to use; if present, this must be the last Ratio group in the table. Ratios of 2:2 are the same as 1:1.

Aspect ratios are matched against the target device by normalizing the entire ratio range record based on the current X resolution and performing a range check of Y resolutions for each record after normalization. Once a match is found, the search stops. If the 0,0,0 group is encountered during the search, it is used (therefore if this group is not at the end of the ratio groupings, no group that follows it will be used). If there is not a match and there is no 0,0,0 record, then there is no VDMX data for that aspect ratio.

Note that range checks are conceptually performed as follows:

(deviceXRatio == Ratio.xRatio) && (deviceYRatio >= Ratio.yStartRatio) && (deviceYRatio <= Ratio.yEndRatio)

Each ratio grouping refers to a specific VDMX record group; there must be at least 1 VDMX group in the table.

The bCharSet value is used to denote cases where the VDMX group was computed based on a subset of the glyphs present in the font file. The currently defined values for character set are:

uCharSet	Description
0	No subset; the VDMX group applies to all glyphs in the font. This is used for symbol or dingbat fonts.
1	Windows ANSI subset; the VDMX group was computed using only the glyphs required to complete the Windows ANSI character set. Windows will ignore any VDMX entries that are not for the ANSI subset (i.e. uCharSet = 1)
VDMX groups immediately follow the table header. Each set of records (there need only be one set) has the following layout:

Type	Name	Description
USHORT	recs	Number of height records in this group
BYTE	startsz	Starting yPelHeight
BYTE	endsz	Ending yPelHeight
Vtable	entry[recs]	The VDMX records
struct	vTable {

BYTE yPelHeight;	/* yPelHeight to which values apply */

BYTE yMax;	/* yMax (in pels) for this yPelHeight */

BYTE yMin;	/* yMin (in pels) for this yPelHeight */

}

This table must appear in sorted order (sorted by yPelHeight), but need not be continous. It should have an entry for every pel height where the yMax and yMin do not scale linearly, where linearly scaled heights are defined as:

Hinted yMax and yMin are identical to scaled/rounded yMax and yMin

It is assumed that once yPelHeight reaches 255, all heights will be linear, or at least close enough to linear that it no longer matters. Please note that while the Ratios structure can only support ppem sizes up to 255, the vTable structure can support much larger pel heights (up to 65535). The choice of SHORT and USHORT for vTable is dictated by the requirement that yMax and yMin be signed values (and 127 to -128 is too small a range) and the desire to word-align the vTable elements.


'PCLT' - PCL 5 Table

The 'PCLT' table is an optional table that is not used directly by Microsoft Windows v3.1, but it is highly recommended that this table be present in all TrueType font  files.  Extra information on many of these fields can be found in the HP PCL 5 Printer Language Technical Reference Manual available from Hewlett-Packard Boise Printer Division.

The format for the table is:

Type	Name of Entry
FIXED	Version
ULONG	FontNumber
USHORT	Pitch
USHORT	xHeight
USHORT	Style
USHORT	TypeFamily
USHORT	CapHeight
USHORT	SymbolSet
CHAR	Typeface[16]
CHAR	CharacterComplement[8]
CHAR	FileName[6]
CHAR	StrokeWeight
CHAR	WidthType
BYTE	SerifStyle
BYTE	Reserved (pad)
Version

Table version number 1.0 is represented as 0x00010000.

FontNumber

This 32-bit number is segmented in two parts. The most significant bit indicates native versus converted format. Only font vendors should create fonts with this bit zeroed. The 7 next most significant bits are assigned by Hewlett-Packard Boise Printer Division to major font vendors. The least significant 24 bits are assigned by the vendor. Font vendors should attempt to insure that each of their fonts are marked with unique values.

Vendor codes:

A	Adobe Systems
B	Bitstream Inc.
C	Agfa Corporation
H	Bigelow & Holmes
L	Linotype Company
M	Monotype Corporation plc
Pitch

The width of the space in FUnits (FUnits are described by the unitsPerEm field of the 'head' table). Monospace fonts derive the width of all characters from this field.

xHeight

The height of the optical line describing the height of the lowercase x in FUnits. This might not be the same as the measured height of the lowercase x.

Style

The most significant 6 bits are reserved. The 5 next most significant bits encode structure. The next 3 most significant bits encode appearance width. The 2 least significant bits encode posture.

Structure (bits 5-9)

0	Solid (normal, black)
1	Outline (hollow)
2	Inline (incised, engraved)
3	Contour, edged (antique, distressed)
4	Solid with shadow
5	Outline with shadow
6	Inline with shadow
7	Contour, or edged, with shadow
8	Pattern filled
9	Pattern filled #1 (when more than one pattern)
10	Pattern filled #2 (when more than two patterns)
11	Pattern filled #3 (when more than three patterns)
12	Pattern filled with shadow
13	Pattern filled with shadow #1 (when more than one pattern or shadow)
14	Pattern filled with shadow #2 (when more than two patterns or shadows)
15	Pattern filled with shadow #3 (when more than three patterns or shadows)
16	Inverse
17	Inverse with border
18-31	reserved
Width (bits 2-4)

0	normal
1	condensed
2	compressed, extra condensed
3	extra compressed
4	ultra compressed
5	reserved
6	expanded, extended
7	extra expanded, extra extended
Posture (bits 0-1)

0	upright
1	oblique, italic
2	alternate italic (backslanted, cursive, swash)
3	reserved
TypeFamily

The 4 most significant bits are font vendor codes. The 12 least significant bits are typeface family codes. Both are assigned by HP Boise Division.

Vendor Codes (bits 12-15)

0	reserved
1	Agfa Corporation
2	Bitstream Inc.
3	Linotype Company
4	Monotype Corporation plc
5	Adobe Systems
6	font repackagers
7	vendors of unique typefaces
8-15	reserved
CapHeight

The height of the optical line describing the top of the uppercase H in FUnits. This might not be the same as the measured height of the uppercase H.

SymbolSet

The most significant 11 bits are the value of the symbol set "number" field. The value of the least significant 5 bits, when added to 64, is the ASCII value of the symbol set "id" field. Symbol set values are assigned by HP Boise Division. Unbound fonts, or "typefaces" should have a symbol set value of 0. See the PCL 5 Printer Language Technical Reference Manual or the PCL 5 Comparison Guide for the most recent published list of codes.

Examples

	PCL	decimal
Windows 3.1 "ANSI"	19U	629
Windows 3.0 "ANSI"	9U	309
Adobe "Symbol"	19M	621
Macintosh	12J	394
PostScript ISO Latin 1	11J	362
PostScript Std. Encoding	10J	330
Code Page 1004	9J	298
DeskTop	7J	234
TypeFace

This 16-byte ASCII string appears in the "font print" of PCL printers. Care should be taken to insure that the base string for all typefaces of a family are consistent, and that the designators for bold, italic, etc. are standardized.

Example:

Times New
Times New	Bd
Times New	It
Times New	BdIt
Courier New
Courier New	Bd
Courier New	It
Courier New	BdIt
CharacterComplement

This 8-byte field identifies the symbol collections provided by the font, each bit identifies a symbol collection and is independently interpreted. Symbol set bound fonts should have this field set to all F's (except bit 0).

Example:

DOS/PCL Complement	0xFFFFFFFF003FFFFE
Windows 3.1 "ANSI"	0xFFFFFFFF37FFFFFE
Macintosh	0xFFFFFFFF36FFFFFE
ISO 8859-1 Latin 1	0xFFFFFFFF3BFFFFFE
ISO 8859-1,2,9 Latin 1,2,5	0xFFFFFFFF0BFFFFFE
The character collections identified by each bit are as follows:

31	ASCII (supports several standard interpretations)
30	Latin 1 extensions
29	Latin 2 extensions
28	Latin 5 extensions
27	Desktop Publishing Extensions
26	Accent Extensions (East and West Europe)
25	PCL Extensions
24	Macintosh Extensions
23	PostScript Extensions
22	Code Page Extensions
The character complement field also indicates the index mechanism used with an unbound font. Bit 0 must always be cleared when the font elements are provided in Unicode order.

FileName

This 6-byte field is composed of 3 parts. The first 3 bytes are an industry standard typeface family string. The fourth byte is a treatment character, such as R, B, I. The last two characters are either zeroes for an unbound font or a two character mnemonic for a symbol set if symbol set found.

Examples:

TNRR00	Times New (text weight, upright)
TNRI00	Times New Italic
TNRB00	Times New Bold
TNRJ00	Times New Bold Italic
COUR00	Courier
COUI00	Courier Italic
COUB00	Courier Bold
COUJ00	Courier Bold Italic
Treatment Flags:

R	Text, normal, book, etc.
I	Italic, oblique, slanted, etc.
B	Bold
J	Bold Italic, Bold Oblique
D	Demibold
E	Demibold Italic, Demibold Oblique
K	Black
G	Black Italic, Black Oblique
L	Light
P	Light Italic, Light Oblique
C	Condensed
A	Condensed Italic, Condensed Oblique
F	Bold Condensed
H	Bold Condensed Italic, Bold Condensed Oblique
S	Semibold (lighter than demibold)
T	Semibold Italic, Semibold Oblique
other treatment flags are assigned over time.

StrokeWeight

This signed 1-byte field contains the PCL stroke weight value. Only values in the range -7 to 7 are valid:

-7	Ultra Thin
-6	Extra Thin
-5	Thin
-4	Extra Light
-3	Light
-2	Demilight
-1	Semilight
0	Book, text, regular, etc.
1	Semibold (Medium, when darker than Book)
2	Demibold
3	Bold
4	Extra Bold
5	Black
6	Extra Black
7	Ultra Black, or Ultra
Type designers often use interesting names for weights or combinations of weights and styles, such as Heavy, Compact, Inserat, Bold No. 2, etc. PCL stroke weights are assigned on the basis of the entire family and use of the faces. Typically, display faces don't have a "text" weight assignment.

WidthType

This signed 1-byte field contains the PCL appearance width value. The values are not directly related to those in the appearance with field of the style word above. Only values in the range -5 to 5 are valid.

-5	Ultra Compressed
-4	Extra Compressed
-3	Compressed, or Extra Condensed
-2	Condensed
0	Normal
2	Expanded
3	Extra Expanded
SerifStyle

This signed 1-byte field contains the PCL serif style value. The most significant 2 bits of this byte specify the serif/sans or contrast/monoline characterisitics of the typeface.

Bottom 6 bit values:

0	Sans Serif Square
1	Sans Serif Round
2	Serif Line
3	Serif Triangle
4	Serif Swath
5	Serif Block
6	Serif Bracket
7	Rounded Bracket
8	Flair Serif, Modified Sans
9	Script Nonconnecting
10	Script Joining
11	Script Calligraphic
12	Script Broken Letter
Top 2 bit values:

0	reserved
1	Sans Serif/Monoline
2	Serif/Contrasting
3	reserved
Reserved

Should be set to zero.


Support of Macintosh Character set
Microsoft UGL Character Set

Support of Macintosh Character set

To support the basic Macintosh Character set additional characters are needed. These will not be available to non-Apple systems or application modules; they will be located in the font file to allow the sharing of the same font file between Apple and Microsoft platforms. This requires adding the following characters/glyphs:

Apple Index	IBM GCID	Description
173	SA540000	not equal to
182	SA490000	partial differential sign
184	SA810000	repeated product
186	SA510000	integral sign
198		increment
215		lozenge
218	SP120001	division slash
	SA100000	minus (Postscript name: minus)
		french franc (Postscript name:franc)
240		apple logo
222	LF530000	latin small ligature fi
223	LF550000	latin small ligature fl
Note 1: The two last glyphs are rendering form only. There is no provision to make them available as characters to the applications. Processing of ligatures is the domain of future extensions to the GDI text drawing functions.

Note 2: With the exception of the three last characters all characters/glyphs enumerated above are a part of Unicode.  Apple character index 240 (apple logo) will not appear in Microsoft's fonts (as Apple will not grant permission for Microsoft to ship fonts with Apple's trademark); the apple logo should be mapped to the non-existing character glyph.


New UGL definition

The UGL indexes are based upon Unicode values. In addition, the description of each character or glyph is the ISO name whenever possible. Font files for Microsoft platfoms must use Unicode indicies (given here as hexadecimal values).

The PostScript names are given where they are known or defined. PostScript names for otherwise unknown characters should be based on their Unicode index. For example, the box drawing light character should be called '2500'. The only characters that are not presently assigned PostScript names are the forms characters from Unicode index 2500 thru 256c. Note that Adobe uses GCID's for unassigned PostScript names.

Unicode Index	IBM GCID	PostScript Name	Descriptive Name
ASCII

0020	SP010000	space	space
0021	SP020000	exclam	exclamation mark
0022	SP040000	quotedbl	quotation mark
0023	SM010000	numbersign	number sign
0024	SC030000	dollar	dollar sign
0025	SM020000	percent	percent sign
0026	SM030000	ampersand	ampersand
0027	SP050000	quotesingle	apostrophe
0028	SP060000	parenleft	left parenthesis
0029	SP070000	parenright	right parenthesis
002a	SM040000	asterisk	asterisk
002b	SA010000	plus	plus sign
002c	SP080000	comma	comma
002d	SP100000	hyphen	hyphen-minus
002e	SP110000	period	period
002f	SP120000	slash	slash
0030	ND100000	zero	digit zero
0031	ND010000	one	digit one
0032	ND020000	two	digit two
0033	ND030000	three	digit three
0034	ND040000	four	digit four
0035	ND050000	five	digit five
0036	ND060000	six	digit six
0037	ND070000	seven	digit seven
0038	ND080000	eight	digit eight
0039	ND090000	nine	digit nine
003a	SP130000	colon	colon
003b	SP140000	semicolon	semicolon
003c	SA030000	less	less-than sign
003d	SA040000	equal	equals sign
003e	SA050000	greater	greater-than sign
003f	SP150000	question	question mark
0040	SM050000	at	commercial at
0041	LA020000	A	latin capital letter a
0042	LB020000	B	latin capital letter b
0043	LC020000	C	latin capital letter c
0044	LD020000	D	latin capital letter d
0045	LE020000	E	latin capital letter e
0046	LF020000	F	latin capital letter f
0047	LG020000	G	latin capital letter g
0048	LH020000	H	latin capital letter h
0049	LI020000	I	latin capital letter i
004a	LJ020000	J	latin capital letter j
004b	LK020000	K	latin capital letter k
004c	LL020000	L	latin capital letter l
004d	LM020000	M	latin capital letter m
004e	LN020000	N	latin capital letter n
004f	LO020000	O	latin capital letter o
0050	LP020000	P	latin capital letter p
0051	LQ020000	Q	latin capital letter q
0052	LR020000	R	latin capital letter r
0053	LS020000	S	latin capital letter s
0054	LT020000	T	latin capital letter t
0055	LU020000	U	latin capital letter u
0056	LV020000	V	latin capital letter v
0057	LW020000	W	latin capital letter w
0058	LX020000	X	latin capital letter x
0059	LY020000	Y	latin capital letter y
005a	LZ020000	Z	latin capital letter z
005b	SM060000	bracketleft	left square bracket
005c	SM070000	backslash	backslash
005d	SM080000	bracketright	right square bracket
005e	SD150000	asciicircum	circumflex accent
005f	SP090000	underscore	underline
0060	SD130000	grave	grave accent
0061	LA010000	a	latin small letter a
0062	LB010000	b	latin small letter b
0063	LC010000	c	latin small letter c
0064	LD010000	d	latin small letter d
0065	LE010000	e	latin small letter e
0066	LF010000	f	latin small letter f
0067	LG010000	g	latin small letter g
0068	LH010000	h	latin small letter h
0069	LI010000	i	latin small letter i
006a	LJ010000	j	latin small letter j
006b	LK010000	k	latin small letter k
006c	LL010000	l	latin small letter l
006d	LM010000	m	latin small letter m
006e	LN010000	n	latin small letter n
006f	LO010000	o	latin small letter o
0070	LP010000	p	latin small letter p
0071	LQ010000	q	latin small letter q
0072	LR010000	r	latin small letter r
0073	LS010000	s	latin small letter s
0074	LT010000	t	latin small letter t
0075	LU010000	u	latin small letter u
0076	LV010000	v	latin small letter v
0077	LW010000	w	latin small letter w
0078	LX010000	x	latin small letter x
0079	LY010000	y	latin small letter y
007a	LZ010000	z	latin small letter z
007b	SM110000	braceleft	left curly bracket
007c	SM130000	bar	vertical line
007d	SM140000	braceright	right curly bracket
007e	SD190000	asciitilde	tilde
Latin-1, also corresponding to ISO 8859-1 or ANSI

00a0	SP300000	nbspace	no-break space
00a1	SP030000	exclamdown	inverted exclamation mark
00a2	SC040000	cent	cent sign
00a3	SC020000	sterling	pound sign
00a4	SC010000	currency	currency sign
00a5	SC050000	yen	yen sign
00a6	SM650000	brokenbar	broken bar
00a7	SM240000	section	section sign
00a8	SD170000	dieresis	diaeresis
00a9	SM520000	copyright	copyright sign
00aa	SM210000	ordfeminine	feminine ordinal indicator
00ab	SP170000	guillemotleft	left guillemet
00ac	SM660000	logicalnot	not sign
00ad	SP320000	sfthyphen	soft hyphen
00ae	SM530000	registered	registered trade mark sign
00af	SM150000	overstore	macron, overline
00b0	SM190000	degree	degree sign
00b1	SA020000	plusminus	plus-minus sign
00b2	ND021000	twosuperior	superscript two
00b3	ND031000	threesuperior	superscript three
00b4	SD110000	acute	acute accent
00b5	SM170000	mu	micro sign
00b6	SM250000	paragraph	paragraph sign
00b7	SD630000	middot	middle dot, kana conjoctive
00b8	SD410000	cedilla	cedilla
00b9	ND011000	onesuperior	superscript one
00ba	SM200000	ordmasculine	masculine ordinal indicator
00bb	SP180000	guillemotright	right guillemet
00bc	NF040000	onequarter	vulgar fraction one quarter
00bd	NF010000	onehalf	vulgar fraction one half
00be	NF050000	threequarters	vulgar fraction three quarters
00bf	SP160000	questiondown	inverted question mark
00c0	LA140000	Agrave	latin capital letter a with grave accent
00c1	LA120000	Aacute	latin capital letter a with acute accent
00c2	LA160000	Acircumflex	latin capital letter a with circumflex accent
00c3	LA200000	Atilde	latin capital letter a with tilde
00c4	LA180000	Adieresis	latin capital letter a with diaeresis
00c5	LA280000	Aring	latin capital letter a with ring above
00c6	LA520000	AE	latin capital letter a with e
00c7	LC420000	Ccedilla	latin capital letter c with cedilla
00c8	LE140000	Egrave	latin capital letter e with grave accent
00c9	LE120000	Eacute	latin capital letter e with acute accent
00ca	LE160000	Ecircumflex	latin capital letter e with circumflex accent
00cb	LE180000	Edieresis	latin capital letter e with diaeresis
00cc	LI140000	Igrave	latin capital letter i with grave accent
00cd	LI120000	Iacute	latin capital letter i with acute accent
00ce	LI160000	Icircumflex	latin capital letter i with circumflex accent
00cf	LI180000	Idieresis	latin capital letter i with diaeresis
00d0	LD620000	Eth	latin capital letter eth
(same GCID as character at position 0110)

00d1	LN200000	Ntilde	latin capital letter n with tilde
00d2	LO140000	Ograve	latin capital letter o with grave accent
00d3	LO120000	Oacute	latin capital letter o with acute accent
00d4	LO160000	Ocircumflex	latin capital letter o with circumflex accent
00d5	LO200000	Otilde	latin capital letter o with tilde
00d6	LO180000	Odieresis	latin capital letter o with diaeresis
00d7	SA070000	multiply	multiplication sign
00d8	LO620000	Oslash	latin capital letter o with oblique stroke
00d9	LU140000	Ugrave	latin capital letter u with grave accent
00da	LU120000	Uacute	latin capital letter u with acute accent
00db	LU160000	Ucircumflex	latin capital letter u with circumflex accent
00dc	LU180000	Udieresis	latin capital letter u with diaeresis
00dd	LY120000	Yacute	latin capital letter y with acute accent
00de	LT640000	Thorn	latin capital letter thorn
00df	LS610000	germandbls	latin small letter sharp s
00e0	LA130000	agrave	latin small letter a with grave accent
00e1	LA110000	aacute	latin small letter a with acute accent
00e2	LA150000	acircumflex	latin small letter a with circumflex accent
00e3	LA190000	atilde	latin small letter a with tilde
00e4	LA170000	adieresis	latin small letter a with diaeresis
00e5	LA270000	aring	latin small letter a with ring above
00e6	LA510000	ae	latin small letter a with e
00e7	LC410000	ccedilla	latin small letter c with cedilla
00e8	LE130000	egrave	latin small letter e with grave accent
00e9	LE110000	eacute	latin small letter e with acute accent
00ea	LE150000	ecircumflex	latin small letter e with circumflex accent
00eb	LE170000	edieresis	latin small letter e with diaeresis
00ec	LI130000	igrave	latin small letter i with grave accent
00ed	LI110000	iacute	latin small letter i with acute accent
00ee	LI150000	icircumflex	latin small letter i with circumflex accent
00ef	LI170000	idieresis	latin small letter i with diaeresis
00f0	LD630000	eth	latin small letter eth
00f1	LN190000	ntilde	latin small letter n with tilde
00f2	LO130000	ograve	latin small letter o with grave accent
00f3	LO110000	oacute	latin small letter o with acute accent
00f4	LO150000	ocircumflex	latin small letter o with circumflex accent
00f5	LO190000	otilde	latin small letter o with tilde
00f6	LO170000	odieresis	latin small letter o with diaeresis
00f7	SA060000	divide	division sign
00f8	LO610000	oslash	latin small letter o with oblique stroke
00f9	LU130000	ugrave	latin small letter u with grave accent
00fa	LU110000	uacute	latin small letter u with acute accent
00fb	LU150000	ucircumflex	latin small letter u with circumflex accent
00fc	LU170000	udieresis	latin small letter u with diaeresis
00fd	LY110000	yacute	latin small letter y with acute accent
00fe	LT630000	thorn	latin small letter thorn
00ff	LY170000	ydieresis	latin small letter y with diaeresis
European
0102	LA240000	Abreve	latin capital letter a with breve
0103	LA230000	abreve	latin small letter a with breve
0104	LA440000	Aogonek	latin capital letter a with ogonek
0105	LA430000	aogonek	latin small letter a with ogonek
0106	LC120000	Cacute	latin capital letter c with acute accent
0107	LC110000	cacute	latin small letter c with acute accent
010c	LC220000	Ccaron	latin capital letter c with hacek
010d	LC210000	ccaron	latin small letter c with hacek
010e	LD220000	Dcaron	latin capital letter d with hacek
010f	LD210000	dcaron	latin small letter d with hacek
0110	LD620000	Dslash	latin capital letter d with stroke
(Same GDID as character at position 00d0)

0111	LD610000	dmacron	latin small letter d with stroke
("dslash" is the preferrable name; "dmacron" is used to match the Macintosh.)

0118	LE440000	Eogonek	latin capital letter e with ogonek
0119	LE430000	eogonek	latin small letter e ogenek
011a	LE220000	Ecaron	latin capital letter e with hacek
011b	LE210000	ecaron	latin small letter e with hacek
011e	LG240000	Gbreve	latin capital letter g with breve
011f	LG230000	gbreve	latin small letter g with breve
0130	LI300000	Idot	latin capital letter i with dot above
0131	LI610000	dotlessi	latin small letter i without dot above
0139	LL120000	Lacute	latin capital letter l with acute accent
013a	LL110000	lacute	latin small letter l with acute accent
013d	LL220000	Lcaron	latin capital letter l with hacek
013e	LL210000	lcaron	latin small letter l with hacek
013f	LL640000	Ldot	latin capital letter l with middle dot
0140	LL630000	ldot	latin small letter l with middle dot
0141	LL620000	Lslash	latin capital letter l with stroke
0142	LL610000	lslash	latin small letter l with stroke
0143	LN120000	Nacute	latin capital letter n with acute accent
0144	LN110000	nacute	latin small letter n with acute accent
0147	LN220000	Ncaron	latin capital letter n with hacek
0148	LN210000	ncaron	latin small letter n with hacek
0150	LO260000	Odblacute	latin capital letter o with double acute accent
0151	LO250000	odblacute	latin small letter o with double acute accent
0152	LO520000	OE	latin capital ligature o with e
0153	LO510000	oe	latin small ligature o with e
0154	LR120000	Racute	latin capital letter r with acute accent
0155	LR110000	racute	latin small letter r with acute accent
0158	LR220000	Rcaron	latin capital letter r with hacek
0159	LR210000	rcaron	latin small letter r with hacek
015a	LS120000	Sacute	latin capital letter s with acute accent
015b	LS110000	sacute	latin small letter s with acute accent
015e	LS420000	Scedilla	latin capital letter s with cedilla
015f	LS410000	scedilla	latin small letter s with cedilla
0160	LS220000	Scaron	latin capital letter s with hacek
0161	LS210000	scaron	latin small letter s with hacek
0162	LT420000	Tcedilla	latin capital letter t with cedilla
0163	LT410000	tcedilla	latin small letter t with cedilla
0164	LT220000	Tcaron	latin capital letter t with hacek
0165	LT210000	tcaron	latin small letter t with hacek
016e	LU280000	Uring	latin capital letter u with ring above
016f	LU270000	uring	latin small letter u with ring above
0170	LU260000	Udblqcute	latin capital letter u with double acute accent
0171	LU250000	udblacute	latin small letter u with double acute accent
0178	LY180000	Ydieresis	latin capital letter y with diaeresis
0179	LZ120000	Zacute	latin capital letter z with acute accent
017a	LZ110000	zacute	latin small letter z with acute accent
017b	LZ300000	Zdot	latin capital letter z with dot above
017c	LZ290000	zdot	latin small letter z with dot above
017d	LZ220000	Zcaron	latin capital letter z with hacek
017e	LZ210000	zcaron	latin small letter z with hacek
Extended Latin
0192	SC070000	florin	latin small letter script f,florin sign
Modifier Letters (spacing)
02dd	SD250000	hungarumlaut	modifier letter double prime
02c7	SD210000	caron	modifier letter hacek
02c9	SD310000	macron	modifier letter macron
02d8	SD230000	breve	breve
02d9	SD290000	dotaccent	dot above
02da	SD270000	ring	ring above
02db	SD430000	ogonek	ogonek
02c6	SD150100	circumflex	nonspacing circumflex accent
02dc	SD190100	tilde	nonspacing tilde
Greek
0393	GG020000	Gamma	greek capital letter gamma
0398	GT620000	Theta	greek capital letter theta
03a6	GF020000	Phi	greek capital letter phi
03b1	GA010000	alpha	greek small letter alpha
03b4	GD010000	delta	greek small letter delta
03b5	GE010000	epsilon	greek small letter epsilon
03c0	GP010000	pi	greek small letter pi
03c3	GS010000	sigma	greek small letter sigma
03c4	GT010000	tau	greek small letter tau
03c6	GF010000	phi	greek small letter phi
General Punctuation
2013	SS680000	endash	endash
2014	SM900000	emdash	emdash
2017	SM100000	underscoredbl	double underline
2018	SP190000	quoteleft	left single quotation mark
2019	SP200000	quoteright	right single quotation mark
201a	SP260000	quotesinglbase	single low quotation mark
201c	SP210000	quotedblleft	left double quotation mark
201d	SP220000	quotedblright	right double quotation mark
201e	SP230000	quotedblbase	double low quotation mark
2020	SM340000	dagger	dagger
2021	SM350000	daggerdbl	doubledagger
2022	SM570000	bullet	bullet
2026	SV520000	ellipsis	horizontal ellipsis
2030	SM560000	perthousand	permille sign
2039	SP270000	guilsinglleft	left single guillemet
203a	SP280000	guilsinglright	right single guillemet
203c	SP330000	exclamdbl	double exclamation marks
Superscripts and Subscripts
207f	LN011000	nsuperior	superscript latin letter small n
Currency
20a3	undef	franc	french franc
20a7	SC060000	peseta	peseta sign
Letterlike Symbols
2122	SM540000	trademark	trademark ligature
Arrows
2190	SM300000	arrowleft	leftward arrow
2191	SM320000	arrowup	upward arrow
2192	SM310000	arrowright	rightward arrow
2193	SM330000	arrowdown	downward arrow
2194	SM780000	arrowboth	left and right pointing arrow
2195	SM760000	arrowupdn	up and down pointing arrow
21a8	SM770000	arrowupdnbse	up and down pointing arrow with base
Mathematical Operators
2126	GO320000	ohm	greek capital letter omega
2202	SA490000	partialdiff	partial differential sign
2206	undef	Delta	increment
220f	SA810000	product	repeated product
2211	GS020000	summation	greek capital letter sigma
Although this is the "Sigma" character, "summation" is used to match the Macintosh.

2212	SA000000	minus	minus
2215	SP120001	fraction	division slash
2219	SA790000	periodcentered	middle dot
221a	SA800000	radical	radical sign
221e	SA450000	infinity	infinity sign
221f	SA420000	orthogonal	right angle sign
2229	SA380000	intersection	intersection
222b	SA510000	integral	integral sign
2248	SA700000	approxequal	almost equals
2260	SA540000	notequal	not equal to
2261	SA480000	equivalence	is identical to
2264	SA520000	lessequal	less than or equal to
2265	SA530000	greaterequal	greater than or equal to
Miscellaneous Technical
2302	SM790000	house	small house
2310	SM680000	revlogicalnot	reversed not sign
2320	SS260000	integraltp	mathematical integral sign top half
2321	SS270000	integralbt	mathematical integral sign bottom half
Forms
2500	SF100000	use the	box drawings light horizontal
2502	SF110000	unicode ID	box drawings light vertical
250c	SF010000	for all items	box drawings light down and right
		in this column
2510	SF030000		box drawings light down and left
2514	SF020000		box drawings light up and right
2518	SF040000		box drawings light up and left
251c	SF080000		box drawings light vertical and right
2524	SF090000		box drawings light vertical and left
252c	SF060000		box drawings light down and horizontal
2534	SF070000		box drawings light up and horizontal
253c	SF050000		box drawings light vertical and horizontal
2550	SF430000		box drawings double horizontal
2551	SF240000		box drawings double vertical
2552	SF510000		box drawings down single and right double
2553	SF520000		box drawings down double and right single
2554	SF390000		box drawings double down and right
2555	SF220000		box drawings down single and left double
2556	SF210000		box drawings down double and left single
2557	SF250000		box drawings double down and left
2558	SF500000		box drawings up single and right double
2559	SF490000		box drawings up double and right single
255a	SF380000		box drawings double up and right
255b	SF280000		box drawings up single and left double
255c	SF270000		box drawings up double and left single
255d	SF260000		box drawings double up and left
255e	SF360000		box drawings vertical single and right double
255f	SF370000		box drawings vertical double and right single
2560	SF420000		box drawings double vertical and right
2561	SF190000		box drawings vertical single and left double
2562	SF200000		box drawings vertical double and left single
2563	SF230000		box drawings double vertical and left
2564	SF470000		box drawings down single and horizontal double
2565	SF480000		box drawings down double and horizontal single
2566	SF410000		box drawings double down and horizontal
2567	SF450000		box drawings up single and horizontal double
2568	SF460000		box drawings up double and horizontal single
2569	SF400000		box drawings double up and horizontal
256a	SF540000		box drawings vertical single and horizontal double
256b	SF530000		box drawings vertical double and horizontal single
256c	SF440000		box drawings double vertical and horizontal
Bars
2580	SF600000	upblock	upper half block
2584	SF570000	dnblock	lower half block
2588	SF610000	block	full block
258c	SF580000	lfblock	left half block
2590	SF590000	rtblock	right half block
2591	SF140000	ltshade	light shade
2592	SF150000	shade	medium shade
2593	SF160000	dkshade	dark shade
Geometric Shapes
25a0	SM470000	filledbox	full square
25ac	SM700000	filledrect	full rectangle
25b2	SM600000	triagup	full upward pointing triangle
25ba	SM590000	triagrt	full rightward pointer
25bc	SV040000	triagdn	full downward pointing triangle
25c4	SM630000	triaglf	full leftward pointer
25ca	SA660000	lozenge	lozenge
25cb	SM750000	circle	circle
25d8	SM570001	invbullet	inverse circle bullet
25d9	SM750002	invcircle	inverse circle
Dingbats
263a	SS000000	smileface	smiling face white
263b	SS010000	invsmileface	reverse image smiling face
263c	SM690000	sun	radiant sun
2640	SM290000	female	female sign
2642	SM280000	male	male sign
2660	SS050000	spade	spade symbol
2663	SS040000	club	club symbol
2665	SS020000	heart	heart symbol
2666	SS030000	diamond	diamond symbol
266a	SM930000	musicalnote	musicnote
266b	SM910000	musicalnotedbl	two musical notes
The following characters/glyphs are not part of the new UGL character set but must be located in the font files for usage by Apple character sets.

Unicode Index	IBM GCID	PostScript Name	Descriptive Name
f000	undef	apple	apple logo (as the non-existing character glyph)
f001	LF530000	fi	latin small ligature fi
f002	LF550000	fl	latin small ligature fl
Important notes:

It is required that fonts for Microsoft platforms have an entry for each of these new UGL indexes. However as TrueType font files use an internal mapping table to access their private UGL indexes, it is feasible to map similar looking characters or glyphs to single internal glyph (e.g. latin capital letter eth and latin capital letter d with stroke).

The CharToIndexMap table used for this list of characters will be implemented with the format 4 as referenced earlier in this document (see Chapter 4).

Note that space (0020) and no-break space (00a0) should be mapped to a glyph with no contours and a positive advance width; this advance width should be the same.

Lining numbers (0030 through 0039; i.e. the digits 0 - 9) should be monospaced. Old style figures need not be monospaced.

White space should be evenly distributed between the left and right side bearings of glyphs. Extra space should be placed on the right if grid-fitting results in an odd number of pixels.

For further recommendations pertaining to the Apple character set, please see Appendix C.


Windows 3.1 Character Set

There have been several questions about Microsoft's large UGL character set and how it relates to TrueType fonts on Windows. For Windows 3.1, it is possible to create a font without all the UGL characters. The absolute minimum would be the Windows ANSI set (described below). If you also want to support the Macintosh or PostScript/TrueImage with the same font, you would, of course, also want to include the full Macintosh/PostScript character set. The mapping of this character set into Unicode and Microsoft's UGL list can be found in Appendix C.

For compatability reasons, it is suggested that the Windows ANSI set and the Macintosh/PostScript set be supported in all your fonts. But fonts without the full UGL character set will not properly support codepages under OS/2.

The Windows ANSI character set can be defined fairly simply in terms of Unicode indicies. The Unicode range from 0020 to 00ff encompasses the majority of the Windows ANSI set. Windows 3.0 added two additional characters to this list; they are mapped into the otherwise unused range between 128 and 159 (80 to 9f hex). For Windows 3.1, an additional 22 typographical characters are mapped into this same range. The complete list of characters mapped into the previously unused character code range follows below.

Character	ANSI-Position	Unicode Index
baseline single quote	130 (82 hex)	201A
florin	131 (83 hex)	0192
baseline double quote	132 (84 hex)	201E
ellipsis	133 (85 hex)	2026
dagger	134 (86 hex)	2020
double dagger	135 (87 hex)	2021
circumflex accent	136 (88 hex)	02C6
permile	137 (89 hex)	2030
S Hacek	138 (8A hex)	0160
left single guillemet	139 (8B hex)	2039
OE ligature	140 (8C hex)	0152
left single quote	145 (91 hex)	2018
right single quote	146 (92 hex)	2019
2018 and 2019 were put into the character set as of Windows 3.0.

left double quote	147 (93 hex)	201C
right double quote	148 (94 hex)	201D
bullet	149 (95 hex)	2022
endash	150 (96 hex)	2013
emdash	151 (97 hex)	2014
tilde accent	152 (98 hex)	02DC
trademark ligature	153 (99 hex)	2122
s Hacek	154 (9A hex)	0161
right single guillemet	155 (9B hex)	203A
oe ligature	156 (9C hex)	0153
Y Dieresis	159 (9F hex)	0178


Minimum Character Set Requirements

What follows is the minimum recommended character set for making portable TrueType fonts. This is the union of the Windows 3.1 character set, the Macintosh character set and the PostScript character set.  A font with at least these glyphs will work on a wide range of devices properly.

Unicode Index	PostScript Name	Descriptive Name
ASCII
0020	space	space
0021	exclam	exclamation mark
0022	quotedbl	quotation mark
0023	numbersign	number sign
0024	dollar	dollar sign
0025	percent	percent sign
0026	ampersand	ampersand
0027	quotesingle	apostrophe
0028	parenleft	left parenthesis
0029	parenright	right parenthesis
002a	asterisk	asterisk
002b	plus	plus sign
002c	comma	comma
002d	hyphen	hyphen-minus
002e	period	period
002f	slash	slash
0030	zero	digit zero
0031	one	digit one
0032	two	digit two
0033	three	digit three
0034	four	digit four
0035	five	digit five
0036	six	digit six
0037	seven	digit seven
0038	eight	digit eight
0039	nine	digit nine
003a	colon	colon
003b	semicolon	semicolon
003c	less	less-than sign
003d	equal	equals sign
003e	greater	greater-than sign
003f	question	question mark
0040	at	commercial at
0041	A	latin capital letter a
0042	B	latin capital letter b
0043	C	latin capital letter c
0044	D	latin capital letter d
0045	E	latin capital letter e
0046	F	latin capital letter f
0047	G	latin capital letter g
0048	H	latin capital letter h
0049	I	latin capital letter i
004a	J	latin capital letter j
004b	K	latin capital letter k
004c	L	latin capital letter l
004d	M	latin capital letter m
004e	N	latin capital letter n
004f	O	latin capital letter o
0050	P	latin capital letter p
0051	Q	latin capital letter q
0052	R	latin capital letter r
0053	S	latin capital letter s
0054	T	latin capital letter t
0055	U	latin capital letter u
0056	V	latin capital letter v
0057	W	latin capital letter w
0058	X	latin capital letter x
0059	Y	latin capital letter y
005a	Z	latin capital letter z
005b	bracketleft	left square bracket
005c	backslash	backslash
005d	bracketright	right square bracket
005e	asciicircum	circumflex accent
005f	underscore	underline
0060	grave	grave accent
0061	a	latin small letter a
0062	b	latin small letter b
0063	c	latin small letter c
0064	d	latin small letter d
0065	e	latin small letter e
0066	f	latin small letter f
0067	g	latin small letter g
0068	h	latin small letter h
0069	i	latin small letter i
006a	j	latin small letter j
006b	k	latin small letter k
006c	l	latin small letter l
006d	m	latin small letter m
006e	n	latin small letter n
006f	o	latin small letter o
0070	p	latin small letter p
0071	q	latin small letter q
0072	r	latin small letter r
0073	s	latin small letter s
0074	t	latin small letter t
0075	u	latin small letter u
0076	v	latin small letter v
0077	w	latin small letter w
0078	x	latin small letter x
0079	y	latin small letter y
007a	z	latin small letter z
007b	braceleft	left curly bracket
007c	bar	vertical line
007d	braceright	right curly bracket
007e	asciitilde	tilde
Latin-1, also corresponding to ISO 8859-1 or ANSI
00a0	nbspace	no-break space
00a1	exclamdown	inverted exclamation mark
00a2	cent	cent sign
00a3	sterling	pound sign
00a4	currency	currency sign
00a5	yen	yen sign
00a6	brokenbar	broken bar
00a7	section	section sign
00a8	dieresis	diaeresis
00a9	copyright	copyright sign
00aa	ordfeminine	feminine ordinal indicator
00ab	guillemotleft	left guillemet
00ac	logicalnot	not sign
00ad	sfthyphen	soft hyphen
00ae	registered	registered trade mark sign
00af	overstore	macron, overline
00b0	degree	degree sign
00b1	plusminus	plus-minus sign
00b2	twosuperior	superscript two
00b3	threesuperior	superscript three
00b4	acute	acute accent
00b5	mu	micro sign
00b6	paragraph	paragraph sign
00b7	middot	middle dot, kana conjoctive
00b8	cedilla	cedilla
00b9	onesuperior	superscript one
00ba	ordmasculine	masculine ordinal indicator
00bb	guillemotright	right guillemet
00bc	onequarter	vulgar fraction one quarter
00bd	onehalf	vulgar fraction one half
00be	threequarters	vulgar fraction three quarters
00bf	questiondown	inverted question mark
00c0	Agrave	latin capital letter a with grave accent
00c1	Aacute	latin capital letter a with acute accent
00c2	Acircumflex	latin capital letter a with circumflex accent
00c3	Atilde	latin capital letter a with tilde
00c4	Adieresis	latin capital letter a with diaeresis
00c5	Aring	latin capital letter a with ring above
00c6	AE	latin capital letter a with e
00c7	Ccedilla	latin capital letter c with cedilla
00c8	Egrave	latin capital letter e with grave accent
00c9	Eacute	latin capital letter e with acute accent
00ca	Ecircumflex	latin capital letter e with circumflex accent
00cb	Edieresis	latin capital letter e with diaeresis
00cc	Igrave	latin capital letter i with grave accent
00cd	Iacute	latin capital letter i with acute accent
00ce	Icircumflex	latin capital letter i with circumflex accent
00cf	Idieresis	latin capital letter i with diaeresis
00d0	Eth	latin capital letter eth
00d1	Ntilde	latin capital letter n with tilde
00d2	Ograve	latin capital letter o with grave accent
00d3	Oacute	latin capital letter o with acute accent
00d4	Ocircumflex	latin capital letter o with circumflex accent
00d5	Otilde	latin capital letter o with tilde
00d6	Odieresis	latin capital letter o with diaeresis
00d7	multiply	multiplication sign
00d8	Oslash	latin capital letter o with oblique stroke
00d9	Ugrave	latin capital letter u with grave accent
00da	Uacute	latin capital letter u with acute accent
00db	Ucircumflex	latin capital letter u with circumflex accent
00dc	Udieresis	latin capital letter u with diaeresis
00dd	Yacute	latin capital letter y with acute accent
00de	Thorn	latin capital letter thorn
00df	germandbls	latin small letter sharp s
00e0	agrave	latin small letter a with grave accent
00e1	aacute	latin small letter a with acute accent
00e2	acircumflex	latin small letter a with circumflex accent
00e3	atilde	latin small letter a with tilde
00e4	adieresis	latin small letter a with diaeresis
00e5	aring	latin small letter a with ring above
00e6	ae	latin small letter a with e
00e7	ccedilla	latin small letter c with cedilla
00e8	egrave	latin small letter e with grave accent
00e9	eacute	latin small letter e with acute accent
00ea	ecircumflex	latin small letter e with circumflex accent
00eb	edieresis	latin small letter e with diaeresis
00ec	igrave	latin small letter i with grave accent
00ed	iacute	latin small letter i with acute accent
00ee	icircumflex	latin small letter i with circumflex accent
00ef	idieresis	latin small letter i with diaeresis
00f0	eth	latin small letter eth
00f1	ntilde	latin small letter n with tilde
00f2	ograve	latin small letter o with grave accent
00f3	oacute	latin small letter o with acute accent
00f4	ocircumflex	latin small letter o with circumflex accent
00f5	otilde	latin small letter o with tilde
00f6	odieresis	latin small letter o with diaeresis
00f7	divide	division sign
00f8	oslash	latin small letter o with oblique stroke
00f9	ugrave	latin small letter u with grave accent
00fa	uacute	latin small letter u with acute accent
00fb	ucircumflex	latin small letter u with circumflex accent
00fc	udieresis	latin small letter u with diaeresis
00fd	yacute	latin small letter y with acute accent
00fe	thorn	latin small letter thorn
00ff	ydieresis	latin small letter y with diaeresis
European
0106	Cacute	latin capital letter c with acute accent
0107	cacute	latin small letter c with acute accent
010c	Ccaron	latin capital letter c with hacek
010d	ccaron	latin small letter c with hacek
0111	dmacron	latin small letter d with stroke
("dslash" is the preferrable name; "dmacron" is used to match the Macintosh.)

011e	Gbreve	latin capital letter g with breve
011f	gbreve	latin small letter g with breve
0130	Idot	latin capital letter i with dot above
0131	dotlessi	latin small letter i without dot above
0141	Lslash	latin capital letter l with stroke
0142	lslash	latin small letter l with stroke
0152	OE	latin capital ligature o with e
0153	oe	latin small ligature o with e
015e	Scedilla	latin capital letter s with cedilla
015f	scedilla	latin small letter s with cedilla
0160	Scaron	latin capital letter s with hacek
0161	scaron	latin small letter s with hacek
0178	Ydieresis	latin capital letter y with diaeresis
017d	Zcaron	latin capital letter z with hacek
017e	zcaron	latin small letter z with hacek
Extended Latin
0192	florin	latin small letter script f,florin sign
Modifier Letters (spacing)
02dd	hungarumlaut	modifier letter double prime
02c7	caron	modifier letter hacek
02d8	breve	breve
02d9	dotaccent	dot above
02da	ring	ring above
02db	ogonek	ogonek
02c6	circumflex	nonspacing circumflex accent
02dc	tilde	nonspacing tilde
Greek
03c0	pi	greek small letter pi
General Punctuation
2013	endash	endash
2014	emdash	emdash
2018	quoteleft	left single quotation mark
2019	quoteright	right single quotation mark
201a	quotesinglbase	single low quotation mark
201c	quotedblleft	left double quotation mark
201d	quotedblright	right double quotation mark
201e	quotedblbase	double low quotation mark
2020	dagger	dagger
2021	daggerdbl	doubledagger
2022	bullet	bullet
2026	ellipsis	horizontal ellipsis
2030	perthousand	permille sign
2039	guilsinglleft	left single guillemet
203a	guilsinglright	right single guillemet
Currency
20a3	franc	french franc
Letterlike Symbols

2122	trademark	trademark ligature
Mathematical Operators
2126	ohm	greek capital letter omega
2202	partialdiff	partial differential sign
2206	Delta	increment
220f	product	repeated product
2211	summation	greek capital letter sigma
 While this is really the "Sigma" character, "summation" is used to match the Macintosh.

2212	minus	minus
2215	fraction	division slash
2219	periodcentered	middle dot
221a	radical	radical sign
221e	infinity	infinity sign
222b	integral	integral sign
2248	approxequal	almost equals
2260	notequal	not equal to
2264	lessequal	less than or equal to
2265	greaterequal	greater than or equal to
Geometric Shapes
25ca	lozenge	lozenge
Not a part of Unicode, for Macintosh compatibility only
f000	apple	apple logo (as the non-existing character glyph)
f001	fi	latin small ligature fi
f002	fl	latin small ligature fl
Windows Character Set for Times New Roman

	0	1	2	3	4	5	6	7	8	9	A	B	C	D	E	F
000x
001x
002x		!	"	#	$	%	&	'	(	)	*	+	,	-	.	/
003x	0	1	2	3	4	5	6	7	8	9	:	;	<	=	>	?
004x	@	A	B	C	D	E	F	G	H	I	J	K	L	M	N	O
005x	P	Q	R	S	T	U	V	W	X	Y	Z	[	\	]	^	_
006x	`	a	b	c	d	e	f	g	h	i	j	k	l	m	n	o
007x	p	q	r	s	t	u	v	w	x	y	z	{	|	}	~
008x	€	�	‚	ƒ	„	…	†	‡	ˆ	‰	Š	‹	Œ	�	Ž	�
009x	�	'	'				-	-	˜	™	š	›	œ	�	ž	Ÿ
00Ax		¡	¢	£	¤	¥	¦	§	¨	©	ª	«	¬	­	®	¯
00Bx	°	±	²	³	´	µ	¶	·	¸	¹	º	»	¼	½	¾	¿
00Cx	À	Á	Â	Ã	Ä	Å	Æ	Ç	È	É	Ê	Ë	Ì	Í	Î	Ï
00Dx	Ð	Ñ	Ò	Ó	Ô	Õ	Ö	×	Ø	Ù	Ú	Û	Ü	Ý	Þ	ß
00Ex	à	á	â	ã	ä	å	æ	ç	è	é	ê	ë	ì	í	î	ï
00Fx	ð	ñ	ò	ó	ô	õ	ö	÷	ø	ù	ú	û	ü	ý	þ	ÿ


Instructions by Category
Instruction Set Summary - Instructions by Category

Pushing data onto the interpreter stack

Instruction	Opcode	Takes from IS	Pushes
NPUSHB[ ]	0x40	n, b1, b2,...bn	b1,b2...bn
NPUSHW[ ]	0x41	n, w1, w2,...wn	w1,w2...wn
PUSHB[abc]	0xB0 - 0xB7	b0, b1,..bn	b0, b1, ...,bn
PUSHW[abc]	0xB8 - 0xBF	w0,w1,..wn	w0 ,w1, ...wn

Managing the Storage Area

Instruction	Opcode	Pops	Pushes
RS[ ]	0x43	location	value
WS[ ]	0x42	value, location	-

Managing the Control Value Table

Instruction	Opcode	Pops	Pushes
WCVTP[ ]	0x44	value, location	-
WCVTF[ ]	0x70/	value, location	-
RCVT[ ]	0x45	location	value
Managing the Graphics State

Setting and getting the freedom_vector and the projection_vector

Instruction	Opcode	Pops	Pushes
SVTCA[a]	0x00 - 0x01	-	-
SPVTCA[a]	0x02 - 0x03	-	-
SFVTCA[a]	0x04 - 0x05	-	-
SPVTL[a]	0x06 - 0x07	p1, p2	-
SFVTL[a]	0x08 - 0x09	p1, p2	-
SFVTPV[ ]	0x0E	-	-
SDPVTL[a]	0x86 - 0x87	p1, p2	-
SPVFS[ ]	0x0A	y, x	-
SFVFS[ ]	0x0B	y, x	-
GPV[ ]	0x0C	-	x, y
GFV[ ]	0x0D	-	x, y
Setting  reference points and glyph element pointers

Instruction	Opcode	Pops	Pushes
SRP0[ ]	0x10	p	-
SRP1[ ]	0x11	p	-
SRP2[ ]	0x12	p	-
SZP0[ ]	0x13	n	-
SZP1[ ]	0x14	n	-
SZP2[ ]	0x15	n	-
SZPS[ ]	0x16	n	-
Setting the round_state

Instruction	Opcode	Pops	Pushes
RTHG[ ]	0x19	-	-
RTG[ ]	0x18	-	-
RTDG[ ]	0x3D	-	-
RDTG[ ]	0x7D	-	-
RUTG[ ]	0x7C	-	-
ROFF[ ]	0x7A	-	-
SROUND[ ]	0x76	n	-
S45ROUND[ ]	0x77	n	-
Setting other graphics state variables

Instruction	Opcode	Pops	Pushes
INSTCTRL	0x8E	value	-
SLOOP[ ]	0x17	n	-
SMD[ ]	0x1A	distance	-
SCANCTRL[ ]	0x85	n	-
SCANTYPE[ ]	0x8D	n	-
SCVTCI[ ]	0x1D	n	-
SSWCI[ ]	0x1E	n	-
SSW[ ]	0x1F	n	-
FLIPON[ ]	0x4D	-	-
FLIPOFF[ ]	0x4E	-	-
SANGW[ ]	0x7E	weight	-
SDB[ ]	0x5E	n	-
SDS[ ]	0x5F	n	-
Reading and Writing Data

Instruction	Opcode	Pops	Pushes
GC[a]	0x46 - 0x47	p	value
SCFS[ ]	0x48	value, p	-
MD[a]	0x49 - 0x4A	p1,p2	distance
MPPEM[ ]	0x4B	-	ppem
MPS[ ]	0x4C	-	pointSize
Managing Outlines

Flipping Points

Instruction	Opcode	Pops	Pushes
FLIPRGON[ ]	0x81	highpoint, lowpoint	-
FLIPRGOFF[ ]	0x82	highpoint, lowpoint	-
FLIPPT[ ]	0x80	p	-
Shifting Points

Instruction	Opcode	Pops	Pushes
SHC[a]	0x34 - 0x35	c	-
SHZ[a]	0x36 - 0x37	e	-
SHPIX[ ]	0x38	p1, p2, amount	-
SHP	0x32 - 0x33	p	-
Moving Points

Instruction	Opcode	Pops	Pushes
MDAP[ a ]	0x2E - 0x2F	p	-
MIAP[a]	0x3E - 0x3F	n, p	-
MDRP[abcde]	0xC0 - 0xDF	p	-
MIRP[abcde]	0xE0 - 0xFF	n, p	-
ALIGNRP[ ]	0x3C	p1, p2, ... , ploop	-
AA[ ]	0x7F	p	-
ISECT[ ]	0x0F	a1, a0, b1, b0, p	-
ALIGNPTS[ ]	0x27	p1, p2	-
Interpolating Points

Instruction	Opcode	Pops	Pushes
UTP[ ]	0x29	p	-
IUP[a]	0x30 - 0x31	-	-

Managing Exceptions

Instruction	Opcode	Pops	Pushes
DELTAP1[ ]	0x5D	n, p1, arg1, ..., pn, argn	-
DELTAP2[ ]	0x71	n, p1, arg1, ..., pn, argn	-
DELTAP3[ ]	0x72	n, p1, arg1, ..., pn, argn	-
DELTAC1[ ],	0x73	n, c1, arg1, ..., cn, argn	-
DELTAC2[ ]	0x74	n, c1, arg1, ..., cn, argn	-
DELTAC3[ ]	0x75	n, c1, arg1, ..., cn, argn	-

Managing the stack

Instruction	Opcode	Pops	Pushes
DUP[ ]	0x20	e	e, e
POP[ ]	0x21	e	-
CLEAR[ ]	0x22	all items on the stack	-
SWAP[ ]	0x23	e1, e2	e1, e2
DEPTH[ ]	0x24	-	n
CINDEX[ ]	0x25	k	ek
MINDEX[ ]	0x26	k, e1, e2, ..., ek	ek-1, ek-2, ..., e1, ek
ROLL	0x8a	-	-

Logical functions

Instruction	Opcode	Pops	Pushes
LT[ ]	0x50	e1, e2	(e2 < e1 Boolean value
LTEQ[ ]	0x51	e1, e2	(e2  e1) Boolean value
GT[ ]	0x52	e1, e2	(e2 > e1) Boolean value
GTEQ[ ]	0x53	e1, e2	(e2   e1) Boolean value
EQ[ ]	0x54	e1, e2	(e2 = e1) Boolean value
NEQ[ ]	0x55	e1, e2	(e2  e1) Boolean value
ODD[ ]	0x56	e	(e mod 2) = 1 Boolean value
EVEN[ ]	0x57	e	(e mod 2) = 0 Boolean value
AND[ ]	0x5A	e1, e2	( e2 and e1 )  Boolean value
OR[ ]	0x5B	e1, e2	( e2 or e1 )Boolean value
NOT[ ]	0x5C	e	( not e )Boolean value

Managing the flow of control

Instruction	Opcode	Pops	Pushes
IF[ ]	0x58	e	-
EIF[ ]	0x59	-	-
ELSE	0x1B
JMPR	0x1C	offset
JROT[ ]	0x78	e, offset	-
JROF[ ]	0x79	e, offset	-

Arithmetic functions

Instruction	Opcode	Pops	Pushes
ADD[ ]	0x60	n1, n2	(n1 + n2)
SUB[ ]	0x61	n1, n2	(n2 - n1)
DIV[ ]	0x62	n1, n2	(n2 ¥ 64)/ n1
MUL[ ]	0x63	n1, n2	(n1 ¥ n2)/64
ABS[ ]	0x64	n	|n|
NEG[ ]	0x65	n1	-n1
FLOOR[ ]	0x66	n1	n
CEILING[ ]	0x67	n1	n
MAX[ ]	0X8B	e1, e2	max(e1, e2)
MIN[ ]	0X8C	e1, e2	min(e1, e2)

Compensating for the engine characteristics

Instruction	Opcode	Pops	Pushes
ROUND[ab]	0x68 - 0x6B	n1	n2
NROUND[ab]	0x6C - 0x6F	n1	n2

Defining and using functions and instructions

Instruction	Opcode	Pops	Pushes
FDEF[ ]	0x2C	f	-
ENDF[ ]	0x2D	-	-
CALL[ ]	0x2B	f	-
LOOPCALL[ ]	0x2A	f, count	-
IDEF[ ]	0x89	o	-

Debugging

Instruction	Opcode	Pops	Pushes
DEBUG[ ]	0x4F	opcode	-

Miscellaneous

Instruction	Opcode	Pops	Pushes
GETINFO[ ]	0x88	selector	result


Instructions by Name

Instruction	Opcode	Takes from IS	Pushes
AA[ ]	0x7F	p	-
ABS[ ]	0x64	n	|n|
ADD[ ]	0x60	n1, n2	(n1 + n2)
ALIGNPTS[ ]	0x27	p1, p2	-
ALIGNRP[ ]	0x3C	p1, p2, ... , ploop	-
AND[ ]	0x5A	e1, e2	( e2 and e1 )  Boolean value
CALL[ ]	0x2B	f	-
CEILING[ ]	0x67	n1	n
CINDEX[ ]	0x25	k
CLEAR[ ]	0x22	all items on the stack	-
DEBUG[ ]	0x4F	opcode	-
DELTAC1[ ],	0x73	n, c1, arg1, ..., cn, argn	-
DELTAC2[ ]	0x74	n, c1, arg1, ..., cn, argn	-
DELTAC3[ ]	0x75	n, c1, arg1, ..., cn, argn	-
DELTAP1[ ]	0x5D	n, p1, arg1, ..., pn, argn	-
DELTAP2[ ]	0x71	n, p1, arg1, ..., pn, argn	-
DELTAP3[ ]	0x72	n, p1, arg1, ..., pn, argn	-
DEPTH[ ]	0x24	-	n
DIV[ ]	0x62	n1, n2	(n2 * 64)/ n1
DUP[ ]	0x20	e	e, e
EIF[ ]	0x59	-	-
ELSE[ ]	0x1B
ENDF[ ]	0x2D	-	-
EQ[ ]	0x54	e1, e2	(e2= e1) Boolean value
EVEN[ ]	0x57	e	(e mod 2) = 0 Boolean value
FDEF[ ]	0x2C	f	-
FLIPOFF[ ]	0x4E	-	-
FLIPON[ ]	0x4D	-	-
FLIPPT[ ]	0x80	p1, p2, ..., ploop	-
FLIPRGOFF[ ]	0x82	highpoint, lowpoint	-
FLIPRGON[ ]	0x81	highpoint, lowpoint	-
FLOOR[ ]	0x66	n1	n
GC[a]	0x46 - 0x47	p	value
GETINFO[ ]	0x88	selector	result
GFV[ ]	0x0D	-	x, y
GPV[ ]	0x0C	-	x, y
GT[ ]	0x52	e1, e2	(e2 > e1) Boolean value
GTEQ[ ]	0x53	e1, e2	(e2 ≥ e1) Boolean value
IDEF[ ]	0x89	o	-
IF[ ]	0x58	e	-
INSTCTRL[]	0x8E	value	-
IP[ ]	0x39	p1, p2, ... , ploop	-
ISECT[ ]	0x0F	a1, a0, b1, b0, p	-
IUP[a]	0x30 - 0x31	-	-
JMPR[]	0x1C	offset
JROF[ ]	0x79	e, offset	-
JROT[ ]	0x78	e, offset	-
LOOPCALL[ ]	0x2A	f, count	-
LT[ ]	0x50	e1, e2	(e2 < e1 Boolean value
LTEQ[ ]	0x51	e1, e2	(e2 ≤ e1) Boolean value
MAX[ ]	0X8B	e1, e2	max(e1, e2)
MD[a]	0x49 - 0x4A	p1,p2	distance
MDAP[ a ]	0x2E - 0x2F	p	-
MDRP[abcde]	0xC0 - 0xDF	p	-
MIAP[a]	0x3E - 0x3F	n, p	-
MIN[ ]	0X8C	e1, e2	min(e1, e2)
MINDEX[ ]	0x26	k, e1, e2, ..., ek	ek-1, ek-2, ..., e1, ek
MIRP[abcde]	0xE0 - 0xFF	n, p	-
MPPEM[ ]	0x4B	-	ppem
MPS[ ]	0x4C	-	pointSize
MSIRP[a]	0x3A - 0x3B	distance, p	-
MUL[ ]	0x63	n1, n2	(n1 ¥ n2)/64
NEG[ ]	0x65	n1	-n1
NEQ[ ]	0x55	e1, e2	(e2 [image] e1) Boolean value
NOT[ ]	0x5C	e	( not e )Boolean value
NPUSHB[ ]	0x40	n, b1, b2,...bn	b1,b2...bn
NPUSHW[ ]	0x41	n, w1, w2,...wn	w1,w2...wn
NROUND[ab]	0x6C - 0x6F	n1	n2
ODD[ ]	0x56	e	(e mod 2) = 1 Boolean value
OR[ ]	0x5B	e1, e2	( e2 or e1 )Boolean value
POP[ ]	0x21	e	-
PUSHB[abc]	0xB0 - 0xB7	b0, b1,..bn	b0, b1, ...,bn
PUSHW[abc]	0xB8 - 0xBF	w0,w1,..wn	w0 ,w1, ...wn
RCVT[ ]	0x45	location	value
RDTG[ ]	0x7D	-	-
ROFF[ ]	0x7A	-	-
ROLL	0x8a	-	-
ROUND[ab]	0x68 - 0x6B	n1	n2
RS[ ]	0x43	location	value
RTDG[ ]	0x3D	-	-
RTG[ ]	0x18	-	-
RTHG[ ]	0x19	-	-
RUTG[ ]	0x7C	-	-
S45ROUND[ ]	0x77	n	-
SANGW[ ]	0x7E	weight	-
SCANCTRL[ ]	0x85	n	-
SCANTYPE[ ]	0x8D	n	-
SCFS[ ]	0x48	value, p	-
SCVTCI[ ]	0x1D	n	-
SDB[ ]	0x5E	n	-
SDPVTL[a]	0x86 - 0x87	p1, p2	-
SDS[ ]	0x5F	n	-
SFVFS[ ]	0x0B	y, x	-
SFVTCA[a]	0x04 - 0x05	-	-
SFVTL[a]	0x08 - 0x09	p1, p2	-
SFVTPV[ ]	0x0E	-	-
SHC[a]	0x34 - 0x35	c	-
SHP[a]	0x32 - 0x33	p1, p2, ..., ploop	-
SHPIX[ ]	0x38	p1, p2, amount	-
SHZ[a]	0x36 - 0x37	e	-
SLOOP[ ]	0x17	n	-
SMD[ ]	0x1A	distance	-
SPVFS[ ]	0x0A	y, x	-
SPVTCA[a]	0x02 - 0x03	-	-
SPVTL[a]	0x06 - 0x07	p1, p2	-
SROUND[ ]	0x76	n	-
SRP0[ ]	0x10	p	-
SRP1[ ]	0x11	p	-
SRP2[ ]	0x12	p	-
SSW[ ]	0x1F	n	-
SSWCI[ ]	0x1E	n	-
SUB[ ]	0x61	n1, n2	(n2 - n1)
SVTCA[a]	0x00 - 0x01	-	-
SWAP[ ]	0x23	e1, e2	e1, e2
SZP0[ ]	0x13	n	-
SZP1[ ]	0x14	n	-
SZP2[ ]	0x15	n	-
SZPS[ ]	0x16	n	-
UTP[ ]	0x29	p	-
WCVTF[ ]	0x70	value, location	-
WCVTP[ ]	0x44	value, location	-
WS[ ]	0x42	value, location	-


Graphics State Summary

The following tables summarize the variables that make up the Graphics State. Nearly all of the Graphics State variables have a default value as shown below. That value is reestablished for every glyph in a font. Instructions are available for resetting the value of all Graphics State variables. Some state variables can be reset in the CVT Program. In such cases the value set becomes the new default and will be reestablished for each glyph. When value of a state variable is changed by instructions associated with a particular glyph, it will hold only for that glyph.

The setting of the Graphics State variables will affect the actions of certain instructions. Affected instructions are listed for each variable.

Graphics State Variable	Default	Set With	Affects
auto_flip	TRUE	FLIPOFF FLIPON	MIAP MIRP
control_value_cut_in	17/16 pixels	LCVTCI	MIAP MIRP
delta_base	9	SDB	DELTAP1 DELTAP2 DELTAP3 DELTAC1 DELTAC2 DELTAC3
delta_shift	3	SDS	DELTAP1 DELTAP2 DELTAP3 DELTAC1 DELTAC2 DELTAC3
dual_projection_vectors	--	SDPVTL	IP GC MD MDRP MIRP
freedom_vector	x-axis	SFVTCA SFVTL SFTPV SVTCA SFVFS	GFV
gep0	1	SCE0 SCES	AA ALIGNPTS ALIGNRP DELTAP1 DELTAP2 DELTAP3 IP ISECT MD MDAP MIAP MIRP MSIRP SHC SHE SHP UTP
gep1	1	SCE1 SCES	AA ALIGNPTS ALIGNRP IP MD MDRP MIRP MSIRP SHC SHE SHP SFVTL SPVTL
gep2	1	SCE3 SCES	ISECT IUP GC SHC SHP SFVTL SHPIX SPVTL SC
instruct_Control	0	INSTCTRL	all instructions
loop	1	SLOOP	ALIGNRP FLIPPT IP SHP SHPIX
minimum_distance	1 pixel	LMD	MDRP MIRP
projection_vector	x-axis	SPVTCA SPVTL SVTCA SPVFS	GPV
round_state	1	RDTG ROFF RTDG RTG RTHG RUTG SROUND S45ROUND	MDAP MIAP MDRP MIRP ROUND
rp0	0	SRP0	IP MDAP MIAP MIRP MSIRP SHC SHE SHP
rp1	0	SRP1	IP MDAP MDRP MIAP MSIRP SHC SHE SHP
rp2	0	SRP2	IP MDRP MIRP MSIRP SHC SHE SHP
scan_control	FALSE	SCANCTRL SCANTYPE
singe_width_cut_in	0 pixels	SSWCI	MIAP MIRP
single_width_value	0 pixels	SSW	MIAP MIRP


Standard Macintosh Character Set to UGL
Macintosh to Microsoft UGL Mapping

The following tables show how to translate Apple's Macintosh character indices and ordering into Microsoft's UGL order.  Note that the UGL codes reflect the  UGL Unicode codes and ordering, found in Chapter 5.

Since the Macintosh requires the use of 'cmap' subtable format 0 (which only allows for BYTE glyph indices), the glyph required by the Macintosh must appear within the first 256 position in the 'glyf' table.  Please see Appendix D for more information.

The PostScript names for each of these glyphs can be found in Chapter 5.

The tables will show the actual characters to the extent possible.  Macintosh characters that do not map to the UGL will have blank (  ) UGL indices.

Standard Macintosh Character Set to UGL

Mac Index	Unicode Index	Char	IBM GCID	Descriptive Name
0-31				ASCII control codes
32	0020		SP010000	space
33	0021	!	SP020000	exclamation mark
34	0022	"	SP040000	quotation mark
35	0023	#	SM010000	number sign
36	0024	$	SC030000	dollar sign
37	0025	%	SM020000	percent sign
38	0026	&	SM030000	ampersand
39	0027	'	SP050000	apostrophe
40	0028	(	SP060000	left parenthesis
41	0029	)	SP070000	right parenthesis
42	002a	*	SM040000	asterisk
43	002b	+	SA010000	plus sign
44	002c	,	SP080000	comma
45	002d	-	SP100000	hyphen-minus
46	002e	.	SP110000	period
47	002f	/	SP120000	slash
48	0030	0	ND100000	digit zero
49	0031	1	ND010000	digit one
50	0032	2	ND020000	digit two
51	0033	3	ND030000	digit three
52	0034	4	ND040000	digit four
53	0035	5	ND050000	digit five
54	0036	6	ND060000	digit six
55	0037	7	ND070000	digit seven
56	0038	8	ND080000	digit eight
57	0039	9	ND090000	digit nine
58	003a	:	SP130000	colon
59	003b	;	SP140000	semicolon
60	003c	<	SA030000	less-than sign
61	003d	=	SA040000	equals sign
62	003e	>	SA050000	greater-than sign
63	003f	?	SP150000	question mark
64	0040	@	SM050000	commercial at
65	0041	A	LA020000	latin capital letter a
66	0042	B	LB020000	latin capital letter b
67	0043	C	LC020000	latin capital letter c
68	0044	D	LD020000	latin capital letter d
69	0045	E	LE020000	latin capital letter e
70	0046	F	LF020000	latin capital letter f
71	0047	G	LG020000	latin capital letter g
72	0048	H	LH020000	latin capital letter h
73	0049	I	LI020000	latin capital letter i
74	004a	J	LJ020000	latin capital letter j
75	004b	K	LK020000	latin capital letter k
76	004c	L	LL020000	latin capital letter l
77	004d	M	LM020000	latin capital letter m
78	004e	N	LN020000	latin capital letter n
79	004f	O	LO020000	latin capital letter o
80	0050	P	LP020000	latin capital letter p
81	0051	Q	LQ020000	latin capital letter q
82	0052	R	LR020000	latin capital letter r
83	0053	S	LS020000	latin capital letter s
84	0054	T	LT020000	latin capital letter t
85	0055	U	LU020000	latin capital letter u
86	0056	V	LV020000	latin capital letter v
87	0057	W	LW020000	latin capital letter w
88	0058	X	LX020000	latin capital letter x
89	0059	Y	LY020000	latin capital letter y
90	005a	Z	LZ020000	latin capital letter z
91	005b	[	SM060000	left square bracket
92	005c	\	SM070000	backslash
93	005d	]	SM080000	right square bracket
94	005e	ˆ	SD150000	circumflex accent
95	005f	_	SP090000	underline
96	0060	`	SD130000	grave accent
97	0061	a	LA010000	latin small letter a
98	0062	b	LB010000	latin small letter b
99	0063	c	LC010000	latin small letter c
100	0064	d	LD010000	latin small letter d
101	0065	e	LE010000	latin small letter e
102	0066	f	LF010000	latin small letter f
103	0067	g	LG010000	latin small letter g
104	0068	h	LH010000	latin small letter h
105	0069	i	LI010000	latin small letter i
106	006a	j	LJ010000	latin small letter j
107	006b	k	LK010000	latin small letter k
108	006c	l	LL010000	latin small letter l
109	006d	m	LM010000	latin small letter m
110	006e	n	LN010000	latin small letter n
111	006f	o	LO010000	latin small letter o
112	0070	p	LP010000	latin small letter p
113	0071	q	LQ010000	latin small letter q
114	0072	r	LR010000	latin small letter r
115	0073	s	LS010000	latin small letter s
116	0074	t	LT010000	latin small letter t
117	0075	u	LU010000	latin small letter u
118	0076	v	LV010000	latin small letter v
119	0077	w	LW010000	latin small letter w
120	0078	x	LX010000	latin small letter x
121	0079	y	LY010000	latin small letter y
122	007a	z	LZ010000	latin small letter z
123	007b	{	SM110000	left  curly bracket
124	007c	|	SM130000	vertical line
125	007d	}	SM140000	right curly bracket
126	007e	~	SD190000	tilde
127				non-display character (DEL)
128	00c4	Ä	LA180000	latin capital letter a with diaeresis
129	00c5	Å	LA280000	latin capital letter a with  ring above
130	00c7	Ç	LC420000	latin capital letter c with cedilla
131	00c9	É	LE120000	latin capital letter e with acute accent
132	00d1	Ñ	LN200000	latin capital letter n with tilde
133	00d6	Ö	LO180000	latin capital letter o with diaeresis
134	00dc	Ü	LU180000	latin capital letter u with diaeresis
135	00e1	á	LA110000	latin small letter a with acute accent
136	00e0	à	LA130000	latin small letter a with grave accent
137	00e2	â	LA150000	latin small letter a with circumflex accent
138	00e4	ä	LA170000	latin small letter a with diaeresis
139	00e3	ã	LA190000	latin small letter a with tilde
140	00e5	å	LA270000	latin small letter a with ring above
141	00e7	ç	LC410000	latin small letter c with cedilla
142	00e9	é	LE110000	latin small letter e with acute accent
143	00e8	è	LE130000	latin small letter e with grave accent
144	00ea	ê	LE150000	latin small letter e with circumflex accent
145	00eb	è	LE170000	latin small letter e with diaeresis
146	00ed	í	LI110000	latin small letter i with acute accent
147	00ec	ì	LI130000	latin small letter i with grave accent
148	00ee	î	LI150000	latin small letter i with circumflex accent
149	00ef	ï	LI170000	latin small letter i with diaeresis
150	00f1	ñ	LN190000	latin small letter n with tilde
151	00f3	ó	LO110000	latin small letter o with acute accent
152	00f2	ò	LO130000	latin small letter o with grave accent
153	00f4	ô	LO150000	latin small letter o with circumflex accent
154	00f6	ö	LO170000	latin small letter o with diaeresis
155	00f5	õ	LO190000	latin small letter o with tilde
156	00fa	ú	LU110000	latin small letter u with acute accent
157	00f9	ù	LU130000	latin small letter u with grave accent
158	00fb	û	LU150000	latin small letter u with circumflex accent
159	00fc	ü	LU170000	latin small letter u with diaeresis
160	2020	†	SM340000	dagger
161	00b0	°	SM190000	degree sign
162	00a2	¢	SC040000	cent sign
163	00a3	£	SC020000	pound sign
164	00a7	§	SM240000	section sign
165	2022		SM570000	bullet
166	00b6	¶	SM250000	paragraph sign
167	00df	ß	LS610000	latin small leter sharp s
168	00ae	®	SM530000	registered trademark sign
169	00a9	©	SM520000	copyright sign
170	2122	™	SM540000	trademark ligature
171	00b4	´	SD110000	acute accent
172	00a8	¨	SD170000	diaeresis
173	2260	≠	SA540000	not equal to
174	00c6	Æ	LA520000	latin capital letter a with e
175	00d8	Ø	LO620000	latin capital letter o with oblique stroke
176	221e	∞	SA450000	infinity sign
177	00b1	±	SA020000	plus-minus sign
178	2264	≤	SA520000	Less than or equal to
179	2265	≥	SA530000	Greater than or equal to
180	00a5	¥	SC050000	yen sign
181	00b5	µ	SM170000	micro sign
182	2202	¶	SA490000	partial differential sign
183	2211	∑	GS020000	summation
184	220f	Π	SA810000	repeated product
185	03c0	π	GP010000	greek small letter pi
186	222b		SA510000	integral sign
187	00aa	ª	SM210000	feminine ordinal indicator
188	00ba	º	SM200000	masculine ordinal indicator
189	2126	Ω	GO320000	greek capital letter omega
190	00e6	æ	LA510000	latin small letter a with e
191	00f8	ø	LO610000	latin small letter o with oblique stroke
192	00bf	¿	SP160000	inverted question mark
193	00a1	¡	SP030000	inverted exclamation point
194	00ac	¬	SM660000	not sign
195	221a	√	SA800000	radical sign
196	0192	ƒ	SC070000	latin small letter script f, florin sign
197	2248	≈	SA700000	almost equals
198	2206	Δ		increment
199	00ab	«	SP170000	left pointing double angle quotation mark
200	00bb	»	SP180000	right pointing double angle quotation mark
201	2026	…	SV520000	horizontal ellipsis
202	00a0		SP300000	no-break space
203	00c0	À	LA140000	latin capital letter a with grave accent
204	00c3	Ã	LA200000	latin capital letter a with tilde
205	00d5	Õ	LO200000	latin capital letter o with tilde
206	0152	Œ	LO520000	latin capital ligature o with e
207	0153	œ	LO510000	latin small ligature o with e
208	2013	-	SS680000	en-dash
209	2014		SM900000	em-dash
210	201c		SP210000	left double quotation mark
211	201d		SP220000	right double quotation mark
212	2018	`	SP190000	left single quotation mark
213	2019	´	SP200000	right single quotation mark
214	00f7	÷	SA060000	division sign
215	25ca	à	SA660000	lozenge
216	00ff	ÿ	LY170000	latin small letter y with diaeresis
217	0178	Ÿ	LY180000	latin capital letter y with diaeresis
218	2215	/	SP120001	division
219	00a4	¤	SC010000	currency sign
220	2039	<	SP270000	single left pointing angle quotation mark
221	203a	>	SP280000	single right pointing angle quotation mark
222	f001	fi	LF530000	fi ligature small
223	f002	fl	LF550000	fl ligature small
224	2021	‡	SM350000	double-dagger
225	2219	·	SA790000	middle dot
226	201a	‚	SP260000	single low quotation mark
227	201e	„	SP230000	double low quotation mark
228	2030	‰	SM560000	permille sign
229	00c2	Â	LA160000	latin capital letter a with circumflex accent
230	00ca	Ê	LE160000	latin capital letter e with circumflex accent
231	00c1	Á	LA120000	latin capital letter a with acute accent
232	00cb	Ë	LE180000	latin capital letter e with diaeresis
233	00c8	È	LE140000	latin capital letter e with grave accent
234	00cd	Í	LI120000	latin capital letter i with acute accent
235	00ce	Î	LI160000	latin capital letter i with circumflex accent
236	00cf	Ï	LI180000	latin capital letter i with diaeresis
237	00cc	Ì	LI140000	latin capital letter i with grave accent
238	00d3	Ó	LO120000	latin capital letter o with acute accent
239	00d4	Ô	LO160000	latin capital letter o with circumflex accent
240	f000			apple logo (may also appear at position 20)
241	00d2	Ò	LO140000	latin capital letter o with grave accent
242	00da	Ú	LU120000	latin capital letter u with acute accent
243	00db	Û	LU160000	latin capital letter u with circumflex accent
244	00d9	Ù	LU140000	latin capital letter u with grave accent
245	0131		LI610000	latin capital letter i without dot above
246	02c6	^	SD150100	circumflex accent
247	02d6		SD190100	nonspacing tilde
248	00af	¯	SD310000	macron
249	02d8		SD230000	breve
250	02d9		SD290000	dot above
251	02da		SD270000	ring above
252	00b8	¸	SD410000	cedilla
253	02dd		SD250000	double acute accent
254	02db		SD430000	ogonek
255	02c7		SD210000	caron


PostScript Text Characters in the Macintosh Set

These characters are only accessibleby their PostScript name, and cannot be accessed from a Macintosh keyboard.

PostScript Name	Unicode Index	IBM GCID	Unicode Name
brokenbar	00a6	SM650000	broken bar
Eth	00d0	LD620000	latin capital letter eth
eth	00f0	LD630000	latin small letter eth
Yacute	00dd	LY120000	latin capital letter y with  acute accent
yacute	00fd	LY110000	latin small letter y with  acute accent
Thorn	00de	LT640000	latin capital letter thorn
thorn	00fe	LT630000	latin small letter thorn
minus	2212	SA000000	minus
multiply	00d7	SA070000	multiplication sign
onesuperior	00b9	ND011000	superscript one
twosuperior	00b2	ND021000	superscript two
threesuperior	00b3	ND031000	superscript three
onehalf	00bd	NF010000	vulgar fraction one half
onequarter	00bc	NF040000	vulgar fraction one quarter
threequarters	00be	NF050000	vulgar fraction three quarters
franc	20a3		french franc
Gbreve	011e	LG240000	latin capital letter g with breve
gbreve	011f	LG230000	latin small letter g with breve
Idot	0130	LI300000	latin capital letter i with  dot above
Scedilla	015e	LS420000	latin capital letter s with cedilla
scedilla	015f	LS410000	latin small letter s with cedilla
Cacute	0106	LC120000	latin capital letter c with  acute accent
cacute	0107	LC110000	latin small letter c with  acute accent
Ccaron	010c	LC220000	latin capital letter c with hacek
ccaron	010d	LC210000	latin small letter c with hacek
dmacron	0111	LD610000	latin small letter d with stroke
Lslash	0141	LL620000	latin capital letter l with stroke
lslash	0142	LL610000	latin small letter l with stroke
Scaron	0160	LS220000	latin capital letter s with hacek
scaron	0161	LS210000	latin small letter s with hacek
Zcaron	017d	LZ220000	latin capital letter z with hacek
zcaron	017e	LZ210000	latin small letter z with hacek


Other Miscellaneous Characters

PostScript Name	UGL Index	IBM GCID	Char	Unicode Name
				propeller (appears only in Apple System Font, position #17)


Apple's Mapping Requirements and Recommendations

The following are lists of required characteristics for glyphs mapped to the stated character codes.

Glyph 0 is the missing character glyph.

Glyph 1 is the null glyph; it has no contours and zero advance width.

All characters in the character set defined above must be present. Certain specified characters, however, are mapped to glyph 0 (the missing character glyph) as stated below.

The following character codes must be mapped to glyph 0 (the missing character glyph). Note that all character codes are given as decimal values.

001-031	Misc. ASCII control codes (note exceptions below)

127	DEL	Delete

The following characters must map to glyph 1 (the null glyph).

000	NUL	Null

008	BS	Backspace

013	CR	Carriage Return (in a right-to-left font)

029	GS	Group Seperator

The following characters must map to a glyph with no contours and positive advance width:

009	HT	Horiztontal Tabulation

013	CR	Carriage Return (in a left-right font)

032	space

202	figureSpace (No-Break Space)

The following groups of characters must have the same width

009 (HT) and 032 (space)

The following is a list of recommendations for the glyphs mapped to the character codes stated:

Lining numbers should be monospaced. These include 048 through 057 (digits zero through nine). Old style figures need not be monospaced.

In cursive fonts, glyphs should overlap to allow glyphs to join together in device-independent text. A five per cent (5%) overlap is recommended.

White space should be evenly distributed between the left and right side bearings of glypExtra space should be placed on the right if grid-fitting results in an odd number of pixels.


Glyph Ordering

This lays out the order for the first 258 glyphs as suggested by Apple. Note this is a glyph ordering and not a character mapping.

Glyph #	Name	PostScript name
1	missing character glyph	.notdef
2	null
3	CR
4	space	space
:	:	:
:	:	:
:	:	:
226	caron
227	latin capital letter  L with stroke	Lslash
:	:	:
:	:	:
258	latin small letter d with stroke	dmacron


Table Requirements & Recommendations
Microsoft TrueType Files

There are many ways to construct a TrueType font file.  This appendix outlines the recommended method for constructing a font file that will operate on the Macintosh, Windows and OS/2, as well as with applications using Microsoft's TrueType Font Adaptation Kit. It should be noted that all TrueType fonts use Motorola-style byte ordering (Big Endian).

Table Requirements & Recommendations

In the table that follows below, the table names give the name of the TrueType tables in their internal tag format (e.g. "head" for the Font Header Table).

Table	Requirements & Recommendations

cmap	At least two subtables are required.  First is for platform id 3, encoding id 1 (Microsoft Unicode, UGL character set); this subtable must use cmap format 4 to map characters to the UGL character set specified in Chapter 5.  The second is for platform id 1, encoding id 0 (Macintosh, Roman character set); this subtable must use cmap format 0 to map characters to the standard Macintosh character set specified in Appendix C.  In order for the Macintosh 'cmap' table to be useful, the glyphs required for the Macintosh must have glyph indices less than 256 (since the 'cmap' subtable format 0 uses BYTE indices and therefor cannot index any glyph above 255). Note that the "apple logo" (_) and "propellor" () should be mapped to the nonexistent glyph. Remember that, despite references to "first" and "second" subtables, the subtables must be stored in sorted order by platform and encoding id.

glyf	Must contain all data required to construct the complete UGL character set as specified in Chapter 5.  In order for the Macintosh 'cmap' table to be useful, the glyphs required for the Macintosh must have glyph indices less than 256 (since the 'cmap' subtable format 0 uses BYTE indices and therefor cannot index any glyph above 255).  This, of course, means that all the glyphs needed to map to the Macintosh character set (as per Appendix C) must be placed within the first 256 glyph "slots" in this table.

head	All data required.

hhea	All data required.  It is suggested that monospaced fonts set numberLongMetrics to one.

hmtx	All data required.

loca	All data required.  In order for the Macintosh 'cmap' table to be useful, the glyphs required for the Macintosh must have glyph indices less than 256 (since the 'cmap' subtable format 0 uses BYTE indices and therefor cannot index any glyph with an index greater than 255). Beyond this requirement, the actual ordering of the glyphs in the font can be optimized based on expected utilization, with the most frequently used glyphs appearing at the beginning of the font file.  Additionally, glyphs that are often used together should be grouped together in the file.  The will help to minimize the amount of swapping required when the font is loaded into memory.

maxp	All data required.

name	At least two sets of name records required.  First is for platform id 3, encoding id 1 (Microsoft UGL character set); all name strings for this set of name records must use the UGL character set as defined in Chapter 5.  Note that this requires two bytes per character.  The second set of name records is for platform id 1, encoding id 0 (Macintosh Roman character set); all names for this set of name records must use the standard Macintosh character set defined in Appendix C.  Note that this requires only one byte per character.  Each set of name records should appear for US English (language id = 0x0409 for Microsoft records, language id = 0 for Macintosh records); additional language strings for the Microsoft set of records (platform id 3) may be added at the discretion of the font vendor.  All Name ID's defined in Chapter 4 should be defined for both sets of name records. Remember that, despite references to "first" and "second", the name record must be stored in sorted order (by platform id, encoding id, language id, name id). The 'name' table platform/encoding IDs must match the 'cmap' table platform/encoding IDs, which is how Windows knows which name set to use.

OS/2	All data required.

post	All information required, although the VM Usage fields may be set to zero.  Format 2 is required in order to support the two-byte glyph indices in the UGL character set.  Glyph names for the PostScript character set must be defined as per the "PostScript Reference Manual" (Adobe Systems Incorporated,  1988); note that names for all glyphs must be supplied as it cannot be assumed that  all Microsoft platforms will support the default names supplied on the Macintosh.  Names for the UGL glyphs outside the PostScript set should be assigned a four character hexidecimal string that corresponds to their UGL index (e.g. '2302' for the small house glyph). See Chapter 5 for the complete UGL character set, including PostScript glyph names (where defined).

cvt	Should be defined only if required by the font instructions.

fpgm	Should be defined only if required by the font instructions.

hdmx	This table is not necessary at all unless instructions are used to control the "phantom points", and should be omitted if bit 2 of the flags field in the 'head' table is zero (see 'head' table documentation in Chapter 4).   Microsoft recommends that this table be included for fonts with one or more non-linearly scaled glyphs (i.e. bit 2 or 4 of flags is set to 1).  Device records should be defined for 8 through 14 point, and even point sizes from 16 through 24 point.  These records should be for both 96 dpi (CGA, EGA, VGA) and 300 dpi (laser and ink jet printers) devices; note that the dpi values are for horizontal resolutions.  This will add approximately 9,600 bytes to the font file.  However, there will be a significant improvement in speed when requesting advance widths covered by these device records.   The widths that are covered are (in pixels): 11, 12, 13, 15, 16, 17, 19, 21, 24, 27, 29, 32, 33, 37, 42, 46, 50, 54, 58, 67, 75, 83, 92, 100.  All values have been rounded to the nearest pixel.  Note that at 300 dpi, a 12 point character would contain 37.5 pixels (rounded down to 37 for this list). If the font includes an 'LTSH' table, the hdmx values are not needed above the linearity threshold.

kern	Should contain a single kerning pair subtable (format 0).  Windows and OS/2 will not support format 2 (two-dimensional array of kern values by class).  Windows and OS/2 will not support multiple tables; only the first format 0 table found will be used. Also, Windows and OS/2 will not support coverage bits 0 through 4 (i.e. assumes horizontal data, kerning values, no cross stream, and override).

LTSH	Should be defined if bit 2 or 4 of flags in 'head' is set.

prep	Should be defined only if required by the font instructions.

VDMX	Should be present if hints cause the font to scale non-linearly. If not present, the font is assumed to scale linearly. Clipping may occur if values in this table are absent and font exceeds linear height.


Non-UGL Fonts

Note that  non-UGL fonts like Symbol or ITC Zapf Dingbats must use platform id 3 and encoding id 0 (Microsoft Unicode, non-UGL character set) for Microsoft, while platform id 1 and encoding id 0 (Macintosh, Roman character set) should be used for the Macintosh. The 'cmap' subtable for these fonts for platform id 3, encoding 0 (Microsoft Unicode, non-UGL) must be format 4, and the character codes should start at 0xF000 (which is the start of the Unicode User Space). Remember that the 'name' table encoding should agree with the 'cmap' table. The 'cmap' subtable for platform id 1, encoding 0 (Macintosh, Roman) should be format 0 and follow the standard PostScript character encodings. It is suggested that the 'cmap' format 4 encodings be derived by simply adding 0xF000 to the format 0 encodings.  Please note that under both OS/2 and Windows, only the first 224 characters of non-UGL fonts will be accessible (assumes that the first character is a space, then accesses that plus the next 223 characters. It does not matter where in user space these start, but 0xF020 is suggested). fsFirstCharIndex would be set based on the minimum Unicode value used (probably 0xF020). fsLastCharIndex would be set, in a similar fashion, to the maximum Unicode value.

This affects the 'cmap', 'post', 'glyf' and 'name' tables.  The requirements and recommendations for all other tables remain the same.


Device Resolutions

OS/2 and Windows make use of a logical device resolution.  The physical resolution of a device is also available, but fonts will be rendered based on the logical resolution.  The table below lists some important logical resolutions in dots per inch (Horizontal x Vertical). The most important ratios (in order) are 1:1, 1.67:1 and 1.33:1.

Device	Resolution	Aspect Ratio
CGA	96 x 48	2:1
EGA	96 x 72	1.33:1
VGA	96 x 96	1:1
8514	120 x 120	1:1
Dot Matrix	120 x 72	1.67:1
Laser Printer	300 x 300	1:1


Baseline to Baseline Distances
Baseline to Basleline Distances

The suggested Baseline to Baseline Distance (BTBD) is computed differently for Windows and the Macintosh, and it is based on different TrueType metrics. However, if the recommendations below are followed, the BTBD will be the same for both Windows and the Mac.

Windows Metric	TrueType Metric
ascent	usWinAscent
descent	usWinDescent
internal leading	usWinAscent - usWinDescent - unitsPerEm
external leading	MAX (0, LineGap - ((usWinAscent - usWinDescent) - (Ascender - Descender))
Suggested BTBD = ascent + descent + external leading
Pixels above the ascent or below the descent will be clipped from the character; this is true for all output devices.

The usWinAscent, usWinDescent  are values from the 'OS/2' table. The unitsPerEm values is from the 'head' table. The LineGap, Ascender and Descender values are from the 'hhea' table. Ascender and Descender are metrics defined by Apple and are not to be confused with the Windows ascent or descent, nor should they be confused with the true typographic ascender and descender that are found in AFM files. It should be clear that the "external leading" can never be less than zero.

Macintosh Metric	TrueType Metric
ascender	Ascender
descender	Descender
leading	LineGap
Suggested BTBD = ascender + descender + leading
If pixels extend above the ascent or below the descent, the character will be squashed in the vertical direction so that all pixels fit within these limitations; this is true for screen display only.

If you perform some simple algebra, you will see that the suggested BTBD across both Macintosh and Windows will be identical if and only if:
LineGap >= (yMax - yMin) - (Ascender - Descender)

These metrics are returned as part of the logical font data structure by the GDI

CreateLogFont( ) API.

These metrics are returned by the Mac QuickDraw GetFontInfo( ) API.


Style Bits

For backwards compatibility with previous versions of Windows, the macStyle bits in the 'head' table will be used to determine whether or not a font is regular, bold or italic (in the absence of an 'OS/2' table). This is completely independent of the usWeightClass and PANOSE information in the 'OS/2' table, the ItalicAngle in the 'post' table, and all other related metrics. If the 'OS/2' table is present, then the fsSelection bits are used to determine this information.


Miscellaneous Recommendations

SCANCTRL or the drop-out control rasterizer should be avoided for Roman fonts above 8 points per em (ppem) when the font is not under rotation. Do not use this unless needed. SCANCTRL should only be enabled at or below 8 ppem or when the font is rotated.  It should not be used for "stretched" fonts (e.g. fonts displayed at non-square aspect ratios, like that found on an EGA).

The Apple 'cmap' subtable should be constructed according to the recommendations in Appendix C.

As suggested in the introduction to Chapter 4, all tables should be multiples of four bytes. While this is not required by the TrueType rasterizer, it does prevent ambiguous checksum calculations.

All tables should be recorded in the table directory with their actual length. To ensure that checksums are calculated correctly, it is suggested that tables begin on LONG word boundries, as mentioned in Chapter 4. Any extra space after a table (and before the next LONG word boundry) should be padded with zeros.

The preferred suffix for TrueType font files under Windows  *.TTF.

The Subfamily string in the 'name' table should be used for varients of weight (ultra light to extra black) and style (oblique/italic or not).  So, for example, the full font name of "Helvetica Narrow Italic" should be defined as Family name "Helvetica Narrow" and Subfamily "Italic". This is so that Windows can group the standard four weights of a font in a reasonable fashion for non-typographically aware applications which only support combinations of "bold" and "italic".


AA
Adjust Angle(No Longer Supported)

AA[ ]

Code Range 	0x7F

Pops	p: point number (ULONG)

Pushes	 -

Uses	zp1 with point p, zp0 with rp0

AA was a prototype instruction from an earlier version of the rasterizer which is no longer supported.  It is now a no-op which pops its arguments from the stack and may be deleted entirely from later versions of the rasterizer.

AA attempts to find the best angle for the line. A good angle,  for TrueType fonts, is defined as an angle with a small pixel pattern repetition period. If AA can move point p along the freedom_vector so that the line from rp0 to point p is at a good angle, it will do so.

The instruction considers 152 different distinct angles. These are all the angles that have a repetition period of less than 9 pixels. The instruction does not change an angle of more than about ± 10-12 degrees. Within this range it will search for an angle that has the smallest penalty. The penalty must be less than 10 pixels. The penalty is defined as (in pixels):

R + l * a

where

R:	repetition period

l:	line rp0 to point p projected into a unit vector at an angle orthogonal to the angle being examined

a:	angle_weight/64

When acting on small point sizes, the instruction is likely to make a large adjustment to the angle. When acting on sufficiently large point sizes, the instruction does not change the angle at all. If high values are used for angle_weight, the angle does not change much. If low values are used for angle_weight, the angle changes significantly.


ABS
ABSolute value

ABS[ ]

Code Range	0x64

Pops	n

Pushes	|n|: absolute value of n (F26Dot6)

Pops n off the stack and pushes onto the stack the absolute value of n.

Example:

case 1:

case 2:


ADD

ADD[ ]

Code Range	0x60

Pops	n1, n2 (F26Dot6)

Pushes	(n2 + n1)

Pops n1 and n2 off the stack and pushes the sum of the two elements onto the stack.


AND
logical AND

AND[ ]

Code Range	0x5A

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	( e1 and e2 ): logical and of e1 and e2 (ULONG)

Pops e1 and e2 off the stack and pushes onto the stack the result of a logical and of the two elements. Zero is returned if either or both of the elements are FALSE (have the value zero). One is returned if both elements are TRUE (have a non zero value).

case 1:

AND[ ]

case 2:

AND[ ]


CALL
CALL function

CALL[ ]

Code Range	0x2B

Pops	f: function identifier number (integer in the range 0 to n-1 where n is specified
in the 'maxp' table )

Pushes	-

Calls the function identified by the number f.


CEILING

CEILING[ ]

Code Range 	0x67

Pops	n1: number whose ceiling is desired (F26Dot6)

Pushes 	n: ceiling of n1 (F26Dot6)

Pops n1 and returns n, the least integer value greater than or equal to n1. For instance, the ceiling of 15 is 15, but the ceiling of 15.3 is 16. The ceiling of  -0.8 is 0. (n is the least integer value greater than or equal to n1)

Example:

CEILING[ ]

case 1:

case 2:


DEBUG
DEBUG call

DEBUG[ ]

Code Range	0x4F

Pops	number (ULONG)

Pushes	-

This instruction is only for debugging purposes and should not be a part of a finished font. Some implementations may not support this instruction.

On Microsoft platforms, this instruction will issue an interrupt 3 (INT 3); if a debugger is loaded, this will result in a debug trap. On entry to the debugger, DS:BX (or EBX if running in 386 mode) will point at the local graphics state structure (documented elsewhere).  To resume, execution must be restarted at the instruction  following the INT 3.

On a Macintosh, this instruction will go to MacsBug and print the number taken from the stack. Typing "g" will cause execution to resume.


DIV
DIVide

DIV[ ]

Code Range	0x62

Pops	n1: divisor (F26Dot6)

n2: dividend (F26Dot6)

Pushes

Pops n1 and n2 off the stack and pushes onto the stack the quotient obtained by dividing n2 by n1. Note that this truncates rather than rounds the value.


ENDF
END Function definition

ENDF[ ]

Code Range	0x2D

Pops	-

Pushes	-

Marks the end of a function definition or an instruction definition.


EVEN

EVEN[ ]

Code Range	0x57

Pops	e1: stack element (F26Dot6)

Pushes	Boolean value (ULONG in the range [0,1])

Tests whether the number at the top of the stack is even. Pops e1 off the stack and rounds it before testing it.  If the rounded number is even, one, signifying TRUE, is pushed onto the stack if it is odd, zero, signifying FALSE, is placed onto the stack.

Example:

EVEN[ ]

This example assume that round_state is RTG.


FDEF
Function DEFinition

FDEF[ ]

Code Range	0x2C

Pops	f: function identifier number (integer in the range 0 to n-1 where n is specified
in the 'maxp' table )

Pushes	-

Marks the start of a function definition.  The argument f is a number that uniquely identifies this function. A function definition can appear only in the Font Program or the CVT program.


FLOOR

FLOOR[ ]

Code Range	0x66

Pops	n1: number whose floor is desired (F26Dot6)

Pushes	n : floor of n1 (F26Dot6)

Pops n1 and returns n, the greatest integer value less than or equal to n1.

Example:

FLOOR[ ]

case 1:

case 2:

case 3:


GETINFO
GET INFOrmation

GETINFO[ ]

Code Range	0x88

Pops	selector (integer)

Pushes	result (integer)

GETINFO is used to obtain data about the font scaler version and the characteristics of the current glyph. The instruction pops a selector used to determine the type of information desired and pushes a result onto the stack.

A selector value of 1 indicates that the scaler version number is the desired information, a value of 2 is a request for glyph rotation status, a value of 4 asks whether the glyph has been stretched.  (Looking at this another way, setting bit 0 asks for the scaler version number, setting bit 1 asks for the rotation information, setting bit 2 ask for stretching information. To request information on two or more of these set the appropriate bits.)

The result pushed onto the stack contains the requested information.  More precisely, bits 0 through 7 comprise the Scaler version number. Version 1 is Macintosh System 6 INIT, version 2 is Macintosh System 7, and version 3 is Windows 3.1. Version Version numbers 0 and 4 through 255 are reserved.

Bit 8 is set to 1 if the current glyph has been rotated. It is 0 otherwise. Setting bit 9 to 1 indicates that the glyph has been stretched. It is 0 otherwise.

When the selector is set to request more than one piece of information, that information is OR'd together and pushed onto the stack. For example, a selector value of 6 requests both information on rotation and stretching and will result in the setting of both bits 8 and 9.


IDEF
Instruction DEFinition

IDEF[ ]

Code Range	0x89

Pops	opcode (8 bit code padded with zeroes to ULONG)

Pushes	-

Begins the definition of an instruction. The instruction definition terminates when at ENDF, which is encountered in the instruction stream. Subsequent executions of the opcode popped will be directed to the contents of this instruction definition (IDEF). IDEFs should be defined in the Font Program or the CVT Program. An IDEF affects only undefined opcodes. If the opcode in question is already defined, the interpreter will ignore the IDEF. This is to be used as a patching mechanism for future instructions.


ALIGNPTS
ALIGN Points

ALIGNPTS[ ]

Code Range	0x27

Pops	p1: point number (ULONG)
p2: point number (ULONG)

Pushes	-

Uses	zp0 with point p1 and zp1 with point p2

Makes the distance between point 1 and point 2 zero by moving both along the freedom_vector to the average of both their projections along the projection_vector.

Example:

ALIGNPTS[] 3 7


ALIGNRP
ALIGN Relative Point

ALIGNRP[ ]

Code Range 	0x3C

Pops	p: point number (ULONG)

Pushes 	-

Uses	zp1 with point p and zp0 with rp0 loop

Reduces the distance between rp0 and point p to zero. Since distance is measured along the projection_vector and movement is along the freedom_vector, the effect of the instruction is to align points.

case 1:

P  	F

case 2:

P  	F


CINDEX
Copy the INDEXed element to the top of the stack

CINDEX[ ]

Code Range	0x25

Pops	k : stack element number

Pushes	ek: indexed element (ULONG)

Puts a copy of the kth stack element on the top of the stack.

Example:

CINDEX[ ]


CLEAR
Clear the entire stack

CLEAR[ ]

Code Range	0x22

Pops	all the items on the stack (ULONGs)

Pushes	 -

Clears all elements from the stack.


DELTAC1
DELTA exception C1

DELTAC1[ ]

Code Range	0x73

Pops	n: number of pairs of exception specifications and CVT entry
numbers  (ULONG)

c1, arg1, c2, arg2,..., cn, argn: (pairs of ULONGs)

Pushes	-

DELTAC1 changes the value in each CVT entry specified at the size and by the amount specified in its paired argument.

The grouping [argi, ci ] can be executed n times. The value of argi may vary between iterations.


DELTAC2
DELTA exception C2

DELTAC2[ ]

Code Range	0x74

Pops	n:	number of pairs of exception specifications and CVT entry numbers
(ULONG)

c1, arg1, c2, arg2,..., cn, argn: (pairs of ULONGs)

Pushes 	-

DELTAC2 changes the value in each CVT entry specified at the size and by the amount 	 specified in its paired argument.

The grouping [argi, ci] can be executed n times. The value of argi may vary between iterations.


DELTAC3
DELTA exception C3

DELTAC3[ ]

Code Range	0x75

Pops	n:	number of pairs of  CVT entry numbers and exception
specifications (ULONG)

c1, arg1, c2 arg2,..., cn, argn:	pairs of CVT entry number and exception
specifications (pairs of ULONGs)

Pushes	-

DELTAC3 changes the value in each CVT entry specified at the size and by the amount specified in its paired argument.

The grouping [argi, ci] can be executed n times. The value of argi may vary between iterations.


DELTAP1
DELTA exception P1

DELTAP1[ ]

Code Range	0x5D

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2, ..., pn, argn: n pairs of exception specifications and
points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_base, delta_shift

DELTAP1 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of points and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi may vary between iterations.


DELTAP2
DELTA exception P2

DELTAP2[ ]

Code Range	0x71

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2,  ..., pn, argn: n pairs of exception specifications and points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_shift, delta_base

DELTAP2 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of points and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi may vary between iterations.


DELTAP3
DELTA exception P3

DELTAP3[ ]

Code Range	0x72

Pops	n: number of pairs of exception specifications and points (ULONG)

p1, arg1, p2, arg2, ..., pn, argn: n pairs of exception specifications and
points (pairs of ULONGs)

Pushes	-

Uses	zp0, delta_base, delta_shift

DELTAP3 moves the specified points at the size and by the amount specified in the paired argument. An arbitrary number of point and arguments can be specified.

The grouping [argi, pi] can be executed n times. The value of argi  may vary between iterations.


DEPTH
Returns the DEPTH of the stack

DEPTH[ ]

Code Range	 0x24

Pops	-

Pushes	n: number of elements (ULONG)

Pushes n, the number of elements currently in the stack onto the stack.

Example:


DUP
Duplicate top stack element

DUP[ ]

Code Range	0x20

Pops	e: stack element (ULONG)

Pushes	e, e (two ULONGs)

Duplicates the element at the top of the stack.


EIF
End IF

EIF[ ]

Code Range	0x59

Pops	-

Pushes	-

Marks the end of an IF[ ] instruction.


ELSE

ELSE[ ]

Code Range	0x1B

Pops	-

Pushes	-

Marks the start of the sequence of instructions that are to be executed if an IF instruction encounters a FALSE value on the stack. This sequence of instructions is terminated with an EIF instruction.


EQ
EQual

EQ[ ]

Code Range	0x54

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If they are equal, one signifying TRUE is pushed onto the stack. If they are not equal, 0, signifying FALSE is placed onto the stack.

Example:

EQ[ ]


FLIPOFF
Set the auto_flip Boolean to OFF

FLIPOFF[ ]

Code Range	0x4E

Pops	-

Pushes	-

Sets	auto_flip

Affects	MIRP, MIAP

Set the auto_flip Boolean in the Graphics State to FALSE causing the MIRP and MIAP instructions to use the sign of Control Value Table entries.  The default auto_flip Boolean value is TRUE.


FLIPON
Set the auto_flip Boolean to ON

FLIPON[ ]

Code Range 	0x4D

Pops	-

Pushes 	-

Sets	auto_flip

Affects	MIRP, MIAP

Sets the auto_flip Boolean in the Graphics State to TRUE causing the MIRP and MIAP instructions to ignore the sign of Control Value Table entries.The default auto_flip Boolean value is TRUE.


FLIPPT
FLIP PoinT

FLIPPT[ ]

Code Range	0x80

Pops	p: point number (ULONG)

Pushes	-

Uses	loop

Flips points that are off the curve so that they are on the curve and points that are on the curve so that they are off the curve. The point is not marked as touched. The result of a FLIPPT instruction is that the contour describing part of a glyph outline is redefined.

Before:

After


FLIPRGOFF
FLIP RanGe OFF

FLIPRGOFF[ ]

Code Range	0x82

Pops	highpoint: highest point number in range of points to be flipped (ULONG)

lowpoint: lowest point number in range of points to be flipped (ULONG)

Pushes	-

Flips a range of points beginning with lowpoint and ending with highpoint so that any on curve points become off the curve points.

NOTE: This instruction changes the curve but the position of the points is unaffected.  Accordingly, points affected by this instruction are not marked as touched.

Example:

FLIPRGOFF[ ] 8 6

Before :

After:


FLIPRGON
FLIP  RanGe ON

FLIPRGON[ ]

Code Range	0x81

Pops	highpoint: highest point number in range of points to be flipped (ULONG)

lowpoint: lowest point number in range of points to be flipped (ULONG)

Pushes	-

Flips a range of points beginning with lowpoint and ending with highpoint so that any off the curve points become on the curve points. The points are not marked as touched.

Example:

FLIPRGON[ ] 1 5

Before:

After:

Will make all off curve points between point 0 and point 5 into on curve points as shown


GC
Get Coordinate projected onto the projection_vector

GC[a]

Code Range	0x46 - 0x47

a	0: use current position of point p

1: use the position of point p in the original outline

Pops	p: point number (ULONG)

Pushes	value: coordinate location (F26Dot6)

Uses	zp2

Measures the coordinate value of point p on the current projection_vector and pushes the value onto the stack.

Example

The following example shows that the value returned by GC is dependent upon the current position of the projection_vector. Note that point p is at the position (300,420) in the coordinate grid.

GC[1] 9

P

P

P

The projection_vector is parallel to the line from (0,0) to (300,420)


GFV
Get Freedom_Vector

GFV[ ]

Code Range	0x0D

Pops	-

Pushes	x: x-component of freedom_vector (2.14 number padded with zeroes)

y: y component of freedom_vector (2.14 number padded with zeroes)

Gets	freedom_vector

Puts the x and y  components of the freedom_vector on the stack. The freedom_vector is put onto the stack as two 2.14 coordinates.

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example

GFV[ ]


GPV
Get Projection_Vector

GPV[ ]

Code Range	0x0C

Pops	-

Pushes	x: x component of projection_vector  (2.14 fixed point number padded
with zeroes)

y : y component of projection_vector  (2.14 fixed point number padded
with zeroes)

Gets	projection_vector

Pushes the x and y components of the projection_vector onto the stack as two 2.14 numbers.

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

case 1:

P

The stack entry 0x4000 which when interpreted as a 2.14 number is simply 1. This command reveals that, in this case, the projection_vector is a unit vector that points in the x-direction.

case 2:

P

Here the projection_vector is a unit vector that point in the direction of the y-axis.

case 3:

P

 NOTE:  0x2D41 is the hex equivalent of  [image] . As a result of this instruction, the projection_vector is set to a 45 degree angle relative to the x-axis.


GT
Greater Than

GT[ ]

Code Range	0x52

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If e2 is greater than e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not greater than e1, 0, signifying FALSE, is placed onto the stack.

Example:

GT[ ]


GTEQ
Greater Than or Equal

GTEQ[ ]

Code Range	0x53

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 off the stack and compares them. If e2 is greater than or equal to e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not greater than or equal to e1, 0, signifying FALSE, is placed onto the stack.

Example:

GTEQ[ ]


IF
IF test

IF[ ]

Code Range	0x58

Pops	e: stack element (ULONG)

Pushes	-

Tests the element popped off the stack: if it is zero (FALSE), the instruction pointer is jumped to the next ELSE or EIF instruction in the instruction stream. If the element at the top of the stack is nonzero (TRUE),  the next instruction in the instruction stream is executed. Execution continues until an ELSE instruction is encountered or an EIF instruction ends the IF. If an else statement is found before the EIF, the instruction pointer is moved to the EIF statement.

case 1:

Element at top of stack is TRUE; instruction pointer is unaffected. IF terminates with EIF.

case 2:

Element at top of stack is TRUE. The instruction stream is sequentially executed until ELSE is encountered whereupon the instruction pointer jumps to the EIF statement that terminates the IF.

case 3:

Element at the top of the stack is FALSE; instruction pointer is moved to the ELSE statement; instructions are then executed sequentially; EIF ends the IF statement.


INSTCTRL
INSTRuction execution ConTRoL

INSTCTRL[]

Code Range	0x8E

Pops	s:	selector (int32)
value: USHORT (padded to 32 bits) used to set value of
instruction_control

Pushes	-

Sets	instruction_control

Sets the instruction control state variable making it possible to turn on or off the execution of instructions and to regulate use of parameters set in the CVT program.

This instruction clears and sets various control flags. The selector is used to choose the relevant flag. The value determines the new setting of that flag. In version 1.0 there are only two flags in use:

Flag 1 is used to inhibit grid-fitting. It is chosen with a selector value of 1. If this flag is set to TRUE (v=1), any instructions associated with glyphs will not be executed. For example, to inhibit grid-fitting when a glyph is being rotated or stretched, use the following sequence on the preprogram:

PUSHB[000] 6	/* ask GETINFO to check for stretching or rotation */
GETINFO[]	/* will push TRUE if glyph is stretched or ratated */
IF[]	/* tests value at top of stack */
PUSHB[000] 1	/* value for INSTCTRL */
PUSHB[000] 1	/* selector for INSTCTRL */
INSTRCTRL[]	/* based on selector and value will turn grid-fitting off */
EIF[]

Flag 2 is used to establish that any parameters set in the CVT program should be ignored when instructions associated with glyphs are executed. These include, for example, the values for scantype and the CVT cut-in. When flag2 is set to TRUE, the default values of those parameters will be used regardless of any changes that may have been made in those values by the preprogram. When flag2 is set to FALSE, parameter values changed by the CVT program will be used in glyph instructions.

INSTCTRL[] can only be executed in the CVT program.


IP
Interpolate Point by the last relative stretch

IP[ ]

Code Range	0x39

Pops	p: point number (ULONG)

Pushes	-

Uses	zp0 with rp1, zp1 with rp2, zp2 with point p, loop

Moves point p so that its relationship to rp1 and rp2 is the same as it was in the original uninstructed outline. Measurements are made along the projection_vector, and movement to satisfy the interpolation relationship is constrained to be along the freedom_vector. This instruction is illegal if rp1 and rp2 have the same position on the projection_vector.

F [image] P

In the example shown, assume that the points referenced by rp1 and rp2 are moved as shown. An IP instruction is then used to preserve their relative relationship with point p. After the IP the following should be true

D(p, rp1)/D(p',rp1') = D(p,rp2)/D(p', rp2')

In other words, the relative distance is preserved.


ISECT
moves point p to the InterSECTion of two lines

ISECT[ ]

Code Range	0x0F

Pops	b1: end point of line 2  (ULONG)
b0: start point of line 2  (ULONG)
a1: end point of line 1  (ULONG)
a0: start point of line 1  (ULONG)
p: point to move (ULONG)

Pushes	 -

Uses	zp2 with point p, zp1 with line A, zp0 with line B

Puts point p at the intersection of the lines A and B. The points a0 and a1 define line A. Similarly, b0 and b1 define line B. ISECT ignores the freedom_vector in moving point p.

Example:

ISECT[ ] 21 9 5 4 7


IUP
Interpolate Untouched Points through the outline

IUP[a]

Code Range	0x30 - 0x31

a	0: interpolate in the y-direction

1: interpolate in the x-direction

Pops	-

Pushes	-

Uses	zp2

Considers a glyph contour by contour, moving any untouched points in each contour that are between a pair of touched points. If the coordinates of an untouched point were originally between those of the touched pair, it is linearly interpolated between the new coordinates, otherwise the untouched point is shifted by the amount the nearest touched point is shifted.

This instruction operates on points in the glyph zone pointed to by zp2. This zone should almost always be zone 1. Applying IUP to zone 0 is an error.

Consider three consecutive points all on the same contour. Two of the three points, p1 and p3 have been touched. Point p2 is untouched. The effect of an IUP in the x-direction is to move point p2 so that is in the same relative position to points p1 and p3 before they were moved.

The IUP instruction does not touch the points it moves. Thus the untouched points affected by an IUP instruction will be affected by subsequent IUP instructions unless they are touched by an intervening instruction. In this case, the first interpolation is ignored and the point is moved based on its original position.


JMPR
JuMP

JMPR[ ]

Code Range	0x1C

Pops	offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

The signed offset is added to the instruction pointer and execution is resumed at the new location in the instruction steam. The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.


glyph

A single graphic symbol, as actually realized on paper or a display screen.


JROF
Jump Relative On False

JROF[ ]

Code Range	0x79

Pops	e: stack element (ULONG)
offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

In the case where the Boolean is FALSE, the signed offset will be added to the instruction pointer and execution will be resumed there; otherwise, the jump is not taken.  The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.

case 1:

element is FALSE.

case 2:

element is TRUE.

Logical functions

The TrueType instruction set includes a set of logical functions that can be used to test the value of a stack element or to compare the values of two stack elements. The logical functions compare 32 bit values (ULONG) and return a Boolean value to the top of the stack.


JROT
Jump Relative On True

JROT[ ]

Code Range	0x78

Pops	e:stack element (ULONG)
offset: number of bytes to move instruction pointer (ULONG)

Pushes	-

Obtains an offset and tests a Boolean value. If the Boolean is TRUE, the signed offset will be added to the instruction pointer and execution will be resumed at the address obtained. Otherwise, the jump is not taken. The jump is relative to the position of the instruction itself. That is, the instruction pointer is still pointing at the JROT[ ] instruction when offset is added to obtain the new address.

Example:

case 1:

element is FALSE.

case 2:

element is TRUE.


LOOPCALL
LOOP and CALL function

LOOPCALL[ ]

Code Range	0x2A

Pops	count: 	number of times to call the function (signed word) the
'maxp' table
f: function number integer in the range 0 to n-1 where n
is specified in
Pushes	-

Calls the function f, count number of times.

Example:

Assume the Font Program contains this:

PUSHB(000), 17 	push 17 onto the stack

FDEF[ ]	start defining function 17
    ...	contents of function

    ...

ENDF[ ]	end the definition

PUSHB(000),5	push count

PUSHB(000),17	push function number

LOOPCALL[ ]	call function17, 5 times


LT
Less Than

LT[ ]

Code Range	0x50

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e2 and e1 off the stack and compares them: if e2 is less than e1, 1, signifying TRUE, is pushed onto the stack if e2 is not less than e1, 0, signifying FALSE, is placed onto the stack.

Example:

LT[ ]


LTEQ
Less Than or Equal

LTEQ[ ]

Code Range	0x51

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e2 and e1 off the stack and compares them. If e2 is less than or equal to e1, 1, signifying TRUE, is pushed onto the stack. If e2 is not less than or equal to e1, 0, signifying FALSE, is placed onto the stack.

Example:

LTEQ[ ]


MAX
MAXimum of top two stack elements

MAX[ ]

Code Range	0x8B

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	maximum of e1 and e2

Pops two elements, e1 and e2, from the stack and pushes the larger of these two quantities onto the stack.


MD
Measure Distance

MD[ ]

Code Range	0x49 - 0x4A

a	0: measure distance in grid-fitted outline

1: measure distance in original outline

Pops	p1: point number (ULONG)
p2: point number (ULONG)

Pushes	distance (F26Dot6)

Uses	zp0 with point p1, zp1 with point p2

Measures the distance between outline point p1 and outline point p2. The value returned is in  pixels (F26Dot6) If distance is negative, it was measured against the projection vector. Reversing the order in which the points are listed will change the sign of the result.

Example:

In the illustration below MD[1] between points 25 and 31 will return a smaller value that MD[0] at 10 pixels per em on a 72 dpi device. The difference is due to the effects of grid-fitting which, at this size, stretches out the counter.

P


MDAP
Move Direct Absolute Point

MDAP[ a ]

Code Range	0x2E - 0x2F

a:	0: do not round the value

1: round the value

Pops	p: point number (ULONG)

Pushes 	-

Sets 	rp0 = rp1 = point p

Uses 	zp0

Sets the reference points rp0 and rp1 equal to point p. If a=1, this instruction rounds point p to the grid point specified by the state variable round_state. If a=0, it simply marks the point as touched in the direction(s) specified by the current freedom_vector.

Example:

MDAP[0]

When a=0, the point is simply marked as touched and the values of rp0 and rp1 set to point p.

F [image] P

MDAP[1] assuming that the round_state is round to grid and the freedom_vector is a shown.

F [image]  P


MDRP
Move Direct Relative Point

MDRP[abcde]

Code Range	0xC0 - 0xDF

a	0: do not set rp0 to point p after move

1: do set rp0 to point p after move

b	0: do not keep distance greater than or equal
to minimum_distance

1: keep distance greater than or equal to
minimum_distance

c	0: do not round distance

1: round the distance

de	distance type for engine characteristic compensation

Pops	p: point number (ULONG)

Pushes	-

Sets	after point p is moved, rp1 is set equal to rp0, rp2 is set equal to point p;
if the a flag is set to TRUE, rp0 is set equal to point p

Uses	zp0 with rp0 and zp1 with point p, round_state, single_width_value,
single_width_cut_in

MDRP moves point p along the freedom_vector so that the distance from its new position to the current position of rp0 is the same as the distance between the two points in the original uninstructed outline, and then adjusts it to be consistent with the Boolean settings. Note that it is only the original positions of rp0 and point p and the current position of rp0 that determine the new position of point p along the freedom_vector.

MDRP is typically used to control the width or height of a glyph feature using a value which comes from the original outline. Since MDRP uses a direct measurement and does not reference the control_value_cut_in, it is used to control measurements that are unique to the glyph being instructed. Where there is a need to coordinate the control of a point with the treatment of points in other glyphs in the font, a MIRP instruction is needed.

Though MDRP does not refer to the CVT, its effect does depend upon the single-width cut-in value. If the device space distance between the measured value taken from the uninstructed outline and the single_width_value is less than the single_width_cut_in, the single_width_value will be used in preference to the outline distance. In other words, if the two distances are sufficiently close (differ by less than the single_width_cut_in), the single_width_value will be used.

The setting of the round_state Graphics State variable will determine whether and how the distance of point p from point q is rounded. If the round bit is not set, the value will be unrounded. If the round bit is set, the effect will depend upon the choice of rounding state. The value of the minimum distance variable is the smallest possible value the distance between two points can be rounded to.

Distances measured with the MDRP instruction must be either black, white or grey. Indicating this value in Booleans de allows the interpreter to compensate for engine characteristics as needed. The value de specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

Example 1:

Graphics State Settings

Before MDRP
F [image] P

rp0	7
rp1	?
rp2	?

Case 1:

After MDRP[00001] 8

F [image] P
rp0	7
rp1	7
rp2	8

Case 2:

After MDRP[10001] 8

F [image] P
rp0	8
rp1	7
rp2	8

Example 2:

Point p is moved so that its distance from rp1 is the same as it was in the original outline.

F [image] P


MIAP
Move Indirect Absolute Point

MIAP[a]

Code Range 	0x3E - 0x3F

a	0: don't round the distance and don't look at
    the control_value_cut_in

1: round the distance and look at the
    control_value_cut_in

Pops	n: CVT entry number (F26Dot6)

p: point number (ULONG)

Pushes 	-

Sets	rp0 = rp1 = point p

Uses	zp0, round_state, control_value_cut_in

Moves point p to the absolute coordinate position specified by the nth Control Value Table entry . The coordinate is measured along the current projection_vector. If a=1, the position will be rounded as specified by round_state. If a=1, and if the device space difference between the CVT value and the original position is greater than the control_value_cut_in, then the original position will be rounded (instead of the CVT value.)

Rounding is done as if the entire coordinate system has been rotated to be consistent with the projection_vector. That is, if round_state is set to 1, and the projection_vector and freedom_vector are at a 45_ angle to the x-axis, then a MIAP[1] of a point to 2.9 pixels will round to 3.0 pixels along the projection_vector.

The a Boolean above controls both rounding and the use of the control_value_cut_in.  If you would like the meaning of this Boolean to specify only whether or not the MIAP[ ] instruction should look at the control_value_cut_in value, use the ROFF[ ] instruction to turn off rounding.

This instruction can be used to create Twilight Zone points.

Example:

MIAP[1] 4 7

case 1:

rounding is OFF

The point is moved to the position specified in the CVT

case 2:

the cut_in test succeeds and rounding is RTG

The value in the CVT is subjected to the rounding rule and then the point is moved to the rounded position.

case 3:

the cut_in test fails and rounding is OFF

Here the point is not moved.

case 4:

the cut_in test fails and rounding is RTG

In this case the point is moved to the nearest grid position.


MIN
MINimum of top two stack elements

MIN[ ]

Code Range	0x8C

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	minimum of e1 and e2

Pops two elements, e1 and e2, from the stack and pushes the smaller of these two quantities onto the stack.


MINDEXV
Move the INDEXed element to the top of the stack

MINDEX[ ]

Code Range	0x26

Pops	k: stack element number

Pushes

Moves the indexed element to the top of the stack.

MINDEX[ ]


MIRP
Move Indirect Relative Point

MIRP[abcde]

Code Range	0xE0 - 0xFF

a	0: Do not set RP0 to p

1: Set rp0 to p

b	0: Do not keep distance greater than or equal to
minimum_distance

1: Keep distance greater than or equal to
minimum_distance

c	0: Do not round the distance and do not look at the
control_value_cut_in

1: Round the distance and look at the
control_value_cut_in value

de: 	distance type for engine characteristic compensation

Pops	n: CVT entry number (F26Dot6)
p: point number (ULONG)

Pushes	-

Uses	zp0 with rp0 and zp1 with point p.
round_state, control_value_cut_in, single_width_value,
single_width_cut_in

Sets 	After it has moved the point this instruction sets rp1 = rp0,
rp2 = point p, and if a has the value TRUE,  rp0  is set to point p.

A MIRP instruction makes it possible to preserve the distance between two points subject to a number of qualifications. Depending upon the setting of Boolean flag b, the distance can be kept greater than or equal to the value established by the minimum_distance state variable. Similarly, the instruction can be set to round the distance according to the round_state graphics state variable. The value of the minimum distance variable is the smallest possible value the distance between two points can be rounded to. Additionally, if the c Boolean is set, the MIRP instruction acts subject to the control_value_cut_in. If the difference between the actual measurement and the value in the CVT is sufficiently small (less than the cut_in_value), the CVT value will be used and not the actual value. If the device space difference between this distance from the CVT and the single_width_value is smaller than the single_width_cut_in, then use the single_width_value rather than the outline or Control Value Table distance.

MIRP measures distance relative  to point rp0. More formally, MIRP moves point p along the freedom_vector so that the distance from p to rp0 is equal to the distance stated in the reference CVT entry (assuming that the cut_in test succeeds)

The c Boolean above controls both rounding and the use of Control Value Table entries. If you would like the meaning of this Boolean to specify only whether or not the MIRP[ ] instruction should look at the control_value_cut_in, use the ROFF[ ] instruction to turn off rounding. In this manner, it is possible to specify rounding off and no cut_in.

The value de specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.

Example 1

MIRP[00110] 3 17

case 1:

the cut_in test succeeds and rounding is off

The point is moved so that the distance from RP0 is equal to that given in CVT entry 17.

case 2:

the cut_in test succeeds and rounding is set to RTG

The distance in the CVT is rounded and the point is moved by the rounded distance.

case 3:

the cut_in test fails and the round_state is OFF

The point is not moved.

case 4:

the cut_in test fails and the round_state is RTG

The current position of the point is rounded to the grid.


MPPEM
Measure Pixels Per EM

MPPEM[ ]

Code Range	0x4B

Pops	-

Pushes	ppem: pixels per em (ULONG)

This instruction pushes the number of pixels per em onto the stack. Pixels per em is a function of the resolution of the rendering device and the current point size and the current transformation matrix. This instruction looks at the projection_vector and returns the number of pixels per em in that direction.


MPS
Measure Point Size

MPS[ ]

Code Range	0x4C

Pops	-

Pushes	pointSize: the size in points of the current glyph (F26Dot6)

Pushes the current point size onto the stack.

Measure point size can be used to obtain a value which serves as the basis for choosing whether to branch to an alternative path through the instruction stream. It makes it possible to treat point sizes below or above a certain threshold differently.

12, 18, and 36 point Helvetica g at 72 dpi


MSIRP
Move Stack Indirect Relative Point

MSIRP[a]

Code Range	0x3A - 0x3B

a	0: don't set reference point to point p after move

1: do set reference point to point p after move

Pops	d: distance (F26Dot6)

p: point number (ULONG)

Pushes	-

Uses	zp1 with point p and zp0 with rp0.

Makes the distance between a point p and rp0 equal to the value specified on the stack. The distance on the stack is in fractional pixels (F26Dot6). An MSIRP has the same effect as a MIRP instruction except that it takes its value from the stack rather than the Control Value Table. As a result, the cut_in does not affect the results of a MSIRP. Additionally, MSIRP is unaffected by the round_state.


MUL
MULtiply

MUL[ ]

Code Range	0x63

Pops	n1, n2: multiplier and multiplicand (F26Dot6)

Pushes	n1 * n2

Pops n1 and n2 off the stack and pushes onto the stack the product of the two elements.


NEG
NEGate

NEG[ ]

Code Range	0x65

Pops	n1

Pushes	-n1: negation of n1 (F26Dot6)

This instruction pops n1 off the stack and pushes onto the stack the negated value of n1.

NEG[ ]


NEQ
Not EQual

NEQ[ ]

Code Range	0x55

Pops	e1:stack element (ULONG)
e2: stack element (ULONG)

Pushes	Boolean value (ULONG in the range [0,1])

Pops e1 and e2 from the stack and compared them. If they are different, one, signifying TRUE is pushed onto the stack. If they are equal, zero, signifying FALSE is placed on the stack.

Example:


NOT
logical NOT

NOT[ ]

Code Range	0x5C

Pops	e: stack element (ULONG)

Pushes	(not e): logical negation of e (ULONG)

Pops e off the stack and returns the result of a logical NOT operation performed on e. If originally zero, one is pushed onto the stack if originally nonzero, zero is pushed onto the stack.

Example:

case 1:

case 2:


NPUSHB
PUSH N Bytes

NPUSHB[ ]

Code Range	0x40

From  IS	n: number of bytes to push (1 byte interpreted as an integer)
b1, b2,...bn: sequence of n bytes

Pushes 	b1, b2,...bn: sequence of n bytes each padded to 32 bits (ULONG)

Takes n unsigned bytes from the instruction stream, where n is an unsigned integer in the range (0..255), and pushes them onto the stack. n itself is not pushed onto the stack.


NPUSHW
PUSH N Words

NPUSHW[ ]

Code Range	0x41

From IS	n: number of words to push (one byte interpreted as an integer)
w1, w2,..wn: sequence of n words formed from pairs of bytes,
the high byte appearing first

Pushes	w1, w2,...wn: sequence of n words each sign extended to 32 bits (LONG)

Takes n 16-bit signed words from the instruction stream, where n is an unsigned integer in the range (0..255), and pushes them onto the stack. n itself is not pushed onto the stack.


NROUND
No ROUNDing of value

NROUND[ab]

Flags	ab: distance type for engine characteristic compensation

Pops	n1

Pushes	n2

Code	0x6C - 0x6F

NROUND[ab] does the same operation as ROUND[ab] (above), except that it does not round the result obtained after compensating for the engine characteristics. n1 is popped off the stack and, depending on the engine characteristics, increases or decreases by a set amount. This figure is then pushed back onto the stack as n2.

The value ab specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.


ODD

ODD[ ]

Code Range	0x56

Pops	e1: stack element (F26Dot6)

Pushes	Boolean value

Tests whether the number at the top of the stack is odd. Pops e1 from the stack and rounds it before testing it. If the rounded number is odd, one, signifying TRUE, is pushed onto the stack if it is even, zero, signifying FALSE is placed onto the stack.

Example:

ODD[ ]

This example assume that round_state is RTG.


OR
logical OR

OR[ ]

Code Range	0x5B

Pops	e1: stack element (ULONG)
e2: stack element (ULONG)

Pushes	(e1 or e2): logical or of e1 and e2 (ULONG)

Pops e1 and e2 off the stack and pushes onto the stack the result of a logical or operation between the two elements. Zero is returned if both of the elements are FALSE. One is returned if either both of the elements are TRUE.

Example:

case 1:

OR[ ]

case 2:

OR[ ]


POP
POP top stack element

POP[ ]

Code Range	0x21

Pops	e: stack element (ULONG)

Pushes	-

Pops the top element of the stack.


PUSHB
PUSH Bytes

PUSHB[abc]

Code Range	0xB0 - 0xB7

abc	number of bytes to be pushed - 1

From IS	b0, b1,..bn: sequence of n + 1 bytes

Pushes	b0, b1, ...,bn: sequence of n + 1 bytes each padded to 32 bits (ULONG)

Takes the specified number of bytes from the instruction stream and pushes them onto the interpreter stack.

The variables a, b, and c are binary digits representing numbers from 000 to 111 (0-7 in binary). Because the actual number of bytes (n) is from 1 to 8, 1 is automatically added to the abc figure to obtain the actual number of bytes pushed.

Example:


PUSHW
PUSH Words

PUSHW[abc]

Code Range	0xB8 - 0xBF

abc	number of words to be pushed - 1.

From IS	w0,w1,..wn: sequence of n+1 words formed from pairs of bytes,
the high byte appearing first

Pushes	w0 ,w1,...wn: sequence of n+1 words each sign extended to 32 bits
(LONG)

Takes the specified number of words from the instruction stream and pushes them onto the interpreter stack.

The variables a, b, and c are binary digits representing numbers from 000 to 111 (0-7 binary). Because the actual number of bytes (n) is from 1 to 8, 1 is automatically added to the abc figure to obtain the actual number of bytes pushed.

Example:


RCVT
Read Control Value Table

RCVT[ ]

Code Range	0x45

Pops	location: CVT entry number (ULONG)

Pushes	value: CVT value (F26Dot6)

Gets	Control Value Table entry

Pops a location from the stack and pushes the value in the location specified in the Control Value Table onto the stack.


RDTG
Round Down To Grid

RDTG[ ]

Code Range	0x7D

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 3 (dtg). In this state, distances are rounded down to the closest integer grid line.

Example:


ROFF
Round OFF

ROFF[ ]

Code Range	0x7A

Pop	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 5 (off). In this state rounding is turned off.

Example:


ROLL
ROLL the top three stack elements

ROLL[ ]

Code Range 	0x8a

Pops	a, b, c (top three stack elements)

Pushes	b, a, c (elements reordered)

Performs a circular shift of the top three objects on the stack with the effect being to move the third element to the top of the stack and to move the first two elements down one position. ROLL is equivalent to MINDEX[ ] 3.


ROUND
ROUND value

ROUND[ab]

Flags	ab: distance type for engine characteristic compensation

Pops	n1

Pushes	n2

Code	0x68 - 0x6B

Rounds a value according to the state variable round_state while compensating for the engine. n1 is popped off the stack and, depending on the engine characteristics, is increased or decreased by a set amount. The number obtained is then rounded and pushed back onto the stack as n2.

The value ab specifies the distance type as described in Chapter 2. Three values are possible: Gray=0, Black=1, White=2.


RS
Read Store

RS[ ]

Code Range	0x43

Pops	location: Storage Area location (ULONG)

Pushes	value: Storage Area value (ULONG)

Gets	Storage Area value

This instruction reads a 32-bit value from the Storage Area location popped from the stack and pushes the value read onto the stack. It pops an address from the stack and pushes the value found in that Storage Area location to the top of the stack. The number of available storage locations is specified in the maxProfile table in the font file.

Example:

The effect of the RS instruction is to push the value 0x1B of the Storage Area onto the Stack.


RTDG
Round To Double Grid

RTDG[ ]

Code Range	0x3D

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 2 (dg). In this state, distances are rounded to the closest half or integer pixel.

Example:


RTG
Round To Grid

RTG[ ]

Code Range 	0x18

Pops	-

Pushes 	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 1 (g). In this state, distances are rounded to the closest grid line.

Example:


RTHG
Round To Half Grid

RTHG[ ]

Code Range 	0x19

Pops	-

Pushes 	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 0 (hg). In this state, the coordinates of a point are rounded to the nearest half grid line.

Example:


RUTG
Round Up To Grid

RUTG[ ]

Code Range	0x7C

Pops	-

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

Sets the round_state variable to state 4 (utg). In this state distances are rounded up to the closest integer pixel boundary.

Example:


S45ROUND
Super ROUND 45 degrees

S45ROUND[ ]

Code Range	0x77

Pops	n: ULONG decomposed to obtain period, phase, threshold (ULONG)

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

S45ROUND is analogous to SROUND. The gridPeriod is SQRT(2)/2 pixels rather than 1 pixel. It is useful for measuring at a 45 degree angle with the coordinate axes.


SANGW
Set Angle _Weight

SANGW[ ]

Code Range	0x7E

Pops	weight: value for angle_weight

Pushes	-

Sets	angle_weight

SANGW is no longer needed because of dropped support to the AA (Adjust Angle) instruction. AA was the only instruction that used angle_weight in the global graphics state.

Pops a weight value from the stack and sets the value of the angle_weight state variable accordingly.


SCANCTRL
SCAN conversion ConTRoL

SCANCTRL[ ]

Code Range	0x85

Pops	n: flags indicating when to turn on dropout control mode
(16-bit word padded to 32 bits)

Pushes	-

Sets	scan_control

SCANCTRL is used to set the value of the Graphics State variable scan_control which in turn determines whether the scan converter will activate dropout control for this glyph. Use of the dropout control mode is determined by three conditions:

1. Is the glyph rotated?

2. Is the glyph stretched?

3. Is the current setting for ppem less than a specified threshold?

The interpreter pops a word from the stack and looks at the lower 13 bits.

Bits 0-7 represent the threshold value for ppem. A value of FF in bits 0-7 means invoke dropout_control for all sizes. A value of 0 in bits 0-7 means never invoke dropout_control.

Bits 8-13 are used to turn on dropout_control in cases where the specified conditions are met. Bits 8, 9 and 10 are used to turn on the dropout_control mode (assuming other conditions do not block it). Bits 11, 12, and 13 are used to turn off the dropout mode unless other conditions force it.

Bit 	Meaning if set

8	Set dropout_control to TRUE if other conditions do not block and ppem is
less than or equal to the threshold value.

9	Set dropout_control to TRUE if other conditions do not block and the glyph
is rotated.

10 	Set dropout_control to TRUE if other conditions do not block and the glyph
is stretched.

11	Set dropout_control to FALSE unless ppem is less than or equal to the
threshold value.

12	Set dropout_control to FALSE unless the glyph is rotated.

13	Set dropout_control to FALSE unless the glyph is stretched.

For example

0x0000	No dropout control is invoked

0x01FF	Always do dropout control

0x0A10	Do dropout control if the glyph is rotated and has less than 16 pixels per em

The scan converter can operate in either a "normal" mode or in a "fix dropout" mode depending on the value of a set of enabling and disabling flags.


SCANTYPE

SCANTYPE[ ]

Code Range	0x8D

Pops	n: 16-bit integer

Pushes	-

Sets	scan_control

Pops a 16-bit integer whose value is used to determine which rules the scan converter will use. If the value of the argument is 0, the fast scan converter will be used. If the value of the integer is 1 or 2, the dropout control mode will be set. More specifically,

if n=0  rules 1, 2, and 3 are invoked (dropout control scan conversion including stubs)

if n=1  rules 1, 2, and 4 are invoked (dropout control scan conversion excluding stubs)

if n=2  rules 1 and 2 are invoked (fast scan conversion)

The scan conversion rules are shown here:

Rule 1

If a pixel's center falls within the glyph outline, that pixel is turned on and becomes part of that glyph.

Rule 2

If a contour falls exactly on a pixel's center, that pixel is turned on.

Rule 3

If a scan line between two adjacent pixel centers (either vertical or horizontal) is intersected by both an on-Transition contour and an off-Transition contour and neither of the pixels was already turned on by rules 1 and 2, turn on the left-most pixel (horizontal scan line) or the bottom-most pixel (vertical scan line)

Rule 4

Apply Rule 3 only if the two contours continue to intersect other scan lines in both directions. That is, do not turn on pixels for 'stubs'. The scanline segments that form a square with the intersected scan line segment are examined to verify that they are intersected by two contours.  It is possible that these could be different contours than the ones intersecting the dropout scan line segment.  This is very unlikely but may have to be controlled with grid-fitting in some exotic glyphs.


SCFS
Sets Coordinate From the Stack using projection_vector and freedom_vector

SCFS[ ]

Code Range	0x48

Pops	value: distance from origin to move point (F26Dot6)

p: point number (ULONG)

Pushes	-

Uses	zp2

Moves point p from its current position along the freedom_vector so that its component along the projection_vector becomes the value popped off the stack.


SCVTCI
Set Control Value Table Cut In

SCVTCI[ ]

Code Range 	0x1D

Pops	n: value for cut_in (F26Dot6)

Pushes 	-

Sets 	control_value_cut_in

Affects	MIAP, MIRP

Sets the control_value_cut_in in the Graphics State. The value n is expressed in sixty-fourths of a pixel.

Increasing the value of the cut_in will increase the range of sizes for which CVT values will be used instead of the original outline value.


SDB
Set Delta_Base in the graphics state

SDB[ ]

Code Range	0x5E

Pops	n: value for the delta_base (ULONG)

Pushes	-

Sets	delta_base

Affects	DELTAP1, DELTAP2, DELTAP3, DELTAC1, DELTAC2, DELTAC3

Pops a number, n, and sets delta_base to the value n. The default for delta_base is 9.


SDPVTL
Set Dual Projection_Vector To Line

SDPVTL[a]

Code Range	0x86 - 0x87

a	0: Vector is parallel to line
1: Vector is perpendicular to line

Pops	p1: first point number (ULONG)

p2: second point number (ULONG)

Pushes	-

Sets	dual_projection_vector

Pops two point numbers from the stack and uses them to specify a line that defines a second, dual_projection_vector. This dual_projection_vector uses coordinates from the scaled outline before any grid-fitting took place. It is used only with the IP, GC, MD, MDRP and MIRP instructions. Those instructions will use the dual_projection_vector when they measure distances between ungrid-fitted points. The dual_projection_vector will disappear when any other instruction that sets the projection_vector is used.

D	P

NOTE: The dual_projection_vector is set parallel to the points as they appeared in the original outline before any grid-fitting took place.


SDS
Set Delta_Shift in the graphics state

SDS[ ]

Code Range	0x5F

Pops	n: value for the delta_shift (ULONG)

Pushes	-

Sets	delta_shift

Affects	DELTAP1, DELTAP2, DELTAP3, DELTAC1, DELTAC2, DELTAC3

Sets delta_shift to the value n. The default for delta_shift is 3.

Reading and writing data

The following instructions make it possible to get and to set a point coordinate, to measure the distance between two points, and to determine the current settings for pixels per em and point size.


SFVFS
Set Freedom_Vector From Stack

SFVFS[ ]

Code	0x0B

Pops	y: y component of freedom_vector (2.14 fixed point number padded
with zeroes)

x: x component of freedom_vector (2.14 fixed point number padded
with zeroes)

Pushes	-

Sets	freedom_vector

Sets the direction of the freedom_vector using the values x and y taken from the stack. The vector is set so that its projections onto the x  and y -axes are x and y, which are specified as signed (two's complement) fixed-point (2.14) numbers.

The square root of [image] must be equal to 0x4000 (hex).

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

 F

Sets the freedom_vector to a unit vector that points in the direction of the y-axis.


SFVTCA
Set Freedom_Vector to Coordinate Axis

SFVTCA[a]

Code range	0x04 - 0x05

a 	0: set the freedom_vector to the y-axis
1: set the freedom_vector to the x-axis

Pops	-

Pushes	-

Sets	freedom_vector

Sets the freedom_vector to one of the coordinate axes depending upon the value of the flag a.

Example:

SFVTCA[0]

F

Sets the freedom_vector to the y-axis ensuring that movement will be along that axis.


SFVTL
Set Freedom_Vector To Line

SFVTL[a]

Code Range	0x08 - 0x09

a	0:set freedom_vector to be parallel to the line segment defined by points
p1 and p2

1:set freedom_vector  perpendicular to the line segment defined by points p1
and p2; the vector is rotated counter clockwise 90 degrees

Pops	p1: point number (ULONG)

p2: point number (ULONG)

Pushes	-

Sets	freedom_vector

Uses	zp1 points to the zone containing point p1
zp2 points to the zone containing point p2

Sets the freedom_vector to a unit vector parallel or perpendicular to the line segment defined by points p1 and p2.

If parallel the freedom_vector points from p1 toward p2 as shown.

F

If perpendicular the freedom_vector is obtained by rotating the parallel vector in a counter clockwise manner as shown.

 F


SFVTPV
Set Freedom_Vector To Projection Vector

SFVTPV[ ]

Code	0x0E

Pops	-

Pushes	-

Sets	freedom_vector

Sets the freedom_vector to be the same as the projection_vector.

Before

P 	F

After

P 	F


SHC
SHift Contour by the last point

SHC[a]

Code Range	0x34 - 0x35

a	0: uses rp2 in the zone pointed to by zp1

1: uses rp1 in the zone pointed to by zp0

Pops	c: contour to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with contour c
freedom_vector, projection_vector

Shifts every point on contour c by the same amount that the reference point has been shifted. Each point is shifted along the freedom_vector so that the distance between the new position of the point and the old position of that point is the same as the distance between the current position of the reference point and the original position of the reference point. The distance is measured along the projection_vector. If the reference point is one of the points defining the contour, the reference point is not moved by this instruction.

This instruction is similar to SHP, but every point on the contour is shifted.


SHP
SHift Point by the last point

SHP[a]

Code Range	0x32 - 0x33

a	0: uses rp2 in the zone pointed to by zp1

1: uses rp1 in the zone pointed to by zp0

Pops	p: point to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with point p
loop, freedom_vector, projection_vector

Shift point p by the same amount that the reference point has been shifted. Point p is shifted along the freedom_vector so that the distance between the new position of point p and the current position of point p is the same as the distance between the current position of the reference point and the original position of the reference point.

NOTE: Point p is shifted from its current position, not its original position. The distance that the reference point has shifted is measured between its current position and the original position.

In the illustration below rp is the original position of the reference point, rp' is the current position of the reference point, p is the original position of point p, p' is the current position, p" the position after it is shifted by the SHP instruction.  (White indicates original position, grey is current position, black is position to which this instruction moves a point).


SHPIX
SHift point by a PIXel amount

SHPIX[ ]

Code Range	0x38

Pops	amount: magnitude of the shift (F26Dot6)

p1, p2,...pn: points to be shifted (ULONG)

Pushes	-

Uses	zp2, loop

Shifts the points specified by the amount stated. When the loop variable is used, the amount to be shifted is put onto the stack only once. That is, if loop = 3, then the contents of the top of the stack should be point p1, point p2, point p3, amount. The value amount is expressed in sixty-fourths of a pixel.

SHPIX is unique in relying solely on the direction of the freedom_vector. It makes no use of the projection_vector. Measurement is made in the direction of the freedom_vector.

Example

The instruction shifts points 27, 28, and 29 by 80/64  or 1.25 pixels in the direction of the freedom vector. The distance is measured in the direction of the freedom_vector; the projection vector is ignored.

SHPIX[]


SHZ
SHift Zone by the last pt

SHZ[a]

Code Range	0x36 - 0x37

a 	0:  the reference point rp2 is in the zone pointed to by zp1

1: the reference point rp1 is in the zone pointed to by zp0

Pops	e: zone to be shifted (ULONG)

Pushes	-

Uses	zp0 with rp1 or zp1 with rp2 depending on flag
zp2 with e
freedom_vector, projection_vector

Shift the points in the specified zone (Z1 or Z0) by the same amount that the reference point has been shifted. The points in the zone are shifted along the freedom_vector so that the distance between the new position of the shifted points and their old position is the same as the distance between the current position of the reference point and the original position of the reference point.

SHZ[a] uses zp0 with rp1 or zp1 with rp2. This instruction always uses zp2 with e. This instruction is similar to SHC, but all points in the zone are shifted, not just the points on a single contour.


SLOOP
Set LOOP variable

SLOOP[ ]

Code Range	0x17

Pops	n: value for loop Graphics State variable (integer)

Pushes	 -

Sets	loop

Affects	ALIGNRP, FLIPPT, IP, SHP, SHPIX

Pops a value, n, from the stack and sets the loop variable count to that value. The loop variable works with the SHP[a], SHPIX[a], IP[ ], and ALIGNRP[ ]. The value n indicates the number of times the instruction is to be repeated. After the instruction executes, the loop variable and LOOPCALL[ ] are reset to 1.


SMD
Set Minimum_ Distance

SMD[ ]

Code Range 	0x1A

Pops	distance: value for minimum_distance (F26Dot6)

Pushes 	 -

Sets 	minimum_distance

Pops a value from the stack and sets the minimum_distance variable to that value.  The distance is assumed to be expressed in sixty-fourths of a pixel.


SPVFS
Set Projection_Vector From Stack

SPVFS[ ]

Code Range	0x0A

Pops	y: y component of projection_vector (2.14 fixed point number padded
with zeroes)

x: x component of projection_vector (2.14 fixed point number padded
with zeroes)

Pushes	-

Sets	projection_vector

Sets the direction of the projection_vector, using values x and y taken from the stack, so that its projections onto the x and y-axes are x and y, which are specified as signed (two's complement) fixed-point (2.14) numbers.

The square root of [image] must be equal to 0x4000 (hex).

If values are to be saved and used by a glyph program, font program or preprogram across different resolutions, extreme care must be used. The values taken from or put on the stack are 2.14 fixed-point values for the x and y components of the vector in question. The values are based on the normalized vector lengths. More simply, the values must always be set such that (X**2 + Y**2) is 1.

If a TrueType program uses specific values for X and Y to set the vectors to certain angles, these values will not produce identical results across different aspect ratios. Values that work correctly at 1:1 aspect ratios (such as VGA and 8514) will not necessarily yield the desired results at a ratio of 1.33:1 (e.g. the EGA).

By the same token, if a TrueType program is making use of the values returned by GPV and GFV, the values returned for a specific angle will vary with the aspect ratio in use at the time.

Example:

SPVFS[ ]

Sets the projection_vector to a unit vector that points in the direction of the x-axis


SPVTCA
Set Projection_Vector To Coordinate Axis

SPVTCA[a]

Code range	0x02 - 0x03

a	0: set the projection_vector to the y-axis
1: set the projection_vector to the x-axis

Pops	-

Pushes	-

Sets	projection_vector

Sets the projection_vector to one of the coordinate axes depending on the value of the flag a.

Example:

SPVTCA[0]

P

Sets the projection_vector to the y-axis assuring the measurement will be in that direction.


SPVTL
Set Projection_Vector To Line

SPVTL[a]

Code Range	0x06 - 0x07

a	0: sets projection_vector to be parallel to line segment from p1 to p2
1:sets projection_vector to be perpendicular to line segment from p1 to p2;
the vector is rotated counter clockwise 90 degrees

Pops	p1: point number (ULONG)

p2: point number (ULONG)

Pushes	-

Uses	point p1 in the zone pointed at by zp1
point p2 in the zone pointed at by zp2

Sets 	projection_vector

Sets the projection_vector to a unit vector parallel or perpendicular to the line segment from point p1 to point p2.

  P

If parallel, the projection_vector points from p1 toward p2 as shown.

If perpendicular the projection_vector is obtained by rotating the parallel vector in a counter clockwise manner as shown.

 P

case 1:

SPVTL[0]

 P

Sets the projection_vector to be parallel to the line from point 7 to point 14.

case 2:

SPVTL[1]

P

Sets the projection_vector to be perpendicular to the line from point 7  to point 14.

case 3:

SPVTL[1]

P

The order in which the points are specified matters.  This instruction sets the projection_vector to be perpendicular to the line from point 14 to point 7.


SROUND
Super ROUND

SROUND[ ]

Code Range	0x76

Pops	n: number decomposed to obtain period, phase, threshold

Pushes	-

Sets	round_state

Affects	MDAP, MDRP, MIAP, MIRP, ROUND

SROUND allows you fine control over the effects of the round_state variable by allowing you to set the values of three components of the round_state: period, phase, and threshold.

More formally, SROUND maps the domain of 26.6 fixed point numbers into a set of discrete values that are separated by equal distances. SROUND takes one argument from the stack, n, which is decomposed into a period, phase and threshold.

The period specifies the length of the separation or space between rounded values in terms of grid spacing.

The phase specifies the offset of the values from multiples of the period.

The threshold specifies the part of the domain that is mapped onto each value. More intuitively, the threshold tells a value when to fall forward to the next largest integer.

Only the lower 8 bits of the argument n are used. For SROUND gridPeriod is equal to 1.0 pixels. The byte is encode as follows: bits 7 and 6 encode the period, bits 5 and 4 encode the phase and bits 3, 2, 1 and 0 encode the threshold as shown here.

period

0	period = gridPeriod/2

1	period = gridPeriod

2	period = gridPeriod*2

3	Reserved

phase

0	phase = 0

1	phase= period/4

2	phase = period/2

3	phase = gridPeriod*3/4

threshold

0	threshold = period -1

1	threshold = -3/8 * period

2	threshold = -2/8 * period

3	threshold = -1/8 * period

4	threshold = 0/8 * period

5	threshold = 1/8 * period

6	threshold = 2/8 * period

7	threshold =3/8 * period

8	threshold = 4/8 * period

9	threshold = 5/8 * period

10	threshold = 6/8 period

11	threshold = 7/8 * period

12	threshold = 8/8 * period

13	threshold = 9/8 * period

14	threshold = 10/8 * period

15	threshold = 11/8 * period

For example, SROUND(01:01:1000) maps numbers into the values 0.25, 1.25, 2.25, .... The numbers from -0.25 to 0.75 are mapped into 0.25.  The range of numbers [0.75, 1.75) map into 1.25.  Similarly, the numbers from [1.75, 2.75) map into the number 2.25 and so on.

Rounding occurs after compensation for engine characteristics, so the steps in the rounding of a number n are:

add engine compensation to n.

subtract the phase from n.

add the threshold to n.

truncate n to the next lowest periodic value (ignore the phase).

add the phase back to n.

if rounding caused a positive number to become negative, set n to the positive round value closest to 0.

if rounding caused a negative number of become positive, set n to the negative round value closest to 0.

the period parameters can have values of 1/2 pixel, 1 pixel, or 2 pixels.

the phase parameters can have values of 0 pixels, 1/4 pixel, 1/2 pixel, or 3/4 pixel.

the threshold parameters can have values of -3/8 period, -2/8 period,... 11/8 period.  It can also have the special value largest-number-smaller-than-period which causes rounding equivalent to CEILING.


SRP0
Set Reference Point 0

SRP0[ ]

Code Range	0x10

Pops	p: point number (ULONG)

Pushes	-

Sets	rp0

Affects	IP, MDAP, MIAP, MIRP, MSIRP, SHC, SHE, SHP

Pops a point number from the stack and sets rp0 to that point number.


SRP1
Set Reference Point 1

SRP1[ ]

Code Range	0x11

Pops	p: point number (ULONG)

Pushes	-

Sets	rp1

Affects	IP, MDAP, MDRP, MIAP, MSIRP, SHC, SHE, SHP

Pops a point number from the stack and sets rp1 to that point number.


SRP2
Set Reference Point 2

SRP2[ ]

Code Range	0x12

Pops	p:point number (ULONG)

Pushes	-

Sets	rp2

Pops a point number from the stack and sets rp2 to that point number.


SSW
Set Single-width

SSW[ ]

Code Range	0x1F

Pops	n: value for single_width_value (F26dot6)

Pushes 	-

Sets	single_width_value

Sets the single_width_value in the Graphics State. The single_width_value is expressed in sixty-fourths of a pixel.


SSWCI
Set Single_Width_Cut_In

SSWCI[ ]

Code Range 	0x1E

Pops	n: value for single_width_cut_in (F26dot6)

Pushes 	-

Sets	single_width_cut_in

Affects	MIAP, MIRP

Sets the single_width_cut_in in the Graphics State. The value n is expressed in sixty-fourths of a pixel.


SUB
SUBtract

SUB[ ]

Code Range	0x61

Pops	n1, n2 (F26Dot6)

Pushes	(n2 - n1): difference

Pops n1 and n2 off the stack and pushes the difference between the two elements onto the stack.


SVTCA
Set freedom and projection Vectors To Coordinate Axis

SVTCA[a]

Code range	0x00 - 0x01

a 	0: set vectors to the y-axis
1: set vectors to the x-axis

Pops	-

Pushes	-

Sets	projection_vector
freedom_vector

Sets both the projection_vector and freedom_vector to the same one of the coordinate axes.

The SVTCA is a shortcut for using both the SFVTCA and SPVTCA instructions. SVTCA[1] is equivalent to SFVTCA[1] followed by SPVTCA[1]. This instruction ensures that both movement and measurement are along the same coordinate axis.

Example:

SVTCA[1]

P [image] F

Sets both measurement and movement to the x-direction.

SVTCA[0]

P [image] F

Sets both measurement and movement to the y-direction.


SWAP
SWAP the top two elements on the stack

SWAP[ ]

Code Range	0x23

Pops	e2: stack element (ULONG)
e1: stack element (ULONG)

Pushes	e1, e2 (pair of ULONGs)

Swaps the top two elements of the stack making the old top element the second from the top and the old second element the top element.


SZP0
Set Zone Pointer 0

SZP0[ ]

Code Range	0x13

Pops	n:zone number (ULONG)

Pushes	-

Sets 	zp0

Affects	ALIGNPTS, ALIGNRP, DELTAP1, DELTAP2, DELTAP3, IP,
ISECT, MD, MDAP, MIAP, MIRP, MSIRP, SHC, SHE, SHP, UTP

Pops a zone number, n, from the stack and sets zp0 to the zone with that number. If n is 0, zp0 points to zone 0. If n is 1, zp0 points to zone 1. Any other value for n is an error.

Example:


SZP1
Set Zone Pointer 1

SZP1[ ]

Code Range 	0x14

Pops	n:zone number (ULONG)

Pushes	-

Sets	zp1

Affects	ALIGNRPTS, ALIGNRP, IP, MD, MDRP, MSIRP, SHC, SHE, SHP,
SFVTL, SPVTL

Pops a zone number, n, from the stack and sets zp1 to the zone with that number. If n is 0, zp1 points to zone 0. If n is 1, zp1 points to zone 1. Any other value for n is an error.

Example


SZP2
Set Zone Pointer 2

SZP2[ ]

Code Range 	0x15

Pops	n:zone number (ULONG)

Pushes	-

Sets	zp2

Affects	ISECT, IUP, GC, SHC, SHP, SFVTL, SHPIX, SPVTL, SC

Pops a zone number, n, from the stack and sets zp2 to the zone with that number. If n is 0, zp2 points to zone 0. If n is 1, zp2 points to zone 1. Any other value for n is an error.


SZPS
Set Zone PointerS

SZPS[ ]

Code Range	0x16

Pops	n:zone number (ULONG)

Pushes 	-

Sets	zp0, zp1, zp2

Affects	ALIGNPTS, ALIGNRP, DELTAP1, DELTAP2, DELTAP3, GC, IP,
ISECT, IUP, MD, MDAP, MDRP, MIAP, MIRP, MSIRP, SC, SFVTL,
SHPIX, SPVTL, SHC, SHE, SHP, SPVTL, UTP

Pops a zone number from the stack and sets all of the zone pointers to point to the zone with that number. If n is 0, all three zone pointers will point to zone 0. If n is 1, all three zone pointers will point to zone 1. Any other value for n is an error


UTP
UnTouch Point

UTP[ ]

Code Range	0x29

Pops	p: point number (ULONG)

Pushes	-

Uses	zp0 with point p

Marks point p as untouched. A point may be touched in the x-direction, the y-direction, both, or neither. This instruction uses the current freedom_vector to determine whether to untouch the point in the x-direction, the y-direction, or both. Points that are marked as untouched will be moved by an IUP (interpolate untouched points) instruction. Using UTP you can ensure that a point will be affected by IUP even if it was previously touched.


WCVTF
Write Control Value Table in FUnits

WCVTF[ ]

Code Range	0x70

Pops	location: Control Value Table location (ULONG)

value: number in FUnits (ULONG)

Pushes	-

Sets	Control Value Table entry

Pops a location and a value from the stack and puts the specified value in the specified address in the Control Value Table. This instruction assumes the value is expressed in FUnits and not pixels. The value is scaled before being written to the table.


WCVTP
Write Control Value Table in Pixel units

WCVTP[ ]

Code Range	0x44

Pops	value: number in pixels (F26Dot6 fixed point number)

location: Control Value Table location (ULONG)

Pushes	-

Sets	Control Value Table entry

Pops a location and a value from the stack and puts that value in the specified location in the Control Value Table. This instruction assumes the value is in pixels and not in FUnits.


WS
Write Store

WS[ ]

Code Range	0x42

Pops	value: Storage Area location (ULONG)

location: Storage Area value (ULONG)

Pushes	-

Sets	Storage Area value

This instruction writes a 32-bit value into the storage location indexed by locations. It works by popping a value and then a location from the stack. The value is placed in the Storage Area location specified by that address. The number of storage locations is specified in the maxProfile table in the font file.

Example:

Write the value 0x0000 0118 to location 3A in the Storage Area.