home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / dvips583.zip / contrib.zip / dvips / contrib / bbfig / bb.ps next >
Text File  |  1998-11-03  |  12KB  |  580 lines

  1. %!
  2. % bb.ps --
  3. %
  4. % Prints a file, but keeps track of bounding box info, and prints the box at
  5. % the end (around the figure.)
  6. %
  7. % $Header: bb.ps,v 1.14 91/03/21 13:04:02 cosell Exp $
  8. % RCS log info at end
  9.  
  10. 50 dict /$BoundingBox exch def
  11.  
  12. $BoundingBox begin
  13.  
  14. /xdef {
  15.     exch def
  16. } def
  17.  
  18. /xstore {
  19.     exch store
  20. } def
  21.  
  22. /addcoords {
  23.     exch
  24.     4 -1 roll add
  25.     3 1 roll add
  26. } def
  27.  
  28. %
  29. % Stubs of old functions.
  30. %
  31.  
  32. /-stroke /stroke load def
  33. /-fill /fill load def
  34. /-eofill /eofill load def
  35. /-image /image load def
  36. /-show /show load def
  37. /-awidthshow /awidthshow load def
  38. /-showpage /showpage load def
  39. /-restore  /restore load def
  40. /-imagemask /imagemask load def
  41.  
  42. end % $BoundingBox
  43.  
  44. %
  45. % New Functions.   --- These go into the user dict to intercept the calls
  46. %
  47.  
  48. /stroke {
  49.         $BoundingBox begin
  50.     gsave
  51.     initmatrix
  52.     (stroke called\n) traceprint %%DEBUG
  53.     {
  54.          strokepath    % Make sure to take line width into account.
  55.         0 setlinejoin
  56.         flattenpath
  57.     } stopped {        % strokepath often hits a limitcheck.
  58.         (Can't set up a strokepath\n) traceprint % DEBUG
  59.         grestore    % Restore the original path
  60.         gsave
  61.     } if
  62.     includepath            % Accumulate it into our box.
  63.     grestore
  64.  
  65.     -stroke
  66.     end % $BoundingBox
  67. } def
  68.  
  69. /fill {
  70.         $BoundingBox begin
  71.     gsave
  72.     (fill called\n) traceprint %%DEBUG
  73.     includepath
  74.     grestore
  75.  
  76.     -fill
  77.     end % $BoundingBox
  78. } def
  79.  
  80. /eofill {
  81.         $BoundingBox begin
  82.     gsave
  83.     (eofill called\n) traceprint %%DEBUG
  84.     includepath
  85.     grestore
  86.  
  87.     -eofill
  88.     end % $BoundingBox
  89. } def
  90.  
  91. %
  92. % Text is implemented by reducing everything to an `awidthshow'.
  93. %
  94.  
  95. /show {
  96.         $BoundingBox begin
  97.     (show called\n) traceprint %%DEBUG
  98.     0 0 0 0 0        % Extra parameters for awidthshow
  99.     6 -1 roll        % Bring the string back up
  100.     awidthshow
  101.     end % $BoundingBox
  102. } def
  103.  
  104. /widthshow {
  105.         $BoundingBox begin
  106.         (widthshow called\n) traceprint %%DEBUG
  107.     0 0            % Extra parameters for awidthshow
  108.     3 -1 roll        % Bring the string back up.
  109.     awidthshow
  110.     end % $BoundingBox
  111. } def
  112.  
  113. /ashow {
  114.         $BoundingBox begin
  115.         (ashow called\n) traceprint %%DEBUG
  116.     0 0 0
  117.     6 3 roll
  118.     awidthshow
  119.     end % $BoundingBox
  120. } def
  121.  
  122.  
  123. % This does all of the work of the text-rendering operators
  124. %   What it does, is compute, basically brute force, what 'charpath'
  125. %   would have given us virtually for free, if 'show' were the only
  126. %   operator that we needed to do.
  127.  
  128. /awidthshow {
  129.     $BoundingBox begin
  130.     gsave
  131.     6 (awidthshow:) debug %%DEBUG
  132.     currentpoint
  133.     2 copy /@starty xdef /@startx xdef
  134.     2 index stringwidth    % Get the natural length of the string
  135.     addcoords            % Add to the start to get the end.
  136.  
  137.     2 index length        % How many characters?
  138.  
  139.     dup            % Add the offsets to each character
  140.     6 index mul
  141.     exch 5 index mul
  142.     addcoords
  143.  
  144.     5 index 3 index
  145.     chcount        % How many padding characters?
  146.  
  147.     dup            % Add the offsets for each pad.
  148.     9 index mul
  149.     exch 8 index mul
  150.     addcoords
  151.  
  152.     /@endy xdef /@endx xdef
  153.  
  154.     % We now have the left and right edges (in user coords)
  155.     % of the text.  Now we need only correct for the vertical
  156.     % displacements needed for the font and we can get the
  157.     % top and bottom edges of the enclosing box
  158.  
  159.     fontheight        % Get the height and depth of the current font.
  160.  
  161.     @startx @starty addcoords
  162.     /@starty xdef /@startx xdef
  163.     @endx @endy addcoords
  164.     /@endy xdef /@endx xdef
  165.     newpath
  166.     @startx @starty moveto
  167.     @endx @starty lineto
  168.     @endx @endy lineto
  169.     @startx @endy lineto
  170.     closepath
  171.         includepath
  172.     grestore
  173.  
  174.     -awidthshow
  175.     end % $BoundingBox
  176. } def
  177.  
  178. %
  179. % `image':
  180. %
  181. % Assume here that the image lands in the unit square.
  182. %
  183.  
  184. /image {
  185.         $BoundingBox begin
  186.         (image called\n) traceprint %%DEBUG
  187.     gsave
  188.     newpath
  189.     0 0 moveto
  190.     1 0 rlineto
  191.     1 1 rlineto
  192.     -1 0 rlineto
  193.     closepath
  194.     includepath
  195.     grestore
  196.  
  197.     -image
  198.     end % $BoundingBox
  199. } def
  200.  
  201. /imagemask
  202. {
  203.     $BoundingBox begin
  204.     (imagemask called\n) traceprint %%DEBUG
  205.     gsave
  206.     newpath
  207.     0 0 moveto
  208.     1 0 rlineto
  209.     1 1 rlineto
  210.     -1 0 rlineto
  211.     closepath
  212.     includepath
  213.     grestore
  214.  
  215.     -imagemask
  216.     end % $BoundingBox
  217. } def
  218.  
  219. % Just define this one out of existence
  220. /framedevice { pop pop pop pop } def
  221.  
  222. % Handle restoring VM --- this is all OK, except that we have to
  223. % hang onto the bb info we collected while in the about-to-be-discarded
  224. % environment
  225.  
  226. /restore
  227. {
  228.     $BoundingBox begin
  229.     (restore called\n) traceprint %%DEBUG
  230.     tracedump  %% HACK, but the only way I see right now to get this stuff!
  231.     bbox-llx bbox-lly bbox-urx bbox-ury
  232.     5 -1 roll
  233.     -restore
  234.     /bbox-ury xstore /bbox-urx xstore
  235.     /bbox-lly xstore /bbox-llx xstore
  236.     end % $BoundingBox
  237. } def
  238.  
  239.  
  240. %
  241. % `showpage':
  242. %
  243. % Just draw the box around the figure and print the page, and then initialize
  244. % the bounding box variables again.
  245. %
  246.  
  247. $BoundingBox begin
  248. /temp-string 10 string def
  249. end % $BoundingBox
  250.  
  251. /showpage {
  252.     $BoundingBox begin
  253.     initgraphics
  254.  
  255.         (showpage\n) traceprint % DEBUG
  256.     dump-bbox  % DEBUG
  257.  
  258.         /bbox-llx round_down
  259.     /bbox-lly round_down
  260.     /bbox-ury round_up
  261.     /bbox-urx round_up
  262.  
  263.     bbox-llx bbox-lly moveto        % Make the box
  264.     bbox-llx bbox-ury lineto
  265.     bbox-urx bbox-ury lineto
  266.     bbox-urx bbox-lly lineto
  267.     closepath
  268.  
  269.     bwstroke            % Draw the box.
  270.  
  271. % Print the size of the bounding box both above and below the actual box
  272.     0 setgray
  273.     /Courier findfont 10 scalefont setfont
  274.     bbox-llx 36 max bbox-lly 12 sub 36 max moveto
  275.     (%%BoundingBox: ) -show
  276.     bbox-llx temp-string cvs -show ( ) -show
  277.     bbox-lly temp-string cvs -show ( ) -show
  278.     bbox-urx temp-string cvs -show ( ) -show
  279.     bbox-ury temp-string cvs -show
  280.  
  281.     bbox-llx 36 max bbox-ury 12 add 740 min moveto
  282.     (%%BoundingBox: ) -show
  283.     bbox-llx temp-string cvs -show ( ) -show
  284.     bbox-lly temp-string cvs -show ( ) -show
  285.     bbox-urx temp-string cvs -show ( ) -show
  286.     bbox-ury temp-string cvs -show
  287.  
  288.     init
  289.     -showpage
  290.     tracedump        %% DEBUG
  291.     end % $BoundingBox
  292. } def
  293.  
  294. %
  295. % BoundingBox functions:
  296. %
  297. % We accumulate the information about the bounding box into four variables.
  298. % The data is stored in default coordinates.
  299. %
  300.  
  301. $BoundingBox begin
  302.  
  303. /init {
  304.     /bbox-llx 99999 store
  305.     /bbox-lly 99999 store
  306.     /bbox-urx -99999 store
  307.     /bbox-ury -99999 store
  308. } def
  309.  
  310. /bbox-llx 0 def
  311. /bbox-lly 0 def
  312. /bbox-urx 0 def
  313. /bbox-ury 0 def
  314.  
  315. %
  316. % - `includepath' -
  317. %
  318. % Incorporates the bounding box of the path into the bounding box info.
  319. %   ... Gets the bounding box in default coords
  320.  
  321. /includepath {
  322.         (Adding a path: ) traceprint %%DEBUG
  323.     gsave
  324.         initmatrix
  325.     {
  326.         0 setlinejoin
  327.         flattenpath
  328.     } stopped {
  329.         (Couldn't flatten the path\n) traceprint % DEBUG
  330.         grestore
  331.         gsave
  332.         initmatrix
  333.     } if
  334.     { pathbbox } stopped not
  335.     {
  336.             4 2 roll    % Just so we get lower-left first
  337.         2 copy dump-coord %%DEBUG
  338.         dup bbox-lly lt {
  339.             /bbox-lly xstore
  340.         } {
  341.             pop
  342.         } ifelse
  343.         dup bbox-llx lt {
  344.             /bbox-llx xstore
  345.         } {
  346.             pop
  347.         } ifelse
  348.  
  349.         (; ) traceprint 2 copy dump-coord (\n) traceprint %%DEBUG
  350.         dup bbox-ury gt {
  351.             /bbox-ury xstore
  352.         } {
  353.             pop
  354.         } ifelse
  355.         dup bbox-urx gt {
  356.             /bbox-urx xstore
  357.         } {
  358.             pop
  359.         } ifelse
  360.         dump-bbox  %%DEBUG
  361.     } if
  362.     grestore
  363. } def
  364.  
  365. %
  366. % A nice black-and white line drawing function.
  367. %
  368.  
  369. /bwstroke {
  370.     0 setlinewidth            % Thinnest possible lines
  371.     1 setgray            % White first
  372.     [5] 0 setdash            % Only half the line
  373.     gsave -stroke grestore
  374.     0 setgray            % Then black
  375.     [5] 5 setdash            % On the other half
  376.     -stroke
  377. } def
  378.  
  379. %
  380. % Stuff for text.
  381. %
  382.  
  383. %
  384. % char-code string `chcount' occurs
  385. %
  386. % Counts the number of times a character appears in a string.
  387. %
  388.  
  389. /chcount {
  390.     0 exch
  391.     {
  392.         2 index eq {
  393.             1 add
  394.         } if
  395.     } forall
  396.     exch pop
  397. } def
  398.  
  399. %
  400. % - `fontheight' heightx heighty depthx depthy
  401. %
  402. % Returns the offsets to the lowest point and highest point in the current
  403. % font.
  404. %
  405.  
  406. /fontheight {
  407.     currentfont begin
  408.     /FontBBox load aload pop
  409.     exch pop 0 exch
  410.     FontMatrix transform
  411.     4 2 roll
  412.     exch pop 0 exch
  413.     FontMatrix transform
  414.     end
  415. } def
  416.  
  417. % key round_{down|up} -  These will round the value of the given key
  418. %                         up or down, as appropriate, to the nearest integer
  419. /round_up   { dup load ceiling cvi store } def
  420. /round_down { dup load floor   cvi store } def
  421.  
  422. % key binddefinition - this will do a 'bind' on the procedure given by 'key'
  423. /binddefinition
  424. {
  425.     dup where
  426.     {
  427.         exch
  428.         2 copy
  429.         get bind put
  430.     }
  431.     { undefined } ifelse
  432. } def
  433.  
  434. % Given two numbers on the stack, return with just the smallest
  435. /min { 2 copy ge { exch } if pop } def
  436.  
  437. % Dito for the largest of the pair
  438. /max { 2 copy lt { exch } if pop } def
  439.  
  440.  
  441. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  442. %
  443. %   Debugging utilities
  444. %
  445.  
  446. /$tracedict where
  447. {  % Trace package loaded... do the tracing
  448.     pop
  449. % This is a debugging function to print out what is going on.
  450. %  Format <argn> <argn-1> ... <arg1> n <string> debug <argn> ... <arg1>
  451. %    (that is, the 'n' args will be *left* on the stack!)
  452. /debug
  453. {
  454.     traceprint (\n) traceprint
  455.     dup 1 add   % Now total number of args (including arg count)
  456.     copy
  457.     {
  458.         (    ) traceprint
  459.     trace=
  460.         (\n) traceprint
  461.     } repeat
  462.     pop    % Remove the extra copy of the arg count
  463. } def
  464.  
  465. % Print out a coordinate on the stack:  x y ---
  466. /dump-coord
  467. {
  468.     (\() traceprint exch trace= (, ) traceprint trace= (\)) traceprint
  469. } def
  470.  
  471. % Print out bb's current notion of its bounding box
  472.  
  473. /dump-bbox
  474. {
  475.     (Bounding Box: ) traceprint
  476.     bbox-llx bbox-lly dump-coord
  477.     (; ) traceprint
  478.     bbox-urx bbox-ury dump-coord
  479.     (\n) traceprint
  480. } def
  481.  
  482. tracebegin %% DEBUG
  483.  
  484. }
  485. { % No trace package loaded, so don't trace.  Stub out the various calls
  486.  
  487. /traceprint { pop } def
  488. /dump-coord { pop pop } def
  489. /dump-bbox { } def
  490. /debug { pop  pop } def
  491. /tracedump { } def
  492.  
  493. } ifelse
  494.  
  495. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  496.  
  497. % Bind everything
  498.  
  499. /xdef binddefinition
  500. /xstore binddefinition
  501. /addcoords binddefinition
  502. /stroke binddefinition
  503. /fill binddefinition
  504. /eofill binddefinition
  505. /show binddefinition
  506. /widthshow binddefinition
  507. /ashow binddefinition
  508. /awidthshow binddefinition
  509. /image binddefinition
  510. /showpage binddefinition
  511. /init binddefinition
  512. /includepath binddefinition
  513. /bwstroke binddefinition
  514. /chcount binddefinition
  515. /fontheight binddefinition
  516.  
  517. /debug binddefinition
  518. /dump-coord binddefinition
  519. /dump-bbox binddefinition
  520.  
  521. % Start it up.
  522.  
  523. init
  524.  
  525. end % $BoundingBox
  526.  
  527. %  end of bb.ps
  528.  
  529. % $Log:    bb.ps,v $
  530. % Revision 1.14  91/03/21  13:04:02  cosell
  531. % Relocated the position of the constrained BBox info
  532. %
  533. % Revision 1.13  91/03/21  12:21:04  cosell
  534. % Forced the %BoundingBox info to stay within the page boundaries
  535. %
  536. % Revision 1.12  91/03/21  12:15:17  cosell
  537. % Added a tracing hook to bridge restores.
  538. %
  539. % Revision 1.11  90/07/02  08:48:40  cosell
  540. % bbfig now correctly copes with empty paths
  541. %
  542. % Revision 1.10  90/06/27  10:47:22  cosell
  543. % Added a bunch of improvements from Joe Pallas at stanford.
  544. %
  545. % Revision 1.9  90/06/26  10:50:20  cosell
  546. % Stack got botched in the 'debug' stub
  547. %
  548. % Revision 1.8  90/06/25  09:34:51  cosell
  549. % Minor bug in 'restore'
  550. %
  551. % Revision 1.7  90/06/25  09:29:58  cosell
  552. % Added code to catch and deal with 'restore'.  Thanks to Frank
  553. % Jensen for finding this one
  554. %
  555. % Revision 1.6  90/06/25  09:23:26  cosell
  556. % Small bugfix in the text-handling stuff
  557. %
  558. % Revision 1.5  90/06/10  09:04:02  cosell
  559. % Changed the printed string to explictly say "%%BoundingBox"
  560. %
  561. % Revision 1.4  90/06/10  08:55:39  cosell
  562. % Added 'bind' machinery to insulate this package from later redefinitions
  563. % of things we need from the systemdict.
  564. %
  565. % Revision 1.3  90/06/10  08:28:53  cosell
  566. % Added debugging hooks.  They don't affect anything (and don't do
  567. % anything) in the normal use of bbfig.  But if the 'trace' package
  568. % is loaded ahead of this, it'll print out some helpful info.  Probably
  569. % I'll end up removing all of this if/when I really get the package
  570. % up to snuff.
  571. %
  572. % Revision 1.2  90/05/25  12:08:24  cosell
  573. % Major improvements and tuneups:  fixed it to really use its private
  574. % discionary, and the most importnat: it now computes the bounding box
  575. % in *default* coords
  576. %
  577. % Revision 1.1  90/05/23  08:18:54  cosell
  578. % Initial revision
  579. %   This is Ned Bachelder's original version
  580.