|
|
1.1 ! root 1: % ! 2: % Dump a PostScript object, occasionally in a form that can be sent back ! 3: % through the interpreter. Similiar to Adobe's == procedure, but output ! 4: % is usually easier to read. No binding so operators like rcheck and exec ! 5: % can be conviently redefined. ! 6: % ! 7: ! 8: /GrabitDict 100 dict dup begin ! 9: ! 10: /recursive true def ! 11: /scratchstring 200 string def ! 12: /slowdown 100 def ! 13: ! 14: /column 0 def ! 15: /lastcolumn 80 def ! 16: /level 0 def ! 17: /multiline 100 array def ! 18: /nextname 0 def ! 19: /arraylength 0 def ! 20: /lengthonly false def ! 21: ! 22: /GrabitSetup { ! 23: counttomark {OmitNames exch true put} repeat pop ! 24: 0 0 moveto % for hardcopy output ! 25: } def ! 26: ! 27: /OmitNames 30 dict def % ignore these names ! 28: /OtherDicts 200 dict def % unrecognized dictionaries ! 29: ! 30: % ! 31: % All strings returned to the host go through Print. First pass through an ! 32: % array has lengthonly set to true. ! 33: % ! 34: ! 35: /Print { ! 36: dup type /stringtype ne {scratchstring cvs} if ! 37: lengthonly { ! 38: length arraylength add /arraylength exch def ! 39: }{ ! 40: dup length column add /column exch def ! 41: print flush ! 42: slowdown {1 pop} repeat ! 43: } ifelse ! 44: } def ! 45: ! 46: /Indent {level {( ) Print} repeat} def ! 47: /Newline {(\n) Print lengthonly not {/column 0 def} if} def ! 48: ! 49: /NextLevel {/level level 1 add def multiline level 0 put} def ! 50: /LastLevel {/level level 1 sub def} def ! 51: ! 52: % ! 53: % Make a unique name for each unrecognized dictionary and remember the name ! 54: % and dictionary in OtherDicts. ! 55: % ! 56: ! 57: /Register { ! 58: dup type /dicttype eq { ! 59: /nextname nextname 1 add def ! 60: dup (UnknownDict ) dup ! 61: (UnknownDict) length nextname ( ) cvs putinterval ! 62: 0 (UnknownDict) length nextname ( ) cvs length add getinterval cvn ! 63: exch OtherDicts 3 1 roll put ! 64: } if ! 65: } def ! 66: ! 67: % ! 68: % Replace array or dictionary values by known names. Lookups are in the ! 69: % standard PostScript dictionaries and in OtherDicts. If found replace ! 70: % the value by the name and make it executable so nametype omits the ! 71: % leading /. ! 72: % ! 73: ! 74: /Replace { ! 75: false ! 76: 1 index type /dicttype eq {pop true} if ! 77: 1 index type /arraytype eq 2 index xcheck not and {pop true} if ! 78: { ! 79: false ! 80: [userdict systemdict statusdict serverdict OtherDicts] { ! 81: { ! 82: 3 index eq ! 83: {exch pop exch pop cvx true exit} ! 84: {pop} ! 85: ifelse ! 86: } forall ! 87: dup {exit} if ! 88: } forall ! 89: pop ! 90: } if ! 91: } def ! 92: ! 93: % ! 94: % Simple type handlers. In some cases (e.g. savetype) what's returned can't ! 95: % be sent back through the interpreter. ! 96: % ! 97: ! 98: /booleantype {{(true )}{(false )} ifelse Print} def ! 99: /marktype {pop (mark ) Print} def ! 100: /nulltype {pop (null ) Print} def ! 101: /integertype {Print ( ) Print} def ! 102: /realtype {Print ( ) Print} def ! 103: /filetype {pop (-file- ) Print} def ! 104: /fonttype {pop (-fontID- ) Print} def ! 105: /savetype {pop (-saveobj- ) Print} def ! 106: ! 107: % ! 108: % Special formatting for operators is enabled if the flag in multiline ! 109: % (for the current level) is set to 1. In that case each operator, after ! 110: % being printed, is looked up in OperatorDict. If found the value is used ! 111: % as an index into the OperatorProcs array and the object at that index ! 112: % is retrieved and executed. Currently only used to choose the operators ! 113: % that end a line. ! 114: % ! 115: ! 116: /operatortype { ! 117: dup Print ( ) Print ! 118: multiline level get 1 eq { ! 119: scratchstring cvs cvn dup OperatorDict exch known { ! 120: OperatorDict exch get ! 121: OperatorProcs exch get exec ! 122: }{ ! 123: pop ! 124: column lastcolumn gt {Newline Indent} if ! 125: } ifelse ! 126: }{pop} ifelse ! 127: } def ! 128: ! 129: % ! 130: % Executable names are passed to operatortype. Non-executable names get a ! 131: % leading /. ! 132: % ! 133: ! 134: /nametype { ! 135: dup xcheck { ! 136: operatortype ! 137: }{ ! 138: (/) Print Print ( ) Print ! 139: } ifelse ! 140: } def ! 141: ! 142: % ! 143: % Arrays are processed in two passes. The first computes the length of the ! 144: % string returned to the host without any special formatting. If it extends ! 145: % past the last column special formatting is enabled by setting a flag in ! 146: % array multiline. Arrays are processed in a for loop so the last element ! 147: % easily recognized. At that point special fortmatting is disabled. ! 148: % ! 149: ! 150: /packedarraytype {arraytype} def ! 151: ! 152: /arraytype { ! 153: NextLevel ! 154: lengthonly not { ! 155: /lengthonly true def ! 156: /arraylength 0 def ! 157: dup dup type exec ! 158: arraylength 20 gt arraylength column add lastcolumn gt and { ! 159: multiline level 1 put ! 160: } if ! 161: /lengthonly false def ! 162: } if ! 163: ! 164: dup rcheck not { ! 165: (-array- ) Print pop ! 166: }{ ! 167: dup xcheck {({)}{([)} ifelse Print ! 168: multiline level get 0 ne {Newline Indent}{( ) Print} ifelse ! 169: 0 1 2 index length 1 sub { ! 170: 2 copy exch length 1 sub eq multiline level get 1 eq and { ! 171: multiline level 2 put ! 172: } if ! 173: 2 copy get exch pop ! 174: dup type /dicttype eq { ! 175: Replace ! 176: dup type /dicttype eq { ! 177: dup Register Replace ! 178: recursive { ! 179: 2 copy cvlit ! 180: /def load 3 1 roll ! 181: count 3 roll ! 182: } if ! 183: exch pop ! 184: } if ! 185: } if ! 186: dup type exec ! 187: dup xcheck not multiline level get 1 eq and { ! 188: 0 index type /arraytype eq ! 189: 1 index type /packedarray eq or ! 190: 1 index type /stringtype eq or {Newline Indent} if ! 191: } if ! 192: } for ! 193: multiline level get 0 ne {Newline LastLevel Indent NextLevel} if ! 194: xcheck {(} )}{(] )} ifelse Print ! 195: } ifelse ! 196: LastLevel ! 197: } def ! 198: ! 199: % ! 200: % Dictionary handler. Try to replace the value by a name before processing ! 201: % the dictionary. ! 202: % ! 203: ! 204: /dicttype { ! 205: dup ! 206: rcheck not { ! 207: (-dictionary- ) Print pop ! 208: }{ ! 209: dup maxlength Print ( dict dup begin) Print Newline ! 210: NextLevel ! 211: { ! 212: 1 index OmitNames exch known { ! 213: pop pop ! 214: }{ ! 215: Indent ! 216: Replace % arrays and dicts by known names ! 217: Register % new dictionaries in OtherDicts ! 218: exch ! 219: cvlit dup type exec % key first - force a / ! 220: dup type exec % then the value ! 221: (def) Print Newline ! 222: } ifelse ! 223: } forall ! 224: LastLevel ! 225: Indent ! 226: (end ) Print ! 227: } ifelse ! 228: } def ! 229: ! 230: % ! 231: % Strings containing characters not in AsciiDict are returned in hex. All ! 232: % others are ASCII strings and use AsciiDict for character mapping. ! 233: % ! 234: ! 235: /onecharstring ( ) def ! 236: /twocharstring ( ) def ! 237: ! 238: /stringtype { ! 239: dup ! 240: rcheck not { ! 241: (-string- ) Print ! 242: }{ ! 243: /hexit false def ! 244: dup { ! 245: onecharstring 0 3 -1 roll put ! 246: AsciiDict onecharstring cvn known not { ! 247: /hexit true def exit ! 248: } if ! 249: } forall ! 250: ! 251: hexit {(<)}{(\()} ifelse Print ! 252: 0 1 2 index length 1 sub { ! 253: 2 copy 1 getinterval exch pop ! 254: hexit { ! 255: 0 get /n exch def ! 256: n -4 bitshift 16#F and 16 twocharstring cvrs pop ! 257: n 16#F and twocharstring 1 1 getinterval 16 exch cvrs pop ! 258: twocharstring ! 259: }{cvn AsciiDict exch get} ifelse ! 260: Print ! 261: column lastcolumn gt { ! 262: hexit not {(\\) Print} if ! 263: Newline ! 264: } if ! 265: } for ! 266: hexit {(> )}{(\) )} ifelse Print ! 267: } ifelse ! 268: pop ! 269: } def ! 270: ! 271: % ! 272: % ASCII characters and replacement strings. Ensures the returned string will ! 273: % reproduce the original when passed through the scanner. Strings containing ! 274: % characters not in this list should be returned as hex strings. ! 275: % ! 276: ! 277: /AsciiDict 128 dict dup begin ! 278: (\n) cvn (\\n) def ! 279: (\r) cvn (\\r) def ! 280: (\t) cvn (\\t) def ! 281: (\b) cvn (\\b) def ! 282: (\f) cvn (\\f) def ! 283: ( ) cvn ( ) def ! 284: (!) cvn (!) def ! 285: (") cvn (") def ! 286: (#) cvn (#) def ! 287: ($) cvn ($) def ! 288: (%) cvn (\\%) def ! 289: (&) cvn (&) def ! 290: (') cvn (') def ! 291: (\() cvn (\\\() def ! 292: (\)) cvn (\\\)) def ! 293: (*) cvn (*) def ! 294: (+) cvn (+) def ! 295: (,) cvn (,) def ! 296: (-) cvn (-) def ! 297: (.) cvn (.) def ! 298: (/) cvn (/) def ! 299: (0) cvn (0) def ! 300: (1) cvn (1) def ! 301: (2) cvn (2) def ! 302: (3) cvn (3) def ! 303: (4) cvn (4) def ! 304: (5) cvn (5) def ! 305: (6) cvn (6) def ! 306: (7) cvn (7) def ! 307: (8) cvn (8) def ! 308: (9) cvn (9) def ! 309: (:) cvn (:) def ! 310: (;) cvn (;) def ! 311: (<) cvn (<) def ! 312: (=) cvn (=) def ! 313: (>) cvn (>) def ! 314: (?) cvn (?) def ! 315: (@) cvn (@) def ! 316: (A) cvn (A) def ! 317: (B) cvn (B) def ! 318: (C) cvn (C) def ! 319: (D) cvn (D) def ! 320: (E) cvn (E) def ! 321: (F) cvn (F) def ! 322: (G) cvn (G) def ! 323: (H) cvn (H) def ! 324: (I) cvn (I) def ! 325: (J) cvn (J) def ! 326: (K) cvn (K) def ! 327: (L) cvn (L) def ! 328: (M) cvn (M) def ! 329: (N) cvn (N) def ! 330: (O) cvn (O) def ! 331: (P) cvn (P) def ! 332: (Q) cvn (Q) def ! 333: (R) cvn (R) def ! 334: (S) cvn (S) def ! 335: (T) cvn (T) def ! 336: (U) cvn (U) def ! 337: (V) cvn (V) def ! 338: (W) cvn (W) def ! 339: (X) cvn (X) def ! 340: (Y) cvn (Y) def ! 341: (Z) cvn (Z) def ! 342: ([) cvn ([) def ! 343: (\\) cvn (\\\\) def ! 344: (]) cvn (]) def ! 345: (^) cvn (^) def ! 346: (_) cvn (_) def ! 347: (`) cvn (`) def ! 348: (a) cvn (a) def ! 349: (b) cvn (b) def ! 350: (c) cvn (c) def ! 351: (d) cvn (d) def ! 352: (e) cvn (e) def ! 353: (f) cvn (f) def ! 354: (g) cvn (g) def ! 355: (h) cvn (h) def ! 356: (i) cvn (i) def ! 357: (j) cvn (j) def ! 358: (k) cvn (k) def ! 359: (l) cvn (l) def ! 360: (m) cvn (m) def ! 361: (n) cvn (n) def ! 362: (o) cvn (o) def ! 363: (p) cvn (p) def ! 364: (q) cvn (q) def ! 365: (r) cvn (r) def ! 366: (s) cvn (s) def ! 367: (t) cvn (t) def ! 368: (u) cvn (u) def ! 369: (v) cvn (v) def ! 370: (w) cvn (w) def ! 371: (x) cvn (x) def ! 372: (y) cvn (y) def ! 373: (z) cvn (z) def ! 374: ({) cvn ({) def ! 375: (|) cvn (|) def ! 376: (}) cvn (}) def ! 377: (~) cvn (~) def ! 378: end def ! 379: ! 380: % ! 381: % OperatorDict can help format procedure listings. The value assigned to each ! 382: % name is used as an index into the OperatorProcs array. The procedure at that ! 383: % index is fetched and executed after the named operator is printed. What's in ! 384: % OperatorDict is a matter of taste rather than correctness. The default list ! 385: % represents our choice of which of Adobe's operators should end a line. ! 386: % ! 387: ! 388: /OperatorProcs [{} {Newline Indent}] def ! 389: ! 390: /OperatorDict 250 dict def ! 391: ! 392: OperatorDict /arc 1 put ! 393: OperatorDict /arcn 1 put ! 394: OperatorDict /ashow 1 put ! 395: OperatorDict /awidthshow 1 put ! 396: OperatorDict /banddevice 1 put ! 397: OperatorDict /begin 1 put ! 398: OperatorDict /charpath 1 put ! 399: OperatorDict /clear 1 put ! 400: OperatorDict /cleardictstack 1 put ! 401: OperatorDict /cleartomark 1 put ! 402: OperatorDict /clip 1 put ! 403: OperatorDict /clippath 1 put ! 404: OperatorDict /closefile 1 put ! 405: OperatorDict /closepath 1 put ! 406: OperatorDict /concat 1 put ! 407: OperatorDict /copypage 1 put ! 408: OperatorDict /curveto 1 put ! 409: OperatorDict /def 1 put ! 410: OperatorDict /end 1 put ! 411: OperatorDict /eoclip 1 put ! 412: OperatorDict /eofill 1 put ! 413: OperatorDict /erasepage 1 put ! 414: OperatorDict /exec 1 put ! 415: OperatorDict /exit 1 put ! 416: OperatorDict /fill 1 put ! 417: OperatorDict /flattenpath 1 put ! 418: OperatorDict /flush 1 put ! 419: OperatorDict /flushfile 1 put ! 420: OperatorDict /for 1 put ! 421: OperatorDict /forall 1 put ! 422: OperatorDict /framedevice 1 put ! 423: OperatorDict /grestore 1 put ! 424: OperatorDict /grestoreall 1 put ! 425: OperatorDict /gsave 1 put ! 426: OperatorDict /handleerror 1 put ! 427: OperatorDict /if 1 put ! 428: OperatorDict /ifelse 1 put ! 429: OperatorDict /image 1 put ! 430: OperatorDict /imagemask 1 put ! 431: OperatorDict /initclip 1 put ! 432: OperatorDict /initgraphics 1 put ! 433: OperatorDict /initmatrix 1 put ! 434: OperatorDict /kshow 1 put ! 435: OperatorDict /lineto 1 put ! 436: OperatorDict /loop 1 put ! 437: OperatorDict /moveto 1 put ! 438: OperatorDict /newpath 1 put ! 439: OperatorDict /nulldevice 1 put ! 440: OperatorDict /pathforall 1 put ! 441: OperatorDict /print 1 put ! 442: OperatorDict /prompt 1 put ! 443: OperatorDict /put 1 put ! 444: OperatorDict /putinterval 1 put ! 445: OperatorDict /quit 1 put ! 446: OperatorDict /rcurveto 1 put ! 447: OperatorDict /renderbands 1 put ! 448: OperatorDict /repeat 1 put ! 449: OperatorDict /resetfile 1 put ! 450: OperatorDict /restore 1 put ! 451: OperatorDict /reversepath 1 put ! 452: OperatorDict /rlineto 1 put ! 453: OperatorDict /rmoveto 1 put ! 454: OperatorDict /rotate 1 put ! 455: OperatorDict /run 1 put ! 456: OperatorDict /scale 1 put ! 457: OperatorDict /setcachedevice 1 put ! 458: OperatorDict /setcachelimit 1 put ! 459: OperatorDict /setcacheparams 1 put ! 460: OperatorDict /setcharwidth 1 put ! 461: OperatorDict /setdash 1 put ! 462: OperatorDict /setdefaulttimeouts 1 put ! 463: OperatorDict /setdostartpage 1 put ! 464: OperatorDict /seteescratch 1 put ! 465: OperatorDict /setflat 1 put ! 466: OperatorDict /setfont 1 put ! 467: OperatorDict /setgray 1 put ! 468: OperatorDict /sethsbcolor 1 put ! 469: OperatorDict /setidlefonts 1 put ! 470: OperatorDict /setjobtimeout 1 put ! 471: OperatorDict /setlinecap 1 put ! 472: OperatorDict /setlinejoin 1 put ! 473: OperatorDict /setlinewidth 1 put ! 474: OperatorDict /setmargins 1 put ! 475: OperatorDict /setmatrix 1 put ! 476: OperatorDict /setmiterlimit 1 put ! 477: OperatorDict /setpacking 1 put ! 478: OperatorDict /setpagetype 1 put ! 479: OperatorDict /setprintname 1 put ! 480: OperatorDict /setrgbcolor 1 put ! 481: OperatorDict /setsccbatch 1 put ! 482: OperatorDict /setsccinteractive 1 put ! 483: OperatorDict /setscreen 1 put ! 484: OperatorDict /settransfer 1 put ! 485: OperatorDict /show 1 put ! 486: OperatorDict /showpage 1 put ! 487: OperatorDict /start 1 put ! 488: OperatorDict /stop 1 put ! 489: OperatorDict /store 1 put ! 490: OperatorDict /stroke 1 put ! 491: OperatorDict /strokepath 1 put ! 492: OperatorDict /translate 1 put ! 493: OperatorDict /widthshow 1 put ! 494: OperatorDict /write 1 put ! 495: OperatorDict /writehexstring 1 put ! 496: OperatorDict /writestring 1 put ! 497: ! 498: end def ! 499: ! 500: % ! 501: % Put an object on the stack and call Grabit. Output continues until stack ! 502: % is empty. For example, ! 503: % ! 504: % /letter load Grabit ! 505: % ! 506: % prints a listing of the letter procedure. ! 507: % ! 508: ! 509: /Grabit { ! 510: /saveobj save def ! 511: GrabitDict begin ! 512: { ! 513: count 0 eq {exit} if ! 514: count {dup type exec} repeat ! 515: (\n) print flush ! 516: } loop ! 517: end ! 518: currentpoint % for hardcopy output ! 519: saveobj restore ! 520: moveto ! 521: } def ! 522:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.