123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- %
- % Dump a PostScript object, occasionally in a form that can be sent back
- % through the interpreter. Similiar to Adobe's == procedure, but output
- % is usually easier to read. No binding so operators like rcheck and exec
- % can be conviently redefined.
- %
- /GrabitDict 100 dict dup begin
- /recursive true def
- /scratchstring 200 string def
- /slowdown 100 def
- /column 0 def
- /lastcolumn 80 def
- /level 0 def
- /multiline 100 array def
- /nextname 0 def
- /arraylength 0 def
- /lengthonly false def
- /GrabitSetup {
- counttomark {OmitNames exch true put} repeat pop
- 0 0 moveto % for hardcopy output
- } def
- /OmitNames 30 dict def % ignore these names
- /OtherDicts 200 dict def % unrecognized dictionaries
- %
- % All strings returned to the host go through Print. First pass through an
- % array has lengthonly set to true.
- %
- /Print {
- dup type /stringtype ne {scratchstring cvs} if
- lengthonly {
- length arraylength add /arraylength exch def
- }{
- dup length column add /column exch def
- print flush
- slowdown {1 pop} repeat
- } ifelse
- } def
- /Indent {level {( ) Print} repeat} def
- /Newline {(\n) Print lengthonly not {/column 0 def} if} def
- /NextLevel {/level level 1 add def multiline level 0 put} def
- /LastLevel {/level level 1 sub def} def
- %
- % Make a unique name for each unrecognized dictionary and remember the name
- % and dictionary in OtherDicts.
- %
- /Register {
- dup type /dicttype eq {
- /nextname nextname 1 add def
- dup (UnknownDict ) dup
- (UnknownDict) length nextname ( ) cvs putinterval
- 0 (UnknownDict) length nextname ( ) cvs length add getinterval cvn
- exch OtherDicts 3 1 roll put
- } if
- } def
- %
- % Replace array or dictionary values by known names. Lookups are in the
- % standard PostScript dictionaries and in OtherDicts. If found replace
- % the value by the name and make it executable so nametype omits the
- % leading /.
- %
- /Replace {
- false
- 1 index type /dicttype eq {pop true} if
- 1 index type /arraytype eq 2 index xcheck not and {pop true} if
- {
- false
- [userdict systemdict statusdict serverdict OtherDicts] {
- {
- 3 index eq
- {exch pop exch pop cvx true exit}
- {pop}
- ifelse
- } forall
- dup {exit} if
- } forall
- pop
- } if
- } def
- %
- % Simple type handlers. In some cases (e.g. savetype) what's returned can't
- % be sent back through the interpreter.
- %
- /booleantype {{(true )}{(false )} ifelse Print} def
- /marktype {pop (mark ) Print} def
- /nulltype {pop (null ) Print} def
- /integertype {Print ( ) Print} def
- /realtype {Print ( ) Print} def
- /filetype {pop (-file- ) Print} def
- /fonttype {pop (-fontID- ) Print} def
- /savetype {pop (-saveobj- ) Print} def
- %
- % Special formatting for operators is enabled if the flag in multiline
- % (for the current level) is set to 1. In that case each operator, after
- % being printed, is looked up in OperatorDict. If found the value is used
- % as an index into the OperatorProcs array and the object at that index
- % is retrieved and executed. Currently only used to choose the operators
- % that end a line.
- %
- /operatortype {
- dup Print ( ) Print
- multiline level get 1 eq {
- scratchstring cvs cvn dup OperatorDict exch known {
- OperatorDict exch get
- OperatorProcs exch get exec
- }{
- pop
- column lastcolumn gt {Newline Indent} if
- } ifelse
- }{pop} ifelse
- } def
- %
- % Executable names are passed to operatortype. Non-executable names get a
- % leading /.
- %
- /nametype {
- dup xcheck {
- operatortype
- }{
- (/) Print Print ( ) Print
- } ifelse
- } def
- %
- % Arrays are processed in two passes. The first computes the length of the
- % string returned to the host without any special formatting. If it extends
- % past the last column special formatting is enabled by setting a flag in
- % array multiline. Arrays are processed in a for loop so the last element
- % easily recognized. At that point special fortmatting is disabled.
- %
- /packedarraytype {arraytype} def
- /arraytype {
- NextLevel
- lengthonly not {
- /lengthonly true def
- /arraylength 0 def
- dup dup type exec
- arraylength 20 gt arraylength column add lastcolumn gt and {
- multiline level 1 put
- } if
- /lengthonly false def
- } if
- dup rcheck not {
- (-array- ) Print pop
- }{
- dup xcheck {({)}{([)} ifelse Print
- multiline level get 0 ne {Newline Indent}{( ) Print} ifelse
- 0 1 2 index length 1 sub {
- 2 copy exch length 1 sub eq multiline level get 1 eq and {
- multiline level 2 put
- } if
- 2 copy get exch pop
- dup type /dicttype eq {
- Replace
- dup type /dicttype eq {
- dup Register Replace
- recursive {
- 2 copy cvlit
- /def load 3 1 roll
- count 3 roll
- } if
- exch pop
- } if
- } if
- dup type exec
- dup xcheck not multiline level get 1 eq and {
- 0 index type /arraytype eq
- 1 index type /packedarray eq or
- 1 index type /stringtype eq or {Newline Indent} if
- } if
- } for
- multiline level get 0 ne {Newline LastLevel Indent NextLevel} if
- xcheck {(} )}{(] )} ifelse Print
- } ifelse
- LastLevel
- } def
- %
- % Dictionary handler. Try to replace the value by a name before processing
- % the dictionary.
- %
- /dicttype {
- dup
- rcheck not {
- (-dictionary- ) Print pop
- }{
- dup maxlength Print ( dict dup begin) Print Newline
- NextLevel
- {
- 1 index OmitNames exch known {
- pop pop
- }{
- Indent
- Replace % arrays and dicts by known names
- Register % new dictionaries in OtherDicts
- exch
- cvlit dup type exec % key first - force a /
- dup type exec % then the value
- (def) Print Newline
- } ifelse
- } forall
- LastLevel
- Indent
- (end ) Print
- } ifelse
- } def
- %
- % Strings containing characters not in AsciiDict are returned in hex. All
- % others are ASCII strings and use AsciiDict for character mapping.
- %
- /onecharstring ( ) def
- /twocharstring ( ) def
- /stringtype {
- dup
- rcheck not {
- (-string- ) Print
- }{
- /hexit false def
- dup {
- onecharstring 0 3 -1 roll put
- AsciiDict onecharstring cvn known not {
- /hexit true def exit
- } if
- } forall
- hexit {(<)}{(\()} ifelse Print
- 0 1 2 index length 1 sub {
- 2 copy 1 getinterval exch pop
- hexit {
- 0 get /n exch def
- n -4 bitshift 16#F and 16 twocharstring cvrs pop
- n 16#F and twocharstring 1 1 getinterval 16 exch cvrs pop
- twocharstring
- }{cvn AsciiDict exch get} ifelse
- Print
- column lastcolumn gt {
- hexit not {(\\) Print} if
- Newline
- } if
- } for
- hexit {(> )}{(\) )} ifelse Print
- } ifelse
- pop
- } def
- %
- % ASCII characters and replacement strings. Ensures the returned string will
- % reproduce the original when passed through the scanner. Strings containing
- % characters not in this list should be returned as hex strings.
- %
- /AsciiDict 128 dict dup begin
- (\n) cvn (\\n) def
- (\r) cvn (\\r) def
- (\t) cvn (\\t) def
- (\b) cvn (\\b) def
- (\f) cvn (\\f) def
- ( ) cvn ( ) def
- (!) cvn (!) def
- (") cvn (") def
- (#) cvn (#) def
- ($) cvn ($) def
- (%) cvn (\\%) def
- (&) cvn (&) def
- (') cvn (') def
- (\() cvn (\\\() def
- (\)) cvn (\\\)) def
- (*) cvn (*) def
- (+) cvn (+) def
- (,) cvn (,) def
- (-) cvn (-) def
- (.) cvn (.) def
- (/) cvn (/) def
- (0) cvn (0) def
- (1) cvn (1) def
- (2) cvn (2) def
- (3) cvn (3) def
- (4) cvn (4) def
- (5) cvn (5) def
- (6) cvn (6) def
- (7) cvn (7) def
- (8) cvn (8) def
- (9) cvn (9) def
- (:) cvn (:) def
- (;) cvn (;) def
- (<) cvn (<) def
- (=) cvn (=) def
- (>) cvn (>) def
- (?) cvn (?) def
- (@) cvn (@) def
- (A) cvn (A) def
- (B) cvn (B) def
- (C) cvn (C) def
- (D) cvn (D) def
- (E) cvn (E) def
- (F) cvn (F) def
- (G) cvn (G) def
- (H) cvn (H) def
- (I) cvn (I) def
- (J) cvn (J) def
- (K) cvn (K) def
- (L) cvn (L) def
- (M) cvn (M) def
- (N) cvn (N) def
- (O) cvn (O) def
- (P) cvn (P) def
- (Q) cvn (Q) def
- (R) cvn (R) def
- (S) cvn (S) def
- (T) cvn (T) def
- (U) cvn (U) def
- (V) cvn (V) def
- (W) cvn (W) def
- (X) cvn (X) def
- (Y) cvn (Y) def
- (Z) cvn (Z) def
- ([) cvn ([) def
- (\\) cvn (\\\\) def
- (]) cvn (]) def
- (^) cvn (^) def
- (_) cvn (_) def
- (`) cvn (`) def
- (a) cvn (a) def
- (b) cvn (b) def
- (c) cvn (c) def
- (d) cvn (d) def
- (e) cvn (e) def
- (f) cvn (f) def
- (g) cvn (g) def
- (h) cvn (h) def
- (i) cvn (i) def
- (j) cvn (j) def
- (k) cvn (k) def
- (l) cvn (l) def
- (m) cvn (m) def
- (n) cvn (n) def
- (o) cvn (o) def
- (p) cvn (p) def
- (q) cvn (q) def
- (r) cvn (r) def
- (s) cvn (s) def
- (t) cvn (t) def
- (u) cvn (u) def
- (v) cvn (v) def
- (w) cvn (w) def
- (x) cvn (x) def
- (y) cvn (y) def
- (z) cvn (z) def
- ({) cvn ({) def
- (|) cvn (|) def
- (}) cvn (}) def
- (~) cvn (~) def
- end def
- %
- % OperatorDict can help format procedure listings. The value assigned to each
- % name is used as an index into the OperatorProcs array. The procedure at that
- % index is fetched and executed after the named operator is printed. What's in
- % OperatorDict is a matter of taste rather than correctness. The default list
- % represents our choice of which of Adobe's operators should end a line.
- %
- /OperatorProcs [{} {Newline Indent}] def
- /OperatorDict 250 dict def
- OperatorDict /arc 1 put
- OperatorDict /arcn 1 put
- OperatorDict /ashow 1 put
- OperatorDict /awidthshow 1 put
- OperatorDict /banddevice 1 put
- OperatorDict /begin 1 put
- OperatorDict /charpath 1 put
- OperatorDict /clear 1 put
- OperatorDict /cleardictstack 1 put
- OperatorDict /cleartomark 1 put
- OperatorDict /clip 1 put
- OperatorDict /clippath 1 put
- OperatorDict /closefile 1 put
- OperatorDict /closepath 1 put
- OperatorDict /concat 1 put
- OperatorDict /copypage 1 put
- OperatorDict /curveto 1 put
- OperatorDict /def 1 put
- OperatorDict /end 1 put
- OperatorDict /eoclip 1 put
- OperatorDict /eofill 1 put
- OperatorDict /erasepage 1 put
- OperatorDict /exec 1 put
- OperatorDict /exit 1 put
- OperatorDict /fill 1 put
- OperatorDict /flattenpath 1 put
- OperatorDict /flush 1 put
- OperatorDict /flushfile 1 put
- OperatorDict /for 1 put
- OperatorDict /forall 1 put
- OperatorDict /framedevice 1 put
- OperatorDict /grestore 1 put
- OperatorDict /grestoreall 1 put
- OperatorDict /gsave 1 put
- OperatorDict /handleerror 1 put
- OperatorDict /if 1 put
- OperatorDict /ifelse 1 put
- OperatorDict /image 1 put
- OperatorDict /imagemask 1 put
- OperatorDict /initclip 1 put
- OperatorDict /initgraphics 1 put
- OperatorDict /initmatrix 1 put
- OperatorDict /kshow 1 put
- OperatorDict /lineto 1 put
- OperatorDict /loop 1 put
- OperatorDict /moveto 1 put
- OperatorDict /newpath 1 put
- OperatorDict /nulldevice 1 put
- OperatorDict /pathforall 1 put
- OperatorDict /print 1 put
- OperatorDict /prompt 1 put
- OperatorDict /put 1 put
- OperatorDict /putinterval 1 put
- OperatorDict /quit 1 put
- OperatorDict /rcurveto 1 put
- OperatorDict /renderbands 1 put
- OperatorDict /repeat 1 put
- OperatorDict /resetfile 1 put
- OperatorDict /restore 1 put
- OperatorDict /reversepath 1 put
- OperatorDict /rlineto 1 put
- OperatorDict /rmoveto 1 put
- OperatorDict /rotate 1 put
- OperatorDict /run 1 put
- OperatorDict /scale 1 put
- OperatorDict /setcachedevice 1 put
- OperatorDict /setcachelimit 1 put
- OperatorDict /setcacheparams 1 put
- OperatorDict /setcharwidth 1 put
- OperatorDict /setdash 1 put
- OperatorDict /setdefaulttimeouts 1 put
- OperatorDict /setdostartpage 1 put
- OperatorDict /seteescratch 1 put
- OperatorDict /setflat 1 put
- OperatorDict /setfont 1 put
- OperatorDict /setgray 1 put
- OperatorDict /sethsbcolor 1 put
- OperatorDict /setidlefonts 1 put
- OperatorDict /setjobtimeout 1 put
- OperatorDict /setlinecap 1 put
- OperatorDict /setlinejoin 1 put
- OperatorDict /setlinewidth 1 put
- OperatorDict /setmargins 1 put
- OperatorDict /setmatrix 1 put
- OperatorDict /setmiterlimit 1 put
- OperatorDict /setpacking 1 put
- OperatorDict /setpagetype 1 put
- OperatorDict /setprintname 1 put
- OperatorDict /setrgbcolor 1 put
- OperatorDict /setsccbatch 1 put
- OperatorDict /setsccinteractive 1 put
- OperatorDict /setscreen 1 put
- OperatorDict /settransfer 1 put
- OperatorDict /show 1 put
- OperatorDict /showpage 1 put
- OperatorDict /start 1 put
- OperatorDict /stop 1 put
- OperatorDict /store 1 put
- OperatorDict /stroke 1 put
- OperatorDict /strokepath 1 put
- OperatorDict /translate 1 put
- OperatorDict /widthshow 1 put
- OperatorDict /write 1 put
- OperatorDict /writehexstring 1 put
- OperatorDict /writestring 1 put
- end def
- %
- % Put an object on the stack and call Grabit. Output continues until stack
- % is empty. For example,
- %
- % /letter load Grabit
- %
- % prints a listing of the letter procedure.
- %
- /Grabit {
- /saveobj save def
- GrabitDict begin
- {
- count 0 eq {exit} if
- count {dup type exec} repeat
- (\n) print flush
- } loop
- end
- currentpoint % for hardcopy output
- saveobj restore
- moveto
- } def
|