A form is a self-contained description of any arbitrary graphics, text, or sampled images that are to be painted multiple times, either on several pages or at several locations on the same page. The appearance of a form is described by a PostScript procedure that invokes graphics operators. This can be a problem since procedures can not include inline image data.^
Language support for forms is a LanguageLevel 2 feature.
What distinguishes a form from an ordinary procedure is that it is self-contained and behaves according to certain rules. By defining a form, a program declares that each execution of the form will produce the same output, which depends only on the graphics state at the time the form is executed. The forms definition does not refer to variable information in virtual memory, and its execution has no side effects in VM.
These rules permit the PostScript interpreter to save the graphical output of the form in a cache. Later, when the same form is used again, the interpreter substitutes the saved output instead of reexecuting the forms definition. This can significantly improve performance when the form is used many times. There are various uses for forms:
As its name suggests, a form can serve as the template for an entire page. For example, a program that prints filled-in tax forms can first paint the fixed template as a form, then paint the variable information on top of it.
A form can also be any graphical element that is to be used repeatedly. For example, in output from computer-aided design systems, it is common for certain standard components to appear many times. A companys logo can be treated as a form.
The use of forms requires two steps:
1. Describe the appearance of the form. Create a form dictionary containing descriptive information about the form. A crucial element of the dictionary is the PaintProc procedure, a PostScript procedure that can be executed to paint the form.
2. Invoke the form. Invoke the execform operator with the form dictionary as the operand. Before doing so, a program should set appropriate parameters in the graphics state; in particular, it should alter the current transformation matrix to control the position, size, and orientation of the form in user space. Every form dictionary must contain a FormType entry, which identifies the particular form type that the dictionary describes and determines the format and meaning of its remaining entries. At the time of publication, only one form type, type 1, has been defined. Table 4.4 shows the contents of the form dictionary for this form type. (The dictionary can also contain any additional entries that its PaintProc procedure may require.)
KEY | TYPE | VALUE |
FormType | integer | (Required) A code identifying the form type that this dictionary describes. The only valid value defined at the time of publication is 1. |
XUID | array | (Optional) An extended unique ID that uniquely identifies the form (see Section 5.6.2, Extended Unique ID Numbers). The presence of an XUID entry in a form dictionary enables the PostScript interpreter to save cached output from the form for later use, even when the form dictionary is loaded into virtual memory multiple times (for instance, by different jobs). To ensure correct behavior, XUID values must be assigned from a central registry. This is particularly appropriate for forms treated as named resources. Forms that are created dynamically by an application program should not contain XUID entries. |
BBox | array | (Required) An array of four numbers in the form coordinate system, giving the coordinates of the left, bottom, right, and top edges, respectively, of the forms bounding box. These boundaries are used to clip the form and to determine its size for caching. |
Matrix | matrix | (Required) A transformation matrix that maps the forms coordinate space into user space. This matrix is concatenated with the current transformation matrix before the PaintProc procedure is called. |
PaintProc | procedure | (Required) A PostScript procedure for painting the form. |
Implementation | any | An additional entry inserted in the dictionary by the execform operator, containing information used by the interpreter to support form caching. The type and value of this entry are implementation-dependent. |
The form is defined in its own form coordinate system, defined by concatenating the matrix specified by the form dictionarys Matrix entry with the current transformation matrix each time the execform operator is executed. The form dictionarys BBox value is interpreted in the form coordinate system, and the PaintProc procedure is executed within that coordinate system.
The execform operator first checks whether the form dictionary has previously been used as an operand to execform. If not, it verifies that the dictionary contains the required elements and makes the dictionary read-only. It then paints the form, either by invoking the forms PaintProc procedure or by substituting cached output produced by a previous execution of the same form.
Whenever execform needs to execute the form definition, it does the following:
1. Invokes gsave
2. Concatenates the matrix from the form dictionarys Matrix entry with the CTM
3. Clips according to the BBox entry
4. Invokes newpath
5. Pushes the form dictionary on the operand stack
6. Executes the forms PaintProc procedure
7. Invokes grestore
The PaintProc procedure is expected to consume its dictionary operand and to use the information at hand to paint the form. It must obey certain guidelines to avoid disrupting the environment in which it is executed:
It should not invoke any of the operators unsuitable for use in encapsulated PostScript files.
It should not invoke showpage, copypage, or any device setup operator.
Except for removing its dictionary operand, it should leave the stacks unchanged.
It should have no side effects beyond painting the form. It should not alter objects in virtual memory or anywhere else. Because of the effects of caching, the PaintProc procedure is called at unpredictable times and in unpredictable environments. It should depend only on information in the form dictionary and should produce the same effect every time it is called.
Form caching is most effective when the graphics state does not change between successive invocations of execform for a given form. Changes to the translation components of the CTM usually do not influence caching behavior; other changes may require the interpreter to reexecute the PaintProc procedure.
/VerySimpleForm << /FormType 1 % all forms are FormType 1 /PaintProc % draw a red square { pop gsave 0 0 moveto 1 0 0 setrgbcolor [ 0 0 72 72 ] rectfill grestore } bind /BBox [ 0 0 77 72 ] % 1 inch square form/image /Matrix [ 1 0 0 1 0 0] % no scaling or translating >> def 10 10 translate VerySimpleForm execform 100 100 translate VerySimpleForm execform
See also:
Questions: