%!
% bb.ps --
%
% Prints a file, but keeps track of bounding box info, and prints the box at
% the end (around the figure.)
%
% $Header: bb.ps,v 1.14 91/03/21 13:04:02 cosell Exp $
% RCS log info at end
50 dict /$BoundingBox exch def
$BoundingBox begin
/xdef {
exch def
} def
/xstore {
exch store
} def
/addcoords {
exch
4 -1 roll add
3 1 roll add
} def
%
% New Functions. --- These go into the user dict to intercept the calls
%
/stroke {
$BoundingBox begin
gsave
initmatrix
(stroke called\n) traceprint %%DEBUG
{
strokepath % Make sure to take line width into account.
0 setlinejoin
flattenpath
} stopped { % strokepath often hits a limitcheck.
(Can't set up a strokepath\n) traceprint % DEBUG
grestore % Restore the original path
gsave
} if
includepath % Accumulate it into our box.
grestore
%
% Text is implemented by reducing everything to an `awidthshow'.
%
/show {
$BoundingBox begin
(show called\n) traceprint %%DEBUG
0 0 0 0 0 % Extra parameters for awidthshow
6 -1 roll % Bring the string back up
awidthshow
end % $BoundingBox
} def
/widthshow {
$BoundingBox begin
(widthshow called\n) traceprint %%DEBUG
0 0 % Extra parameters for awidthshow
3 -1 roll % Bring the string back up.
awidthshow
end % $BoundingBox
} def
/ashow {
$BoundingBox begin
(ashow called\n) traceprint %%DEBUG
0 0 0
6 3 roll
awidthshow
end % $BoundingBox
} def
% This does all of the work of the text-rendering operators
% What it does, is compute, basically brute force, what 'charpath'
% would have given us virtually for free, if 'show' were the only
% operator that we needed to do.
/awidthshow {
$BoundingBox begin
gsave
6 (awidthshow:) debug %%DEBUG
currentpoint
2 copy /@starty xdef /@startx xdef
2 index stringwidth % Get the natural length of the string
addcoords % Add to the start to get the end.
2 index length % How many characters?
dup % Add the offsets to each character
6 index mul
exch 5 index mul
addcoords
5 index 3 index
chcount % How many padding characters?
dup % Add the offsets for each pad.
9 index mul
exch 8 index mul
addcoords
/@endy xdef /@endx xdef
% We now have the left and right edges (in user coords)
% of the text. Now we need only correct for the vertical
% displacements needed for the font and we can get the
% top and bottom edges of the enclosing box
fontheight % Get the height and depth of the current font.
% Just define this one out of existence
/framedevice { pop pop pop pop } def
% Handle restoring VM --- this is all OK, except that we have to
% hang onto the bb info we collected while in the about-to-be-discarded
% environment
/restore
{
$BoundingBox begin
(restore called\n) traceprint %%DEBUG
tracedump %% HACK, but the only way I see right now to get this stuff!
bbox-llx bbox-lly bbox-urx bbox-ury
5 -1 roll
-restore
/bbox-ury xstore /bbox-urx xstore
/bbox-lly xstore /bbox-llx xstore
end % $BoundingBox
} def
%
% `showpage':
%
% Just draw the box around the figure and print the page, and then initialize
% the bounding box variables again.
%
$BoundingBox begin
/temp-string 10 string def
end % $BoundingBox
init
-showpage
tracedump %% DEBUG
end % $BoundingBox
} def
%
% BoundingBox functions:
%
% We accumulate the information about the bounding box into four variables.
% The data is stored in default coordinates.
%
$BoundingBox begin
/init {
/bbox-llx 99999 store
/bbox-lly 99999 store
/bbox-urx -99999 store
/bbox-ury -99999 store
} def
%
% A nice black-and white line drawing function.
%
/bwstroke {
0 setlinewidth % Thinnest possible lines
1 setgray % White first
[5] 0 setdash % Only half the line
gsave -stroke grestore
0 setgray % Then black
[5] 5 setdash % On the other half
-stroke
} def
%
% Stuff for text.
%
%
% char-code string `chcount' occurs
%
% Counts the number of times a character appears in a string.
%
/chcount {
0 exch
{
2 index eq {
1 add
} if
} forall
exch pop
} def
%
% - `fontheight' heightx heighty depthx depthy
%
% Returns the offsets to the lowest point and highest point in the current
% font.
%
/fontheight {
currentfont begin
/FontBBox load aload pop
exch pop 0 exch
FontMatrix transform
4 2 roll
exch pop 0 exch
FontMatrix transform
end
} def
% key round_{down|up} - These will round the value of the given key
% up or down, as appropriate, to the nearest integer
/round_up { dup load ceiling cvi store } def
/round_down { dup load floor cvi store } def
% key binddefinition - this will do a 'bind' on the procedure given by 'key'
/binddefinition
{
dup where
{
exch
2 copy
get bind put
}
{ undefined } ifelse
} def
% Given two numbers on the stack, return with just the smallest
/min { 2 copy ge { exch } if pop } def
% Dito for the largest of the pair
/max { 2 copy lt { exch } if pop } def
/$tracedict where
{ % Trace package loaded... do the tracing
pop
% This is a debugging function to print out what is going on.
% Format <argn> <argn-1> ... <arg1> n <string> debug <argn> ... <arg1>
% (that is, the 'n' args will be *left* on the stack!)
/debug
{
traceprint (\n) traceprint
dup 1 add % Now total number of args (including arg count)
copy
{
( ) traceprint
trace=
(\n) traceprint
} repeat
pop % Remove the extra copy of the arg count
} def
% Print out a coordinate on the stack: x y ---
/dump-coord
{
(\() traceprint exch trace= (, ) traceprint trace= (\)) traceprint
} def
% Print out bb's current notion of its bounding box
% $Log: bb.ps,v $
% Revision 1.14 91/03/21 13:04:02 cosell
% Relocated the position of the constrained BBox info
%
% Revision 1.13 91/03/21 12:21:04 cosell
% Forced the %BoundingBox info to stay within the page boundaries
%
% Revision 1.12 91/03/21 12:15:17 cosell
% Added a tracing hook to bridge restores.
%
% Revision 1.11 90/07/02 08:48:40 cosell
% bbfig now correctly copes with empty paths
%
% Revision 1.10 90/06/27 10:47:22 cosell
% Added a bunch of improvements from Joe Pallas at stanford.
%
% Revision 1.9 90/06/26 10:50:20 cosell
% Stack got botched in the 'debug' stub
%
% Revision 1.8 90/06/25 09:34:51 cosell
% Minor bug in 'restore'
%
% Revision 1.7 90/06/25 09:29:58 cosell
% Added code to catch and deal with 'restore'. Thanks to Frank
% Jensen for finding this one
%
% Revision 1.6 90/06/25 09:23:26 cosell
% Small bugfix in the text-handling stuff
%
% Revision 1.5 90/06/10 09:04:02 cosell
% Changed the printed string to explictly say "%%BoundingBox"
%
% Revision 1.4 90/06/10 08:55:39 cosell
% Added 'bind' machinery to insulate this package from later redefinitions
% of things we need from the systemdict.
%
% Revision 1.3 90/06/10 08:28:53 cosell
% Added debugging hooks. They don't affect anything (and don't do
% anything) in the normal use of bbfig. But if the 'trace' package
% is loaded ahead of this, it'll print out some helpful info. Probably
% I'll end up removing all of this if/when I really get the package
% up to snuff.
%
% Revision 1.2 90/05/25 12:08:24 cosell
% Major improvements and tuneups: fixed it to really use its private
% discionary, and the most importnat: it now computes the bounding box
% in *default* coords
%
% Revision 1.1 90/05/23 08:18:54 cosell
% Initial revision
% This is Ned Bachelder's original version