PostScript file class Public application programming interface (API) P.J. Drongowski 8 January 2005 Some kinds of information are best communicated visually using computer graphics. Pictures, diagrams, etc. can be rendered to a wide variety of devices such as display screens and printers. PostScript is an industry-standard, device independent page description language. A PostScript program describes what to draw on one or more pages: text, images, lines, arcs, etc. The PostScript language provides a flexible means to control the placement, orientation, scale and attributes (grey scale, fill pattern) of the primitive graphic forms that it supports. Writing PostScript primitives is a tedious and error prone process. The PostscriptFile class is a reusable module that hides some of the details of the PostScript language in order to make graphics programming easier. The PostscriptFile class virtualizes the concept of a PostScript file and exports an application programming interface (API) that is similar to a simple graphics device. (The API is an abstraction of a simple graphics device.) The PostscriptFile class provides a convenient application programming interface for simple, PostScript-based graphics. ************************* Imaging model ************************* The API exposes and uses the PostScript imaging model. Graphic marks are made on a "page." The origin of the default user coordinate space is the lower left corner of the page. The default coordinate space unit is 1/72 inch, roughly corresponding to a printer's point. Calls to API functions such as line, box, circle, etc. define graphic marks. Once all graphic marks have been defined, the function showpage must be called to actually render the marks. The function showpage can be called more than once, thereby defining multiple pages in the same document. The coordinate space can be altered through the use of coordinate space transformations such as translate, rotate and scale. ************************* The graphics state ************************* The API exposes the PostScript graphics state. The graphics state is a set of parameters that control the definition and rendering of graphic marks. Three functions directly control the graphics state: * The function initgraphics sets parameters in the graphics state to their initial default values. * The function gsave pushes the current graphics state onto the graphics state stack. * The function grestore pops the topmost graphics state from the graphics state stack and makes it the current graphics state. The gsave and grestore functions let a programmer save the current graphics state and then recall it at a later time. The graphics state includes the current line width, gray level (to control fill operations), font, and current transformation matrix (CTM.) The CTM maps all coordinate points and thus defines the current coordinate space. Since the CTM is part of the graphics state and can be saved and restored, coordinate spaces can be defined relative to each other. This naturally supports the placement of subcomponents within parent components. ************************* Using the API ************************* Modules wishing to use the API must include the declaration of the API, psfile.h, and make calls through the API. A calling module performs the following sequence of operations to draw a picture: * Defines a PostscriptFile object. * Calls the method function open on the PostscriptFile object to create a disk file to hold the PostScript language statements that are generated by the drawing functions, etc. * Calls one or more method functions (e.g., line, rect, circle) to describe graphical marks to be drawn on the current page. The method functions write one or more PostScript primitives to the file in order to describe the graphical marks. * Calls the showpage method function to indicate that the current page description is complete. When the file is interpreted by a previewer or printer, the marks on the page are rendered by the graphics device. * Repeats steps 2 and 3 above for each page to be drawn. * Calls the method function close to close the PostScript file. The user may preview the finished PostScript file using the Ghostscript previewer (gs) or print the file to get hard-copy. Ghostscript is an open source interpreter for the PostScript language. Ghostscript previewers are available for all common platforms: * Linux: gs and gsnd * Sun and Windows: gsview * Macintosh: MacGSview (OS 9), Panther Previewer (10.3) If you would like to learn more about the PostScript language itself, the PostScript file itself is a text file and the resulting PostScript program can be browsed using the more command or even changed using a text editor like Emacs. The Ghostscript interpreter (gsnd) can be run interactively without a display and is one way to play with PostScript and its stacks. Interactive interpretation is good for learning PostScript although the interpreter does not forgive errors lightly or is very informative when a PostScript program breaks. ************************* Example program ************************* Here is a very short example program using the API. #include "psfile.h" int main(int argc, char *argv[]) { // Create a PostscriptFile object PostscriptFile psf ; // Open the Postscript file psf.open("x_marks_the_spot.ps") ; // Draw into the Postscript file psf.line(225, 225, 375, 375) ; psf.line(225, 375, 375, 225) ; // Perform a showpage operation after drawing psf.showpage() ; // Close the Postscript file psf.close() ; } ************************* File-related functions ************************* bool open(char *filename) The open function creates a disk file for the PostScript language description of the page(s) to be rendered. The file has the specified file name. The function returns true if the open operation succeeded. The function returns false on failure. The calling program should always check for success/failure and handle failure appropriately. void close() The close function closes the disk file. No further output should be attempted once the file is closed. ************************************* Graphics state-related functions ************************************* void initgraphics() The initgraphics function restores the graphic state to its default values. The gray level is reset to black. The current coordinate transformation matrix (CTM) is reset to the identify matrix (no translation, scaling or rotation.) void gsave() The gsave function pushes the current graphics state onto the graphics state stack. The current graphics state is unmodified. void grestore() The grestore function pops the topmost graphics state from the graphics state stack and makes it the current graphics state. **************************** Transformation functions **************************** void rotate(double angle) The rotate function concatenates a rotation matrix to the current transformation matrix (CTM) in the graphics state. The angle of rotation is given in degrees. void translate(int tx, int ty) The translate function concatenates a translation matrix to the current transformation matrix (CTM) in the graphics state. The x- and y-axis offsets are given by the parameters tx and ty. void scale(double sx, double sy) The scale function concatenates a scaling matrix to the current transformation matrix (CTM) in the graphics state. The x- and y-axis scale factors are given by the parameters sx and sy. The scale factors are independent. A negative scale factor may be used to reflect coordinate points across an axis. ************************* Drawing functions ************************* void setgray(double gray) The setgray function sets the fill color. The parameter, gray, specifies the gray level where 0.0 is black and 1.0 is white. void line(int x1, int y1, int x2, int y2) The line function draws a line from coordinate point (x1,y1) to coordinate point (x2,y2). void rect(int x, int y, int width, int height) The rect function defines a rectangle. The lower left corner of the rectangle is the coordinate point (x,y). The rectangle as the specified (horizontal) width and (vertical) height. void box(int x, int y, int width, int height) The box function is similar to the rect function. It draws a filled rectangle instead of a line around the perimeter of the rectangle. The fill color is specified the current gray level in the graphics state. void circle(int x, int y, int radius) The circle function defines a circle with the specified radius. The center of the circle is at the coordinate point (x,y). void disc(int x, int y, int radius) The disc function is similar to the circle function. It draws a filled circle instead of a line around the perimeter of the circle. The fill color is specified the current gray level in the graphics state. void showpage() The showpage function causes the defined graphic marks to be physically rendered by the device (graphic display, printer, etc.) A showpage operation performs an implicit initgraphics operation and the graphics state is reset to its defaults. No marks will be rendered (physically drawn) unless showpage is called. ******************************* Font/text-related functions ******************************* void font(char *key, double scale) Make the specified font the current font in the graphics state. The parameter key is a string that selects a font. Supported key values (fonts) are: Times-Roman Helvetica Courier Symbol Times-Bold Helvetica-Bold Courier-Bold Times-Italic Helvetica-Oblique Courier-Oblique Times-BoldItalic Helvetica-BoldOblique Courier-BoldOblique Here is a simple example: psf.font("Times-Roman", 12.0) ; where psf is a PostscriptFile object. void show(int x, int y, char *text) Draws the specified text string at the coordinate point (x,y). The x value specifies the left hand side of the string. The y value specified the so-called "base line" of the string. The call: psf.show(144, 144, "A string") ; draws the text "A string" at the coordinate point (144,144). Due to limitations of PostScript language string syntax, any open or close parenthesis characters must be preceded by a two backslash escape characters. Paul J. Drongowski Computer Science Department Tufts University Medford, MA Copyright (c) 2005 Paul J. Drongowski