In the PostScript language, text is rendered with the show oper- ator (or one of its relatives). The show operator is somewhat spe- cial in the PostScript imaging model, in that there are very specific requirements for setting text that may not apply when rendering other graphic elements.
In particular, text characters are normally set one after another, along a baseline. The show operator leaves the current point when it is done, rather than destroying the path as other path painting operators do. Furthermore, show requires not only a current point but a current font in order to render text (unlike other painting operators).
In order to effectively make use of the PostScript imaging mod- el, one should understand just what effect the show operator has, and when it is appropriate, for instance, to use gsave and grestore to preserve the current point (and the current font). Let us consider two variations that print a couple of lines of 10- point text (listing 3-5).
listing 3-5
%!PS-Adobe-2.0
%%Title: text examples %%EndComments
/F { findfont exch scalefont setfont } bind def /S1 { moveto show } bind def
/S21 { moveto gsave show grestore } bind def /S22 { %def
0 exch rmoveto gsave show grestore } bind def
%%EndProlog % method 1:
10 /Times-Roman F (method 1:) 72 512 S1
(Viva Nuestra Senora de Guadelupe!) 72 500 S1 (Viva la Independencia!) 72 488 S1
% method 2:
10 /Times-Roman F (method 2:) 72 412 S21
( There was a young lady named Bright,) -12 S22 ( Whose speed was far faster than light;) -12 S22 ( She set out one day) -12 S22
( In a relative way) -12 S22
( And returned home the previous night.) -12 S22 ( -Arthur Buller) -12 S22
showpage %%Trailer
The first method in listing 3-5 (labeled method 1 in the com- ments) has a very simple procedure (called S1) which does a moveto and a show. The x,y location for the text is passed on the stack along with the string, and the current font is understood already to exist. The second example (called method 2) uses a dif- ferent approach. The first line uses an x,y pair, as does method 1, except that it uses gsave and grestore to preserve the current point after show is finished. Subsequent lines of text are set with just a relative quantity (an amount to move down before
printing the line). This enables the driver to generate and trans- mit less data, but there is a greater computation cost in doing the gsave, grestore, exch, and rmoveto for each line.
The two examples above are inherently based on the behavior of the show operator: It always leaves the current point at an adjusted position (usually to the right of the text shown) based on the character widths. In method 2, the second line (and sub- sequent lines) of text are dependent on the first, in the sense that the position is relative to the first line.
Another approach might be to have a procedure for setting an entire paragraph, where the inter-line spacing is constant for the whole paragraph, and the moveto can be generated easily from within the code.
The rest of this book is dedicated to the decision-making pro- cess. The PostScript language execution and imaging models pro- vide great freedom in setting text, but in any environment there are constraints or advantages that may dictate using one method over another. Understanding the workings of the mech- anism will help you to make these decisions.
CHARACTER WIDTHS
Character widths are stored within PostScript language font pro- grams as displacements in coordinate space. The best way to think of text setting is to view each character as an origin, a shape, and a width. The relationship between the shape and the origin is fixed—the origin is the 0,0 point in character space (described later) and the character draws itself relative to that location. The width is essentially an implicit rmoveto that occurs after the character shape is rendered. (See figure 3.3).
The character width is not related to the actual execution of the character shape (the shape may even be in the font cache, and not get executed at all). This is not important unless you are building font characters yourself. (See also Section 9.3). Remem- ber that characters widths have both an x and a y component. A common bug is to call stringwidth but to forget that there are two values returned. Typically, the extra number stays on the stack until a typecheck occurs later.
figure 3.3
The important thing to remember is to use the way The PostScript language renders text instead of fighting it. Below are some aspects of the execution and imaging models that com- monly present difficulty. Each of these is a symptom of not hav- ing used the language effectively:
• When you try to use save and restore at the page boundaries, you discover that it destroys the current font at the bottom of the page, and it needs to be explicitly re-set at the beginning of the next page. • You find that changing fonts in the middle of a line of
text makes it hard to justify the line, since the character widths are different for the two fonts.
• You are using stringwidth to determine where text is going to be placed. (The application should always con- trol placement of text, and should know the character widths beforehand.)
• When you relocate or remove graphics from a file, the text does not print in the correct position on the page, since it relies on the current point being in the right place.
G
origin (current point when show executes) character width (displacement after show)
Some thought is required to build a complex program, and using the PostScript language is no exception. Learning the character- istics of each text operator and remembering the semantics of the imaging model will help enormously in designing a simple and efficient program.