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

Ú

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 [pi, argi] 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 [pi, argi] 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 [pi, argi] 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 [ci, argi] 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 [ci, argi] 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 [ci, argi] 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.