home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol1 / printer / psprimer < prev    next >
Text File  |  1990-01-26  |  12KB  |  308 lines

  1. (c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.  
  8.  
  9.                  PostScript Primer for Programmers
  10.  
  11.                     by Carolyn Scheppner - CATS
  12.  
  13.  
  14.  
  15. PostScript is a programming language that provides a hardware-independent 
  16. standard for representing the printed page.  PostScript objects include the
  17. Adobe fonts which can be scaled, condensed, expanded, outlined, italicized
  18. and rendered anywhere on a page.  PostScript can also draw lines and curves 
  19. to create geometric shapes which may be outlined or filled with any shade.
  20. In fact, any arbitrary image can be manipulated with PostScript.  Let's take
  21. a closer look at these capabilities by trying a few simple examples.  
  22.  
  23.  
  24. PostScript, like Forth, is a very stack-oriented language.  Most PostScript 
  25. commands take their arguments from the stack and the commands are given using 
  26. postfix notation - that is, with operators following their operands.  Here 
  27. are a few PostScript statements in postfix notation:
  28.  
  29.  
  30. PostScript Statement             Meaning
  31.  
  32.    10  40 moveto        % Move to x,y position 10,40. 
  33.                         %
  34.    (Hi)   show          % Print the string "Hi".
  35.                         %
  36.    /LM 20 def           % Assign the value 20 to variable LM.
  37.                         %
  38.    3   5  add           % Push 3 then 5 on stack and add them, 
  39.                         %   leaving 8 on stack.
  40.  
  41.  
  42. Some operations like "moveto" return no result.  Instead they change the state
  43. of internal PostScript variables.  For instance "moveto" changes your position
  44. in the co-ordinate system used by PostScript for drawing operations.  This is 
  45. similar to moving the pen in Logo with the SETXY command.  Other operations 
  46. like "add" and "currentpoint" place results on the stack where subsequent 
  47. operations can make use of the results.  Here is an example which moves to
  48. a new position in the PostScript co-ordinate system:
  49.  
  50.     currentpoint     %  Places the current x,y co-ordinate on the stack
  51.                      %    (y on top).
  52.     10 add           %  Adds 10 to the item on top of the stack 
  53.                      %    (the y position).
  54.     moveto           %  Moves to the new x,y co-ordinates which 
  55.                      %     are on top of the stack (x,y+10). 
  56.  
  57.  
  58. Sometimes the results of an operation are not in the order you need for the
  59. next operation.  In this case, the operands on the stack can be duplicated, 
  60. discarded, exchanged or assigned to variables.  Here is a longer example
  61. which assigns the length of the string "Hello" to a variable:
  62.  
  63.     (Hello)          % Pushes the string "Hello" onto the stack.
  64.                      %
  65.     dup              % Duplicates the top stack entry and pushes
  66.                      %      it onto the stack.
  67.     stringwidth      % Takes the duplicate entry off of the stack 
  68.                      %      and uses it to calculate width and height.
  69.                      %      Width and height are pushed onto the stack.
  70.     pop              % Throw away the height, leaving width on stack.
  71.                      %
  72.     /strw            % Pushes the variable name strw onto the stack.
  73.                      %
  74.     exch             % Swaps the top 2 stack items - now the order is  
  75.                      %        /strw, width.
  76.     def              % Assigns the value of width to the variable strw.
  77.                      %        (i.e. /strw width def)
  78.  
  79. PostScript control structures are also stack oriented.  You create a control 
  80. structure by pushing a condition on the stack, followed by a procedure,
  81. followed by a control operator.  The procedure can be any number of statements
  82. delimited by the curly braces {}.  The example below will print "Is 3", if 
  83. the varible xyz is equal to 3:
  84.  
  85.     xyz 3 eq          % Checks if the variable xyz equals 3.  If so, TRUE is
  86.                       %    pushed onto the stack.  Otherwise FALSE is pushed.
  87.     {(Is 3) show} if  % Executes the statements in curly braces if TRUE is on 
  88.                       %    the top of the stack.
  89.  
  90. The use of curly braces is not limited to control statements.  You can use 
  91. them with the "def" operator to group together several operations that define
  92. a complex new procedure which you can use just like the built-in operators.
  93. This lets you build powerful commands that can be included at the start of 
  94. your code, allowing your "main" program to be just a sequence of simple 
  95. procedure calls.  Here's an example:
  96.  
  97.     % === Variables
  98.     /TM   740 def    % set top margin variable
  99.     /LM    20 def    % set left margin variable
  100.  
  101.     % === Procedures
  102.     /topofpage  { LM TM moveto } def    % move to top left corner       
  103.  
  104. This code makes a new "topofpage" command that you can use in your programs.
  105. Note that in PostScript co-ordinate system, (0,0) is at the lower left corner 
  106. of the page, and unless scaled, each unit represents 1/72 of an inch.
  107.  
  108. Now that you have a better idea of how PostScript works, let's consider a 
  109. more complicated example.  A complete PostScript program which generates
  110. a company letterhead is shown below.  The example contains a variety of 
  111. procedures that simplify the selection and styling of fonts and the centering
  112. and justification of strings.
  113.  
  114. If you do not have a PostScript printer, you may want to try the PostScript 
  115. interpreter by Greg Lee on Fish Disk #101.  You can use this to test out
  116. your own PostScript code and preview the layout of pages you create.  I have 
  117. included conditional code for Greg's interpreter in the letterhead example. 
  118. Activate it by setting the InterpFlag variable to 1.  
  119.  
  120. You may have to fiddle a bit with the value I add to the right margin (RM) in 
  121. the conditional code for the interpreter.  I scale the output so that the 
  122. whole page is compressed to fit on the Amiga's screen, but an adjustment to 
  123. the right margin variable seems to be needed to match the printer's horizontal
  124. layout.  Larger font sizes seem to need larger adjustments. 
  125.  
  126. The front end of the letterhead example could be used as a base for your own
  127. letterhead, overhead, report cover or sign making programs.  Add your own 
  128. procedures for new features such as graphic elements or shade-filled outline 
  129. text.  To learn more about programming in PostScript, see the PostScript 
  130. Language Reference Manual or the PostScript Language Tutorial and Cookbook, 
  131. by Adobe Systems Incorporated.
  132.       
  133. (PostScript is a registered trademark of Adobe Systems Inc.)
  134.  
  135.  
  136.  
  137. ----------------- Lauren, code starts here ---------------------------
  138.  
  139. %! PostScript (R) Letterhead Example  by  C. Scheppner
  140. %  PostScript and fontnames are registered trademarks of Adobe Systems Inc.
  141.  
  142. % === Save the initial state
  143. save
  144.  
  145. % === Conditional Flag for Greg Lee's ps interpreter, Fish Disk #101
  146. /InterpFlag 0 def        % Set to 1 for interpreter, 0 for printer
  147.  
  148.  
  149. % === My margins (RM modified in Interpreter Changes)
  150. /TM 740 def    % top margin
  151. /BM 20 def     % bottom margin
  152. /RM 582 def    % right margin
  153. /LM 20 def     % left margin
  154.  
  155.  
  156. % === Start of Conditional Changes for Interpreter
  157. InterpFlag 1 eq {
  158. 2 pencolor 
  159. /showpage {
  160.    % do nothing
  161.    } def
  162. /RM RM 260 add def  % fixes spacing somehow
  163. .54 .65 scale       % scale to fit page on screen
  164. erasepage } if
  165. % === End of Changes for Interpreter
  166.  
  167.  
  168. % === My Variables initialized to defaults (Note: Margins defined above)
  169. /pagenum 0 def     % Keep track of page numbers
  170. /fsize 20 def      % Font size (height)
  171. /fwidth 20 def     % Font width
  172. /ftilt 0 def       % Font tilt
  173. /outline 0 def     % Outline flag
  174. /cpx LM def        % Currentpoint X for user savecp/restorecp
  175. /cpy TM def        % Currentpoint Y for user savecp/restorecp
  176. /tcpx LM def       % Temp cpx for oshow
  177. /tcpy TM def       % Temp cpy for oshow
  178.  
  179.  
  180. % === My Subroutines
  181.  
  182. % === Save/Restore X/Y position
  183. /savecp    { currentpoint /cpy exch def /cpx exch def } def
  184. /restorecp { cpx cpy moveto } def
  185.  
  186. % === Perform a newline based on font size
  187. /newline
  188.  { currentpoint fsize sub
  189.    exch pop
  190.    LM exch
  191.    moveto } def
  192.  
  193. % === Move to top left corner
  194. /topofpage { LM TM moveto } def
  195.  
  196. % === Move to top left corner, increment pagenum
  197. /newpage
  198.  { topofpage
  199.    /pagenum pagenum 1 add def } def
  200.  
  201. % === Called by myshow if outline flag is set  (string on stack)
  202. % === Note: stroke kills currentpoint so I must save/adjust/restore
  203. /oshow
  204.   { currentpoint /tcpy exch def /tcpx exch def
  205.     dup stringwidth pop
  206.     tcpx add
  207.     /tcpx exch def
  208.     true charpath stroke
  209.     tcpx tcpy moveto } def
  210.  
  211. % === Move in X to center string between LM and RM  (string on stack)
  212. /center
  213.  { dup stringwidth pop
  214.    RM LM sub exch sub
  215.    2 div LM add
  216.    currentpoint exch pop
  217.    moveto } def
  218.  
  219. % === Move in X to right justify string against RM  (string on stack)
  220. /rjust
  221.  { dup stringwidth pop
  222.    RM exch sub
  223.    currentpoint exch pop
  224.    moveto } def
  225.  
  226. % === Line show rtns, with and without newline (string on stack)
  227. % === "c" means centered, "r" right justified, 
  228. % === myshow is like normal "show" but does solid or outline on printer
  229.  
  230. /myshow { outline 0 eq { show } {oshow} ifelse } def
  231. /cshow  { center myshow } def
  232. /rshow  { rjust myshow } def
  233. /showline  { myshow newline } def
  234. /cshowline { cshow newline } def
  235. /rshowline { rshow newline } def
  236.  
  237. % === Set pointsize of basefont  (pointsize on stack)
  238. /setsize
  239.   { /fsize exch def
  240.     /fwidth /fsize def
  241.     /ftilt 0 def
  242.     basefont findfont fsize scalefont setfont } def
  243.  
  244. % === Set custom style of basefont  (height width tilt on stack)
  245. /setstyle     % stack = high wide tilt
  246.   { /ftilt exch def
  247.     /fwidth exch def
  248.     /fsize exch def
  249.     basefont findfont [fwidth 0 ftilt fsize 0 0] makefont setfont } def
  250.  
  251. % === Select a font as current basefont  (/Font-Name on stack)
  252. % === For the interpreter, I change all font requests to /simplex
  253. /selectfont
  254.   { InterpFlag 1 eq
  255.       {pop /basefont /simplex def}
  256.       {/basefont exch def} ifelse
  257.     fsize fwidth ftilt setstyle } def
  258.  
  259. % === Turn font outline-only rendering on and off
  260. /setoutline { /outline 1 def } def
  261. /setsolid   { /outline 0 def } def
  262.  
  263. % === Draws a big underline from left to right margin
  264. /bigline {
  265.    newline
  266.    gsave
  267.    0 fsize 3 div rmoveto
  268.    RM LM sub 0 rlineto
  269.    stroke
  270.    grestore
  271.    } def
  272.  
  273.  
  274. % =========================  MAIN PROGRAM  =============================
  275. newpage                           % go to top of page
  276. /AvantGarde-Book selectfont       % select a font
  277.  
  278. 36 24 8 setstyle                  % make condensed italic style
  279. (Propeller Soft  ) show           % show this at current position
  280. 20 14 0 setstyle                  % smaller condensed non-italic
  281.                                   % show next line right-justified
  282. (Creators of "Editor Wars", the game programmers play) rshow
  283. bigline                           % now call big underline subroutine
  284.  
  285. 14 12 0 setstyle                  % smaller condensed non-italic
  286. newline                           % move down a (size 14) line
  287. savecp                            % save current x/y position for below
  288. newline                           % move down a line
  289. (Max E. Byte) cshowline           % show this centered, then newline
  290. (Programming Genius) cshowline    % show this centered, then newline
  291.  
  292. 12 10 0 setstyle                  % even smaller condensed non-italic
  293. restorecp                         % move back to saved x/y position
  294. (12 Speedbump Lane) showline      % show these 3 lines at left
  295. (West Chester, PA.) showline
  296. (19380   USA) showline
  297.  
  298. restorecp                         % move back to saved x/y again
  299. (Phone: (900) 555-1212) rshowline % show these 3 lines at right
  300. (FAX: (900) 555-4321) rshowline
  301. (Telex: 5551010110) rshowline
  302.  
  303. % === Show (print) the page, then restore the initial state
  304. showpage
  305. restore
  306.  
  307.  
  308.