%! ps % This is an attempt at reworking byte 90 /usenewgonzo true store % GONZO JUSTIFY MODULES % ....... % Status ........ Date: Aug 21 1989 % Version 8.0 % changes to version 8: (1) unitkern > and < % (2) invisible [esc]-: default font % (3) more macros % Goals : (1) include keystones % (2) seperate compile % (3) array justify 120 dict /gonzo exch def gonzo begin % now requires activation % justify procs % . . . . % Each justify proc takes the string list and calculates the starting % currentpoint and any needed -spaceadj- and -charadj- /sfix 0 def /cfix 0 def /justx (justF) def % justification l = left f = full, etc. /endtheline {closeline passspaces lastparline {pop pop} {startnewline}ifelse} def /passspaces {{oktohere lslen 1 sub lt { linestring oktohere get 32 eq {/oktohere oktohere 1 add def}{exit} ifelse }{exit} ifelse } loop} def /closeline {/fontsave fontn 4 get def printsubstrings fontsave changefont /ypos ypos yinc sub def colcheck} def % swallowandhang removes any trailing spaces from the line where % they would interfere with fill and right justify. It then optionally % hangs the punctuation as needed. /hangflag true def % default /str ( ) def /hanglist (-.,:;"'\)\261\320) def /hangfract 0.67 def /reallyhang { hanglist { hangchar eq {str 0 hangchar put str stringwidth pop hangfract mul sparechange exch add /sparechange exch def exit }if } forall} def /hangpunct {dup dup /hangchar exch def 97 lt exch 122 gt or {reallyhang} if exit} def /swallowandhang {lastchar 1 sub -1 0 {linestring exch get dup 32 eq {pop /#spaces #spaces 1 sub def /#chars #chars 1 sub def /sparechange sparechange spacewidth add def}{hangpunct} ifelse} for} def /justF {swallowandhang #spaces dup 0 gt {lastparline {sparechange txtwide 0.10 mul ge {/sfix maxsstretch lastlinestretch mul def}{/sfix 0 def} ifelse /cfix 0 def}{sparechange exch div /scfix exch def xpos1 scfix dup maxsstretch lt {/sfix exch def /cfix 0 def}{pop maxsstretch /sfix exch def scfix maxsstretch sub #spaces mul #chars 1 sub div dup maxcstretch lt {/cfix exch def}{maxcstretch dup /cfix exch def sub #chars 1 sub mul #spaces div sfix add /sfix exch def} ifelse }ifelse}ifelse}{pop lastparline {sparechange txtwide 0.10 mul ge {/sfix maxsstretch lastlinestretch mul def}{/sfix 0 def} ifelse /cfix 0 def}{/cfix sparechange #chars 1 sub dup 0 le {pop 1} if div def} ifelse } ifelse endtheline} def /justL {/sfix 0 def /cfix 0 def endtheline} def /justR {/sfix 0 def /cfix 0 def swallowandhang gsave /xadj sparechange def endtheline /xadj 0 def grestore} def /justC {/sfix 0 def /cfix 0 def swallowandhang gsave /xadj sparechange 2 div def endtheline /xadj 0 def grestore} def /str ( ) def /changefont {dup fontn 4 get ne {fontn exch 4 exch put fontn cvx exec /spacewidth ( ) stringwidth pop spacestretch add charstretch add def}{pop} ifelse} def /changejust {dup justx 4 get ne {justx exch 4 exch put} {pop} ifelse} def /escapeproc {pop linestring 1 index /sparechange exch def 2 index 1 add dup 1 sub /oktohere exch def get /cmnd# exch def createss /ssok false def ( ) dup 0 cmnd# put cvn gonzolink exch get exec exch 1 add dup 1 add /ssstart exch def /oktohere {ssstart} def exch exit} def /otherproc {{dup (\033) eq {escapeproc} if dup (\n) eq {pop dup /sparechange exch def 1 index /oktohere exch def createss /oktohere oktohere 1 add def justx cvx exec exit}{pop exit} ifelse}loop } def /spaceproc {/#spaces #spaces 1 add def pop dup /sparechange exch def 1 index /oktohere exch def /ssok true def spacewidth sub dup 0 lt {createss justx cvx exec}{dup /sparechange exch def 1 index 1 add /oktohere exch def}ifelse} def /commandscan {dup ( ) eq {spaceproc}{otherproc} ifelse} def % during a scan, the running line sum is on top of the stack % and the running character counter is next below /firstuseflag true def % removes PostScript stringsave bug /fontn (font1) def /justifylastparline false def /gonzojustify {firstuseflag {fontn 4 50 put 58 changefont /firstuseflag false def} if dup length 1 lt {pop ( )} if dup /linestring exch def length 1 sub /lslen exch def /lastparline false def /sparechange 0 def startfirstline {linestring 2 index 1 getinterval dup ( ) gt {stringwidth pop sub charstretch sub dup 0 lt { #spaces 0 eq {1 index /oktohere exch def /ssok true def} if ssok {createss} if justx cvx exec} if} {dup ( ) eq {spaceproc} {otherproc} ifelse} ifelse exch 1 add dup lslen gt {exit} {exch} ifelse} loop justifylastparline not {/lastparline true def} if /ssok true def dup /oktohere exch def exch dup /sparechange exch def ssok {createss} if justx cvx exec /ypos ypos yparendadj sub def} def /yparendadj 0 def % fillsubstrings - routines to create and fill the ssarray /ssarray 25 array bind def % creates the array at load time % /colcheck {} def % default bottom of page check /xfix {xadj add} def /startnewline { /#ssa 0 def /tabcount 0 def /xpos1 xpos indentcount 0 gt {pm add} if def /shiftproc {[xpos1 {xadj add} ypos {moveto}] cvx} def /ssok true def /#spaces 0 def /#chars 0 def /ssstart oktohere def pop pop ssstart 1 sub txtwide indentcount 0 gt {pm sub /indentcount indentcount 1 sub def} if} def /startfirstline {/#ssa 0 def /tabcount 0 def /xpos1 xpos pm add def /ssstart 0 def /ssok true def /shiftproc {[xpos1 {xadj add} ypos {moveto}] cvx} def /#spaces 0 def /#chars 0 def ssstart txtwide pm sub} bind def /newshiftproc {/shiftproc {{}} def} def /indentcount 0 def /xadj 0 def /createss { oktohere dup /lastchar exch def ssstart sub dup /#chars exch #chars add def /sslen exch def ssarray #ssa mark spacestretch charstretch ssstart sslen shiftproc fontn 4 get] put /#ssa #ssa 1 add def newshiftproc} def % printsubstrings - prints a previously created % ssarray array of form [[string1][string2]...[stringn]] and % length #ssa. Each substring array is in the form % [-spacestretch- -charstretch- -wstringstartpointer- % -wstringlengthpointer- {moveproc} -font-]. % logic and format for currentpoint shift . . . % {{}} use existing currentpoint % {6 3 {rmoveto}} execute currentpoint proc % {6 {xadj add} 3 {moveto}} execute currentpoint proc /oktoprint true def % print suppression flag /printsubstrings {oktoprint {0 1 #ssa 1 sub {ssarray exch get aload pop dup 0 ne {dup fontn 4 get ne {fontn exch 4 exch put fontn cvx exec }{pop} ifelse}{pop} ifelse {exec} forall linestring 3 1 roll getinterval 3 1 roll cfix add 3 1 roll sfix add 3 1 roll 0 exch 0 4 1 roll 32 4 1 roll awidthshow} for } if } bind def % gonzolinks % . . . . . % The gonzolink dictionary links the one-character escape commands % to their gonzoprocs. While this is completely flexible, I recommend % using numerics for font selections, capital numerics for tabs; uppercase % for mode and justify selections; lowercase for immediately executed % PostScript utilities and value changes; and high ASCII for anything that % is special for one specific or unusual job. /gonzolink 50 dict def gonzolink begin /0 {48 changefont} def /1 {49 changefont} def /2 {50 changefont} def /3 {51 changefont} def /4 {52 changefont} def /5 {53 changefont} def /6 {54 changefont} def /7 {55 changefont} def /8 {56 changefont} def /9 {57 changefont} def /: {58 changefont} def /; {59 changefont} def /- {45 changefont} def /= {61 changefont} def /C {67 changejust} def % center justify /F {70 changejust} def % fill justify /L {76 changejust} def % left justify /R {82 changejust} def % right justify /U {Umacro} def /V {Vmacro} def /W {Wmacro} def /X {Xmacro} def /Y {Ymacro} def /Z {Zmacro} def /a {amacro} def /b {bmacro} def /c {cmacro} def /d {dmacro} def /e {emacro} def /f {fmacro} def /g {} def % to prevent reentry /h {/ypos ypos yinc 2 div add def} def /i {initialcap} def % initialcap /j {gonzokern-} def % kerning link default is +1 point /k {gonzokern+} def % kerning link default is -1 point /l {/oktohere oktohere 1 add def endtheline} def % force new line /n {nobreak} def % conditional formfeed /p {/pm pmnorm def} def % normal pmargin /s {showpage} def % showpage /t {plainoldtab} def % tab link /x {} def % exit should be trapped by scanner /y {/ypos ypos yinc add def} def % negative linefeed /z {/pm 0 def} def % zero pmargin end /nobreak {ypos yinc 6 mul sub ybot lt {/ypos ybot def} if} def /initialcap {/ypos ypos yinc add yparendadj add def /pm dropindent def /indentcount dropcount def} def % a simple tab routine for lj only. Tabs relative to xpos /tabs [100 150 200 250 300] def % default tab /plainoldtab {pop tabs tabcount get /curtab exch def txtwide curtab sub /shiftproc {[xpos curtab add ypos {moveto}]cvx} def tabcount tabs length 1 sub lt {/tabcount tabcount 1 add def} if} def /kern -1 def % default kern value /gonzokern+ {kern sub /shiftproc {[ kern 0 {rmoveto}] cvx} def} def /gonzokern- {kern add /shiftproc {[ kern neg 0 {rmoveto}] cvx} def} def % stringmacro lets you do a series of gonzolink commands with a single % macro keystroke. For instance, /amacro {(z3c) stringmacro} def picks % a centered font3 with no paragraph for an embedded [esc]-a. /smac ( ) def /stringmacro {{smac exch 0 exch put smac cvn gonzolink exch get cvx exec} forall} def (\033g) cvn {startgonzo} def % gonzofont forces an unconditional font change. Use 6 gonzofont, etc. /gonzofont {fontn 4 0 put 48 add changefont} def % callout justify routines % .............. % These are used for "quick and dirty" layouts and for % illustration callouts. No scanner is used. cc and % cr align themselves on xpos, independent of txwide. % -xpos- -ypos- (String message) cl --> left justify % -xpos- -ypos- (String message) cf --> fill justify % -xpos- -ypos- (String message) cc --> center justify % -xpos- -ypos- (String message) cr --> right justify /unrestorefont {/firstuseflag false def fontn 4 get fontn 4 63 put changefont} def /cl {save /snapcl exch def /msg exch def /ypos exch def /xpos exch def /justx (justL) def msg gonzojustify snapcl restore unrestorefont} def /cf {save /snapcf exch def /msg exch def /ypos exch def /xpos exch def /justx (justF) def msg gonzojustify snapcf restore unrestorefont} def /cc {save /snapcc exch def /msg exch def /ypos exch def 2500 sub /xpos exch def /txtwide 5000 def /justx (justC) def msg gonzojustify snapcc restore unrestorefont} def /cr {save /snapcr exch def /msg exch def /ypos exch def 5000 sub /xpos exch def /txtwide 5000 def /justx (justR) def msg gonzojustify snapcr restore unrestorefont} def % ctab justify - will take most any input file and convert it to % a proportionally spaced table. The only rule is that double % spaces are prohibited in any entry and that at least two spaces % are needed between successive columns of the input file. % dictionary entries are -xoffset- -{justification}- -(fontnumber)- -txtwide- % -txtwide- is always required but only used with fill justify. It must % be larger than any left justified tab string. /tablist 40 dict def tablist begin /0 [ 0 {cl} (1) 1000] def /1 [ 70 {cc} (1) 1000] def /2 [150 {cf} (1) 80] def /3 [250 {cr} (1) 1000] def /4 [250 {cl} (1) 1000] def /5 [300 {cl} (1) 1000] def /6 [350 {cl} (1) 1000] def /7 [400 {cl} (1) 1000] def /8 [450 {cl} (1) 1000] def /9 [500 {cl} (1) 1000] def end /tabstring ( ) def % this is the searching tab marker /settabstring {tablist tabnum ( ) cvs get aload pop /txtwide exch def 0 get changefont exch xleft add ypos2 4 2 roll cvx exec clear} def /gottatab {exch pop exch /smsg exch def settabstring {smsg ( ) anchorsearch {pop /smsg exch def}{ exit} ifelse } loop /tmsg exch def } def /tabscan {/tmsg exch def /tabnum 0 def {tmsg tabstring search {gottatab /tabnum tabnum 1 add def}{settabstring exit} ifelse} loop} def /ctab {save /snapct exch def /justifylastparline true def /ttmsg exch def /ypos2 exch def /xleft exch def /tabnum 0 def {ttmsg (\n) search {exch pop exch /ttmsg exch def tabscan /ypos2 ypos2 yinc sub def}{tabscan exit} ifelse} loop clear snapct restore unrestorefont} def % scan converter % . . . . . % The gonzo justify routines expect input as () delimited % strings and use the -escape- character for commands. % An input scan converter can be used for "\" character % substitution, to redefine the -escape- character, to % repair AppleTalk bugs, or to solve system problems. 6000 string /scanstr exch def /exitchar 120 def % for esc-x loop exit /escsubchar 33 def % for use escape as is /startgonzo {{ clear /more false def -1 { 1 add dup currentfile read not {pop exit} if dup 13 eq {3 sub} if % fixes AppleTalk bug dup 10 eq {pop /more true def exit} if dup 92 eq {rslashproc}if % dup escsubchar eq {pop 27} if % bypass as comment if not used dup 27 eq {exitproc} if scanstr 3 1 roll put } loop scanstr exch 0 exch getinterval gonzojustify pop more not {/oktoprint true def exit} if} loop} bind def /rslashproc {pop currentfile read not {pop /more false def exit} if dup 41 eq { 1000 } if % replicate right paren dup 40 eq { 1000 } if % replicate left paren dup 92 eq { 1000 } if % replicate reverse slash dup 98 eq { pop 8 1000 } if % substitute bs dup 102 eq { pop 12 1000} if % substitute formfeed dup 116 eq { pop 9 1000} if % substitute tab dup 110 eq { pop /more true def exit} if % end string on linefeed dup 114 eq { pop /more true def exit} if % end string on return dup 48 ge { dup 55 le {dooctal} if} if 1000 eq { } {pop 1 sub dup 1 add 0 } ifelse % substitute or replicate } def /dooctal {48 sub 64 mul /oct exch def currentfile read not {pop /more false def exit} if dup 48 ge { dup 55 le {dothird} {1000} ifelse} if} def /dothird {48 sub 8 mul oct add /oct exch def currentfile read not {pop /more false def exit} if dup 48 ge { dup 55 le {48 sub oct add } if 1000} if} def /exitproc { pop currentfile read not {pop /more false def exit} if dup exitchar eq {pop exit}{exch scanstr exch 27 put exch 1 add dup 3 -1 roll} ifelse} def % end scanner % default font and variable list % . . . . . % initial font /font: {/Helvetica findfont [9 0 0 9 0 0] makefont setfont} def % for drop caps /font0 {/Helvetica-Bold findfont [40 0 0 40 0 0] makefont setfont} def % regular text /font1 {/Helvetica findfont [9 0 0 9 0 0] makefont setfont} def /font2 {/Helvetica-BoldOblique findfont [9 0 0 9 0 0] makefont setfont} def /font3 {/Helvetica-Bold findfont [9 0 0 9 0 0] makefont setfont} def % slightly smaller for numbers and caps in text /font4 {/Helvetica findfont [8 0 0 8 0 0] makefont setfont} def /font5 {/Helvetica-BoldOblique findfont [8 0 0 8 0 0] makefont setfont} def /font6 {/Helvetica-Bold findfont [8 0 0 8 0 0] makefont setfont} def % superscript and subscript /font7 {/Helvetica-Bold findfont [6 0 0 6 0 0] makefont setfont} def /font8 {/Helvetica-Bold findfont [6 0 0 6 0 4] makefont setfont} def % lowered title line /font9 {/Helvetica-Bold findfont [9 0 0 9 0 4] makefont setfont} def % specialty fonts /font- {/ZapfDingbats findfont [9 0 0 9 0 4] makefont setfont} def /font= {/Symbol findfont [9 0 0 9 0 4] makefont setfont} def % ....... % default tab list for ctab. First entry is x offset in points; % second is deferred justify proc. Third is initial font as % string number, and fourth is txtwide in points. Each successive % tab is picked up when two or more spaces occur sequentially. tablist begin /0 [ 0 {cl} (5) 1000] def /1 [5.1 {cl} (5) 1000] def /2 [8.8 {cl} (5) 1000] def /3 [12.5 {cl} (5) 1000] def /4 [16.2 {cl} (5) 1000] def /5 [1600 {cl} (5) 1000] def % use extra to catch any end spaces end % ..... % default constants - redefine for each application /oktoprint true def % print suppression flag /justx (justL) def % left justify /txtwide 500 def % width of column /yinc 11 def % line spacing /charstretch 0.2 def % minimum character kerning /spacestretch 0 def % minimum space kerning /maxsstretch 2.5 def % space fill stretch before character stretch /maxcstretch 1 def % maximum allowable fill character stretch /lastlinestretch 0.25 def % stretch on last line of fill just paragraph /dropcount 3 def % lines indented for drop cap /dropindent 40 def % width reserved for drop cap /pm 0 def % paragraph margin /pmnorm 10 def % normal paragraph indent /xpos 70 def % horizontal start of text /ypos 600 def % vertical start of text /colcheck { } def % link to page or column maker % here is a simple "just dump the text" pagebuilder. Preceed your % text with -startgonzo- and end it with [esc]-x -showpage- [d]. /ytop 750 def /ypos ytop def /ybot 50 def /colcheck { ypos ybot le {showpage /ypos ytop def} if} def % end gonzojustify and scanner end % close gonzo dictionary % name of textfile: powertool.util % .... /.ep0 {} def /.ep1 {} def % last revision: Sept 88 % requires gonzo.dl.4x when used /ps.util.1 200 dict def ps.util.1 begin % A series of everyday working PostScript utilities that include: % (1) stepnrepeat - step and repeat routines % (2) boxdraw - a box drawing and hairline routine % (3) changegray - fast resetting of gray setscreens % (4) curvetrace - a powerful curve tracing routine % (5) rubbergrid - dropout-free flexible layout grids % (6) electronics - electronic schematic icons for rubbergrid % (7) arcjustify - improved circletext routine with kerning % (8) nuisances - single command replacements for complex stuff % (9) - % (10) - % (11) errortrap - improved error trapping routines % (1) step and repeat % . . . . . . . /stepnrptparams 40 dict def stepnrptparams begin /admitonetick [6 5 9 150 60 25 25 true 10 true true] def /babybumper [1 2 10 270 72 40 30 false 20 true false] def /badgeaminit [1 2 3 220 220 90 60 false 250 true false] def /bigbumpstick [1 1 3 792 205 0 0 true 40 true false] def /businesscard [1 3 4 256 143 12 20 true 20 true false] def /decaapus [1 2 5 306 158 0 0 false 50 true false] def /hexsplit [1 2 3 306 264 0 0 false 50 true false] def /lilbumpstick [1 1 5 610 150 0 20 false 60 true false] def /octopus [1 2 4 306 198 0 0 false 50 true false] def /quadsplit [1 2 2 396 306 0 0 true 50 true false] def /readerservice [1 12 25 25 -15 120 450 false 0 false true] def /seqbuscard [1 3 4 256 143 12 20 true 20 true true] def /shiplabel [1 1 4 290 180 314 75 false 0 false false] def /stdplabel [1 1 11 254 74 320 5 false 20 true false] def /tenlabel [1 2 5 305 144 0 45 false 0 false false] def /vhsvideospline [1 1 13 424 56 80 35 false 0 false false] def /3.5disklabel [1 2 3 216 226 100 60 false 20 false false] def /5.25disklabel [1 1 7 316 110 275 35 false 0 false false] def end /setrepeatparams {cvn stepnrptparams exch get aload pop /seqnumber exch def /ticktrue exch def /ticklen exch def /portrait exch def /vertstart exch def /horstart exch def /incvert exch def /inchoriz exch def /numvert exch def /numhoriz exch def /numpages exch def portrait {-90 rotate -792 0 translate } if} def /onetick { 0 ticklen 2 div rmoveto 0 ticklen neg rlineto ticklen 2 div neg dup neg rmoveto ticklen 0 rlineto 0 setlinewidth stroke} def /drawticks {gsave ticktrue {0 0 moveto onetick inchoriz 0 moveto onetick 0 incvert moveto onetick inchoriz incvert moveto onetick} if grestore}def /stepandrepeat { setrepeatparams numpages {gsave horstart vertstart translate gsave numhoriz {gsave numvert { drawticks save /rptsave1 exch def repeatproc rptsave1 restore seqnumber {/runningnumber runningnumber 1 add def} if 0 incvert translate } repeat grestore inchoriz 0 translate} repeat grestore showpage grestore} repeat } def % . . . . . % DEMO -- remove before use: .ep0 /Helvetica-BoldOblique findfont [11 0 0 11 0 0] makefont setfont /startingnumber 673 def /runningnumber startingnumber def /numstring 10 string def /repeatproc {57 70 moveto (This is business card #) show runningnumber numstring cvs show } def % (businesscard) stepandrepeat .ep1 % //////////////////////// % (2) boxdraw % . . . . . % Draws various fancy boxes and sidebars, with or without % rounded corners and double hairlines /boxpath {/strt br bl add 2 div def /br {bl bw add} def % attempted repair /bc {bl bw 2 div add} def /bb {bt bh sub } def newpath strt bt moveto br bt br bb brad arcto br bb bl bb brad arcto bl bb bl bt brad arcto bl bt strt bt brad arcto closepath blw setlinewidth} def /br {bl bw add} def /bc {bl bw 2 div add} def /bb {bt bh sub} def /boxdraw {boxpath stroke} def /boxfill {boxpath gsave fill grestore} def /hairdraw {gsave /hd exch def 0.5 setlinewidth bl bt hd sub moveto bw 0 rlineto 0 2.5 rmoveto bw neg 0 rlineto stroke} def /grabbox {/blw exch def /brad exch def /bh exch def /bt exch def /bw exch def /bl exch def} def /quickboxdraw {grabbox boxdraw} def /quickboxpath {grabbox boxpath} def /quickboxfill {grabbox boxfill} def % defaults /bl 200 def /bw 175 def /bt 500 def /bh 240 def /brad 7 def /blw 2 def /hd 25 def % use examples: boxdraw hd hairdraw -- draws the box and a title % boxpath -- generates only the path without stroking % gsave bl 10 add bb 15 add translate -- locks stuff % to inside of box; grestore exits % 200 175 500 240 7 2 quickboxdraw -- draws without % predefinition, but can't track inside height. % /////////////////////////////// % (3) changegray % . . . . . . . % changes to decent gray screens with single word commands % the "gray" number equals the total number of grays including % black and white. /normspot {{dup mul exch dup mul add 1.0 exch sub} setscreen} def /gray39 {45 7 normspot} def /gray37 {50 0 normspot} def /gray35 {50 30 normspot} def /gray33 {55 45 normspot} def /gray30 {55 25 normspot} def /gray27 {55 15 normspot} def /gray26a {60 0 normspot} def /gray26b {60 35 normspot} def /gray21 {65 30 normspot} def /gray19 {70 45 normspot} def /gray18 {75 15 normspot} def /gray17 {75 0 normspot} def /gray14 {85 35 normspot} def /gray11 {95 20 normspot} def /gray10 {100 0 normspot} def /gray9 {100 45 normspot} def /gray6 {135 25 normspot} def /gray5 {150 0 normspot} def /gray3 {210 45 normspot} def /gray2 {300 0 normspot} def /bestgray {gray9} def % best overall gray /reprogray {gray14} def % for reduced camera prepress /indiagray {gray6} def % ultra fine "india ink" wash /putridgray {gray33} def % default - urp % for fine grey grids that are dropout free .... /finegridgray {105 45 {pop pop 0} setscreen 0.9 setgray} def % ////////////////////////////////// % (4) curvetrace % . . . . . % curvetrace - creates a smooth curved path from a data point list. % enter with currentpoint set and absolute array. /curvetrace {/curvelist exch def tension 0 eq {/tension .000001 def} if curvelist length 3 div 1 sub cvi /#triads exch def /ptr 0 def firstpoint morepoint} def /tension 2.83 def % default value for best fit /showtick false def % don't show points /ticklen 15 def % length of ticks /tickhead ticklen 4 div def /prvx { curvelist ptr 3 sub get } def /curx { curvelist ptr get } def /prvy { curvelist ptr 2 sub get } def /cury { curvelist ptr 1 add get } def /prva { curvelist ptr 1 sub get } def /cura { curvelist ptr 2 add get 180 sub} def /showtic1 { showtick true eq {gsave currentpoint newpath translate cura 180 add rotate ticklen neg 2 div 0 moveto ticklen 0 rlineto tickhead neg dup rlineto tickhead dup rlineto tickhead dup neg exch rlineto 0 setlinewidth stroke 0 ticklen neg 2 div moveto 0 ticklen rlineto stroke grestore} if }def /firstpoint { curx cury 2 copy abs exch abs add 0 eq {pop pop currentpoint curvelist exch 1 exch put curvelist exch 0 exch put}{moveto} ifelse showtic1 /ptr ptr 3 add def}def /morepoint {#triads { curx prvx sub dup mul cury prvy sub dup mul add sqrt tension div /zdist exch def prva cos zdist mul prvx add prva sin zdist mul prvy add cura cos zdist mul curx add cura sin zdist mul cury add curx cury curveto showtic1 /ptr ptr 3 add def} repeat} def /showtick false def % ////////////////////////////////// % (5) Finegray Rubbergrid % . . . . . . % Creates fine gray grids without dropouts or rattiness. % The code shown is device specific for 300 dpi printers. % To create a grid, use -hpos- -vpos- -gridsize- setgrid % Until restored, all further images will be "locked" to % the grid and will expand and contract with it. Note that % optimum linewidths and font sizes will usually be much % less than 1.0 after locking. % To show a grid, use -#hlines- -#vlines- showgrid. % The seegrid command displays the grid when true. % The fat5 command emphasizes every fifth line when true. % the fatter10 command emphasizes every tenth line when true. /quadpixel {transform 4 div round 4 mul itransform} def /setgrid {save /rubbersnap exch def quadpixel /size exch def quadpixel exch quadpixel exch translate size dup scale setfontssmaller} def /drawlines {72 300 div lw mul size div setlinewidth /hposs 0 def #hlines gs div 1 add cvi {hposs 0 moveto 0 #vlines rlineto stroke /hposs hposs gs add def} repeat /vposs 0 def #vlines gs div 1 add cvi {0 vposs moveto #hlines 0 rlineto stroke /vposs vposs gs add def} repeat} def /showgrid{ seegrid {gsave /#vlines exch def /#hlines exch def 106 45 {pop pop 0} setscreen 0.9 setgray /gs 1 def /lw 1 def drawlines fat5 {/gs 5 def /lw 3 def drawlines} if fatter10 {/gs 10 def /lw 5 def drawlines} if grestore}if} def /fat5 true def /fatter10 true def /seegrid true def % use examples: -xpos- -ypos- -gridsize- setgrid % -#hlines- -#vlines- showgrid % {anything you want locked to the grid} % clear rubbersnap restore % rubbergrid utilities - drawing aides for the rubbergrid % line drawing stuff /line1 {.06 dup setlinewidth 5 mul /erase exch def} def /line2 {.12 dup setlinewidth 5 mul /erase exch def} def /line3 {.18 dup setlinewidth 5 mul /erase exch def} def % deferred font setting /setfontssmaller { /font1 {/Helvetica findfont [0.7 0 0 0.8 0 0] makefont setfont} def /font2 {/Helvetica-Bold findfont [0.7 0 0 0.8 0 0] makefont setfont} def /font3 {/Symbol findfont [0.7 0 0 0.8 0 0] makefont setfont} def /font4 {/Helvetica findfont [0.5 0 0 0.4 0 0] makefont setfont} def /font5 {/Helvetica-Bold findfont [1.6 0 0 1 0 0] makefont setfont} def /yinc 1 def /pmnorm 0 def /charstretch 0.033 def /spacestretch 0.05 def /ybot -9999 def /lastlinestretch lastlinestretch 0.1 mul def } def /mt {moveto} def /rm {rmoveto} def /rl {rlineto} def % these draw individual lines /x {rlineto currentpoint stroke moveto} def /r {0 x} def /r+ {dup x} def /r- {dup neg x} def /l {neg 0 x} def /l+ {neg dup neg x} def /l- {neg dup x} def /u {0 exch x} def /d {0 exch neg x} def % these create a path /pl {neg 0 rl} def /pl+ {neg dup neg rl} def /pl- {neg dup rl} def /pr { 0 rl} def /pr+ {dup rl} def /pr- {dup neg rl} def /pu {0 exch rl} def /pd {0 exch neg rl} def % these draw a line and "erase" across the background /ux {0 exch 2 copy gsave 1 setgray erase setlinewidth currentpoint .18 add moveto 0 setlinecap x grestore x } def /dx {neg 0 exch 2 copy gsave 1 setgray erase setlinewidth currentpoint .18 sub moveto 0 setlinecap x grestore x } def /rx {0 2 copy gsave 1 setgray erase setlinewidth currentpoint exch .18 add exch moveto 0 setlinecap x grestore x } def /lx {neg 0 2 copy gsave 1 setgray erase setlinewidth currentpoint exch .18 sub exch moveto 0 setlinecap x grestore x } def /dot { currentpoint newpath 0.150 0 360 arc fill } def /mdot { m dot} def % some small default circles /circ1 {gsave currentpoint newpath 0.20 0 360 arc whitefill line1 stroke grestore} def %for circle /circ2 {gsave currentpoint newpath 0.200 0 360 arc whitefill line2 stroke grestore} def %for complement /circ3 {gsave currentpoint newpath 0.8 0 360 arc line2 stroke grestore} def %for led /circ4 {gsave currentpoint newpath 0.33 0 360 arc whitefill line2 stroke grestore} def %for test point and switches % repeats [ proc distance trips] xrpt /xrpt{gsave aload pop /trips exch def /dist exch def /rproc exch def trips { gsave rproc grestore dist 0 translate } repeat grestore} def /yrpt{gsave aload pop /trips exch def /dist exch def /rproc exch def trips { gsave rproc grestore 0 dist translate } repeat grestore} def % some arrows . . . /uarrow {-.15 -.8 rlineto .3 0 rlineto closepath fill} def /darrow {gsave 180 rotate 0 0.8 rmoveto uarrow grestore} def /rarrow {gsave -90 rotate uarrow grestore} def /larrow { gsave 90 rotate uarrow grestore} def /whitefill { gsave 1 setgray fill grestore} def % ////////////////////////////////// % (6) electronics % . . . . . . % Opaque icons for use with the rubbergrid system. % This is older code that still needs rework. % In general, use -xpos- -ypos- iconname /electronics 200 dict def electronics begin /micro {font3 (m) show font1} def /ohms {font3 (W) show font1} def /tstpt {mt circ4 currentpoint 0.15 0 360 arc fill} def /xinv {0 1.25 rlineto 2.5 -1.25 rlineto -2.5 -1.25 rlineto closepath whitefill line2 stroke} def /rinverter{ mt gsave xinv grestore 2.7 0 rm circ2} def /linverter {mt gsave 180 rotate xinv grestore -2.7 0 rm circ2 } def /res {-0.8 0 rmoveto gsave 1.6 0 rlineto line1 1 setgray stroke grestore 0.10 0.3 rlineto 3 { .20 -.6 rlineto .20 .6 rlineto} repeat .20 -.6 rlineto 0.10 0.3 rlineto stroke} def /hresistor {mt res} def /vresistor { mt gsave 90 rotate res grestore} def /lpot { gsave translate gsave 0 -0.10 translate 0 0 vresistor grestore -.2 0 moveto rarrow grestore} def /cap {currentpoint 2 copy gsave 1 setgray 0 -.20 rlineto stroke grestore moveto -.6 0 rmoveto 1.2 0 rlineto stroke moveto 0 -1.2 rmoveto currentpoint newpath 1 55 125 arc stroke } def /vcap { mt cap } def /hcap { mt gsave 90 rotate cap grestore} def /uvcap { mt gsave 180 rotate cap grestore} def /schmitt {mt 0.3 0.3 rmoveto line1 -0.4 0 rlineto 0 -0.6 rlineto -.2 0 rlineto 0.4 0 rlineto 0 .6 rlineto stroke} def /dpdt {gsave translate 0 0 mt gsave newpath 0 0 mt 1 setgray 0.3 setlinewidth 0 2 rlineto 1.5 0 rlineto 0 -2 rlineto stroke grestore circ2 0 1 rm circ2 0 1 rm circ2 1.5 0 rm circ2 0 -1 rm circ2 0 -1 rm circ2 .2 setlinewidth 1 setlinecap -.35 .05 rm 1 u -.55 0 rm 1 d grestore} def /spdt { gsave translate 0 0 mt gsave newpath 0 0 mt 1 setgray 0.3 setlinewidth 0 2 rlineto 1.5 0 rlineto 0 -2 rlineto stroke grestore circ2 0 1 rm circ2 0 1 rm circ2 0.2 setlinewidth 1 setlinecap .45 0.05 mt 1 u grestore} def /diode{ currentpoint newpath moveto -.3 0 rmoveto gsave .7 -.4 rlineto 0 .8 rlineto closepath fill grestore -0.05 -.4 rmoveto 0 .8 rlineto 0.1 setlinewidth stroke } def /udiode { gsave moveto -90 rotate diode grestore } def /ddiode { gsave moveto 90 rotate diode grestore} def /led { mt currentpoint circ3 ddiode } def % ...... /negpulse { moveto -.35 .5 rmoveto .2 0 rlineto 0 -.5 rlineto 0.3 0 rlineto 0 .5 rlineto .2 0 rlineto stroke} def /pospulse { gsave 180 rotate negpulse grestore} def % .... % +5 /5vdc {gsave 0 .8 rlineto currentpoint stroke .2 add 0.2 0 360 arc gsave 0.1 setlinewidth stroke grestore } def /xend { gsave -.1 0 rmoveto 0 .3 rlineto .2 0 rlineto 0 -.6 rlineto -.2 0 rlineto closepath line1 stroke grestore} def /hxtal { mt gsave -.33 0 rmoveto 0.66 0 rlineto 0.3 setlinewidth 1 setgray stroke grestore gsave currentpoint exch -.35 add exch moveto xend 0.7 0 rmoveto xend grestore gsave 0 0.5 rmoveto 0 -1 rlineto 0.2 setlinewidth stroke grestore} def /sensor { gsave 2 copy vresistor .1 setlinewidth .5 sub newpath .6 0 -180 arcn 0 1.1 rlineto currentpoint stroke exch 0.6 add exch .6 180 0 arcn 0 -1.1 rlineto stroke grestore} def % ...... % gnd /ground { -.4 0 rmoveto 0.8 0 rlineto -.65 -0.2 rmoveto .5 0 rlineto -0.35 -0.2 rmoveto .2 0 rlineto stroke} def /uground {gsave 180 rotate ground grestore} def /lground {gsave -90 rotate ground grestore} def /dground {gsave 90 rotate ground grestore} def /edgecon { gsave line2 mt 0 1.7 rm currentpoint newpath 0.3 180 0 arcn 1.7 d 0.6 l 1.7 u closepath gsave 1 setgray fill grestore stroke grestore} def /whitefill { gsave 1 setgray fill grestore} def /cell { gsave translate newpath 1 setgray 0 setlinecap 0 .3 mt 2 setlinewidth 0 -.6 rlineto stroke 0 setgray -.6 0.2 mt 0.3 setlinewidth 1.2 r stroke -1 -.3 mt line2 2 r grestore} def % //// DIPDRAW PROC ///// % dipdraw - draws a dip integrated circuit. % Enter with currentpoint set to pin 1 and scale % set so that 1.0 = distance between pins. Then % do a numpins-(name)-(hipins)-(lopins) dipdraw % Pin callouts preceeded by / will be complemented. % main dipdraw entry: /dipdraw { save /snap exch def /hipins exch def /lopins exch def /chipname exch def /numpins exch def /howlong {numpins 2 div cvi 1 add} def /howhigh {4 numpins 36 ge {1 add} if} def /stub {howhigh 1.4 sub 2 div} def % internal service subs start here: /pinproc {numpins 2 div cvi{newpath 0 cpos 0.37 0 360 arc gsave 1 setgray fill grestore 0.067 setlinewidth stroke pin# 5 string cvs dup stringwidth pop 2 div neg cpos 0.2 sub moveto show 1 0 translate /pin# pin# dir add def} repeat } def /stretchprint { dup stringwidth pop 2 div neg exch length 1 sub stretch mul 2 div sub 0 moveto callout (/) anchorsearch true eq {currentpoint exch stretch add exch moveto pop dup /callout exch def stringwidth pop callout length 1 sub stretch mul add /barwide exch def 0.033 setlinewidth gsave currentpoint 0.55 add moveto barwide 0 rlineto stroke grestore} if stretch 0 callout ashow} def /pincallouts{0 vpos translate {workstring ( ) search true eq {/callout exch def pop /workstring exch def callout stretchprint 1 0 translate}{dup /callout exch def stretchprint exit } ifelse}loop} def % actual dipdraw process starts here: % ........ the outline: gsave 1 setlinecap 1 setlinejoin currentpoint translate newpath -.55 .45 0.15 0 360 arc fill newpath -1 howhigh 2 div 0.7 -90 90 arc 0 stub rlineto howlong 0 rlineto 0 howhigh neg rlineto howlong neg 0 rlineto closepath 0.36 setlinewidth stroke % ........ pin circles and numbers: /Helvetica-Bold findfont [0.4 0 0 0.55 0 0] makefont setfont gsave /pin# 1 def /dir 1 def /cpos 0 def pinproc grestore gsave /pin# numpins def /dir -1 def /cpos howhigh def pinproc grestore % ........ pin callouts: /Helvetica findfont [0.35 0 0 0.6 0 0] makefont setfont /stretch 0.033 def gsave /workstring hipins def /vpos 0.6 def pincallouts grestore gsave /workstring lopins def /vpos howhigh 1.05 sub def pincallouts grestore % ....... device number: % was 1.4 0 0 1 0 0 /Helvetica-Bold findfont [1.4 0 0 1 0 0] makefont setfont /stretch 0.05 def gsave numpins 2 div 1 sub 2 div howhigh 2 div 0.33 sub translate chipname dup /callout exch def stretchprint grestore % ....... end cleanup: grestore grestore clear snap restore} def % ... % new inductor stuff /lloop { .5 1 -.5 1 0 0 r} def /ltie {.2 -.30 .4 -.30 .6 0 rcurveto} def /lexit{.2 -.40 .4 0 .6 0 rcurveto .4 r } def /lentry {.4 r .2 0 .4 -.4 .6 0 rcurveto} def /hcoil { /numloops exch def lentry numloops 1 sub {lloop ltie} repeat lloop lexit} def /winding {gsave /numloops exch def translate 0 0 moveto 0 rotate numloops hcoil grestore} def /vwinding {gsave /numloops exch def translate 0 0 moveto 90 rotate numloops hcoil grestore} def /vrwinding {gsave /numloops exch def translate 90 rotate 1 -1 scale 0 0 moveto numloops hcoil grestore} def /phonejack {gsave translate 1 setlinecap 0 0 mt 0.15 u 3.85 r 0.3 d 3.85 l 3.95 0.15 mt 0.15 r 0.1 -0.15 rlineto -0.1 -0.15 rlineto 0.15 l 0.3 u 0.4 setlinewidth 2 setlinecap 0 0 mt 2 r 1 setlinecap 0 0.2 mt 2 r 0 -0.2 mt 2 r grestore } def /lilphonejack{ gsave translate 0.8 dup scale 0 0 phonejack grestore} def /varistor {gsave translate gsave -.5 0 mt 0.6 setlinewidth 1 setgray 1 r grestore line2 0.6 0.3 mt 1.2 l 0.6 -0.3 mt 1.2 l -0.45 -0.25 mt 0.3 0.50 rlineto 0.3 -0.50 rlineto 0.3 0.50 rlineto stroke grestore} def /piezo { gsave translate 0 0 mt gsave 5 dup scale circ1 grestore gsave 2.5 dup scale circ1 grestore grestore } def /pctab {gsave 1 setlinecap 1 setlinejoin line2 1 u 2 r 1 d 2 l grestore} def /npn {gsave newpath exch 0.2 sub exch translate -.1 0 1.2 0 360 arc gsave 1 setgray fill grestore line2 stroke -0.2 0 translate line3 -.3 -.7 moveto 1.4 u line1 -.3 0 mt 1.3 l -.2 .4 mt 0.6 0.4 rlineto 1.2 u newpath -.2 -0.4 mt 0.6 -0.4 rlineto 1.2 d newpath 0.4 -0.75 mt -.2 .3 rlineto -.2 -.3 rlineto closepath fill grestore} def /npnl {gsave translate -1 1 scale 0 0 npn grestore} def /pnp {gsave newpath exch 0.2 sub exch translate -.1 0 1.2 0 360 arc gsave 1 setgray fill grestore line2 stroke -0.2 0 translate line3 -.3 -.7 moveto 1.4 u line1 -.3 0 mt 1.3 l -.2 .4 mt 0.6 0.4 rlineto 1.2 u newpath -.2 -0.4 mt 0.6 -0.4 rlineto 1.2 d newpath -.2 .4 mt .3 .4 rlineto .1 -.3 rlineto closepath fill grestore} def /pnpl {gsave translate -1 1 scale 0 0 pnp grestore} def end % -- the electronics dictionary % ////////////////////////// % (7) arc justify - sets circular text. % . . . . . % To use, -xpos -ypos- -radius- (message) arcjustify % A positive radius creates upward curving arcs. % A negative radius creates downward curving arcs. % Use -arckern- to stretch or compress message. /arckern 2 def /str ( ) def /arcjustify {gsave /msg exch def /radius exch def translate msg dup stringwidth pop exch length 1 sub arckern mul add 2 div dup 57.29578 mul radius div msg {str exch 0 exch put gsave rotate 0 radius moveto str dup dup stringwidth pop 2 div 57.29578 mul radius div neg rotate show stringwidth pop arckern add sub dup 57.29578 mul radius div grestore} forall pop pop grestore} def % demo -- /Helvetica-Bold findfont [100 0 0 100 0 0] makefont % setfont 200 0 500 (FREE FONT) arcjustify % ////////////////////////////////// % (6) nuisance solvers % . . . . . . % nuisance - a dictionary of commonly used PostScript sequences % . . . . . . . . . . % Copyright c 1988 by Don Lancaster and Synergetics, Box 809, % Thatcher, AZ 85552. (602) 428-4073. All rights reserved % Personal, non-commercial use permitted so long as this % header remains present and intact. Latest disk costs $24.50. % nuisancedict is usually persistently downloaded as a dictionary. % it is activated when needed by -- nuisance begin -- . 200 dict /nuisance exch def nuisance begin /acos {2 copy dup mul exch dup mul sub sqrt exch pop exch atan} def % arccosine use - xside hypotenuse acos - /asin {2 copy dup mul exch dup mul sub sqrt exch pop atan} def % arcsine use - yside hypotenuse asin - /backwards { 612 0 translate -1 1 scale} % print backwards /baud.1200.d.25 {1200 25 4 dobaud} def /baud.1200.x.25 {1200 25 0 dobaud} def /baud.9600.d.25 {9600 25 4 dobaud} def /baud.9600.x.25 {9600 25 0 dobaud} def /baud.19200.x.25 {19200 25 0 dobaud} def /baud.19200.x.25 {19200 25 0 dobaud} def /baud.38400.d.25 {38400 25 4 dobaud} def /baud.38400.x.25 {38400 25 0 dobaud} def /baud.57600.d.25 {57600 25 4 dobaud} def /baud.57600.x.25 {57600 25 0 dobaud} def /baud.1200.d.9 {1200 9 4 dobaud} def /baud.1200.x.9 {1200 9 0 dobaud} def /baud.9600.d.9 {9600 9 4 dobaud} def /baud.9600.x.9 {9600 9 0 dobaud} def /baud.19200.x.9 {19200 9 0 dobaud} def /baud.19200.x.9 {19200 9 0 dobaud} def /baud.38400.d.9 {38400 9 4 dobaud} def /baud.38400.x.9 {38400 9 0 dobaud} def /baud.57600.d.9 {57600 9 4 dobaud} def /baud.57600.x.9 {57600 9 0 dobaud} def /bestgray {106 45 {dup mul exch dup mul add 1.0 exch sub} setscreen} def /black {0 setgray} def /blackflash {0 0 moveto 1000 0 rlineto 0 1000 rlineto -1000 0 rlineto closepath fill showpage } def % black pre-page for highest print quality /copies { /#copies exch def} def % as in -- 6 copies -- /dobaud {serverdict begin 0 exitserver statusdict begin 3 copy setsccbatch setsccinteractive end quit} def % used by baud commands /feetfirst {180 rotate 612 792 translate} def % eject print feet first /inch {72 mul} def % inches /indiagray {135 35 {dup mul exch dup mul add 1.0 exch sub} setscreen} def /landscape {-90 rotate -792 0 translate} def % pick landscape printing /lightgray {0.99 setgray} def /listfonts {FontDirectory {pop == flush 200 {37 sin pop} repeat } forall} def % send installed font list to host /longjob {statusdict /waittimeout 180 put} def % lengthen job timeout /manual {statusdict /manualfeed true put} def % start manual feed /negative {{1 sub abs} settransfer} def % negative printing /notestpage {serverdict begin 0 exitserver statusdict begin false setdostartpage end end quit} def % cancel test page /outline {false charpath} def % finds character outline path /persist {serverdict begin 0 exitserver} def % starts persistent download /pi 3.1415926 def % you wanted rhubarb instead? /pixel {72 mul 300 div} def % 300 dpi only /positive {{} settransfer} def % restore positive printing /printfonts {/Helvetica findfont [10 0 0 10 0 0] makefont setfont /xpos 150 def /ypos 600 def /yinc 12 def xpos 20 sub ypos 20 add moveto (CURRENTLY INSTALLED FONTS:) show FontDirectory {pop 100 string cvs xpos ypos moveto (/) show show /ypos ypos 12 sub def} forall showpage} def % on paper /putridgray {53 45 {dup mul exch dup mul add 1.0 exch sub} setscreen} def /random {rand 65536 div 32768 div mul cvi} def % as in -- 6 random -- /report {== flush 100 {37 sin pop} repeat } def % top of stack to host /reprogray {85 35 {dup mul exch dup mul add 1.0 exch sub} setscreen} def /reporttimer {mytime 1000 div (\rElapsed time: ) print 20 string cvs print ( seconds.\r) print flush} def % to host /resettimer {/mytime 0 def} def % reset timer % This creates a rounded path from -radius- [x1 y1 x2 y2 ... xn yn] % roundpath. Always start and stop in the MIDDLE of a straight line. /roundpath {/rpdata exch def /rprad exch def rpdata length 1 sub cvi /rppoints exch def rpdata 0 get rpdata 1 get moveto 2 2 rppoints 2 sub {/rpvalue exch def 0 1 3 {rpdata exch rpvalue add get } for rprad arcto pop pop pop pop} for rpdata rppoints 1 sub get rpdata rppoints get lineto} def /superstroke { save /sssnap exch def /sscmd exch def mark 0 2 sscmd length 2 div cvi 1 sub 2 mul {/aposn exch def gsave sscmd aposn get setlinewidth sscmd aposn 1 add get setgray stroke grestore} for clear to mark sssnap restore newpath} def /superinsidestroke {save clip /sssnap exch def /sscmd exch def mark 0 2 sscmd length 2 div cvi 1 sub 2 mul {/aposn exch def gsave sscmd aposn get 2 mul setlinewidth sscmd aposn 1 add get setgray stroke grestore} for cleartomark sssnap restore newpath} def /snoop {1183615869 internaldict begin} def % activates superexec /stall {{37 sin pop} repeat} def % delay as in -- 1500 stall -- /starttimer {usertime /mytimenow exch def} def % add to time so far /stoptimer {usertime mytimenow sub /mytime exch mytime add def} def % for multiple timing intervals /stopwatchoff {stoptimer reporttimer} def % for single shots /stopwatchon {resettimer starttimer} def % for single shots % superstroke and superinsidestroke take a predefined path and a % top-of-stack array of [width1 gray1 width2 gray2 .... widthn grayn] % and do multiple strokes for wires, fancy borders, or braiding. % Note that the FIRST array value pair has to be the WIDEST, etc. % Use superstroke for wires; superinsidestroke for borders. /superstroke { save /sssnap exch def /sscmd exch def 0 2 sscmd length 2 div cvi 1 sub 2 mul {/aposn exch def gsave sscmd aposn get setlinewidth sscmd aposn 1 add get setgray stroke grestore} for clear sssnap restore newpath} def /superinsidestroke {save clip /sssnap exch def /sscmd exch def 0 2 sscmd length 2 div cvi 1 sub 2 mul {/aposn exch def gsave sscmd aposn get 2 mul setlinewidth sscmd aposn 1 add get setgray stroke grestore} for clear sssnap restore newpath} def /tan {dup sin exch cos dup 0 eq {pop 0.000001} if div} def % tangent /tray {statusdict /manualfeed false put} def % stop manual feed /white {1 setgray} def /width {stringwidth pop} def % finds x width of string /yestestpage {serverdict begin 0 exitserver statusdict begin true setdostartpage end end quit} def % restore test page end % the nuisance dictionary % ////////////////////////// % (11) error trapper % . . . . . % Select a more exotic error reporting mechanism on a % job-by-job basis % Use -printerror- at start of file for time-of-error % printout and stack dump % Use -appleerror- at start of file for delayed input % reporting as needed in a half duplex environment /printerror {/$brkpage 64 dict def $brkpage begin /prnt {dup type/stringtype ne{=string cvs}if dup length 6 mul /tx exch def/ty 10 def currentpoint/toy exch def/tox exch def 1 setgray newpath tox toy 2 sub moveto 0 ty rlineto tx 0 rlineto 0 ty neg rlineto closepath fill tox toy moveto 0 setgray show}bind def /nl{currentpoint exch pop lmargin exch moveto 0 -10 rmoveto}def /=={/cp 0 def typeprint nl}def /typeprint{dup type dup currentdict exch known {exec}{unknowntype}ifelse}readonly def /lmargin 72 def /rmargin 72 def /tprint {dup length cp add rmargin gt{nl/cp 0 def}if dup length cp add/cp exch def prnt}readonly def /cvsprint{=string cvs tprint( )tprint }readonly def/unknowntype{exch pop cvlit(??)tprint cvsprint}readonly def/integertype{cvsprint}readonly def/realtype{cvsprint}readonly def /booleantype{cvsprint}readonly def/operatortype{(//)tprint cvsprint} readonly def/marktype{pop(-mark- )tprint}readonly def/dicttype{pop (-dictionary- )tprint}readonly def/nulltype{pop(-null- )tprint}readonly def/filetype{pop(-filestream- )tprint}readonly def/savetype{pop (-savelevel- )tprint}readonly def/fonttype{pop(-fontid- )tprint}readonly def/nametype{dup xcheck not{(/)tprint}if cvsprint}readonly def/stringtype {dup rcheck{(\()tprint tprint(\))tprint}{pop(-string- )tprint}ifelse }readonly def/arraytype{dup rcheck{dup xcheck{({)tprint{typeprint} forall(})tprint}{([)tprint{typeprint}forall(])tprint}ifelse}{pop (-array- )tprint}ifelse}readonly def/packedarraytype{dup rcheck{dup xcheck{({)tprint{typeprint}forall(})tprint}{([)tprint{typeprint} forall(])tprint}ifelse}{pop(-packedarray- )tprint}ifelse}readonly def /courier/Courier findfont 10 scalefont def/OLDhandleerror errordict /handleerror get def end errordict /handleerror {systemdict begin $error begin $brkpage begin newerror{/newerror false store $error /errorname get (ioerror) ne $error /command get (exec) ne or {vmstatus pop pop 0 ne{grestoreall}if initgraphics courier setfont lmargin 720 moveto (ERROR: )prnt errorname prnt nl(OFFENDING COMMAND: )prnt/command load prnt $error/ostack known {nl nl(STACK:)prnt nl nl $error/ostack get aload length{==}repeat}if systemdict/showpage get exec /newerror true store/OLDhandleerror load end end end exec}{end end end} ifelse} {end end end}ifelse} dup 0 systemdict put dup 4 $brkpage put bind readonly put} def /appleerror{/oldhandleerror errordict /handleerror get def errordict /handleerror { /newerror false store {(%stdin) (r) file read true eq {pop}{exit} ifelse } loop 1500 {37 sin pop} repeat /newerror true store oldhandleerror} put} def % ////////////////////////////////// end % the entire utility dictionary % name of textfile: byte.prolog % .... % this is the custom pagemaker for the Byte story. It requires persistent % downloads of my gonzo justification routines and ps.util.1 utilities. % the usual sequence is (1) persistently download gonzo and ps.util.1 % (2) run this file, (3) run byte.fgs, (4) run byte.txt statusdict /waittimeout 180 put % extra time to reload disks /.ep0 {} def /.ep1 {} def %% zzzzzzzzzzz usenewgonzo { (C:\\windows\\desktop\\gonzo\\gonzo.ps) run /quadpixel {transform 4 div round 4 mul itransform} def } if gonzo begin ps.util.1 begin printerror nuisance begin % stuff to print bigger /printtophalf false def /pageprocreset {} def /pageprocreset {/bestgray {reprogray} def landscape 1.33 dup scale printtophalf {0 -325 translate} if } def /pageprocreset {} def pageprocreset % ........................ 200 dict /mydict exch def mydict begin save /stuffsnap exch def /font= {/ZapfDingbats findfont [10 0 0 10 0 0] makefont setfont} def /font- {/ZapfDingbats findfont [160 0 0 160 0 0] makefont setfont} def % /AvantGarde-Book findfont [13 0 0 13 0 0] makefont setfont % /Times-Roman findfont [9 0 0 9 0 0] makefont setfont % /Times-Bold findfont [5 0 0 5 0 0] makefont setfont /font0 {/Times-Bold findfont [51 0 0 52 0 -20] makefont setfont} def % was 38 -30 /font1 {/Times-Roman findfont [9.5 0 0 9.5 0 0] makefont setfont} def /font2 {/Times-Italic findfont [9.5 0 0 9.5 0 0] makefont setfont} def /font3 {/Times-Bold findfont [10 0 0 10 0 0] makefont setfont} def /font4 {/Times-Roman findfont [9 0 0 9 0 0] makefont setfont} def /font5 {/Times-Bold findfont [9 0 0 9 0 0] makefont setfont} def /font6 {/Helvetica findfont [14.5 0 0 14.5 0 0] makefont setfont} def /font7 {/Palatino-Roman findfont [36 0 0 50 0 0] makefont setfont} def /font8 {/Palatino-Roman findfont [30 0 0 40 0 0] makefont setfont} def /font9 {/Benguiat-Bold findfont [14 0 0 14 0 2] makefont setfont} def % for the continueds /font: {/Times-Italic findfont [8.5 0 0 8.5 0 0] makefont setfont} def % pick some template values /txtwide 140 def % width of text columns /coltop 700 def % column top position /yinc 11 def % line spacing % /charstretch 0.2 def % minimum extra space between characters % /spacestretch -0.4 def % minimum extra space between spaces /maxsstretch 0.25 def % trip point for character stretching /maxcstretch 0.1 def % maximum allowable character stretching /dropcount 2 def % number of lines the drop cap drops /dropindent 31 def % indentation for the drop cap /lastlinestretch 0.25 def % slight stretch to last paragraph line /colleft 60 def % first column left margin % /colbot 200 def % column bottom position /numcolumns 3 def % number of columns /colspacing 160 def % width of columns /pmnorm 10 def % paragraph margin % new (byte) /yinc 10 def % line spacing /txtwide 156 def % width of text columns /colleft 50 def % first column left margin /coltop 692 def % column top /colbot 42 def % column bottom position /numcolumns 3 def % number of columns /colspacing 168 def % width of columns /pmnorm 10 def /charstretch 0.02 def /spacestretch -0.6 def /maxsstretch 1.2 def % trip point for character stretching /maxcstretch 0.2 def % maximum allowable character stretching /dropcount 3 def /dropindent 21 def /ypos coltop def % select top text line % decide when to change columns. This particular colcheck also makes room % for figures and prints all but the last page, so it is your pagemaker. % (temp: makefigroom was before colnum) %debug test /colcheck { makefigroom ypos colbot lt {colnum numcolumns ge {showpage pageprocreset /pagenum pagenum 1 add def showfigs /ypos coltop yinc sub def /xpos colleft def /colnum 1 def makefigroom leftpage {false} {true} ifelse /leftpage exch def header footer makefigroom}{/colnum colnum 1 add def /ypos coltop yinc sub def /xpos xpos colspacing add def makefigroom} ifelse} if} def % setup your figures by using a dictionary. The Format is % [ pagenum colmnum {figheight} {figbot} drawiftrue (figname) ] % makefigroom lets the text flow around the figure spaces . . . /makefigroom {figdict { /figvalues exch def pop pagenum figvalues 0 get eq {colnum figvalues 1 get eq {ypos figvalues 3 get cvx exec figvalues 2 get cvx exec add le ypos figvalues 3 get cvx exec ge and {/ypos ypos figvalues 2 get cvx exec yinc div cvi 1 add yinc mul sub def} if} if} if} forall} def % showfigs goes through the dictionary and shows the needed figures % on the required pages /showfigs {figdict {/figvalues exch def pop pagenum figvalues 0 get eq {figvalues 4 get {/hold2 exch def /hold1 exch def save /figsnapx exch def mark /colcheck {} def 0 0 (1 2) cl colleft figvalues 1 get 1 sub colspacing mul add figvalues 3 get cvx exec translate figvalues 5 get cvn cvx exec cleartomark figsnapx restore hold1 hold2} if } if} forall} def % setup the page making routine . . . /setup {/colnum 1 def /xpos colleft def 0 0 showfigs firstpageheader {header} if firstpagefooter {footer} if} def /firstpageheader true def % default in case you don't need this feature. /firstpagefooter true def % default % select two macros to simplify drop caps and centered drop text . . . /amacro {aqua 0.3 setgray (Flzy0) stringmacro} def % start drop cap /bmacro {(iFy1) stringmacro black} def % finish drop cap /cmacro {aqua 0.27 setgray (zynC3) stringmacro} def % centered title /dmacro {(pF1) stringmacro black} def % normal text % Here is a default header routine. Usually, you will want the % subject name on the left for left pages and the publication % name on the right for right pages . . . /header { save /hsnap exch def mark /colcheck {} def /pmnorm 0 def /pm 0 def 0 0 (1 0) cc line1 colleft coltop 8 add translate 0 0 mt colspacing numcolumns 1 sub mul txtwide add r leftpage {0 5 leftheader pagenumcheck cl}{colspacing numcolumns 1 sub mul txtwide add 5 rightheader pagenumcheck cr}ifelse cleartomark hsnap restore} def % byte header here ... /header { save /hsnap exch def mark /colcheck {} def /pmnorm 0 def /pm 0 def /font0 {/Helvetica findfont [8 0 0 8 0 0] makefont setfont} def /font1 {/Times-Roman findfont [9.5 0 0 9.5 0 0] makefont setfont} def colleft colspacing numcolumns 1 sub mul txtwide add 2 div add coltop 30 add moveto /charstretch 0 def gsave aqua 0.33 setgray -27 2 rmoveto 54 0 rlineto 2 setlinewidth stroke grestore /charstretch 3 def gsave 0 27 rmoveto currentpoint (0HANDS ON) cc grestore /charstretch 0.3 def gsave 0 12 rmoveto currentpoint (1SOME ASSEMBLY REQUIRED) cc grestore aqua 0.30 setgray colleft coltop 37 add moveto 0 colspacing numcolumns 1 sub mul txtwide add 0 rlineto 0.5 setlinewidth stroke black cleartomark hsnap restore} def % Here is a default footer routine. Usually, you will want the % page number on the left for left pages and the page number % on the right for right pages . . . /footer {save /fsnap exch def mark /colcheck {} def /pmnorm 0 def /pm 0 def 0 0 (0 0) cc line1 colleft colbot 17 sub translate 0 0 mt leftpage {0 5 leftfooter pagenumcheck cl}{colspacing numcolumns 1 sub mul txtwide add 0.5 rightfooter pagenumcheck cr}ifelse cleartomark fsnap restore} def % temporary byte footer /footer { save /hsnap exch def mark /colcheck {} def /pmnorm 0 def /pm 0 def /font1 {/Times-Roman findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font2 {/Times-Roman findfont [7.5 0 0 7.5 0 0] makefont setfont} def /font3 {/Times-Bold findfont [8 0 0 8 0 0] makefont setfont} def /colright {colleft colspacing numcolumns 1 sub mul add txtwide add} def leftpage {0 0 (|23 ) cc colleft colbot 20 sub pagenum pagenumadjust add ( ) cvs cl colleft 22 add colbot 20 sub (1|/tinton1 B Y T E |/tintoff jj\267jj 2MAY 1990) cl} { 0 0 (23 ) cc colright colbot 20 sub pagenum pagenumadjust add ( ) cvs cr colright 22 sub colbot 20 sub (2MAY 19901 jj\267|/tinton1 jj B Y T E|/tintoff ) cr} ifelse cleartomark hsnap restore} def % Since the pagenumber can be any number of digits, we have to get tricky % here when we replace the "pagenum" marker with the actual digits . . . /pagenumcheck {/strr exch def strr (pagenum) search {/prenum exch def pop /postnum exch def pagenum pagenumadjust add 5 string cvs /thenum exch def postnum length thenum length add prenum length add string /numstring exch def numstring 0 prenum putinterval numstring prenum length thenum putinterval numstring prenum length thenum length add postnum putinterval numstring} if} def /pagenumadjust 50 def /pagenum 1 def % ////// END OF LAYOUT TEMPLATE /////// % Note #1 - Using a grid gets tricky on multi-page documents. To keep things % simple, we are working full size here. Individual figures can be % on their own 10X grid. % Note #2 - This is "medium speed" code. Your final copies can be dramatically % sped up by a compile process. Write or call for details. % Note #3:  = embedded escape command. Use a real escape if you can. % Note #4: Your host must be prevented from forcing extra carriage returns as % part of its formatting. If your host insists on an extra carriage % return every "n" characters, then insert a reverse slash that is % immediately followed by a carriage return after each "n-3" or fewer % characters of continuous text. Or change to another program. % Note #5: Narrow, fill justified columns require several post-justification % editing passes for the best possible appearance. Use hyphenation % and rewording to get good results. % ////// BEGIN DOCUMENT /////////////// % your actual document starts here . . . /leftheader (4MIDNIGHT ENGINEERING) def /rightheader (1March, k1k990) def /pagenum 1 def % for internal figures /pagenumadjust 20 def % printed number plus pagenum /leftfooter (1- pagenum -) def /rightfooter (1- pagenum -) def /firstpagefooter false def % false to cancel /firstpageheader false def % false to cancel /leftpage false def % this picks first page header and footer % /dropcount 3 def % number of lines the drop cap drops % /dropindent 18 def % indentation for the drop cap % dummy -this is repeated in later section /figdict 30 dict def figdict begin /fig0a [1 1 155 {coltop 150 sub} true (titleblurb)] def /fig0b [1 2 155 {coltop 150 sub} false (titleblurb)] def /fig0c [1 3 155 {coltop 150 sub} false (titleblurb)] def /fig1a [1 2 320 {colbot} true (meowwrrr)] def /fig1b [1 3 320 {colbot} false (meowwrrr)] def end % no end of file here !!! continues as byte.figures % name of textfile: byte.figures % .... % These are the included figures for the Byte story % /////// COMMON CODE ////////// % This routine is shared by all the figures /tempfast true def % overwrite in byte.text to print full images /includepix true def /commoncode { 1000 dict /mynewdict exch def mynewdict begin /setboxheight{fixedheight {/bh boxheight def} {/bh bt ypos sub 10 sub def % /bb {bt bh sub} def } ifelse} def makeitbig {-125 300 mul 18 div floor 18 mul 300 div -340 300 mul 36 div floor 36 mul 300 div translate 3 2 div dup scale} if /bl 125 def /bt 715 def /bh boxheight def /brad 0.001 def /blw 0.5 def /hd 25 def /bb {bt bh sub} def % params for boxifier twocolumnswide {/bw 322 def}{/bw 153 def} ifelse /titledraw { save /tsnap exch def /yinc 10 def /txtwide bw 8 add % fudge it for leftjust def /charstretch 0.2 def bl bb 13 sub title cl aqua 0.33 setgray bl bb yinc 5 mul sub moveto bw % fix bug??? 0 rlineto 0.5 setlinewidth stroke tsnap restore} def includepix {/bl 0 def /bt boxheight def 0 yinc 5 mul translate} if /ybot -99999 def /font0{/Times-Bold findfont [9 0 0 9 0 0] makefont setfont} def /font1{/Times-Italic findfont [9 0 0 9 0 0] makefont setfont} def /font2{/NewCenturySchlbk-Bold findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font3{/Helvetica-Oblique findfont [7 0 0 7 0 0] makefont setfont} def /font4{/Helvetica-Bold findfont [7 0 0 7 0 0] makefont setfont} def includepix not { save /hsnap exch def mark /txtwide 1000 def /yinc 12 def bl bt 10 add headerL cl bl bw twocolumnswide not {2 mul} if add bt 10 add headerR cr /yinc 10 def cleartomark hsnap restore } if % no header on inclusion /ypos bt 15 sub def /xpos bl 22 add def /yinc 9 def /ybot -9999 def % standards for inside the figure boxes % . . . . . . . . /denselisting{/bc br bl sub 2 div bl add def /txtwide bw 10 sub def /ybot -99999 def /font0{/Helvetica-Bold findfont [10 0 0 10 0 0] makefont setfont} def /font1{/Helvetica findfont [7 0 0 7 0 0] makefont setfont} def /font2{/Helvetica-Oblique findfont [7 0 0 7 0 0] makefont setfont} def /font3{/Helvetica-Bold findfont [7 0 0 7 0 0] makefont setfont} def /font4{/Courier findfont [7 0 0 7 0 0] makefont setfont} def /ypos bt 10 sub def /xpos bl 6 add def /yinc 8 def /amacro {(hy) stringmacro} def /emacro {/yparendadj yinc 2 div def} def} def /normallisting {/bc br bl sub 2 div bl add def /txtwide bw 20 sub def /ybot -99999 def % /font0{/Helvetica-Bold findfont [12 0 0 12 0 0] makefont setfont} def /font1{/Helvetica findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font8{/Helvetica findfont [6 0 0 6 0 -2] makefont setfont} def /font2{/Helvetica-Oblique findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font3{/Helvetica-Bold findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font4{/Courier findfont [8.5 0 0 8.5 0 0] makefont setfont} def /ypos bt 20 sub def /xpos bl 10 add def /yinc 10 def /pmnorm 0 def /amacro {(Lhy) stringmacro} def /bmacro {(1py) stringmacro} def /cmacro {(3z) stringmacro} def} def } def % end commoncode % for listing format /commonlist { 1000 dict /mynewdict exch def mynewdict begin /setboxheight{fixedheight {/bh boxheight def} {/bh bt ypos sub 10 sub def % /bb {bt bh sub} def } ifelse} def makeitbig {-125 300 mul 18 div floor 18 mul 300 div -340 300 mul 36 div floor 36 mul 300 div translate 3 2 div dup scale} if /bl 125 def /bt 715 def /bh boxheight def /brad 0.001 def /blw 0.5 def /hd 25 def /bb {bt bh sub} def % params for boxifier twocolumnswide {/bw 322 def}{/bw 153 def} ifelse /titledraw { save /tsnap exch def /yinc 10 def /txtwide bw 8 add % fudge it for leftjust 0.75 settint 0.8 setgray /charstretch 0.1 def % gsave newpath bl bb 1.4 add moveto bw 0 rlineto 2.8 setlinewidth stroke grestore gsave newpath bl bt 11.4 sub moveto bw 0 rlineto 22.8 setlinewidth stroke grestore black /txtwide 1000 store bl 10 add bt 16 sub title cl line1 0 0 mt bh u bw r bh d % overwrite color? tsnap restore} def includepix {/bl 0 def /bt boxheight def % 0 yinc 5 mul translate % reg figs only makes room for drop title } if /ybot -99999 def /font0{/Times-Bold findfont [9.5 0 0 9.5 0 0] makefont setfont} def /font1{/Times-Italic findfont [9.5 0 0 9.5 0 0] makefont setfont} def /font2{/NewCenturySchlbk-Bold findfont [8.5 0 0 8.5 0 0] makefont setfont} def /font3{/Helvetica-Oblique findfont [7 0 0 7 0 0] makefont setfont} def /font4{/Helvetica-Bold findfont [7 0 0 7 0 0] makefont setfont} def includepix not { save /hsnap exch def /txtwide 1000 def /yinc 12 def bl bt 10 add headerL cl bl bw twocolumnswide not {2 mul} if add bt 10 add headerR cr /yinc 10 def clear hsnap restore } if % no header on inclusion /ypos bt 15 sub def /xpos bl 22 add def /yinc 9 def /ybot -9999 def /denselisting{/bc br bl sub 2 div bl add def /txtwide bw 10 sub def /ybot -99999 def /font0{/Helvetica-Bold findfont [10 0 0 10 0 0] makefont setfont} def /font1{/Helvetica findfont [7 0 0 7 0 0] makefont setfont} def /font2{/Helvetica-Oblique findfont [7 0 0 7 0 0] makefont setfont} def /font3{/Helvetica-Bold findfont [7 0 0 7 0 0] makefont setfont} def /font4{/Courier findfont [7 0 0 7 0 0] makefont setfont} def /ypos bt 10 sub def /xpos bl 6 add def /yinc 8 def /amacro {(hy) stringmacro} def /emacro {/yparendadj yinc 2 div def} def} def } def % end commonlist /diskicon {save /dsnap exch def translate gsave 0.183 dup scale -45 rotate gsave /quadpixel {} def 0 0 10 setgrid 0 0 mt 20 pu 20 pr 20 pd closepath black fill 1 setlinewidth white gsave newpath 10 2 mt 2.2 setlinewidth 1 setlinecap 0 2.8 rlineto white stroke grestore gsave 10 10 translate 0.12 setlinewidth 45 rotate 0.01 [0 -3 0.866 mul 1.5 -3 0.866 mul 3 0 1.5 3 0.866 mul -1.5 3 0.866 mul -3 0 -1.5 -3 0.866 mul 0 -3 0.866 mul ] roundpath stroke -1.5 3 0.866 mul moveto -1.8 3 0.866 mul lineto -2 3 lineto [ 0 0 30 2 5 10 7 0 -90 2 -5 170 -2 -3 150] curvetrace -1.8 3 -0.866 mul lineto -1.5 -3 0.866 mul lineto stroke grestore 0.12 setlinewidth [13.4 15.7 25 20 20 30] curvetrace stroke [16.5 11 65 17.5 13 40 20 15 35] curvetrace stroke dsnap restore} def % TITLEBLURB ///////////////////////////// /titleblurb {/colcheck {} def /pmnorm 0 def /pm 0 def 7 76 diskicon aqua /font0 {/Helvetica findfont [8 0 0 8 0 0] makefont setfont} def /font1 {/Times-Roman findfont [9.5 0 0 9.5 0 0] makefont setfont} def /font2 {/Times-Roman findfont [9 0 0 9 0 0] makefont setfont} def /font3 {/Helvetica findfont [70 0 0 70 0 0] makefont setfont} def % square colspacing 162 moveto /txtwide 1000 def /charstretch 3 def gsave 0 24 rmoveto currentpoint (|0HANDS ON) cl grestore /charstretch 0.3 def gsave 0 9 rmoveto currentpoint (|1SOME ASSEMBLY REQUIRED |/tinton |3.|1|/tintoff |k|2Don |j|jLancaster) cl } def % /////// FIGURE ONE -- MEOWWRRR, THE PUSS DE RESISTANCE /////// /meowwrrr { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def } if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (|4Lancaster, PostScript Secrets, figure one) def /headerR {makeitbig {(|4|yScale = 1.5:1)}{(|4|yScale = 1:1)} ifelse} def /title (|0Figure 1: |1Meowwrrr, the author's PostScript puss de resistance. These grays have been adjusted here to show what they should look like on a 300 DPI printer. Most current PostScript \ applications and most users instead use the seventeenth worst of all the available 300 DPI grays.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 270 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// save /listsnap exch def % /////// MEOWWRRR - PUSS DE RESISTANCE /////// % der puss % setgrays have been redefined by tinton proc bl 75 add bb -8 add translate 0.37 dup scale nuisance begin bestgray end beige % /// PUSS STARTS HERE /// 1 setlinecap 1 setlinejoin /tension 2.8 def /ctf {curvetrace gsave 0.85 setgray fill grestore 2 setlinewidth 0 setgray stroke}def /ctfd {curvetrace gsave 0.4 setgray fill grestore 2 setlinewidth 0 setgray stroke}def /ctfxx {curvetrace gsave 0.6 0.6 0.6 setrgbcolor fill grestore % gray bat 2 setlinewidth 0 setgray stroke}def /ctfdxx {curvetrace gsave 0.6 0.6 0.6 setrgbcolor fill grestore 2 setlinewidth 0 setgray stroke}def /ct {curvetrace stroke} def /showtick false def % tail /tail { [310 262 -10 360 330 100 308 368 -170 308 368 45 330 380 0 392 285 -100 340 210 -160] curvetrace gsave clip newpath [340 200 25 390 290 90 350 350 170 300 260 0 340 200 -70] curvetrace gsave 0.85 setgray fill grestore gsave clip newpath 0.331 setgray [360 220 90 340 260 120 340 260 20 378 240 -80] curvetrace fill [382 255 110 358 280 150 358 280 30 392 280 -40] curvetrace fill [392 297 135 370 304 180 370 304 50 390 320 20] curvetrace fill [382 322 180 368 322 -160 368 322 70 374 346 20] curvetrace fill grestore 0.5 setlinewidth stroke 2 setlinewidth grestore 2 setlinewidth stroke } def tail % left foot /leftfoot{ [322 111 -110 330 75 -45 385 53 0 406 65 90 368 90 185] ct [406 65 -45 424 75 90 400 98 165] ct [424 72 -25 440 85 90 420 110 150 380 115 170 360 122 135] ct} def leftfoot % right leg /rightleg { [216 130 25 298 175 25 298 175 -160 223 166 150 186 208 120 186 208 -115 168 145 -90 196 107 -30 230 97 0 250 113 90 233 139 125] curvetrace gsave 0.85 setgray fill grestore gsave clip newpath 0.331 setgray [188 112 30 220 122 20 220 122 -90 210 100 -120] curvetrace closepath fill [168 129 -30 208 142 45 208 142 180 168 160 135] curvetrace closepath fill [170 170 -30 212 161 20 212 161 145 178 192 120] curvetrace closepath fill grestore stroke } def rightleg % right foot /rightfoot { [180 87 -160 160 60 -90 185 46 0 200 50 40 248 82 40 256 100 100 250 112 120 ] ct [164 51 -160 142 60 90 163 93 30] ct [141 60 180 130 75 90 160 104 0 197 106 10] ct } def rightfoot % left bod /leftbod { [270 213 -90 310 140 -60 326 110 -15 365 120 70 330 250 135 250 325 135 200 310 -80 220 245 -60 272 197 -10] curvetrace gsave 0.85 setgray fill grestore gsave clip newpath 0.331 setgray [368 128 -160 324 140 135 324 140 -20 370 155 40] curvetrace fill [370 168 -170 309 181 150 309 181 0 365 195 30] curvetrace fill [360 210 -160 287 213 170 287 213 30 348 230 -10] curvetrace fill [335 247 -170 260 225 -145 260 225 70 308 272 30] curvetrace fill [304 274 180 239 249 -150 239 249 45 291 292 15] curvetrace fill [280 298 -150 223 269 -150 223 269 60 265 314 30] curvetrace fill grestore stroke } def leftbod /bat { % upper bat [60 480 -30 90 480 78 130 700 78 109 725 170 73 700 -93 60 480 -93] ctfdxx [85 696 -25 121 695 35] ct % lower bat [40 348 90 60 360 0 80 345 -90 65 334 180 40 348 90] ctfdxx [50 350 -40 72 348 40 72 348 80 78 377 80 50 387 -90 50 350 -90] ctfdxx } def bat % right arm /rightarm { [140 487 0 199 435 -70 173 410 120 140 445 180 100 430 -150 108 465 55 140 487 0] curvetrace gsave 0.85 setgray fill grestore gsave clip newpath 0.331 setgray [113 473 -45 119 446 -100 119 446 60 128 485 120] curvetrace closepath fill [ 136 486 -45 138 450 -100 138 450 50 151 489 120] curvetrace closepath fill [153 441 60 170 460 20 170 460 -120 168 420 -90] curvetrace closepath fill grestore 2 setlinewidth 0 setgray stroke } def rightarm % right fingers /rightfingers{ [56 482 -170 50 448 -45 65 442 0 83 461 85] ct [47 453 -120 50 430 -40 65 428 0 84 450 105] ct [61 497 -80 70 482 -45 84 470 -90 62 459 150 54 474 115 61 497 35] curvetrace gsave 1 setgray fill grestore stroke [95 436 30 112 465 90 92 492 180 77 465 -90 83 450 0 98 467 80] curvetrace gsave 1 setgray fill grestore stroke} def rightfingers % left fingers /leftfingers{ [80 386 -150 50 388 135 40 406 60] curvetrace gsave 1 setgray fill grestore stroke [46 402 135 38 424 45] ct [44 443 -150 44 418 -40] ct [96 400 80 90 415 150] ct [95 412 40 98 430 110 82 438 170] curvetrace gsave 1 setgray fill grestore stroke} def leftfingers % right bod /rightbod{ [186 208 120 140 340 90 172 408 25 188 412 20 188 412 75 195 435 75 ] curvetrace gsave 240 440 rlineto clip newpath [176 210 105 158 330 85 172 390 60 195 405 85 210 440 85 100 400 0 100 200 0] curvetrace gsave 0.85 setgray fill grestore 0.5 setlinewidth stroke grestore stroke} def rightbod % left arm /leftarm{ [74 383 -70 120 320 -40 220 300 0 255 330 80 255 370 100 235 390 180 200 350 -110 200 350 170 145 351 170 145 351 135 95 400 125 95 400 180 74 383 -110] curvetrace gsave 0.85 setgray fill grestore gsave clip newpath 0.331 setgray [76 372 30 108 378 0 108 378 -150 83 358 -130] curvetrace fill [94 346 60 124 360 0 124 360 -150 108 329 -100] curvetrace fill [120 320 60 140 342 60 140 342 -90 134 312 -110] curvetrace fill [145 306 60 154 341 120 154 341 -30 165 302 -100] curvetrace fill [178 298 45 180 340 110 180 340 -30 207 300 -70] curvetrace fill [218 297 90 219 316 80 219 316 10 243 308 -30] curvetrace fill [253 320 170 207 340 140 207 340 -20 260 351 30] curvetrace fill [258 354 140 218 360 -160 218 360 60 255 383 -30] curvetrace fill grestore stroke } def leftarm % left ear /leftear { [270 530 40 340 560 20 340 560 -55 312 490 -120] curvetrace gsave 0.82 setgray fill grestore stroke [300 520 45 338 553 30 338 553 -70 312 504 -130] curvetrace gsave 1 setgray fill grestore 0.5 setlinewidth stroke 2 setlinewidth} def leftear % head /head{ [156 508 -80 228 406 -30 274 390 10 306 401 40 306 401 0 335 432 80 335 432 95 325 447 125 325 447 70 320 508 120 238 540 -160 170 500 -160 170 500 145 156 508 145] curvetrace gsave gsave 0.85 setgray fill grestore clip newpath gsave [273 543 -60 276 503 -120 276 503 40 285 541 120] curvetrace 0.331 setgray fill [287 538 -65 299 480 -85 299 480 65 302 533 100] curvetrace fill [301 534 -65 312 482 -90 312 482 75 314 518 100] curvetrace fill [171 503 -75 188 462 -45 188 462 110 184 506 90 ] curvetrace fill [185 510 -65 206 482 -60 206 482 70 207 522 90] curvetrace fill grestore [210 418 140 196 455 80 235 480 -40 254 437 -60 270 422 -20 298 430 -80 318 430 60 326 433 -50 318 404 -150 260 370 180] curvetrace gsave 1 setgray fill grestore 0.5 setlinewidth stroke grestore stroke} def head % mouth /mouth{ [213 448 25 240 445 -35] ct [226 450 -75 275 400 0 300 411 35] ct [300 411 -155 308 402 0] ct} def mouth % right ear /rightear { [223 501 150 262 580 30 262 580 -60 275 518 -85] curvetrace gsave 0.82 setgray fill grestore stroke [232 502 85 262 570 50 262 570 -70 270 520 -90 270 520 -135 232 502 180] curvetrace gsave 1 setgray fill grestore 0.5 setlinewidth stroke 2 setlinewidth } def rightear % nose /nose { /tension 3.8 def [300 428 60 315 425 -90 302 413 180 300 428 60] curvetrace 0 setgray fill /tension 2.8 def} def nose % right eye /righteye { [255 482 -45 295 450 -15 295 450 -120 272 442 160 262 474 80] curvetrace gsave 1 setgray fill grestore stroke } def righteye % left eye /lefteye { [310 450 60 329 470 60 329 470 -95 321 450 -150 310 450 150] curvetrace gsave 1 setgray fill grestore gsave clip newpath [318 454 70 329 462 30 329 462 -100 326 453 -90 326 453 -170 318 454 150] curvetrace fill grestore stroke } def lefteye % eyebrows /eyebrows { 0.3 setgray [264 498 20 280 488 -60 296 471 20 296 471 -160 280 473 150 264 498 155] curvetrace fill [312 468 60 327 492 75 327 492 -70 328 482 -90 328 482 -120 312 468 -160] curvetrace fill 0 setgray } def eyebrows % right eyeball /righteyeball { [277 445 100 280 458 70 280 458 -30 291 450 -20 291 450 -155 279 445 -160] curvetrace fill} def righteyeball % whiskers /whiskers { [210 392 30 282 412 0] curvetrace 1 setlinewidth stroke [205 404 20 286 416 -5] curvetrace stroke [318 416 -10 388 416 0] curvetrace stroke [322 422 15 385 431 10] curvetrace stroke [325 427 25 383 442 20] curvetrace stroke } def whiskers % neck fill /neckfill { 2 setlinewidth 236 391 moveto 241 398 lineto stroke} def neckfill % .................. % .................. listsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end % commoncode dictionary } def % meowwrrr showpage % ////////// end meowwrrr /////////////// % /////// FIGURE TWO -- THE SECRET GRAY MAP /////// /secretmap { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (|4Lancaster, PostScript Secrets, figure two) def /headerR {makeitbig {(|4|yScale = 1.5:1)}{(|4|yScale = 1:1)} ifelse} def /title (|0Figure 2: |1This secret gray map shows you many of the "hidden" 300 DPI PostScript grays found on the LaserWriter. The best all-around gray is the 106 spot, 45 degree one, \ while a good reprogray for reducing camera-ready originals is available at 85 spots and 35 degrees. The 135 spot, 25 degree screen gives india ink wash effects.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 420 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// save /figsnap exch def % .......................... % ......................... /linestring linestring2 def % needed to run interference /cstretch 0.01 def /sstretch 0.01 def % workaround centering bug? /wanttousepicojustify false store aqua 1 setlinecap 1 setlinejoin 0 bl 97 add quadpixel 0 quadpixel pop bb 35 add quadpixel 0 quadpixel pop translate electronics begin /m {mt} def /mdot {mt dot} def /fat5 false def /fatter10 false def 0 setlinecap 0 0 15 setgrid 10 24 showgrid line2 0 0 m 24 pu 10 pr 24 pd 10 pl gsave aqua 0.92 setgray fill grestore stroke 1 setlinejoin 0 0 m 0 24 rlineto 10 0 rlineto 0 -24 rlineto closepath stroke /line6 {.03 1 mul dup setlinewidth 5 mul /erase exch def} def %% new fake grid line1 0.6 setgray [{0 0 mt 24 u} 1 10 ] xrpt [{0 0 mt 10 r} 1 24 ] yrpt black 0 0 m 24 pu 10 pr 24 pd 10 pl stroke /drawsteps { line6 0 0 m 1 u 1 r 1 u 3 r 1 d 2 r 1 d 6 l 10 0 m 5 u 1 l 2 d 3 l 1 d 2 l 1 d 2 r 1 d 4 r 0 1 m 1 r 1 u 3 r 1 u 1 l 7 u 2 l 1 d 1 l 9 d 10 5 m 1 l 3 u 1 l 3 u 1 l 3 u 1 r 1 u 1 r 2 u 1 r 3 10 m 1 r 1 u 1 r 1 u 1 r 1 u 1 r 3 10 m 3 u 1 l 3 u 2 l 2 16 m 4 u 2 l 2 20 m 3 u 2 l 1 23 m 1 u 2 17 m 3 r 3 u 1 l 1 u 1 l 1 d 1 l 6 13 m 4 u 1 l 1 u 1 r 1 u 2 r 1 d 1 r 1 d 8 19 m 1 u 1 r 1 u 1 r 1 l 1 u 1 l 1 u 1 r 1 u 0 23 m 6 r 1 d 1 r 1 u 1 r 1 u 4 21 m 2 u 1 l 1 u 8 20 m 1 l 1 u 1 l 1 u 1 r 1 u 1 r 1 d 1 r 2 d 4 21 m 2 r 2 u 1 l 1 u gsave 1 setgray 2 23.1 m 0.8 u 4 23.1 m 0.8 u grestore } def drawsteps /cstretch 0.01 def /sstretch 0 def /font6 {/Helvetica-Bold findfont [0.45 0 0 0.45 0 0] makefont setfont} def /showgrays{ %%%% font6 gsave 0.5 0.28 translate 0 0 (|62) cc 9 1 (3) cc 0 3 (5) cc 5 6 (6) cc 9 12 (9) cc 0 13 (10) cc 4 14 (11) cc 7 16 (14) cc 9 19 (19) cc 0 18 (17) cc 3 18 (18) cc 0 21 (26) cc 7 21 (26) cc 3 22 (27) cc 5 22 (30) cc 6 23 (35) cc 0 23 (37) cc 6 20 (21) cc 9 22 (33) cc } def showgrays /Helvetica-Bold findfont [0.45 0 0 0.45 0 0] makefont setfont 1.5 23 (39*) cc 3.5 23 (42*) cc 8 23 (42*) cc /font7 {/Helvetica-Bold findfont [0.45 0 0 0.45 0 0] makefont setfont} def font7 /crr {cr} def -1 23 (|750) crr -1 22 (55) crr -1 21 (60) crr -1 20 (65) crr -1 19 (70) crr -1 18 (75) crr -1 17 (80) crr -1 16 (85) crr -1 15 (90) crr -1 14 (95) crr -1 13 (100) crr -1 12 (105) crr -1 11 (110) crr -1 10 (115) crr -1 9 (120) crr -1 8 (125) crr -1 7 (130) crr -1 6 (135) crr -1 5 (140) crr -1 4 (145) crr -1 3 (150) crr -1 2 (175) crr -1 1 (210) crr -1 0 (300) crr % cc has space dependency in this file only. workaround below. /txtwide 999 store gsave -2.3 12 translate 90 rotate -4.3 0 (Screen density in spots per inch) cl grestore save /snapzzz exch def /yinc 0.5 def % newpath % 3.1 6.9 mt % 2 pu 3.8 pr 2 pd closepath 0.92 setgray fill black /kern 0.1 store 3.3 8.5 (number of gray\n|klevels, including\nblack and white,\nfor each region) cl snapzzz restore -.5 -.3 translate 0.5 -0.8 (0) cc 1.5 -0.8 (5) cc 2.5 -0.8 (10) cc 3.5 -0.8 (15) cc 4.5 -0.8 (20) cc 5.5 -0.8 (25) cc 6.5 -0.8 (30) cc 7.5 -0.8 (35) cc 8.5 -0.8 (40) cc 9.5 -0.8 (45) cc 2 -1.5 (Screen angle in degrees) cl % ..................... % ......................... figsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end end } def % secretmap showpage % ////////// end secretmap /////////////// % /////// FIGURE THREE -- PERFECT GRAYGRID /////// /graygrid { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure three) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (|0Figure 3: |1Uniform and dropout free 300 DPI gray grids can be done at 1:1 scale by first locking to exact four-pixel multiples and then using the special halftone screen function as shown here. Note that each crossing consists of a single and uniform dot. PostScript stays "locked" to the grid until the next occurence of a grestore. ) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 430 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// save /figsnap exch def gsave denselisting /cmacro {/xpos xpos 54 add def /txtwide txtwide 110 sub def} def /dmacro {/xpos xpos -54 add def /txtwide txtwide -110 sub def} def /xpos xpos 10 add def /txtwide txtwide 20 sub def /tabs [20] def /yinc yinc 0.1 sub store black xpos ypos ( |a|1|z % Creates uniform and ultra-fine gray grids without any dropouts or rattiness. % The code shown is device specific and is intended for 300 dpi printers. |h % To create a grid, use -hpos- -vpos- -gridsize- setgrid. Until restored, all further % images will be "locked" to the grid, expanding and contracting with it. Note that % optimum linewidths and font sizes will often be less than 1.0 after locking. |h % To show a grid, use -#hlines- -#vlines- showgrid. |h % The seegrid command displays the grid when true. % The fat5 command emphasizes every fifth line when true. % the fatter10 command emphasizes every tenth line when true. |h /quadpixel {transform 4 div round 4 mul itransform} def |h /setgrid {save /rubbersnap exch def quadpixel /size exch def quadpixel exch quadpixel exch translate size dup scale} def |h /drawlines {72 300 div lw mul size div setlinewidth /hposs 0 def #hlines gs div 1 add cvi {hposs 0 moveto 0 #vlines rlineto stroke /hposs hposs gs add def} repeat /vposs 0 def #vlines gs div 1 add cvi\ {0 vposs moveto #hlines 0 rlineto stroke /vposs vposs gs add def} repeat} def |h /showgrid{ seegrid {gsave /#vlines exch def /#hlines exch def 106 45 {pop pop 0} setscreen 0.9 setgray /gs 1 def /lw 1 def drawlines fat5\ {/gs 5 def /lw 3 def drawlines} if fatter10 {/gs 10 def /lw 5 def drawlines} if grestore}if} def |h /fat5 true def /fatter10 true def /seegrid true def |h % use examples: -xpos- -ypos- -gridsize- setgrid -#hlines- -#vlines- showgrid % {anything you want locked to the grid} rubbersnap restore |h % /// demo - remove before use //// |h 100 200 10 setgrid 20 20 showgrid showpage quit |h ) cl % this draws the grid % WARNING: To appear properly in the magazine, you MUST shoot the final gray % grid image itself at 1:1 scale!!!!!! 0.31 settint 0 bl 79 add quadpixel bt 180 sub quadpixel 8 setgrid 20 20 showgrid [5 5 80 15 15 25] curvetrace 0.15 setlinewidth stroke gsave 5 5 translate 1.8 dup scale 0 0 mt dot grestore gsave 15 15 translate 1.8 dup scale 0 0 mt dot grestore grestore figsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end } def % graygrid showpage % ////////// end graygrid /////////////// % /////// LISTING ONE -- MAKEEEXEC /////// % SPECIAL BYTE LISTING FORMAT /makeeexec { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, listing one) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (|/black |0Listing 1: 1Creating your own PostScript eexec file.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 230 def /showthegrid false def commonlist % figure or text starts here ////////////////////////////////////// save /figsnap exch def gsave denselisting /xpos xpos 5 add def /txtwide txtwide 10 sub def /pm 0 def xpos ypos (|z 1 /mask 16#D971 def /multk1 16#6000 def /mult2 16#6E6D def /adder 16#58BF def /strrx (X) def /trunc 16#FFFF def /char 32 def /hexvalues (0123456789ABCDEF) def h /printashex {cvi /vall exch def vall 16 div cvi hexvalues exch 1 getinterval print vall 15 and hexvalues exch 1 \ getinterval print flush 20 {37 sin pop} repeat formatcount 1 add 32 eq {(\\\ n) print flush 100 {37 sin pop} repeat} if /formatcount formatcount 1 add cvi 3k1 and def} def h /makeeexecfile {/formatcount 0 def 4 {char mask -8 bitshift or char mask -8 bitshift and not and /echar exch def echar printashex flush 15 {37 sin pop} repeat mask echar add dup \ multk1 mul trunc and exch mult2 mul trunc and add trunc and adder add trunc and /mask exch def} repeat \ {currentfile strrx readstring {0 get /char exch def char mask -8 bitshift or char mask -8 bitshift and not and /echar exch def echar printashex flush \ 15 {37 sin pop} repeat mask echar add dup multk1 mul trunc and exch mult2 mul trunc and add trunc and adder add trunc and /mask exch def} {pop exit} ifelse} loop} def h % //// demo - remove before use. //// h 1500 {37 sin pop} repeat h % Here is the expected host-returned blackflashing result ... h % F983EF00C334F148421509DC30FA053D6DD4273E416E6A2EA64F917B5D20E111 % 9F220AF8FC50D545AB51A0D18B6DD7543D27A21CD55887C1C7D51608F6A316EE % 8891D92A6E0D09D1D039159DA3A0781E1380B1228C h makeeexecfile 0 0 moveto 1000 0 rlineto 0 1000 rlineto -1000 0 rlineto closepath fill showpage ) cl grestore figsnap restore % figure or text ends here ////////////////////////// 0.75 settint setboxheight boxdraw titledraw end } def % makeeexec showpage % ////////// end makeeexec /////////////// % /////// LISTING 2 -- MAKEEEXEC /////// % SPECIAL BYTE LISTING FORMAT /readeexec { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, listing one) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Listing 2: 1Reading the PostScript eexec file of Listing 1.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 180 def /showthegrid false def commonlist % figure or text starts here ////////////////////////////////////// save /figsnap exch def gsave denselisting /xpos xpos 5 add def /txtwide txtwide 10 sub def xpos ypos (|z 1 /mask 16#D971 def /multk1 16#6000 def /mult2 16#6E6D def /adder 16#58BF def /trunc 16#FFFF def /strrx (X) def /skip4 -4 def h /readeexecfile {{currentfile strrx readhexstring{0 get /echar exch def echar mask -8 bitshift or echar mask -8 bitshift and not and /char exch def skip4 0 ge {strrx 0 char put strrx print flush \ 15 {37 sin pop} repeat /skip4 skip4 1 add def}{/skip4 skip4 1 add def} ifelse mask echar add dup multk1 mul trunc and exch mult2 mul trunc and add trunc and adder add trunc and /mask exch def}{pop exit} ifelse} loop} def h % //// demo - remove before use. //// h 1500 {37 sin pop} repeat h % Here is the expected host-returned result for this demo . . . h % 0 0 moveto 1000 0 rlineto 0 1000 rlineto -1000 0 rlineto closepath fill showpage h readeexecfile F983EF00C334F148421509DC30FA053D6DD4273E416E6A2EA64F917B5D20E111 9F220AF8FC50D545AB51A0D18B6DD7543D27A21CD55887C1C7D51608F6A316EE 8891D92A6E0D09D1D039159DA3A0781E1380B1228C ) cl grestore figsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end } def % makeeexec showpage % ////////// end makeeexec /////////////// % /////// FIGURE FOUR -- OPAQUE ICONS /////// /opaqueicon { %%%% /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def } if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure four) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Figure 4: jj1Opaque icons greatly simplify drawing PostScript electronic schematics, |t|t, and other "blobs on strings" illustrations. All of the background wires are continuous, and \ get "slid under" the icons simply by placing them earlier in your text file. Line breaks are first printed an opaque fat white, then a thin black.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 270 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// save /listsnap exch def % figure or text starts here ////////////////////////////////////// save /listsnap exch def nuisance begin electronics begin % .............. % .............. /bestgray {reprogray} def /uvsense {gsave translate newpath 0 0 1.5 0 360 arc gsave white fill grestore 0.2 setlinewidth stroke line1 -0.5 -2 mt 1.2 u [0 0 90 0 -.4 0 .5 -.8 -90] curvetrace closepath gsave fill grestore stroke newpath line1 0.5 2 mt 1.2 d [0 0 -90 0 .4 180 -.5 .8 90] curvetrace stroke gsave 0.9 0 translate 1.5 dup scale 0 0 mt dot grestore grestore} def quadpixel {} def bl 5 add bb -28 add 9 setgrid % was 10 33 33 showgrid % gsave 0 3 translate 20 20 showgrid grestore line1 /proc11 { 29 7 mt 27 l circ1 % input line 4 7 hresistor 7 7 hcap 9 10 mt 21 r 10 u % hot end of pots 14 10 mt dot 19 10 mt dot 24 10 mt dot 29 10 mt dot 29 7 mt 2.5 r 13 u [{7 10 mt 5 u 7 13 mt dot 7 12 vcap 7 14 vcap 7 13 mt 1.5 r 2 u } 5 5] xrpt [{9 7 mt 3 u 9 8.5 lpot 8 8.5 mt 1 l 2 ux 0.5 u 9 7 mt dot } 5 5] xrpt % splice inputs 7 15 mt 2 u 6 r 1 u 8.5 15 mt 1.5 u 5.5 r 1.5 u 12 15 mt 1 u 3 r 2 u 13.5 15 mt 0.5 u 2.5 r 2.5 u 17 15 mt 3 u 18.5 15 mt 0.5 u 0.5 l 2.5 u 22 15 mt 1 u 3 l 2 u 23.5 15 mt 1.5 u 3.5 l 1.5 u 27 15 mt 8 u 7 l 1 d 28.5 15 mt 8.5 u 9.5 l 1.5 d 13 22 mt 1 u uground % pin 16 15 22 mt 2 u 7 l circ1 14 22 mt 4.5 ux uground % pin 15 14 25.5 vcap 31.5 20 mt 4 u 13.5 l 2 d 30 20 mt 4.5 ux 13 l 2 d % pin 12 16 22 mt 8 u 10 r circ1 % pin 13 18.5 24.5 mt dot 18.5 24.5 mt 5.5 u dot 18.5 27.5 vcap 21.5 30 hcap 24 30 mt dot 24 30 mt 4 d ground 24 28 vresistor 10 24 mt dot 10 24 mt 4 d ground 10 22 vcap } def proc11 % temp patch on dipdraw clear cleartomark % clear stack /hold11 exch def /hold22 exch def 13 18 mt 16 (KA2223) (GND BIS VCC OUT NF IN NF5 B5) (B1 NF1 B2 NF2 B3 NF3 B4 NF4) dipdraw hold22 hold11 mark % restore stack mark /proc22 { % 9 4.2 (1(108 Hz)) cc % 14 4.2 ((343 Hz)) cc % 19 4.2 ((1080 Hz)) cc % 24 4.2 ((3430 Hz)) cc % 29 4.2 ((10.8 kHz)) cc 26.5 5.5 (1100K x 5) cc 2 8 (INPUT) cc 4 5.5 (4.7 K) cc 7 5.5 (3.3 3m1F) cc 7.8 7.2 (+) cc 7 23.7 (+9 VDC) cr 19.5 26.7 (1000) cl 21.5 28.5 (3.3 3m1F) cc 25.7 27.7 (4.7 K) cc 21.1 30.3 (+) cc 10.5 22.3 (+) cc 9 21.7 (47 3m1F) cr 27 29.7 (OUTPUT) cl 14.4 24.5 (+) cc 12.7 24.9 (22 3m1F) cr 6 13.5 (.0393m1) cr 6 11.5 (0.683m1) cr 11 13.5 (.0123m1) cr 11 11.5 (0.223m1) cr 16 13.5 (3900) cr 16 11.5 (.0683m1) cr 21 13.5 (1200) cr 21 11.5 (.0223m1) cr 26 13.5 (390) cr 26 11.5 (6800) cr } def %% proc22 % .................. % .................. listsnap restore % figure or text ends here ////////////////////////// /twocolumnswide true def twocolumnswide {/bw 322 def}{/bw 153 def} ifelse setboxheight boxdraw titledraw end end end % common - electronics - nuisance } def % opaqueicon showpage % ////////// end opaque icon /////////////// % /////// FIGURE FOUE OPAQUE ICON II /////// /opaqueicon2 { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def } if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure four) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Figure 4: jj1Opaque icons greatly simplify drawing PostScript electronic schematics, |k|k|k|k|k|k|k|k|kflowcharts, and other "blobs on strings" illustrations. All of the background wires are continuous, and \ get "slid under" the icons simply by placing them earlier in your text file. Line breaks are first printed an opaque fat white, then a thin black.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 270 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// save /listsnap exch def % /////// OPAQUE ICON/////// electronics begin line1 10 -27 9 setgrid % 30 30 showgrid black /proc11 { 29 7 mt 27 l circ1 % input line 4 7 hresistor 7 7 hcap 9 10 mt 21 r 10 u % hot end of pots 14 10 mt dot 19 10 mt dot 24 10 mt dot 29 10 mt dot 29 7 mt 2.5 r 13 u [{7 10 mt 5 u 7 13 mt dot 7 12 vcap 7 14 vcap 7 13 mt 1.5 r 2 u } 5 5] xrpt [{9 7 mt 3 u 9 8.5 lpot 8 8.5 mt 1 l 2 ux 0.5 u 9 7 mt dot } 5 5] xrpt % splice inputs 7 15 mt 2 u 6 r 1 u 8.5 15 mt 1.5 u 5.5 r 1.5 u 12 15 mt 1 u 3 r 2 u 13.5 15 mt 0.5 u 2.5 r 2.5 u 17 15 mt 3 u 18.5 15 mt 0.5 u 0.5 l 2.5 u 22 15 mt 1 u 3 l 2 u 23.5 15 mt 1.5 u 3.5 l 1.5 u 27 15 mt 8 u 7 l 1 d 28.5 15 mt 8.5 u 9.5 l 1.5 d 13 22 mt 1 u uground % pin 16 15 22 mt 2 u 7 l circ1 14 22 mt 4.5 ux uground % pin 15 14 25.5 vcap 31.5 20 mt 4 u 13.5 l 2 d 30 20 mt 4.5 ux 13 l 2 d % pin 12 16 22 mt 8 u 10 r circ1 % pin 13 18.5 24.5 mt dot 18.5 24.5 mt 5.5 u dot 18.5 27.5 vcap 21.5 30 hcap 24 30 mt dot 24 30 mt 4 d ground 24 28 vresistor 10 24 mt dot 10 24 mt 4 d ground 10 22 vcap } def proc11 % //// REVISED PROC ///// electronics begin % dipdraw - draws a dip integrated circuit. (old code to be improved) % Enter with currentpoint set to pin 1 and scale % set so that 1.0 = distance between pins. Then % do a numpins-(name)-(hipins)-(lopins) dipdraw % Pin callouts preceeded by / will be complemented. % main dipdraw entry: /dipdraw { save /dipsnap exch def /hipins exch def /lopins exch def /chipname exch def /numpins exch def mark 0 0 0 0 0 0 0 0 0 0 0 0 % temp patch /howlong {numpins 2 div cvi 1 add} def /howhigh {4 numpins 36 ge {1 add} if} def /stub {howhigh 1.4 sub 2 div} def % internal service subs start here: /pinproc {numpins 2 div cvi{newpath 0 cpos 0.37 0 360 arc gsave 1 setgray fill grestore 0.067 setlinewidth stroke pin# 5 string cvs dup stringwidth pop 2 div neg cpos 0.2 sub moveto show 1 0 translate /pin# pin# dir add def} repeat } def /stretchprint { dup stringwidth pop 2 div neg exch length 1 sub stretch mul 2 div sub 0 moveto callout (/) anchorsearch true eq {currentpoint exch stretch add exch moveto pop dup /callout exch def stringwidth pop callout length 1 sub stretch mul add /barwide exch def 0.033 setlinewidth gsave currentpoint 0.55 add moveto barwide 0 rlineto stroke grestore} if stretch 0 callout ashow pop} def /pincallouts{0 vpos translate {workstring ( ) search true eq {/callout exch def pop /workstring exch def callout stretchprint 1 0 translate}{dup /callout exch def stretchprint exit } ifelse}loop} def % actual dipdraw process starts here: % ........ the outline: gsave 1 setlinecap 1 setlinejoin currentpoint translate newpath -1 howhigh 2 div 0.7 -90 90 arc 0 stub rlineto howlong 0 rlineto 0 howhigh neg rlineto howlong neg 0 rlineto closepath gsave grayshade setgray fill grestore grayshade dup 1 ne {0.33}{0} ifelse setgray 0.36 setlinewidth stroke newpath -.55 .45 0.15 0 360 arc fill black % ........ pin circles and numbers: /Helvetica-Bold findfont [0.4 0 0 0.55 0 0] makefont setfont gsave /pin# 1 def /dir 1 def /cpos 0 def pinproc grestore gsave /pin# numpins def /dir -1 def /cpos howhigh def pinproc grestore % pin callouts: /Helvetica findfont [0.35 0 0 0.6 0 0] makefont setfont /stretch 0.033 def gsave /workstring hipins def /vpos 0.6 def pincallouts grestore gsave /workstring lopins def /vpos howhigh 1.05 sub def pincallouts grestore % device number: grayshade 1 ne {0.33}{0} ifelse setgray /Helvetica-Bold findfont [1.4 0 0 1 0 0] makefont setfont /stretch 0.05 def gsave numpins 2 div 1 sub 2 div howhigh 2 div 0.33 sub translate chipname dup /callout exch def stretchprint grestore black % end cleanup: grestore grestore cleartomark dipsnap restore} def end % get out of electronics? beige /grayshade 0.92 store 13 18 mt 16 (KA2223) (GND BIS VCC OUT NF IN NF5 B5) (B1 NF1 B2 NF2 B3 NF3 B4 NF4) dipdraw /cstretch 0 store /sstretch 0 store /font1 /Helvetica 0.8 gonzofont /font2 /Helvetica-Bold 0.8 gonzofont /font3 /Symbol 0.8 gonzofont font1 /proc22 { % 9 4.2 (|1(108 Hz)) cc % 14 4.2 ((343 Hz)) cc % 19 4.2 ((1080 Hz)) cc % 24 4.2 ((3430 Hz)) cc % 29 4.2 ((10.8 kHz)) cc 26.5 5.5 (|1100K x 5) cc 2 8 (|2INPUT) cc 4 5.5 (|14.7 K) cc 7 5.5 (3.3 3m1F) cc 7.8 7.2 (+) cc 7 23.7 (+9 VDC) cr 19.5 26.7 (1000) cl 21.5 28.5 (3.3 3m1F) cc 25.7 27.7 (4.7 K) cc 21.1 30.3 (+) cc 10.5 22.3 (+) cc 9 21.7 (47 3m1F) cr 27 29.7 (|2OUTPUT|1) cl 14.4 24.5 (+) cc 12.7 24.9 (22 3m1F) cr 6 13.5 (.0393m1) cr 6 11.5 (0.683m1) cr 11 13.5 (.0123m1) cr 11 11.5 (0.223m1) cr 16 13.5 (3900) cr 16 11.5 (.0683m1) cr 21 13.5 (1200) cr 21 11.5 (.0223m1) cr 26 13.5 (390) cr 26 11.5 (6800) cr } def proc22 end % electronics dictionary % end opaque internals listsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end % commoncode dictionary } def % mopawueicon2 showpage % ////////// end opaque2 /////////////// % /////// FIGURE FIVE - FRACTAL FERN /////// /fractalfern { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if 0 0 ( ) cc % possible bug fixes 0 setgray newpath % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure five) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Figure 5: 1A PostScript fractal fern. PostScript's ability to do continuous translate- rotate-scale matrix transformations on the fly make it particularly attractive \ for many fractal uses. The code shown here first creates a probability table. It then repeatedly uses the transforms in that table to generate the final image.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 300 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// % .............. % .............. save /figsnap1 exch def save /fernsnap exch def mark % [yourarray] makestring converts an array to a string... /makestring {dup length string dup % new string of right size /NullEncode filter % make a file out of string 3 -1 roll {1 index exch write} forall pop } def %%% Create three image arrays. For RGB 512x512 of one bit per color /hpixels 256 store /vpixels 384 store %% 64 colors are presently "hard wired". Presently light green on full green. /none 2#00000000 def /dark 2#01010101 def /light 2#10101010 def /full 2#11111111 def /addmask [ 2#11000000 2#00110000 2#00001100 2#00000011 ] def /dropmask [ 2#00111111 2#11001111 2#11110011 2#11111100 ] def /makeimagearrays { % make a full green background mark 24576 { light cvi} repeat] makestring /redimagestring exch store mark 24576 { full cvi} repeat] makestring /greenimagestring exch store mark 24576 { light cvi} repeat] makestring /blueimagestring exch store } def makeimagearrays % makes the actual arrays %% insertbit scales and positions a fern dot from the centered unit square. /insertbit { currentpoint 8.333 div 256 mul floor 32 add % fern specific adjustment /yyy exch store 8.333 div 256 mul 128 add floor cvi 10 sub % fern specific adjustment /xxx exch store xxx 4 mod /xxbitposn exch store % calculate bit and byte positions xxx 4 idiv /xxbyte exch store yyy 64 mul cvi xxbyte add /byteposn exch store redimagestring dup byteposn get % modify red bit pair dropmask xxbitposn get and % zero old value none addmask xxbitposn get and or % replace with new value byteposn exch put greenimagestring dup byteposn get % modify green dropmask xxbitposn get and [ dark light ] 2 random get % try some dither for effect addmask xxbitposn get and or byteposn exch put blueimagestring dup byteposn get % modify blue dropmask xxbitposn get and none addmask xxbitposn get and or byteposn exch put } store %%%%%% This is the modified fern code... /wantrealfern false store % optionally plots fern at bottom save /fernsnap exch store /problistcreate {mark /counter 0 def probabilities {128 mul round cvi {transforms counter get} repeat /counter counter 1 add def} forall counttomark 128 sub neg dup 0 gt { [1 0 0 1 0 0] repeat} {pop} ifelse] /problist exch def} bind def /doit {problistcreate 1 1 20 {problist rand -24 bitshift get transform 2 copy moveto % don't insert originals? 0.001 10 rlineto } repeat newpath numdots {problist rand -24 bitshift get transform 2 copy moveto insertbit 0.001 0 rlineto wantrealfern {stroke}{newpath} ifelse } repeat } bind def /numdots 50000 def % increase for denser image; decrease to print faster /transforms [ [0 0 0 .16 0 0] [.2 .23 -.26 .22 0 1.6] [-.15 .26 .28 .24 0 .44] [.85 -.04 .04 .85 0 1.6] ] def /probabilities [ .01 .07 .07 .85 ] def 1 setlinecap 0.02 setlinewidth % 200 300 translate % 30 dup scale % 10 10 translate 0 0.3 0 setrgbcolor doit wantrealfern { % does a temporary grid for scale evaluation -15 -10 translate 0 0 10 setgrid 5 5 showgrid} if fernsnap restore %%%%%%%%%%%%%%%%%%%%% % code to show the image /showimage {gsave translate hpixels vpixels scale % magnify unit square 0.38 dup scale % fit to column hpixels vpixels 2 [hpixels 0 0 vpixels 0 0 ] % define color image redimagestring greenimagestring blueimagestring true 3 colorimage grestore } store 108 140 showimage % end fern image; begin fern listing % nuisance begin % electronics begin denselisting /xpos xpos 10 add def /txtwide txtwide 20 sub def /ypos ypos 166 sub def xpos ypos (1/problistcreate {mark /counter 0 def probabilities {128 mul round cvi {transforms counter get} repeat /counter counter 1 add def}\ forall counttomark 128 sub neg dup 0 gt { [1 0 0 1 0 0] repeat} {pop} ifelse] /problist exch def} bind def h /doit {problistcreate 1 1 20 {problist rand -24 bitshift get transform 2 copy moveto 0.001 10 rlineto} repeat newpath numdots {problist\ rand -24 bitshift get transform 2 copy moveto 0.001 0 rlineto stroke} repeat} bind def h % /// demo - remove before use. /// h /numdots 6000 def % increase for denser image; decrease to print faster h /transforms [ [0 0 0 .16 0 0] [.2 .23 -.26 .22 0 1.6] [-.15 .26 .28 .24 0 .44] [.85 -.04 .04 .85 0 1.6] ] def h /probabilities [ .01 .07 .07 .85 ] def h 1 setlinecap 0 setlinewidth 200 300 translate 30 dup scale doit showpage quit ) cl figsnap1 restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end % end end } def % fractalfern showpage % ////////// end fractal fern /////////////// % /////// FIGURE SIX - PIXEL LINE REMAPPING /////// /pixelmap { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if 0 0 (1 ) cc % reseet centering bug? /txtwide 999 store % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure six) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /pm 0 def /pmnorm 0 def /title (0LFigure 6: jj1Pixel line remapping gives you two powerful non-linear transformation tools that let you map any image onto many complex surfaces. The "flat" image gets broken down into one horizontal \ or vertical pixel line at a time. Each line will then selectively be translated, rotated, and scaled to complete the transformation.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 300 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// /outline {gsave /strr exch def translate 0 0 moveto strr false charpath gsave aqua 0.85 setgray fill grestore line1 stroke grestore} def % actual drawing starts here save /ffsnap exch def mark /quadpixel {} def bl 40 add bt boxheight sub 5 add 7 setgrid % was 9 showthegrid {33 50 showgrid} if % 33 50 showgrid /cstretch 0 store /sstretch 0 store /font8 {/Bookman-Demi findfont [5 0 0 5 0 0] makefont setfont} def /font7 {/Helvetica findfont [1.1 0 0 1.1 0 0] makefont setfont} def /font6 {/Helvetica-Bold findfont [1 0 0 1 0 0] makefont setfont} def /font5 {/Helvetica findfont [0.9 0 0 0.9 0 0] makefont setfont} def font8 1 32.5 (1) outline 1 17.5 (2) outline /yinc 1.3 def /txtwide 999 def /pm 0 def /pmnorm 0 def /charstretch 0.04 def /spacestretch 0.04 def 0.5 30.5 (7A "flat" |/tinton1 |6pixelproc|7|/tintoff image gets scanned one vertical pixel line at a time. Each vertical pixel line is then individually rotated and translated and scaled as needed to\274) cl 0.5 15.7 (7\274 get pasted when and where required on the final image by the use of a |/tinton1 |6mappingproc|7|/tintoff . In this case, we are doing \ a true two point perspective letter. h Non-linear transformations such as these are far more powerful than ordinary linear translate, rotate, or scaling operations. But much slower.) cl save /perspecsnap exch def mark % perspective lettering /px {/zz exch def /yy exch def /xx exch def yo dup yy add div dup xx xo sub mul exch zz zo sub mul} def /psave {/zh zz def /yh yy def /xh xx def} def /prestore {/zz zh def /yy yh def /xx xh def xx yy zz prm} def /psave1 {/zh1 zz def /yh1 yy def /xh1 xx def} def /prestore1 {/zz zh1 def /yy yh1 def /xx xh1 def xx yy zz prm} def /pm {px psave moveto} def /prm {/zi exch def /yi exch def /xi exch def objrot cos xi mul objrot sin yi mul sub xh add objrot sin xi mul objrot cos yi mul add yh add zi zh add px moveto psave} def /prmtostack {/zi exch def /yi exch def /xi exch def objrot cos xi mul objrot sin yi mul sub xh add objrot sin xi mul objrot cos yi mul add yh add zi zh add px} def /pd {px psave lineto} def /prd {/zi exch def /yi exch def /xi exch def objrot cos xi mul objrot sin yi mul sub xh add objrot sin xi mul objrot cos yi mul add yh add zi zh add px lineto psave} def /xrd {0 0 prd} def /xrm {0 0 prm} def /yrd {0 exch 0 prd} def /yrm {0 exch 0 prm} def /zrd {0 exch 0 exch prd} def /zrm {0 exch 0 exch prm} def tempfast {/oversample 0.5 def}{/oversample 0.5 def } ifelse /pixellineremap {0 1 oversample mul pxpwidth 300 mul 72 div cvi {/sline# exch def save /snap1 exch def mark gsave mappingproc newpath sline# 72 mul 300 div 0 moveto 0 pxpheight rlineto 0 0 rlineto 0 pxpheight neg rlineto closepath clip newpath pixelproc grestore cleartomark snap1 restore} for } bind def /mappingproc {10 sline# 72 mul 300 div add 0 16 prmtostack 2 copy /ybot exch def pop exch sline# 72 mul 300 div sub exch dtransform ceiling exch ceiling exch idtransform translate 10 sline# 72 mul 300 div add 0 16 pxpheight add prmtostack exch pop ybot sub pxpheight div 1 exch scale} bind def % demo - remove before use . . . % mark 50 50 setcacheparams /positioning { 0 setlinewidth /xo 00 def /yo 700 def /zo 400 def /objrot 45 def % /Bookman-Demi findfont [125 0 0 125 0 0] makefont setfont mark 10 10 setcacheparams } def /sline# 0 def /tripgray 270 def /pixelproc {reprogray sline# tripgray ge {0.8 setgray} if 0 0 moveto 120 0 rlineto 0 107 rlineto -120 0 rlineto closepath clip 8 setlinewidth stroke 10 10 moveto 0.4 0 (R) ashow} def /pxpwidth 120 def /pxpheight 107 def positioning -1 0 -9 pm /pixelproc1 {beige 0.27 setgray 0 0 moveto 120 0 rlineto 0 107 rlineto -120 0 rlineto closepath clip gsave 0.85 setgray fill grestore 8 setlinewidth stroke 10 10 moveto 0.4 0 (R) ashow} def /font1 /StoneSerif-Bold 125 gonzofont gsave 20 23.5 translate 1 10 div dup scale pixelproc1 grestore % gsave 21 46 translate 1 9 div dup scale positioning pixellineremap grestore cleartomark perspecsnap restore /scanit {gsave translate 0 0 mt line1 14.5 pu 0.4 pr 14.5 pd closepath gsave white fill grestore stroke grestore} def % 10 10 mt 100 u 100 r 26 22 scanit 26.3 4 scanit line1 26.3 36 mt larrow 26.4 36 mt 2 r 25.9 36 mt rarrow 25.8 36 mt 4 l 11.7 35.85 (5scan line one pixel wide) cl %% fudged figure save /fudge exch store 17.2 -1.1 translate 0.09 dup scale % adjust position % perspective transform is % x0 y0 z0 distances from observer to 0 0 0 perspective origin % x is left right y is in out z is up down % x' = y0(x-x0)/(y-y0) % y must go first !! % y' = y0(z-z0)/(y-y0) % this example will use a fixed y for a flat panel. /architectxztransform { /x0 0 def % left right observer to 000 origin /y0 700 def % in out observer to 000 origin /z0 400 def % up-down observer to 000 origin /objrot 45 store % rotation of object in x y plane /xtransform { /vv exch store % must do x transform first /xx vv objrot cos mul store /yy vv objrot sin mul store y0 xx x0 sub yy y0 sub div mul } def /ytransform { /zz exch store y0 zz z0 sub yy y0 sub div mul} def } def architectxztransform % pick the transform here % these procs can be rewritten to do most nonlinear transforms... /movetoproc {moveto} def /linetoproc {lineto} def /curvetoproc {curveto} def /closepathproc {closepath} def % note that the xy transform order varies with the nlt. Starwars needs y first % note that linetoprocs differ when corner cutting is a problem. Starwars does not cut. /movetoproc { 2 copy /lastymt exch store /lasty lastymt store % save close and cp /lastxmt exch store /lastx lastxmt store exch xtransform exch ytransform % x must go first! /moveto cvx} def /linetoproc { /lasty exch store /lastx exch store % save for closepath lastx xtransform lasty ytransform /lineto cvx } def /curvetoproc {/y3 exch store /x3 exch store % can use stack roll - nonobvious /y2 exch store /x2 exch store /y1 exch store /x1 exch store /lasty y3 store /lastx x3 store x1 xtransform y1 ytransform x2 xtransform y2 ytransform x3 xtransform y3 ytransform /curveto cvx } def /closepathproc { lastxmt xtransform lastymt ytransform /lineto cvx /closepath cvx } def % final close should be zero /remapit { mark {movetoproc} {linetoproc} {curvetoproc} {closepathproc} pathforall ] newpath cvx exec } def /nltshow {false charpath remapit} store /font2 /StoneSerif-Bold 50 gonzofont /font1 /StoneSerif-Bold 125 gonzofont /font1 /StoneSerif-Bold [-125 0 0 125 0 0 ] gonzofont font1 beige 0.28 settint /pixelproc1 { /objrot 0 store aqua 0.27 setgray font2 { /y0 700 store 0 0 moveto 70 0 rlineto 0 70 rlineto closepath remapit stroke font2 90 10 moveto (R) nltshow fill } pop /objrot 35 store beige darkcolor setgray 0 0 moveto 120 0 rlineto 0 107 rlineto -120 0 rlineto closepath remapit gsave lightcolor setgray fill grestore 8 setlinewidth stroke font1 114 10 moveto (R) nltshow fill } def 150 500 translate 1 dup scale 1 -1 scale % fudgeit /drawperspec {gsave translate pixelproc1 grestore} def /darkcolor 0.80 store /lightcolor 0.92 store 0 0 drawperspec -49 270 mt 200 pu 160 pl 200 pd closepath gsave clip /darkcolor 0.27 store /lightcolor 0.85 store 0 0 drawperspec grestore newpath fudge restore %%% end fudged figure 26.3 4 scanit line1 1 setlinecap [25.7 22.5 180 23 20.5 -90 23 19.5 -90 26 17 0 ] curvetrace stroke gsave 23 20.65 translate 0 0 mt 1.6 dup scale darrow grestore cleartomark ffsnap restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end } def % pixelmap showpage % ////////// end pixelmap /////////////// % /////// FIGURE SEVEN -- STAR WARS /////// /starwars { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure seven) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Figure 7: jj1"Star Wars" lettering is one of the most popular uses for horizontal pixel line remapping. Each pixel line is shown somewhat \ lower and progressively shorter than the flat original. Since pixel remapping applies to any image, you do not need any access to the actual font paths.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 290 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// % START FREE FONT save /ffsnap exch store % Rewritten code does the srtarwars transform % 100 100 10 setgrid % 26 17 showgrid % starwars transform is % tilt angle q with 0° = flat and 90° = vertical. % k = fullheight tan(q) % x' = xk/(k + y) % y must go first !! % y' = yk/(k + y) /starwarstransform { /tiltangle 60 def % forward tilt angle /fullheight 134 def % vertical size reference /kk tiltangle tan fullheight mul store % magic numble /ytransform { /yy exch store % must do y transform first yy kk mul kk yy add div } def /xtransform { /xx exch store xx kk mul kk yy add div } def } def starwarstransform % pick the transform here % these procs can be rewritten to do most nonlinear transforms... /movetoproc {moveto} def /linetoproc {lineto} def /curvetoproc {curveto} def /closepathproc {closepath} def % note that the xy transform order varies with the nlt. Starwars needs y first % note that linetoprocs differ when corner cutting is a problem. Starwars does not cut. /movetoproc { 2 copy /lastymt exch store /lasty lastymt store % save close and cp /lastxmt exch store /lastx lastxmt store ytransform exch xtransform exch % y must go first! /moveto cvx} def /linetoproc { /lasty exch store /lastx exch store % save for closepath lasty ytransform lastx xtransform exch /lineto cvx } def /curvetoproc {/y3 exch store /x3 exch store % can use stack roll - nonobvious /y2 exch store /x2 exch store /y1 exch store /x1 exch store /lasty y3 store /lastx x3 store y1 ytransform x1 xtransform exch y2 ytransform x2 xtransform exch y3 ytransform x3 xtransform exch /curveto cvx } def /closepathproc { lastymt ytransform lastxmt xtransform exch /lineto cvx /closepath cvx } def % final close should be zero /remapit { mark {movetoproc} {linetoproc} {curvetoproc} {closepathproc} pathforall ] newpath cvx exec } def /nltshow {false charpath remapit} store /font1 /StoneSans-Bold 35 gonzofont /font1 /Helvetica-Bold 35 gonzofont font1 beige 0.28 settint /pixelproc { -0 0 moveto -111 0 rlineto 0 147 rlineto 222 0 rlineto 0 -147 rlineto closepath remapit gsave 0.85 setgray fill grestore 0.33 setgray 1 setlinewidth stroke /cenadj -98 store cenadj 12 moveto (FREE FONT) nltshow fill cenadj 54 moveto (FREE FONT) nltshow fill cenadj 96 moveto (FREE FONT) nltshow fill } def /drawstarwars {gsave translate pixelproc grestore} def 161 183 drawstarwars ffsnap restore % end FREE FONT ======================== save /snap22 exch def denselisting /tabs [130 0] def /ypos ypos 110 sub def /xpos xpos 10 add def /txtwide txtwide 20 sub def xpos ypos ( 21L/resolutionadjust 1 def % raise to debug; lower to eliminate any stripes h /hpixellineremap {0 1 resolutionadjust mul pixelprocht 300 mul 72 div cvi {/slinenum exch def save /snap1 exch def mark mappingproc newpath 0 slinenum 72 mul 300 div moveto pixelprocwidth 0 rlineto 0 72\ 300 div rlineto pixelprocwidth neg 0 rlineto closepath clip newpath pixelproc cleartomark snap1 restore} for } def h /pixelproc {5 5 moveto 0 134 rlineto 222 0 rlineto 0 -134 rlineto closepath stroke 20 15 moveto (FREE FONT) show 20 57 moveto (FREE FONT) show 20 99 moveto (FREE FONT) show} def h /mappingproc {pixelprocwidth 2 div 0 translate tiltfactor pixelprocht mul dup slinenum add div dup scale pixelprocwidth 2 div neg 0 translate} def h % /// demo - remove before use. /// h /AvantGarde-Demi findfont [40 0 0 40 0 0] makefont setfont h /pixelprocht 140 def t% total scanned height /pixelprocwidth 230 def t% total scanned width /tiltfactor 8 def t% the smaller the flatter h gsave 150 300 translate hpixellineremap grestore showpage quit ) cl snap22 restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end } def % starwars showpage % ////////// end starwars /////////////// % /////// FIGURE EIGHT -- PROC CACHE /////// /proccache { /includepix true def % if to be included in layout includepix {/spacestretch 0 def /pm 0 def /pmnorm 0 def} if % requires gonzo.dl.2 % requites ps.util.1 % has internal self-template /headerL (4Lancaster, PostScript Secrets, figure eight) def /headerR {makeitbig {(4yScale = 1.5:1)}{(4yScale = 1:1)} ifelse} def /title (0Figure 8: 1This vertical pixel line remapping example prints in 70 seconds on a NTX. By proc cacheing, or pre-converting the image into two characters in a custom font, the repeat imaging \ time drops to 14 milliseconds, a 5000:1 speed improvement. The first character prints the white label background; the second the label itself.) def % special /makeitbig false def /twocolumnswide true def /fixedheight true def /boxheight 150 def /showthegrid false def commoncode % figure or text starts here ////////////////////////////////////// % START FREE FONT save /ffsnap exch def {{{{ mark 50 50 setcacheparams bl 2 add bt 336 sub translate 0.8 dup scale /resolutionadjust 0.8 def % raise to debug; lower to eliminate any stripes tempfast {/resolutionadjust 8 def} if /ypixellineremap {0 1 resolutionadjust mul pxpwidth 300 mul 72 div cvi {/sline# exch def save /snap1 exch def mark gsave mappingproc newpath sline# 72 mul 300 div 0 moveto 0 pxpheight rlineto 0 0 rlineto 0 pxpheight neg rlineto closepath clip newpath pixelproc grestore cleartomark snap1 restore} for } def /mappingproc {sline# .24 mul dup neg exch pxpwidth 2 div sub canwide div 114.6 mul dup sin canwide 2 div mul exch 3 1 roll add exch cos 1 exch sub tiltangle sin canwide 2 div mul mul translate} def /pixelproc { 0 0 moveto 0 pxpheight rlineto pxpwidth 0 rlineto 0 pxpheight neg rlineto closepath gsave 1 setgray fill grestore 4 setlinewidth stroke 12 6 moveto 1 0 (FREE FONT) ashow} def % this is the flat label % demo - remove before use. % 106 45 {dup mul exch dup mul add 1.0 exch sub} setscreen bestgray 200 300 translate /tiltangle 20 def /canhi 50 tiltangle sin div def /canwide 200 def /NewCenturySchlbk-Bold findfont [30 0 0 33 0 0] makefont setfont /labelypos 8 def /pxpwidth 238 def /pxpheight 35 def gsave newpath 1 dup tiltangle sin scale 1.5 setlinewidth 0 canhi canwide 2 div 0 180 arc 0 0 canwide 2 div 180 0 arc canwide 2 div neg canhi moveto 0 canhi neg rlineto canwide 2 div 0 moveto 0 canhi rlineto gsave 0.85 setgray fill grestore 0 canhi canwide 2 div 0 180 arcn stroke grestore 0 canwide 2 div tiltangle sin mul neg labelypos add translate % draws the can %% ypixellineremap % pastes label on can ffsnap restore % end FREE FONT ======================== }}}} pop % new FREE FONT save /tuna1 exch store 55 9.5 7.9 setgrid % tuna transform is % tilt constant k = (D/2) sin (theta) % x' = (D/2) sin (114.591 x/D) % y' = y - k cos (114.591 x/D) /tiltangle 18 def % forward tilt angle /diam 20 def % major can diameter /magick diam 2 div tiltangle sin mul def % special numble /xtransform { /xx exch store % MUST save for y!!!! diam 2 div 114.591 xx mul diam div sin mul } def /ytransform { /yy exch store yy magick 114.591 xx mul diam div cos mul sub } def % these procs can be rewritten to do most nonlinear transforms... /movetoproc {moveto} def /linetoproc {lineto} def /curvetoproc {curveto} def /closepathproc {closepath} def % initial movetoproc converts to a cruvetrace to try and minimize % corner cutting. Long horizontal lines should be done in segments. /movetoproc { 2 copy /lastymt exch store /lasty lastymt store % save close and cp /lastxmt exch store /lastx lastxmt store exch xtransform exch ytransform % x must go first! /moveto cvx} def /linetoproc { /y3 exch store /x3 exch store x3 lastx sub 3 div lastx add xtransform y3 lasty sub 3 div lasty add ytransform x3 lastx sub 3 div 2 mul lastx add xtransform y3 lasty sub 3 div 2 mul lasty add ytransform x3 dup /lastx exch store xtransform % save for currentpoint y3 dup /lasty exch store ytransform /curveto cvx } def /curvetoproc {/y3 exch store /x3 exch store % can use stack roll - nonobvious /y2 exch store /x2 exch store /y1 exch store /x1 exch store /lasty y3 store /lastx x3 store x1 xtransform y1 ytransform x2 xtransform y2 ytransform x3 xtransform y3 ytransform /curveto cvx } def /closepathproc { lastxmt lastx sub 3 div lastx add xtransform lastymt lasty sub 3 div lasty add ytransform lastxmt lastx sub 3 div 2 mul lastx add xtransform lastymt lasty sub 3 div 2 mul lasty add ytransform lastxmt xtransform lastymt ytransform /curveto cvx /closepath cvx } def % final close should be zero /remapit { mark {movetoproc} {linetoproc} {curvetoproc} {closepathproc} pathforall ] newpath %% dup == cvx exec } def /fudge 3.1415926 2 div store % distance around can to diameter /can { -10 fudge mul 0 mt 6 pu 10{2 fudge mul pr } repeat 6 pd 10{2 fudge mul pl } repeat closepath remapit gsave aqua 0.65 setgray fill grestore line2 stroke } def /lid { 0 6 mt 30 {2 fudge mul pr} repeat remapit gsave aqua 0.8 setgray fill grestore line2 stroke } def /label {-10 1.2 mt 3.5 pu 10 {2 pr} repeat 3.5 pd 10 {2 pl} repeat closepath remapit gsave 0.9 1 0.8 setrgbcolor white fill grestore line2 stroke } def /lettering { /font1 /StoneSans-Bold 5 gonzofont /font1 /StoneSerif-Bold 2.7 gonzofont font1 % -9.6 10 moveto (FREE FONT) false charpath remapit /kernadj {0.18 0 rmoveto} store -8.9 2 moveto (F) false charpath kernadj (R) false charpath kernadj (E) false charpath kernadj (E) false charpath kernadj ( ) false charpath kernadj (F) false charpath kernadj (O) false charpath kernadj (N) false charpath kernadj (T) false charpath remapit black pop 0.27 setgray fill % black line1 stroke } def /drawatunacan {gsave translate can lid label lettering grestore} def 13 5 drawatunacan tuna1 restore % figure or text ends here ////////////////////////// setboxheight boxdraw titledraw end } def % proccache showpage % ////////// end proccache /////////////// % no end of file. continue as byte.txt %%%%%%%%%%%%%%%%%%%%% TEMP BYPASS %%%%%%%%%%%%%% %/fractalfern {} def %/pixelmap {} def %/starwars{} def %/proccache {} def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % name of textfile: byte.text % .... /.ep0 {} def /.ep1 {} def % This is the text portion of the story /tempfast true def % make this false for full details on all figures % ////// BEGIN DOCUMENT /////////////// % your actual document starts here . . . /pagenum 1 def % for internal figures /pagenumadjust 380 def % printed number plus pagenum /leftfooter (|1- pagenum -) def /rightfooter (|1- pagenum -) def /firstpagefooter true def % false to cancel /firstpageheader false def % false to cancel /leftpage false def % this picks first page header and footer % /dropcount 3 def % number of lines the drop cap drops % /dropindent 18 def % indentation for the drop cap % this positions the figures [page column [vposn] printit? (figname)] /figdict 30 dict def figdict begin /fig0a [1 1 140 {coltop 130 sub} true (titleblurb)] def /fig0b [1 2 140 {coltop 130 sub} false (titleblurb)] def /fig0c [1 3 140 {coltop 130 sub} false (titleblurb)] def /fig1a [1 2 320 {colbot} true (meowwrrr)] def /fig1b [1 3 320 {colbot} false (meowwrrr)] def /fig2a [2 1 470 {colbot} true (secretmap)] def % should be secret map /fig2b [2 2 470 {colbot} false (secretmap)] def /fig3a [3 2 480 {colbot} true (graygrid)] def /fig3b [3 3 480 {colbot} false (graygrid)] def /fig4a [4 1 320 {colbot} true (opaqueicon2)] def /fig4b [4 2 320 {colbot} false (opaqueicon2)] def /lst1a [5 2 240 {colbot 189 add} true (makeeexec)] def /lst1b [5 3 240 {coltop 189 add} false (makeeexec)] def /lst2a [5 2 190 {colbot} true (readeexec)] def /lst2b [5 3 190 {colbot} false (readeexec)] def /fig5a [6 2 350 {colbot} true (fractalfern)] def /fig5b [6 3 350 {colbot} false (fractalfern)] def /fig6a [7 1 350 {colbot} true (pixelmap)] def /fig6b [7 2 350 {colbot} false (pixelmap)] def /fig7a [8 2 350 {colbot 209 add} true (starwars)] def /fig7b [8 3 350 {colbot 209 add} false (starwars)] def /fig8a [8 2 210 {colbot} true (proccache)] def /fig8b [8 3 210 {colbot} false (proccache)] def end % figdict % .......................... % /titleblurb {} def % temp /cmacro {aqua 0.27 setgray (3Lz) stringmacro} def % start subtitle /dmacro {(1zFy) stringmacro black} def % end subtitle /emacro {xpos ypos yinc 0.5 mul sub 2.5 sub moveto txtwide 0 rlineto 0.5 setlinewidth stroke /ypos ypos yinc 1.5 mul sub def} def % end line /Ymacro {save aqua 0.27 setgray /yinc 46 def /txtwide 1000 def /colcheck {} def /charstretch 0.7 def xpos colspacing add ypos 90 add maintitle cl restore} def % the title /Zmacro {save aqua 0.27 setgray /yinc 15 def xpos ypos 3 sub blurbette cl restore} def % first blurb /Umacro { /ypos ypos yinc 4 mul sub def save /wiresnap exch def /hold1 exch def /hold2 exch def /hold3 exch def gsave xpos 32 add ypos 2 add 7 setgrid % 15 6 showgrid bestgray 1 setlinecap [1 1 0 13 5 0] curvetrace [1.3 1 0.7 0 0.4 .6] superstroke newpath [1 5 0 13 1 0] curvetrace [1.3 1 0.7 0 0.4 .99] superstroke grestore clear hold3 hold2 hold1 wiresnap restore} def % crossed wires example /Vmacro {/ypos -999 def} def % cure a list1 temp bug %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /wanttousepicojustify true def % this globally turns picojust on or off %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wanttousepicojustify false 40 array dictstack {/^picoset known or} forall not and { % FILL JUSTIFICATION IMPROVER version 3.0, November 3, 1994. c 1994 by % Don Lancaster & Synergetics (602) 428-4073. [support on GEnie PSRT] % Personal use premitted; All commercial & media rights fully reserved. % Install this where it will redefine all print time uses of % the -awidthshow- operator. Use picojust true or false to control. /picoflag true def % selective availability switch /picofract 0.5 def % percentage of excess space to be internalized /picothresh 0.03 def % percentage/100 increment per font change /picomax 0.15 def % percentage/100 max stretch (limits fat chars) /^picoset true def % job multiple def lockout /picojust {/picoflag exch store} def % use for local turn on or off /awidthshow {1 index 4 index 6 index add add 32 eq not picoflag not or {//awidthshow}{/^msg exch store pop /^cst exch store pop pop /^sst exch store /^cct ^msg length store /^rwd ^msg stringwidth pop store /^sct 0 ^msg {( ) search {pop pop exch 1 add exch}{pop exit} ifelse} loop store /^jwd ^cct ^cst mul ^sct ^sst mul add store /^saj ^jwd dup ^rwd add dup 0 eq {pop 0.0001} if div picothresh div floor picothresh mul picofract 1.33 mul mul dup picomax ge {pop picomax} if 1 add store gsave ^saj 1 scale /^rft 1 ^saj 1 sub ^rwd mul ^jwd dup 0 eq {pop 0.0001} if div sub ^saj div store ^sst ^rft mul 0 32 ^cst ^rft mul 0 ^msg //awidthshow grestore ^jwd ^rwd add 0 rmoveto} ifelse} bind def} if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Gonzo character colorizer /blueon {mark /blue cvx 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /blueoff {mark /aqua cvx 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton {mark 0.33 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1 {mark 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1r {mark /red cvx 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tinton1a {mark /aqua cvx 0.25 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /tintoff {mark 0 /setgray cvx] cvx printlist exch 3 index exch put exch 1 add exch} def /staytint {aqua 0.33 setgray} def /staytint1 {aqua 0.25 setgray} def /staytint1r {red 0.25 setgray} def /staytint1b {beige 0.25 setgray} def % //// MAIN TEXT BODY STARTS HERE //// /maintitle (|7P|8|k|kO|kST|7S|8CRIPT |7I|8NSIDER |7S|8E|k|kCRETS) def /blurbette (|6In which the guru expounds upon his favorite subject) def /wanttousepicojustify true def % this globally turns picojust on or off /tabs [95] def /burple {0.75 settint} store setup startgonzo |Z|Y |a I |b t does seem a bit strange for me to be appearing inside someone else's column as their visiting editorializer. But, outside of those ugly mauve curtains and not being able \ to find the switch for their hot tub, the opportunity is most welcome.|p PostScript by Adobe Systems. Please do not call PostScript a page description language. To do so is a gross and demeaning insult, and is roughly comparable to referring to |4UNIX|1 as a "checkbook balancer". Instead, PostScript is an incredibly powerful |2general purpose|1 computer language which can do far more than hold its own against any other modern contender. Yes, PostScript does excel at putting marks on pages. Those features that make PostScript rather good at this include its |2device independence|1, which means that virtually any \ editor or most any old word processor on any host computer can be used. The same device independence lets you make use of phototypesetters, laser printers, display screens, high resolution fax substitutes, signmakers, printed circuit prototypers, plotters, |4CAD/CAM|1 production systems, slide imagers, and photolithography e |43-D|1 "Santa Claus" machines. Another big plus of PostScript lies in its powerful graphic transformation capabilities. Fonts and graphics can be freely intermixed in any combination in any scale along any direction. The font machinery in PostScript is especially impressive, by use of single outline descriptions to create any font size or shape \ from a single master font dictionary. Hinting and weight-vs-size adjustments are often included in the font \ descriptions. Hints can optimize your results on lower resolution output devices, as well as preserving balance in larger headline typography. Since the font descriptions are really procedures, it is easy to post process your final characters for outline, shading, |43-D|1, \ pattern, distortion, and numerous other special effects. A near infinite variety of PostScript fonts are available today. These range from several dozen standards built into PostScript printers up to thousands of fully professional downloadable fonts, down on through \ countless shareware and freeware offerings of lower cost and quality. You can also easily create your own new PostScript fonts or customize existing ones. Another power feature of PostScript involves its extensive use of |2Bezier|1 cubic splines to create smooth and graceful curves whose resolution improves with increasing size and better output devices. PostScript is somewhat related to Forth. An interpreted, stack-oriented, postfix entry (reverse Polish), and \ heavily into the use of dictionaries. PostScript is both reentrant and extensible, meaning that you can add |t |:continued|1|z or redefine any portion of the language in any manner.|p PostScript is also one extremely fun language to apply, easily becoming downright addictive. Since you could create useful output after learning only a very few PostScript \ commands, you don't have to swallow everything at once. I have often seen off-the-street beginning students routinely creating award-winning graphics after a single class session.|p In short, those PostScript vibes feel right. Which, in my opinion, will blow everything else away. Usually, you do not run out and buy a copy of PostScript. Instead, their language is built into your output device, such as a laser printer or \ a phototypesetter. Typical laser printers which use PostScript include the |2Apple|1 LaserWriter |4NT|1 and |4NTX|1 and the |4LC-890|1 by |2NEC|1. One example of a PostScript phototypesetter is the |2Linotron |4200-P|1. Yes, PostScript can be run on older dot matrix and ink-jet printers. This can be done with low cost PostScript clone software emulators. |2GoScript|1, |2Freedom of the Press|1, and |2UltraScript|1 are typical. You communicate with PostScript by using a series of instructions in any old word processor file; downloading \ emulators that accept nearly all earlier graphics and text formats; or when running illustration and pagemaking applications programs. As an advanced and future-oriented general purpose language, PostScript is both richly and loosely typed. For lots of data structures that you can redefine at will. PostScript is polymorphic, giving you a wide range of operators which accept multiple data types as inputs. Most importantly, PostScript allows redefinable primitives. \ This lets you rearrange the scenery to suit yourself. PostScript automatically does all its matrix transformations on the fly, maintaining both a user space and a device space. Its key-value dictionary structures are extremely powerful. One little known yet mind-blowing \ feature of these dictionaries lets you link |2any|1 two data types as a key-value pair. While I'd be most happy to discuss PostScript programming fundamentals with you all day long, this would best be left for another place and another time. What I'd like to do instead \ is introduce to you a dozen disgustingly sneaky and little-known PostScript insider secrets. Should you want more on PostScript fundamentals, check into Adobe's "blue" book, otherwise known as the |2PostScript Language Tutorial and Cookbook|1, and the "red" book, \ that is also called the |2PostScript Reference Manual|1. Or you might call or bingo me for more info. On to our sneaky stuff\274 |c Those Secret Grays |d For some totally unfathomable reason, most PostScript applications packages and most users often end up using the 2seventeenth1 most putrid group of grays available on \ their |4300 DPI|1 PostScript printers. Yet with a few keystrokes, absolutely outstanding grays could get substituted. Some can even simulate an India ink wash.|p Most |4300 DPI|1 PostScript printers are only capable of putting or not putting dots in specific locations on the page. To create a gray, you use combinations of dots \ which we might call a |2spot|1. For instance, a |43 x 3|1 spot could give you ten gray levels (including black and white) with a resolution of |4100|1 spots per inch. Because the spots have to perfectly replicate themselves over the entire page, integer math is involved that decides which spot combinations are |t |:continued|1|z or are not allowed. A \ parameter called the |2screen angle|1 decides \ how the spots should orient on your page. Typically, screen angles near |445|1 degrees are preferred for lower visual artifacts.|p Figure one shows the quality level you should be expecting from |4300 DPI|1, while figure two shows you the secret gray map of the denser grays. Because of that integer tiling, your request for a screen angle and density will automatically get converted into one of those shown on the secret map. Your overall "best" gray is a |4106|1 spot, |445|1 degree one, while the |485,|j|j35|1 option is best for camera-ready copy that is to be reduced. The |4135,|j|j25|1 can \ give you India ink wash effects, but limits paper and toner choices. The default screen is clear on down at |453|1 spots and |445|1 degrees, which explains the "Sunday Funnies" results of most poorly done PostScript. There is, of course, one tradeoff. The denser screens permit you fewer gray levels. But one decent and dense light gray is all you'll need to really spruce up line art. To change a halftone screen, simply enter this sequence\274 |h|C|z|/burple |/tinton1 |2106 45 {dup mul exch dup mul |/tinton1 add 1.0 exch sub} setscreen|1 |h|F|p|/aqua That sequence inside those curly braces is called the |2spot function|1. Other spot functions are available for other uses. Most spot functions do behave similarly when imaging their \ lightest gray. You can use PostScript's |2currentscreen|1 operator to preserve the existing spot function. |c Dropout-free Gray Grids |d There are other sneaky tricks you can pull if you thoroughly understand your PostScript grays.|p Figure three shows you a fine gray |2rubbergrid|1 that is both uniform and dropout-free. Your tricks here use a special spot function and lock to exact \ multiples of four pixels. Note that the lines are all uniform and that each crossing has precisely one pixel dot at its precise center. The nice thing about a rubbergrid is that you can easily expand or contract it to fit your available space. Once created, further graphics and text are locked to the rubbergrid until your next |2restore|1. Your grid could be used only for layout, or else can be a part of your final image. Engineering graphs do look good on the rubbergrid. There are several minor gotchas. The rubbergrid must be done at |41:1|1 scale, and any scaling or repositioning at all gets rather involved. Because of the exact \ quad pixel locking (which seems crucial for preventing |4300 DPI|1 dropouts), your final graph may not end up exactly the size you wanted, and may not be exactly positioned. If you just want a rubbergrid and do not care how it looks, do a\274 |h|C|z|2|/burple |/tinton1 /quadpixel {} def |h|F|1|/aqua to prevent the locking. If you don't lock, you will get the exact size and position you want, but may have dropouts and lineweight variations.|p Note that the grid extends infinitely in all directions, but only the values passed to |2showgrid|1 determine what you see on the page. You can turn off the visible portion of the grid by adding a |4"%"|1 comment to the start of your |2showgrid|1 line. |c Opaque Icons |d Many popular PostScript images can get thought of as blobs sitting on strings. Obvious examples include electronic schematics, flowcharts, printed circuit boards, organizational charts, and work schedules. |t|:continued|1|p A nearly unknown concept called an |2opaque icon|1 can come to the rescue here. One example appears in the electronic schematic of figure four. The rules are that all \ the symbol icons are stored in dictionaries; that all the icons are opaque and will thus erase anything they are sitting on; and that each icon has an obvious |2action point|1 which determines where they sit. Erasure gets done by writing white over your underlining wire or string before creating the rest of the icon. The nice thing about opaque icons is that you can first position them and then later |2slide all of your continuous wires underneath them|1. To do this, you simply place your continuous wires |2earlier|1 in your textfile. Your icons are thus repositionable at any time, without ever worrying about making and breaking any of the actual connections. A related technique is called the |2fat white, thin black|1 ploy. Those wire breaks you see are done by drawing a thick white line, followed by a thin black one. \ The same idea also works for piping and braiding, for unusual borders, isometric depth illusions, and for fonts can that automatically break an underline. |y|y |c Not-so-secret eexec |d PostScript has a very enigmatic |2eexec|1 operator that appears to be of major ongoing helpline interest. |2eexec|1 was a failed early attempt at making PostScript textfiles somewhat harder \ to read at the triple penalties of longer files, slower execution times, and that red flag waving "I've got a secret" attention calling to its own use.|p You can easily sight read any |2eexec|1 file by using a stack dumping error trapper, followed by selectively inserting extra characters into your \ data stream or else truncating your file with a 2[control]-d1 end of file. From your return error messages, your plaintext file is readily reconstructed. All of the needed tools appear in Adobe's red, blue, and green books. For a faster and easier method, listing one shows you how to employ 2eexec1 to encrypt your own PostScript textfile, while Listing two shows you how to1 1convert your previously |2eexec|1 encrypted file back into plaintext. So how does |2eexec|1 work? The key is a sixteen bit pseudorandom sequence. To encrypt, the upper eight bits of the current pseudorandom mask integer gets exclusive-|4OR|1'd \ against an original |4ASCII|1 value, creating a new character that gets saved as a hex pair. Since the exclusive-|4OR|1 function is reversible, a similar process repeated again will get you from the encrypted form back to plaintext. A new pseudorandom value can be calculated by adding the existing value to the current encrypted character, then multiplying by one 416-1bit constant and adding a second \ one. You can find these constants by |2eexec|1ing1 a bunch of |4$00|1 values so as to reconstruct the unshifted pseudorandom sequence. The first four hex pair characters are ignored in the |2eexec|1 interpreter. Presumably, these let you add a user key to your coding process. The short code segment I've chosen for these |2eexec|1 examples is called a |2blackflasher|1. You can use this to eject a solid black page immediately before printing. \ Blackflashing preconditions a laser printer drum and can greatly improve solid blacks and uniform grays whenever superb quality or a camera-ready original is needed. |c Curve Tracing |d PostScript includes a pair of strong |2Bezier|1 cubic spline curve generators in its |2curveto|1 and |2rcurveto|1 operators. These \ let you draw the smooth and continuous curves needed for higher quality typography, signatures, cartoon animation, borders, and anywhere else you may need flowing curves.|p A third order spline curve can have at most a single cusp, a single loop, or two inflection points. To do anything fancier, you'll have to use multiple splines arranged end-to-end. And this is where things can get tricky. \ To look good on the page, adjacent splines must align, have continuous slope, and, ideally, a continuous rate of change of slope where they meet. \ They also, of course, should accurately approximate the desired curve. A |2curvetracing|1 routine can be used to align splines to get a smooth result. While there are lots of options here, the curvetracing \ routine I use seems to give me lots of control and appears to do the job. Curve tracing is based on entering an array of three data values for each and every spline end. The composite curve is then built up spline by spline. These data values do include the |2x|1 position, the |2y|1 position, and the desired slope angle at each spline end. Since you are specifying the end slope, you end up \ guaranteeing the continuous slope match at spline ends. |t|:continued|1|p As a simple example, the single curve of figure three is coded\274 |h|C|2|z|/burple |/tinton1 [5 5 80 15 15 25] curvetrace |h|1|F|p|/aqua We thus start at |45,5|1 with an angle of 4+801 degrees and end up at 415,151 at an exit angle of 4251 degrees. As a more detailed example, the cat of figure one uses extensive curvetracing. Curvetracing can either generate a new path or append an existing one. The convention I use is that initial data values of |40,0|1 will append an existing \ curve. This lets you mix curves and straight lines in the same path. Cusps are created by repeating a data point pair with a different entry and exit angle. Variable curve widths are handled by curvetracing up one side and down the other. To draw a pictorial wire, you first curvetrace the wire path. Next, set a |21 setlinecap|1 for rounded ends. Then stroke fat white to break anything the wire is running \ over. Then stroke black to set the wire outline. Then stroke gray to color the wire\274 |U A complete listing of my PostScript curvetracing routine is included on 4BIX1 as part of the |2meowwrrr|1 listing. More examples, including engineering graphs, appear in my |2Ask the Guru|1, volume II. |c Fractal Art |d If the dire predictions in the red book are taken seriously, any attempt whatsoever at doing fractal art with PostScript will result in the immediate vaporization \ of all small furry animals within an eight block radius of your PostScript printer. In reality, PS is nearly ideal for many fractal uses.|p To prove this, I've taken the fern routine that first appeared in |2A Better Way to Compress Images|1. |4(BYTE1, Jan. |41988)|1 I was struck by how ungainly \ all the translate-rotate-scale ops were done in either of the |4BASIC|1 or |4C|1 example listings. Uh, matrix image transformations between device and user space are inherent to the very core of PostScript. The code works by first creating a table of |4128|1 different transformations based on the probabilities needed. That table is then selectively used to build up your \ final fern. As before, the first twenty dots are thrown out to give the strange attractor time to start strange attracting. Note that a mere |428|1 data values |2completely|1 define the image. What utterly amazes me about this fern fractal image is that you do not really draw it. Instead, you simply let it out, and it leaps at you. |c Gonzo Justification |d I overwhelmingly prefer to work in "raw" PostScript in a non-|4WYSIWYG|1 standard |4ASCII|1 textfile environment. I find this gives me far more control and \ lets me do my PostScript-as-language apps which might not be at all obvious in a screen-oriented or a pagemaking environment.|p One of my ongoing projects around here is my |2gonzo justify routine|1 where I've attempted to produce the highest possible |4300 DPI|1 text justification. These let you fill justify a line with any number of chosen regular, italic, bold, superscripted, subscripted, or custom font selections. As many as six stages of \ microjustification get used. First, all characters are spaced out by a minimum and selectable fixed kerning, eliminating the "collisions" common at very \ small point sizes. Second, spaces get stretched out from their maximum compressible limit up to their normal value. Third, up to one additional pixel is added \ to each character to further improve |4300 DPI|1 readability. Fourth, the spaces get stretched out to an upper aesthetic limit. Fifth, the characters are stretched \ out to an upper pleasing limit. Sixth, and finally, if all else fails, spaces are stretched as far as is necessary to complete the fill. Other gonzo features are individual selectable character kerning, tabbing, \ |t|:continued|V|1|z |1programmable preset keystoning, fully automatic drop caps, \ last paragraph line \ stretch, and hanging punctuation.|p In hanging punctuation, dashes, periods, and commas lean out into your right intercolumn spacing. While seldom seen, hanging punctuation can greatly improve |4300 DPI|1 text.|p Those same gonzo routines are fully programmable, which can let them emulate just about anything.|p You can call me for a free printed listing of my gonzo justify routines. |c Post-Justification Editing |d Communication takes place between author and reader when your desired message is presented at the correct level in the most pleasing manner. In the final analysis, \ the medium is the message. The way the words are shown on the page is just as important as the words themselves.|p In fact, slightly jarring and slightly wordy text presented as tightly and as uniformly as possible will almost always be understood better. For this reason, I feel that there is no point whatsoever in doing |2any|1 editing before typesetting to the final page image standards. |2All|1 of your typesetting \ should be treated as rough drafts, because the aesthetics of the final image are so important. The closer the original author comes to showing the |2exact|1 final page image, the better the communication process will become. And remain. I call this heresy |2post-justification editing|1, and boy is it ever. You always typeset and |2then|1 edit, not vice versa. PostScript makes post-justification editing so fast, so cheap, and so trivial that it is inexcusable not to use it. Another area for post justification editing involves the last manual pass over the final page layouts. No matter how good your machine justification routines, every \ twentieth line or so could end up ungainly or spacey to some extent or another. Use of a hand-patched fix at this point can give you outstanding final results. And no, this final manual pass is not all that expensive or time consuming. As you might gather, the use of post-justification editing is somewhat controversial, since it can give the original author unprecedented control over what they say and how they say it. It \ also gives you a much more tightly controlled linking of the text, figures, and art. Naturally, this is being fought tooth and nail by old-line editors who should know better. |c|y IBM and Clone Interface |d Far and away the number one topic on my PostScript helpline involves |4IBM|1 and clone interface hassles. Since PostScript is device independent, it can easily work with most any host computer at \ all, including, of course, all of the pc clones. Yes, the Apple |2LaserWriter|1 works beautifully with any of these machines. It even includes a free secret and automatic \ two-host network that does not need |2AppleTalk|1 or any fancy cables.|p Virtually all of the clone problems are due to end user misinformation. First and foremost: |2Don't ever, under any circumstances, use a clone parallel printer port to interface a PostScript printer!|1 To do so deprives you of receiving crucial return error messages; \ denies you interactive operation; prevents any host recording; outright eliminates around |490|1 percent of the more useful features of PostScript as a general purpose language; \ while making your printer drivers unbearably klutzy and primitive. Instead, you save all your PostScript routines as standard |4ASCII|1 textfiles to disk. You then pick up those textfiles with a suitable comm program such as |2Crosstalk|1, and use \ them in a two-way interactive |4COM-1|1 environment. A good baseline environment is |49600|1 baud, |48|1 data bits |41|1 stop bit, no parity, full duplex, and software |4XON/XOFF|1 handshaking activated. Note that a simple |2copy|1 to the |4COM-1|1 port also will not give you any of the essential return error messages. There are at least six cable options between clones and LaserWriters. The baseline one I recommend for |4DB-25|1 to |4DB-25|1 interface to |4RS232|1 is\274 |h|C|z|2|/burple |/tinton1 1 to 1 |/tinton1 2 to 3 |/tinton1 3 to 2 |/tinton1 short left 4 & 5 |/tinton1 short right 4 & 5 |/tinton1 6 to 20 |/tinton1 20 to 6 |/tinton1 7 to 7 |/tinton1 8 to 8 |h|F|p|/aqua |1When using |4RS423|1, note that your |4RS232|1 data out goes to |4RXD-|1 and that |t |:continued|1|z |4RXD+1 gets grounded. Failure to ground |4RXD+|1 is far and away the most common \ mistake made here. Similarly, |4TXD-|1 drives the 4RS2321 data-in line, and |4TXD+|1 is unconnected.|p Well after you are reliably receiving your return error messages, you might want to install a persistent printing error trapper. Details on this are in the green book \ and on most PostScript bulletin boards. You can also get one directly from |2Adobe Systems|1. Getting your PostScript comm up and running for the first time can be extremely frustrating. Note that many comm programs will not change their parameters in \ real time. If something does not work during your initial setup, always do a cold reboot, and make sure your PostScript printer is a solid green or idle before you try to talk to it. Do give me a call if you need any additional pc or clone interface help. |c Pixel Line Remapping |d The PostScript transformation matrix that gets you from user space to device space is a six-element linear one. This lets you do all of the usual translation, rotation, and scaling operations. \ As an example, any square can be converted into another square of any size, to a rectangle, a parallelogram, a point, or a line, at any rotation angle anywhere on (or off) your page.|p There are times and places when you want to go beyond linear and make the more complex |2non-linear|1 transformations on the fly. Obvious examples include perspective and star wars lettering, or mapping \ images onto apparently non-flat services. Note that a perspective letter is trapezoidal, and thus cannot normally be done with a linear transformation. I've come up with a sneaky and slow |2pixel line remapping|1 scheme that lets you map most anything onto \ any strange or unusual surfaces. Figure six shows us how pixel line remapping works, while two additional examples are in figures seven and eight. With pixel line remapping, you first create a flat proc that \ you wish to nonlinearly transform. It can be an ordinary PostScript proc, so you do not need access to anything special such as any protected font paths. You then scan this flat image a single pixel line at a time. Each line then gets picked up and then gets translated, scaled, and/or rotated as desired before final placement. There are two mapping routines, one for vertical scanning and another for horizontal scanning. In figure six, we vertical \ scan for perspective lettering. Each successive scan line is shown shorter, higher, and left of original. In figure seven, we \ use horizontal scanning to produce a "star wars" logo. Each new line is shown shorter and below its position in the original. Finally, in figure eight, we wrap a label around an isometric or other |43-D|1 can. Lines left of center are \ shown above and to the right of the original, while lines right of center are shown above and to the left of their original positions on the flat label. Processing speed varies with image size and pixel resolution, being fastest for graphics, intermediate on one single font \ sizes, and rather slow when font sizes change on the fly. The parameter |2resolutionadjust|1 in figure seven lets you handle scaling or do rough drafts much faster. If this value is too high, you get dropouts. Too low, \ and you are wasting your time and get rattier final results. For the ultimate in any non-linear transformations, you can also do |2pixel point remapping|1, but this can take forever on larger images. Until you factor in that \ good old "Uh \261 compared to what?" factor. Point remapping lets you map anything onto any surface, however complex. |c Pseudo Compiling |d PostScript is wrongly accused of being a slow language. Most often the speed measurements are done by using a non-PostScript applications program running on a non-PostScript host, \ creating non-optimized mechanical code and communicating over a glacially slow comm channel.|p PostScript is ridiculously faster than most people assume. To set the record straight, I am very big on the |2book-on-demand|1 publishing where a single title gets produced for each and every customer order. Long page makeup times \ are intolerable here, because each book self-collates on a page-by-page basis. My |46000|1 text character, three column, gonzo justified text with headers, footers, and one or two fairly complex figures may |t|:continued|1|z need a page makeup time of between zero and four seconds. Using an Apple IIe as a host. \ Thus, I consider all of the speed tests made in PostScript printer reviews to be totally ludicrous.|p |1One crucial speedup secret involves ||getting your communications up to a |1decent rate. Note that AppleTalk is not |1significantly faster than an honest |49600|1 baud serial \ channel for typical users most of the time, and that most comm setups involve excessive "Hi|j-|jHow's the wife and kids?" handshaking. I use a custom crafted and honest |457,600|1 \ baud serial channel going out the game paddle port of my |4IIe|1. My handshaking overhead is |2zero|1, since new characters are gotten during interbit delay. Two ultimate comm speedups are to use a local |4SCSI|1 hard disk or else to directly download all your PostScript code over a |4SCSI|1 channel. The real secret to speeding up any interpreted language is to compile it instead. Outside of PostScript 's rather restrictive |2bind|1 command which can sometimes give \ you a fifteen percent or so speedup, a true compiling of your PostScript code can get rather tricky for most users. But there are all sorts of |2pseudo-compiling|1 \ games you can play which can give you some really dramatic speed improvements. Pseudo-compiling works only on the procs that you are going to want to reuse at least once in the future. The trick here is to do all your calculations only once, save |2only the \ results|1 from those calculations, and return them to your host for recording and later reuse. The key rule is to |2save and reuse only genuinely needed information|1. Your pseudo-compiling \ can be done either manually or under program control. Another pseudo-compiling stunt is to |2never change a font more than once per page|1. Since it usually does not matter in which order things go down onto your reprinted PostScript page, you put \ all of your regular text down first, then all your italic text, then all the bold, then the headlines. To do this, you use a custom routine that saves all your strings with their font, \ position, and message info into a bunch of dictionaries. After your first pseudo-compiling run, you then dump these dictionaries back to your host for recording and later reuse. Pseudo-compiled code can also get modestly compacted. Tricks such as a simple formatting operator, dropping leading zeros and dropping the number of significant bits to those \ actually required can further shorten (and thus speed up) your run time files. Adobe's |2Distillery|1 is one example of an automated pseudo-compiling program. A pseudo-compiler of mine that includes font ordering \ has been placed on |4BIX|1, while additional info on my book-on-demand publishing appeared in the January |41990|1 issue of |2Midnight Engineering|1. |c Proc Cacheing |d |1We'll wrap things up here with a very little known PostScript speedup trick that applies to any proc you want to reuse |2at least once at the same size|1. The trick is called |2proc cacheing|1 and it can give you a |412:1|1 up to a |47,000,000:1|1 speedup |k|kof |k|kall |k|kyour |k|kPostScript |k|krun |t|:continued|1|z times. The amazing thing is that \ proc cacheing is more or less free. All you have to do is make some minor changes in your programming style.|p Proc caching can also capture entire page bitmaps and can let you save fast results for later use. Proc cacheing is quite well suited for smaller images that involve long makeready times due to your use of irregular clipping outlines, repeated randomizing, pixel remapping, \ curve tracing, multi-layer effect buildups, extensive oddball math calculations, non-linear transforms, or other slower or intricate operations. PostScript includes a powerful |2font cache|1 that converts font characters into a bitmap the first time they are used. Thus, the initial "s" of a given size \ in your document is done as a descriptive outline procedure. Those results are transferred to the font cache as a bitmap and saved. Repeat use of the "s" character in the same \ size comes from the bitmap and is typically several thousand times or more faster. Figure eight shows us an example of a vertically pixel line remapped "wrap-around" font which lets you place a label on an isometric or other circular surface. In this example, \ proc cacheing gives you a |45000:1|1 speedup on any same-sized future reuse. All you have to do to proc cache is convert any complex or slow routine |2into one or more characters in a custom font|1. Then you simply let the font cacheing mechanism do its thing. There are at least four ways to use font cacheing. Should you define your custom font on the fly, the cache will go away with your current job. This is handy for |412-|1up business cards on older machines with limited memory. If you persistently download your custom font, your speedup will remain so long as printer power is applied. If you have a hard disk attached to your 4NTX1 or \ other PostScript laser printer, the fast image will remain until the next time the disk blows up. Finally, you can easily read the font cache on your hard disk and return it to your host for recording, giving you a permanent fast bitmap. Newer PostScript printers control their font cache with this line\274 |h|C|z|/burple |/tinton1 |2mark M N setcacheparams |h|1|F|p|/aqua The |4N|1 value here is the maximum number of |2bytes|1 allowed in the bitmap of a single character. Multiply this by eight to get the number of bits allowed \ per character. Your |4M|1 value decides which of two cacheing strategies will be used. Bitmaps of less than |4M|1 bytes will get cached as a real bitmap; those greater than \ |4M|1 but less than |4N|1 will get run length encoded. Run length encoding needs less memory than a full bitmap, but typically executes six times slower. To guarantee a real bitmap, simply define |4M|1 as larger than |4N|1. Characters needing a bitmap larger than |4N|1 bytes will not get cached at all. The allowable size of |4M|1 depends upon your printer and how much memory is in it. The simplest method to find your maximum is to increase |4M|1 until you get a |2limitcheck|1 error. Naturally, you will want to open up |4M|1 as wide as you can to let you proc cache your larger images. A three megabyte |4NTX|1 lets you proc cache images up to four square \ inches, while a full twelve megabyte |4NTX|1 handles images up to sixteen square inches. These size restrictions might seem somewhat limiting, but note that the slow portions of many images are often small, and that you can use as many characters \ in your custom font side-by-side to build up any size image at all. As few as 2six1 characters can capture your |2entire|1 page bitmap on a full |2NTX|1. There's several gotchas involved in proc cacheing. Your routine has to be well enough behaved to allow its definition as a custom font character. Each character \ in a font is only allowed to be a single color or a single shade of gray. Thus, you'll need an additional custom character for each color change in your original image. For instance, in figure eight, only the label itself gets proc cached. One proc cached character gets used as a white background mask, erasing the can color, while a \ second proc cached character puts the actual label on top of the erasing white mask. Figure eight is available on |4BIX|1 so you can start exploring proc cacheing on your own. For additional info on proc caching, you can contact me for a free reprint of this exciting new PostScript speedup technique. |y|y|/staytint1 |e |y|h |2Microcomputer pioneer and guru Don Lancaster is the author of 26 books and countless articles. Don does maintain a no-charge PostScript help line found at (928) 428-4073. The best calling \ times are 8-5 weekdays MST. Or circle Reader Service Card 37252 for a free brochure full of more PostScript secrets. |x % and show the final page. Don't skip the |x gonzo ender above! showpage % eof