home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / PSCRIPT / GS241PS.ZIP / BB4GS.PS < prev    next >
Encoding:
Text File  |  1992-04-23  |  15.1 KB  |  600 lines

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