OpenType is an extension of TrueType. This article walks you through every step of TrueType from font design to font display, and these steps also apply to OpenType.

TrueType fonts can be born on paper or converted from other formats. But eventually, the font file must contain a description of each glyph. The following figure shows the process from the original design draft to the digitized glyphs to the digitized Outlines in the font file.

Figure 1 Digital outline represented by FUnit coordinates in the original design draft, digital font and font file

So how do TrueType fonts work on display devices (screens, printers)?

First, the contours stored in the Font file are scaled to the required size, that is, the original contours represented in the Font file as FUnit (Font Uint, Font unit) are converted to device-specific pixel coordinates.

The interpreter then runs the instructions associated with the glyphs, which result in grid-fit of the glyphs. After mesh adaptation, the scan conversion program generates the bitmap image presented on the target device.

Figure 2 font rendering process

  1. Describe the outline of the glyphs as FUnit coordinates in the TrueType font file
  2. The zoom program converts FUnit to pixel coordinates and scales to the size required by the application
  3. The outline scales to the new grid
  4. A scaled contour represented in pixel coordinates
  5. The interpreter performs the instructions associated with the glyph B for mesh adaptation
  6. Mesh fit contour
  7. Mesh fit contour
  8. The scan converter decides which pixels to open
  9. Renders the location on the target device

Digitization of glyphs

The outline of the glyphs contained in a font is represented by continuous points located in a virtual coordinate system.

outline

In TrueType fonts, the shape of a glyph is represented by contour, which is represented by points on virtual coordinates. Simple glyphs may have only one outline, while complex glyphs may have multiple Outlines. Compound glyphs can be composed of multiple simple glyphs. In font files, control characters that have no visible shape are mapped to glyphs that have no outline.

Figure 3 shows glyphs with 1, 2, and 3 Outlines

An outline consists of straight lines and curves. The curve is defined by a series of points describing a second-order Bezier curve. TrueType’s Bezier curve format defines curves using two points: on and off. A line is defined by two consecutive lines and points.

Figure 3 shows a series of lines and lines

The points that make up the curve must be numbered in consecutive numerical numbers, and whether they are numbered in ascending or descending order is also important because it determines the filling pattern of the shapes that make up the glyph. In short, if the curve is numbered in ascending order, the black space, the fill area, is always on the right.

FUnit and EM blocks

In TrueType font files, the position of a point is expressed in font units or FUnit. FUnit is the smallest unit of measure in the EM square, a virtual square used to measure and align glyph. In general, the EM square of a glyph contains the entire length of the glyph, plus extra space to avoid crowding lines when typesetting without extra lead space.

Figure 5 em block

In the days of metallics, glyphs didn’t stick out of em squares, but digital fonts didn’t have these limitations. Em squares can be made large enough to contain all glyphs, including zhuyin glyphs. However, some glyphs can extend em square if necessary. TrueType fonts support both scenarios, and it’s up to the font manufacturer to decide which one to use.

Figure 6 shows the glyph of em square

The EM block defines a two-dimensional coordinate network system where the x axis represents horizontal movement and the Y axis represents vertical movement.

With the grid FUnit

Font digitization, first of all to determine the description of the outline of the point, its accuracy or resolution. The accuracy of these points is determined by the smallest measurable length of the EM grid, known as FUnit. The grid is in a two dimensional coordinate system, the origin is zero, zero. But instead of an infinite plane, the grid lies between -16384 and + 16384 FUnit. The number of points in the grid varies with the choice of FUnit size.

The amount of FUnit contained in each EM grid, known as UPEM (FUnit per EM), is determined by the font designer or manufacturer. However, setting uPEM to an integer power of 2, such as 2048, allows the fastest scaling of the contour.

Figure 7. Grid coordinate system in EM block

There is no rule on where the origin of coordinates in em blocks should be placed. In practice, there are usually some conventions to follow. For example, if the Roman font is used for horizontal typography, its y value of 0 is usually placed at the base of the font. I’m free to put the 0 value of the x coordinate. It’s just possible to perform better if you choose the usual practice.

For example, for fonts that are intended for vertical typography, choosing the visual center of the font as the X-axis origin can make the font line up better. For horizontal fonts, the x value of the left-most point in the font outline can be left side-bearing. Such fonts print faster in PostScript printers.

Figure 8 two font origin options: the left is the font and the left is empty with an X value of 0, and the right is the visual center with an X value of 0

Next, the amount of FUnit, or UPEM, contained in each EM square determines the granularity of the EM square. The larger the UPEM, the higher the accuracy.

Figure 9. Grid of two EM squares: each EM on the left contains 8 units and each EM on the right contains 16 units

FUnit is a relative unit because the actual size it represents varies with the size of the EM square. But the amount of FUnit contained in each em, or UPEM, is a constant, no matter how many glyph are ultimately rendered. When it comes to final rendering, there is another concept: pPEM, the number of points per EM square. The point here is an absolute unit of size, i.e. 1 point = 1/72 inch = 0.353 mm. If a glyph is rendered 9 points large, then each EM square contains 9 points (9 x 0.353=3.17 mm), and if rendered 14 points large, each EM square contains 14 points (14 x 0.353=4.94 mm). Since uPEM stays the same and PPEM changes, the absolute size of FUnit at render time will naturally change as well.

Figure 10. M at 72 and M at 127 and their EM squares. Upem in both cases is 8

In other words, no matter how big the font is rendered, the UPEM in FUint will never change.

Scaling of the font

Let’s take a look at how the font outline in the font file is scaled to the size required by the application.

Equipment room

No matter how precise the glyphs are defined, they must be scaled to fit the size and characteristics of the output device before they are finally printed or displayed. The scaled glyph outline must be described in terms of an absolute metric system that converts the points that define the glyph outline to pixels in a device-specific grid of pixels. To maintain contour accuracy, the smallest unit in the device pixel grid is the nearest 1/64 pixel value.

FUnit to pixel conversion

There are two values that need to be calculated: one is the number of pixels after converting the font represented by FUint, and the other is the number of coordinates after converting the points in the FUnit coordinate system to the points in the pixel coordinate system.

For the first transformation, the final pixel value depends on how many points are rendered, the resolution of the target device dPI, and the FUnit, or UPEM, of the EM square. Assuming a font file with a font width of 550 FUnit, a device resolution of 72ppi, a font upem of 2048, and a render of 18 points, the pixel values of the rendered font are:

18 x 550 x 72 ppi/x 2048 upem (72 dpi) = 4.83 px

In other words, the converted pixel value of the glyph is proportional to its own FUnit value, rendered points, and device resolution, and inversely proportional to the UPEM of the font. Finally, 72dpi is a constant (that is, 1 inch equals 72 points).

For the second transformation, where the coordinates of the glyph midpoints are converted from FUnit to pixels, it is first necessary to know the number of midpoints per EM after the transformation, i.e. Ppem (proportional to the device resolution) :

Ppem = render points x device resolution / 72dpi

Assuming you want to print at 12 pixels and print at a resolution of 300dpi, the PPEM for each glyph is: 12 × 300/72 = 50. This means that each glyph can be represented by 50 dots.

Then, we know the following equation:

Pixel/PPEM = FUnit/UPEM

That is, the ratio of pixel coordinates to pPEM is always equal to the ratio of FUnit coordinates to UPEM. So:

Pixel coordinates = FUnit coordinates x PPEM/UPEM

Let’s say that on a 300dpi laser printer, you want to print a 12-point glyph, and the ppem is 50. Accordingly, if the coordinate of a point in the font outline is (1024, 0) and the font UPEM is 2048, the corresponding pixel coordinate of this point is (25, 0).

The glyph outline fits the grid

Mesh adaptation is achieved by executing instructions. The goal of adaptive meshes is to preserve or present the characteristics of the original design across different sizes and devices, especially to ensure consistent trunk height, uniform spacing, and elimination of pixel dropout.

To achieve these goals, be sure to turn some pixels on when pixelating a glyph. In this case, it may be necessary to alter or distort the original contour definition to produce a high-quality bitmap. This distortion of the original glyph contour is called grid-fitting.

The image below shows the stretching effect of mesh fit on the original design:

FIG. 11 Contours and bitmaps without and after mesh adaptation

Mesh fit is the process of stretching a glyph according to the instructions associated with it. After mesh adaptation, the number of points forming the outline of the glyph remains the same, but the positions (coordinates) of these points will shift.

Understand the instructions

The TrueType instruction set defines a number of instructions for designers to specify how to render glyphs so that they retain the character of the font when scaled. In other words, instructions are used to control the outline of the glyph when adapting the mesh for different sizes or devices.

Meshing means moving points on the contour, and moving points are called “moved”. TrueType fonts do not require instructions to be executed. If the output device has a high resolution and a large number of render points, high-quality glyphs can be produced without instructions. However, in the case of small render points, it is critical to add and run instructions in order to keep the output readable.

How does the TrueType interpreter know how to stretch glyphs to produce acceptable results? This information is contained in the instructions attached to each glyph in the font. The directive specifies the design that glyphs need to retain when scaled. The figure below shows how rendering a 9 point Arial lowercase letter M without running the command results in losing a trunk because the trunk is kept in the center of the pixel. The figure on the right shows that the instructions align the trunk with the grid, leaving the trunk intact.

Figure 12. 9 point Arial before and after the application of the directive

TrueType interpreter

The instructions are interpreted and executed by the TrueType interpreter. Specifically, the interpreter processes a stream or sequence of instructions, and the instructions take arguments from the interpreter’s stack space and put the execution results back on the stack. There are also a few instructions that are responsible for pushing data onto the stack, and these instructions take their own parameters from the instruction stream.

All operations of the interpreter run in the context of Graphics State. Graphic State is a set of variables whose values are used to guide the interpreter and determine the result of the execution of a particular instruction.

The operations of the interpreter can be summarized as follows:

  1. The interpreter retrieves an instruction from an instruction stream, a sequence of instruction opcodes and data. Opcodes are expressed in bytes, and the data may be either a single byte or a double byte (word). The instruction fetches word data from the instruction stream and also creates double-byte words. The high bytes appear first in the instruction stream, followed by the low bytes.
  2. Execute instruction: If it is a push instruction, the parameters are fetched from the instruction stream. Other instructions fetch data from the stack, and the data generated by these instructions is pushed onto the stack. The interpreter stack is a last-in, first-out data structure. Instructions get the data they need from the last item on the stack. The instruction set contains all instructions for loading, unloading, empting, and copying stacks. The effect of instruction execution depends on the variables and values in the Graphics State. Instructions can also modify Graphics State variables.
  3. Repeat the process until all instructions have been executed.

Where is the instruction

Instructions may be stored in many places in the font file. For example, it can appear in Font Program and CVT Program, and it can also appear in Font data. The instructions in the first two tables apply to the entire font, while the instructions in the glyphs data apply only to specific glyphs.

The instructions in Font Program are executed only once when the application reads the Font. The instructions here are used to create function definitions (FDEF) and directive definitions (IDEF). Function and instruction definitions in Font Program can be used anywhere in the Font file.

The instructions in the CVT Program are executed each time the glyph is scaled, but it only applies to changes at the font level, regardless of the particular glyph. Specifically, the instructions in the CVT Program are used to establish values in the Control Value Table. The purpose of the Control Value Table, also known as the CVT, is to assist in maintaining font consistency when running instructions.

Instructions that refer to the median value of the CVT are called indirect instructions, and those that get the value from the glyph data are direct instructions. The CVT value in the TrueType font file is represented as FUnit. When the contour is converted from FUnit to pixel, the values in the CVT are also converted.

When writing values to the CVT, you can use the values in the glyph coordinate system or the original FUnit values. The interpreter scales these values accordingly. The values read from the CVT are always in pixels.

Graphics State

Graphics State contains a table that holds variables and their values. All instructions are run in the Graphics State context. All variables in Graphics State have default values, some of which can be changed in the CVT Program. However, changing the value of the Graphics State variable while working with a single glyph only affects subsequent processing of the corresponding glyph.

Sweep converter

TrueType’s scan converter receives the outline of a glyph and generates a bitmap image of that glyph. The scan converter has two modes. In the first mode, the scan converter uses a simple algorithm to determine which pixels belong to the glyph contour.

  • Rule 1: If the center of a pixel falls on the outline of a glyph, the pixel opens and becomes part of the glyph.
  • Rule 2: If the contour falls right in the center of a pixel, that pixel opens.

If a point has a “winding” value that is not zero, it is considered to be an in-glyph point. To determine the value of “winding” at a point, draw a ray from that point in the direction of infinity. Starting at 0, each time a contour crosses the ray from right to left or from bottom to top, it is subtracted by 1. This crossover is called on transition. Instead, each time a contour crosses the ray from left to right or from top to bottom, it increments by 1. This crossover is called off transition.

As for the direction of the contour, it can be determined by looking at the number of points. Directions are always small to large. The following figure shows how to use the wrap value to determine if a point is inside a glyph.

Figure 13 determines the winding value of a point

Point P1 in the figure has undergone 4 conversions (on, off, on, and off) in total. Since the number of conversions is even, the winding value is 0. In other words, this point is not a point within the glyphs. P2, on the other hand, underwent three transformations (off, on, and off) with a winding value of + 1, so point P2 is a point within the glyph.

Eliminate funnelled

Dropout occurs when two black pixels are connected inside a glyph but cannot be connected through a line that connects only black pixels.

FIG. 14 the letter M has two leaks

The TrueType directive is designed to enable the scan converter to turn on the necessary pixels regardless of the render size or how they are transformed. After all, it is impossible to know in advance all the transformations that will take place in a glyphs. Especially in the case of small PPEM and relatively complex glyph, pixel leakage is inevitable.

The leak point can be tested by looking at the line segment connecting the center of two adjacent pixels. If the line segment intersects both an open and a closed transformation, there is the possibility of a leak point. However, a potential leak becomes a real leak only if the two contours continue in their respective directions and cut off the other line segments connecting the centers of adjacent pixels. If two contours join immediately after crossing a line segment, there will be no leaks, but one of the main branches of the glyph may become shorter.

To avoid pixel leaks, font manufacturers can have scan converters use two additional rules.

  • Rule 3: If a line (vertical or horizontal) between the centers of two adjacent pixels intersects both an open transform and a closed transform contour, and no pixel is opened by rule 1 and Rule 2, the right-most pixel (horizontal line segment) or the bottommost pixel (vertical line segment) is opened.
  • Rule 4: Apply rule 3 only if the two contour lines continue to intersect each other in their respective directions. This does not turn on pixels for stub lines.

The font manufacturer or designer may choose to perform simple scan conversions based on rules I and II, or may use Rules III and IV if necessary. These choices make font – to – font differences. But directives in prePromgram affect the entire font by default, while changes in individual glyphs affect only that font.

A link to the

  • TrueType fundamentals:docs.microsoft.com/zh-cn/typog…