ralerche@lindy.Stanford.EDU (Robert A. Lerche) (06/04/91)
"How do I center a string of text around a point?" Level 1 PostScript has two operators that can extract information about the metrics of characters: "stringwidth" and "charpath". The "stringwidth" operator returns the advance width of its string operand. This is the distance the current point would be moved by a "show" operation on the same string. "stringwidth" returns two numbers on the stack, representing the x and y components of the advance width. Usually the y component is zero because most fonts are displayed along a horizontal line, moving the current point only in the x direction. Also note that the "stringwidth" operator includes any side bearings in its result. It usually does not give an exact measure of the area of the page that will be touched by its operand. If all that an application requires is horizontal centering of a long string of text, the result returned by "stringwidth" is sufficient. A common technique is x y moveto (string) stringwidth pop 2 div neg 0 rmoveto (string) show (This code makes the assumption that the y component of advance width is irrelevant.) The "charpath" operator extracts the graphic shapes of its string operand and appends them to the current path in the graphic state. These shapes can then be processed by other PostScript operators. To get the actual size of the area touched by a character a simple approach is gsave newpath 0 0 moveto (X) true charpath flattenpath pathbbox grestore This code places four numbers on the stack, representing the coordinates of the lower left and upper right corners of the bounding box enclosing the character "X" rendered with the current point at (0,0). There are two things to be careful about when using the code shown above: 1. There are severe limits on the size of the string operand, related to the limit on the number of elements in a graphic path. The PostScript Language Reference Manual recommends taking "charpath"s one character at a time. 2. If user space is rotated or skewed with respect to device space, the result from "pathbbox" may be larger than expected; "pathbbox" returns a rectangle oriented along the user space coordinate axes, which fully encloses a (possibly smaller) rectangle oriented along the coordinate axes of device space. If user space is rotated at an integer multiple of 90 degrees these two rectangeles will be the same, otherwise the rectangle in user space will be larger. So, to center text vertically one must get the bounding boxes of all the characters in the string to be displayed, find the minimum and maximum y coordinate values, and use half the distance between them to displace the text vertically. If an application does this repeatedly, it would be wise to store the bounding boxes in an array indexed by character code, since "charpath" is a slow operation. Font metric information is available outside of a PostScript printer in font metrics files, available from Adobe. A program generating PostScript output can obtain metrics from these files rather than extracting the metrics in the printer.