<<

References

Language Reference, Adobe Topic #15: • Postscript Language Tutorial and Cookbook, Adobe • Adobe's Postscript web site Postscript Intro » http://www.adobe.com/products/postscript/main.html • Postscript resources, Jim Land CSE 413, Autumn 2004 » http://www.geocities.com/SiliconValley/5682/postscript.html Programming Languages • Postscript resources, Doug Zongker (was UW) » http://isotropic.org/uw/postscript/

http://www.cs.washington.edu/education/courses/413/04au/ • First Guide to PostScript, Peter Weingartner » http://www.cs.indiana.edu/docproject/programming/postscript/postscript.html

1 2

What is Postscript? Hello World! in Ghostscript

• Page description language » device independent way of representing a 2D page » emphasis on scalable text, graphics presentation • Simple programming language » stack oriented » interpreted • Fundamental tool for 2D display

images from Doug Zongker papers

3

Hello World! in GSView Page Description Language %!PS /Times-Roman findfont 50 scalefont setfont 72 720 moveto • Graphics operators (Hello, World!) show showpage •Text » any position, orientation, scale • Geometric figures » straight and curved lines » filled spaces • Sampled images » digitized photos, sketches, images

5 6

A-1 Imaging Model ...... Imaging Model

• Current page • Clipping path » independent of the device on which the image will » boundary of the area that may be drawn upon actually be drawn » starts out matching the size of the default page area » starts out empty, then painting operators are used » may be set to any path to add opaque inking to the page • Current path » set of points, lines and curves » path itself is not a mark on the page, it's just a path » inking is done by stroking and/or filling the path

7 8

Coordinate Systems User Coordinates /boxpath { newpath • A Postscript program describes positions in terms 0 0 moveto 0 72 rlineto of the user coordinate system or user space 72 0 rlineto 0 -72 rlineto » independent of the printer's device coordinates closepath } def » units are 1/72 inch, approximately one point 36 700 translate boxpath • Positions on a page are described as (x,y) pairs in 0 setgray a coordinate system imposed on the page fill 72 -14.14 translate » this is the device space 45 rotate boxpath • Coordinates in user space are automatically 2 setlinewidth 0.8 setgray translated to device space when the page is printed stroke

9 10

Programming Language ...... Programming Language • A nice and relatively compact programming • Data Types language » includes reals, booleans, arrays, strings • Stack oriented » procedures are executable arrays » operand stack, dictionary stack • Flexible • Postfix notation » dictionaries to store user defined objects » operators work on data from the stack » static and dynamic graphics capabilities »3+4 ⇒ 3 4 add • Accessible source ⇒ » describe a bezier curve » Printable file is actually just a text program that 72 720 moveto 82 750 92 690 102 720 curveto can be edited with any text editor

11 12

A-2 Stack Stack operation

• The stack is an area of memory where Postscript objects can be stored until consumed GS>5 27 » last in, first out GS<2>pstack 27 » push and pop are generally implicit. Numbers are 5 always pushed as they are encountered. Operators GS<2>add GS<1>pstack can consume objects off the stack and push new 32 objects onto the stack GS<1> » several operators work directly on the stack to move the top few elements around

13 14

Operators Defined Arithmetic Operators

• An operator is a word that causes the • Predefined arithmetic operators include Postscript interpreter to carry out some action » add, div, idiv, mod, mul, sub • PS searches internal dictionaries to see if the » abs, neg word is an operator name » ceiling, floor, round, truncate »sqrt » If listed, PS looks up the associated definition and » atan, cos, sin, exp, ln, log executes it » rand, srand, rrand » Many predefined operators » Can define new operators as needed

15 16

Stack operations Stack operations Postscript also allows you to rearrange and duplicate the • Objects on the operand stack are consumed top elements of the stack so that the needed operands from the top: last in, first out are on top »6 + ( 3 / 8 ) GS>4 5 % stack has two objects on it now » 6 3 8 div add GS<2>2 array % Create a 2-element array and leave reference on stack GS<3>dup % duplicate the reference GS<4>0 % we are going to set element 0 GS>6 3 8 6 3 8 div add GS<5> % stack is now: 4 5 arr arr 0 GS<3>div GS<5>5 -1 roll % stack is now: 5 arr arr 0 4 GS<2>add GS<5>put % stack is now: 5 arr 8 GS<2>dup 1 % stack is now: 5 arr arr 1 GS<1>= GS<4>4 -1 roll % stack is now arr arr 1 5 6.375 3 .375 GS<4>put % stack is now: arr GS> 6.375 GS<1>pstack 6 6 [4 5] GS<1>

17 18

A-3 dup, pop and roll Operand Stack Operators •dup » duplicate the top item on the stack. Useful for array • pop references that are consumed by operations like put and get •exch •pop » remove top element from stack and discard • dup, , index •roll •roll » roll stack contents. Consumes two numbers from top of • clear, count stack. Top number is how many times and what direction to rotate, second number is how many objects are to be • mark, cleartomark, counttomark rotated • 7 8 9 3 1 roll ⇒ 9 7 8 • 7 8 9 3 -1 roll ⇒ 8 9 7

19 20

Interactive Operand Stack Operators Arrays

•== • Postscript arrays are 1-dimensional collections » pops an object from the stack and produces a text of objects representation of the object as best it can » indexed from 0 •pstack » objects can be of any type - integers, strings, other » prints the contents of the stack, but does not arrays, dictionaries, etc remove anything from the stack • Similar to Object arrays in Java, although Postscript arrays can hold primitive elements as well as reference elements

21 22

Creating an array Array example GS>[1 2 3] • An array can be created by directly specifying GS<1>pstack [1 2 3] the elements enclosed in square brackets GS<1>3 array » [ 16 (twelve) 8] creates a 3-element array GS<2>pstack [null null null] • number 16, string "twelve", number 8 [1 2 3] » [ (sum) 6 14 add] creates a 2-element array GS<2>dup 0 (Hi!) put GS<2>pstack • string "sum", number 20 [(Hi!) null null] [1 2 3] GS<2>exch dup 2 333 put • An array can be created with the array operator GS<2>pstack [1 2 333] »3 arraycreates a 3-element array of all null [(Hi!) null null] GS<2>

23 24

A-4 Array bracket operators Array operators put and get

[ • array index any put » put a mark on the stack. The following elements » puts any at index of array are going to be scooped up in an array » removes all three objects from the stack ] • array index get » create an array containing all elements back to the » gets the object at index of array topmost mark. The array is created on the heap in » removes both objects from the stack and returns virtual memory, and an array reference is left on the indexed element on the top of the stack the stack • Note that if you want to use the array reference example: [ 1 1 1 add] ⇒ 2-element array : [1 2] again you need to dup it or name it

25 26

Array operators

• array, [, ] • length • get, put, getinterval, putinterval • astore, aload Variables and Control Flow

• copy

•forall GS>0 [ 1 2 3] {add} forall == 6 GS>

27 28

Variables Several Dictionaries • Postscript uses dictionaries to associate a name • When the interpreter encounters a name, it with an object value searches the current dictionaries for that key »/x 3 def • At least three dictionaries are always present • associate value 3 with key x »user dictionary def » /inch {72 mul} • writeable dictionary in local virtual memory associates names • define function to convert from inches to points with procedures and variables for the program • Postscript dictionaries are similar to the HashMaps »global dictionary that our SymbolTable class maintains in the • writeable dictionary in global virtual memory compiler »system dictionary » key / value pairs • read-only dictionary associates keywords with built-in actions

29 30

A-5 Dictionary Stack Virtual Memory

• References to the dictionaries are kept on the • Postscript environment includes stacks and dictionary stack virtual memory • Interpreter looks up a key by searching the • Operand stack contains simple objects (eg, dictionaries from the top of stack down integers) and references to composite objects » search starts with current dictionary on top of stack (eg, strings, arrays) » initially, user dictionary is top of stack • Virtual memory (VM) is a storage pool for the » system dictionary is bottom of stack values of all composite objects » can define and push additional user dictionaries on top

31 32

save and restore Defining and using a variable • Define a variable ppi and give it a value • Simple user programs define their objects in local » /ppi 72 def VM » push the name ppi on the operand stack as a literal •The save operator makes a snapshot of local VM » push the number 72 on the operand stack » pop both items and store in the current dictionary using ppi •The restore operator throws away the current as the key and 72 as the value local VM and restores the state from the last save • Use the variable's value • Local VM with save/restore pairs is used to » ppi 2 mul encapsulate information whose lifetime conforms » find the value of ppi (72) and push it » push the number 2 to a hierarchical structure like a page » pop both operands, multiply, push the result

33 34

Defining and using a procedure fm constructors are procedures • Define a procedure name and give it a value % Circle constructor. » /inch {72 mul} def % FM call format => Circle(radius) » push the name inch on the operand stack as a literal % PS call format => radius Circle.Circle % Result: Reference to a fields array with » push mark, 72, mul on the operand stack % values set by arguments or defaults. » pop to the mark, create an executable array, and store in /Circle.Circle { the current dictionary using inch as the key and the Circle.fields.SIZEOF array % Create the array executable array as the value dup Circle.fields.radius % radius field • Use the procedure's value 4 -1 roll put % store radius »2 inch dup Circle.fields.grayfill 0.5 put dup Circle.fields.graystroke 0.0 put » push the number 2 dup Circle.fields.linewidth 1.0 put » look up the name inch, find the procedure, execute } def » push 72, pop both numbers, multiply, push the result

35 36

A-6 Boolean operators Conditionals and loops

• Comparison operators GS>2 3 ge • There are several operators for specifying the » eq, ne, gt, lt, ge, le GS<1>== flow of control in a Postscript program false • logical operators GS>2 2.0 eq == • Executable arrays are a basic element for the » not, and, or, xor true control flow operators GS>(abc) (acc) lt == »true, false true » the code block (executable array) is defined in-line GS>[1 2 3] dup eq == » {add 2 div} - calculate 2-value average true GS>[1 2 3] [1 2 3] eq == » the curly brackets defer interpretation of the code and false force the creation of a new executable array GS> (procedure) object

37 38

if, ifelse operators an if example • Take a boolean object and one or two executable % if current point beyond right margin, do LF CR. arrays on the stack. /chkforendofline • Select and execute one of the executable arrays { currentpoint pop % discard y position depending on the boolean value RM gt % current x > right margin? • leaves nothing on the stack { 0 lineheight neg translate % "linefeed" LM 0 moveto % "carriage return" } if

» bool proc if } def

» bool proc1 proc2 ifelse

39 40

repeat operator for operator

• Repeat a procedure body n times • Controls the standard indexed counting loop • n proc repeat • initial increment limit proc for GS>1 1 4 {} for GS>1 2 3 4 3 {pop} repeat » the control value is calculated GS<4>pstack 4 GS<1>== » if greater than limit, the loop exits 3 » otherwise the control value is pushed and 2 1 the procedure is executed GS<4>clear GS>0 1 1 4 {add} for GS<1>== 10 GS>

41 42

A-7 loop and exit operators loop example

% call: radius y lineofcircles • Repeat a procedure an indefinite number of times, /lineofcircles { usually until some condition is met /ypos exch def /radius exch def • The loop operator takes a procedure and executes it /xpos 0 def {xpos pagewidth le until an exit command is encountered within the { doCircle increase-x } procedure { exit } ifelse } loop • proc loop } def » there must be an exit encountered within the body of the procedure, or the code will loop forever

43 44

Recursion Recursion example

• A loop can be set up in a program by having a /fractArrow { gsave procedure call itself kXScale kYScale scale kLineWidth setlinewidth » remember Scheme? down » recursion must always: doLine depth maxdepth le {135 rotate fractArrow -270 rotate fractArrow } if up grestore } def

45 46

Text and Graphics

47 ex23\tiger.ps, from ghostscript examples 48

A-8 Paths basic path construction operators • A drawing starts with a path on the current page •newpath • path is a set of straight lines and curves that define: » initialize current path to be empty » a region to be filled (fill) • closepath » a trajectory that is to be drawn (stroke) » Connect subpath back to its starting point • moveto, rmoveto newpath newpath 95 700 40 0 360 arc 80 720 30 0 360 arc » set current point to (x,y) closepath closepath 1 .5 0 setrgbcolor 0.1 setgray » set current point to (curX+dx, curY+dy) fill gsave 5 setlinewidth • lineto, rlineto stroke grestore » append straight line to (x,y) 1 .9 0 setrgbcolor fill » append straight line to (curX+dx, curY+dy)

49 50

Curve path operators saving the graphics state

•arc, arcn • Sometimes we need to save the current graphics state » append clockwise, counterclockwise arcs (including the path) so that we can reuse it » the stroke and fill operators clear the current path » x y r angle1 angle2 arc » blocks of code may change path, gray value, line width, user •arct, arcto coordinate system, etc » append tangent arcs •gsave »xy x y r arct 1 1 2 2 » save a copy of the current state on the graphics state stack • curveto, rcurveto •grestore » append Bezier curve » restore to the state at the time of the last save

»x1 y1 x2 y2 x3 y3 curveto Arcs&Curves.ps 51 52

Text Using a font

• Postscript treats text as just another way to define • Find the information describing the font graphics paths » the info is in a font dictionary » The content of the text is maintained in a string object »use the findfont operator » The visible representation of the text is determined by • Scale the font to the size needed the font » original font is 1 unit high (usually 1 point) » Fonts are stored as a set of curves for each letter • the representation is the glyph for this character in this font »use the scalefont operator to scale • Set the scaled font as the current font Font: Tannarin BT »use the setfont operator Font: Murray Hill http://www.myfonts.com/

53 54

A-9 Show a text string Fun with fonts

/Palatino-Italic findfont 15 scalefont setfont • Postscript provides much more power for 72 720 moveto (Font design is fun!) show dealing with fonts /NewCenturySchlbk-Roman 15 selectfont 72 700 moveto » fonts are paths - they can be filled, stroked, (Font design is fun!) show clipped to, etc /StandardSymL 15 selectfont 72 680 moveto (Font design is fun!) show » there are several glyph painting operators that provide a variety of width modification effects » numerous font type definitions to support different ways of identifying the characters and defining the glyphs

55 56

“The name is Pond ... LilyPond”

http://lilypond.org/web/index.html

• LilyPond is an "automated engraving system." It formats music beautifully and automatically, and has a friendly syntax for its input files. » input is done in the form of a textual music language » content (the music) and the layout are strictly separated » users can extend the program by using the built-in Scheme interpreter. » PostScript output is generated via the TeX system.

chess.ps snake.ps spiral.ps57 58

strict graph ip_map { MH -- { ERC ALC WH1 HO1 IH1 }; ALC -- MV -- AN; Graphviz MV -- HO3 -- WH1; HO3 -- MT; MT -- LZ -- FL; • graphviz is a set of graph drawing tools MT -- FJ; MT -- ER; » dot - makes hierarchical layouts of directed graphs HO1 -- HR; MT -- DR; HO1 -- CB -- IH1 -- IHC; » neato - makes "spring" model layouts of undirected graphs HO1 -- HV; {IHP IW IH1 IH2 IH4 } -- {IHP IW IH1 IH2 IH4 }; • Graphs are described in DOT language {IH4 IH2} -- {MLM HV}; HO1 -- HO3; » abstract grammar defining DOT HO3 -- IH1; IH2 -- IH4 [len=4]; // hack graph:[ strict ] (graph | digraph) [ ID ] '{' stmt_list '}' } stmt_list:[ stmt [ ';' ] [ stmt_list ] ] etc • Output in Postscript and other languages

http://www.research.att.com/sw/tools/graphviz/

59 60

A-10