12 views

Skip to first unread message

Sep 22, 1993, 6:07:46 PM9/22/93

to

In describing the pathbbox operator, the red book says:

If the user coordinate system is rotated (other than by multiples

of 90 degrees) or skewed, pathbbox may return a bounding box that

is larger than expected.

The following snippet illustrates the problem:

%!

/inch { 72 mul } bind def

/rect { % x0 y0 x1 y1 => rectangle w/ll at (x0,y0) and ur at (x1,y1).

newpath 4 copy moveto 4 -1 roll exch lineto exch 4 2 roll

lineto lineto closepath

} bind def

/Helvetica findfont 48 scalefont setfont

0 setlinewidth

4.25 inch 5.5 inch translate

0 0 moveto

(A) dup gsave true charpath flattenpath pathbbox rect stroke grestore show

0 -100 moveto

30 rotate

(A) dup gsave true charpath flattenpath pathbbox rect stroke grestore show

showpage

The bbox returned for the rotated 'A' is significantly larger than it

"should be". Does someone have some code that gives the "right"

bounding box for a character (string) in a rotated frame?

Alternatively, I'm using pathbbox to find the height of a character.

Is there a way to do this that doesn't use pathbbox and gives the

right answer in rotated frames?

Thanks,

chris goedde

goe...@math.ohio-state.edu

Sep 22, 1993, 11:07:11 PM9/22/93

to

In article <27qibi$7...@ellipse.mps.ohio-state.edu>,

goe...@math.ohio-state.edu (Chris Goedde) wrote:

>

> In describing the pathbbox operator, the red book says:

>

> If the user coordinate system is rotated (other than by multiples

> of 90 degrees) or skewed, pathbbox may return a bounding box that

> is larger than expected.

>

[code deleted]

>

> The bbox returned for the rotated 'A' is significantly larger than it

> "should be". Does someone have some code that gives the "right"

> bounding box for a character (string) in a rotated frame?

>

> Alternatively, I'm using pathbbox to find the height of a character.

> Is there a way to do this that doesn't use pathbbox and gives the

> right answer in rotated frames?

goe...@math.ohio-state.edu (Chris Goedde) wrote:

>

> In describing the pathbbox operator, the red book says:

>

> If the user coordinate system is rotated (other than by multiples

> of 90 degrees) or skewed, pathbbox may return a bounding box that

> is larger than expected.

>

>

> The bbox returned for the rotated 'A' is significantly larger than it

> "should be". Does someone have some code that gives the "right"

> bounding box for a character (string) in a rotated frame?

>

> Alternatively, I'm using pathbbox to find the height of a character.

> Is there a way to do this that doesn't use pathbbox and gives the

> right answer in rotated frames?

Yes (see below). But for what it's worth (although this may be

implementation dependent, of course) pathbbox on a rotated frame will

return the orthogonal pathbbox in which the *rotated pathbbox* would fit.

And then there's always the problem of curves (i.e., Bezier cubics), the

control points of which may fall well outside the curve itself, but will

nonetheless be included in your pathbbox. On the other hand, any font,

curvy or otherwise, that follows the Adobe Type I Font conventions will

include control points that are always, at worst, on the edges of the

apparent charbox, not outside (though be aware that this rule of thumb may

be violated by "very fine" serifs or similar details of the font; but then,

the violation would not be too bad).

In any case, one solution to your problem is to define a procedure that

temporarily "straightens out" your CTM, "etches" the path (but doesn't

stroke, fill or otherwise paint it) in the unrotated CTM, executes the

pathbbox operator, and then grestores back to your original frame. Your

user coordinates don't change, even though the device coordinates, of

course, do. The following code skeleton is exemplary:

Prior to the rotation (or any other CTM skewing [scaling is OK]), get the

CTM into which you want to unrotate your characters:

/mx0 matrix currentmatrix def

Then,

/_pathbbox {

gsave currentpoint newpath moveto

%save currentpoint from which to execute "show"

matrix currentmatrix matrix invertmatrix concat mx0 concat

%straighten out, unskew, unscale, etc., relative

% to whenever you defined /mx0

dup show %or something similar, expecting a string to be on

% the stack

pathbbox %leaves the correct pathbbox on the stack *in your

% rotated, skewed, etc.* coordinate system

grestore %restored skewed system

} bind def

You can of course combine the /mx0 definition into the overall definition

if you want to be a bit more compact, and if you will always be working in

a non-rotated frame until the rotation in question arises. In that case,

scotch the name /mx0 and just keep the initial unrotated matrix on the

stack, rolling it out of the way till it's needed.

Finally, be aware that if you apply pathbbox to massive amounts of text,

you may eat up both memory and time, as all of the individual path elements

are considered in the operation. You may be well-advised to use the

flattenpath operator within the gsave-grestore state prior to calling

pathbbox, although, with a Level 2 printer, I've never had any difficulty.

DMM

__________________________________________________________________________

Dave Marks, Northwestern University, 2145 Sheridan Rd., Evanston, IL 60208

Dept. of Physics and Astronomy, 708/491-8615, Fax: 708/491-9982; Materials

Science Dept., 708/491-3571, Fax: 708/491-7820 dma...@casbah.acns.nwu.edu

Sep 23, 1993, 7:14:22 AM9/23/93

to

In <27qibi$7...@ellipse.mps.ohio-state.edu>

goe...@math.ohio-state.edu (Chris Goedde) writes:

>In describing the pathbbox operator, the red book says:

>

> If the user coordinate system is rotated (other than by multiples

> of 90 degrees) or skewed, pathbbox may return a bounding box that

> is larger than expected.

>

>The following snippet illustrates the problem:

>[code deleted]

>

>The bbox returned for the rotated 'A' is significantly larger than it

>"should be". Does someone have some code that gives the "right"

>bounding box for a character (string) in a rotated frame?

goe...@math.ohio-state.edu (Chris Goedde) writes:

>In describing the pathbbox operator, the red book says:

>

> If the user coordinate system is rotated (other than by multiples

> of 90 degrees) or skewed, pathbbox may return a bounding box that

> is larger than expected.

>

>The following snippet illustrates the problem:

>

>The bbox returned for the rotated 'A' is significantly larger than it

>"should be". Does someone have some code that gives the "right"

>bounding box for a character (string) in a rotated frame?

The book "Real World PostScript" edited by Stephen F. Roth (Published by

Addison-Wesley 1988, ISBN 0-201-06663-7) contains a chapter entitled

"Precise Character Bounding Boxes" by Bill Woodruff. I think you might

find it useful to read that article.

>Alternatively, I'm using pathbbox to find the height of a character.

>Is there a way to do this that doesn't use pathbbox and gives the

>right answer in rotated frames?

If you are writing an application which outputs PostScript code then

your application could read in the .afm (Adobe Font Metrics) file for

the relevant font. Contained in .afm files are the bounding boxes of

each character in the font. You can obtain .afm files for Adobe fonts

and also useful code (written in C) for parsing a .afm file via

anonymous ftp to "ftp.adobe.com". If you don't have ftp then you can

obtain the files from an automated mail server. For details on how to

use this, send an email to "ps-file...@adobe.com" with _just_ the

word "help" in the body of the email.

Ciaran.

--

---- Ciaran McHale (cjmc...@dsg.cs.tcd.ie)

\bi/ Dist. Systems Group, Department of Computer Science, Trinity College,

\/ Dublin 2, Ireland. Telephone: +353-1-7021539 FAX: +353-1-6772204

Sep 25, 1993, 10:13:43 AM9/25/93

to

goe...@math.ohio-state.edu (Chris Goedde) writes:

>The bbox returned for the rotated 'A' is significantly larger than it

>"should be". Does someone have some code that gives the "right"

>bounding box for a character (string) in a rotated frame?

Describing a rectangle by two points implies choosing a set

of preferred axes. Adobe preferred the x and y axes. Nothing

intrinsically wrong about that.

>

>Alternatively, I'm using pathbbox to find the height of a character.

>Is there a way to do this that doesn't use pathbbox and gives the

>right answer in rotated frames?

>

You sound like you're working with Latin fonts. If so, you

can use stringwidth first to find out how the current co-ordinate

system(*) is rotated w.r.t. the default. This won't pick up obliqued

fonts, of course, but you only mention an interest in the height,

so that shouldn't matter.

[* If you know the font has an `upright' fontmatrix, you can

always just look at the CTM of course:-)]

--

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Ian Kemmish 18 Durham Close, Biggleswade, Beds SG18 8HZ

i...@eeyore.dircon.co.uk Tel: +44 767 601 361

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Sep 25, 1993, 5:12:28 PM9/25/93

to

In article <iank.74...@tdc.dircon.co.uk>, ia...@dircon.co.uk (Ian

Kemmish) wrote:

>

> goe...@math.ohio-state.edu (Chris Goedde) writes:

>

> >The bbox returned for the rotated 'A' is significantly larger than it

> >"should be". Does someone have some code that gives the "right"

> >bounding box for a character (string) in a rotated frame?

>

> Describing a rectangle by two points implies choosing a set

> of preferred axes. Adobe preferred the x and y axes. Nothing

> intrinsically wrong about that.

Kemmish) wrote:

>

> goe...@math.ohio-state.edu (Chris Goedde) writes:

>

> >The bbox returned for the rotated 'A' is significantly larger than it

> >"should be". Does someone have some code that gives the "right"

> >bounding box for a character (string) in a rotated frame?

>

> Describing a rectangle by two points implies choosing a set

> of preferred axes. Adobe preferred the x and y axes. Nothing

> intrinsically wrong about that.

I disagree; if the CTM is rotated, *everything* should be rotated. In

fact, the pathbbox operator is completely at odds with the behavior of the

rest of the PostScript operators. Just as Adobe patched the anti-social

behavior of "arcto" in Level 2 by adding "arct", they ought, sometime soon,

to offer "pathbox" (or something) in lieu of "pathbbox" to find the

bounding box in the rotated frame.

Sep 27, 1993, 12:39:25 PM9/27/93

to

In article <iank.74...@tdc.dircon.co.uk>,

Ian Kemmish <ia...@dircon.co.uk> wrote:

>goe...@math.ohio-state.edu (Chris Goedde) writes:

>

>>The bbox returned for the rotated 'A' is significantly larger than it

>>"should be". Does someone have some code that gives the "right"

>>bounding box for a character (string) in a rotated frame?

>

>Describing a rectangle by two points implies choosing a set

>of preferred axes. Adobe preferred the x and y axes. Nothing

>intrinsically wrong about that.

Ian Kemmish <ia...@dircon.co.uk> wrote:

>goe...@math.ohio-state.edu (Chris Goedde) writes:

>

>>The bbox returned for the rotated 'A' is significantly larger than it

>>"should be". Does someone have some code that gives the "right"

>>bounding box for a character (string) in a rotated frame?

>

>Describing a rectangle by two points implies choosing a set

>of preferred axes. Adobe preferred the x and y axes. Nothing

>intrinsically wrong about that.

OK, not wrong, just stupid. :-).

>You sound like you're working with Latin fonts. If so, you

>can use stringwidth first to find out how the current co-ordinate

>system(*) is rotated w.r.t. the default. This won't pick up obliqued

>fonts, of course, but you only mention an interest in the height,

>so that shouldn't matter.

Can you explain what you mean? I don't see how to use stringwidth to

do this.

BTW, thanks to Dave Marks and Ciaran McHale for their responses. I'm

using Dave's suggestion. Of course, this doesn't work under all

conditions (if for example, my file is embedded and rotated in another

file), so I'm still looking for a 'bulletproof' pathbbox.

Aug 9, 2022, 1:04:39 PM8/9/22

to

This reply might be too late for the original poster; nonetheless might help later readers.

PostScript’s pathbbox is not clever. It takes limits in current x-y space of curve control points and line segment ends. So the reported box can be larger than the actual box.

In https://github.com/jdaw1/placemat/blob/main/PostScript/placemat.ps is a function PathBBox, (currently lines 2884–2993, search for “/PathBBox”), which does what pathbbox ought to have done.

First pass it computes the x (and then y) bounds, considering only the ends points of straight lines, and the endpoints of curves (ignores middle controls).

Second pass is for curves only. For those curves with any interior control points outside the already-computed limits (x or y or both), it computes for those axes the cubic coefficients, differentiates once, solves for 0 subject to 0 < t < 1, and then computes the values at those turning points. If these turning points expand the bounding box, the the bounding box is expanded.

A test:

0 0 moveto 1 0 1 1 0 1 curveto

then

pathbbox returns: 0.0 0.0 1.0 1.0, being the bounding box of the control points;

PathBBox returns: 0.0 0.0 0.75 1.0, being the bounding box of the path. Observe that Max[x]=¾.

PostScript’s pathbbox is not clever. It takes limits in current x-y space of curve control points and line segment ends. So the reported box can be larger than the actual box.

In https://github.com/jdaw1/placemat/blob/main/PostScript/placemat.ps is a function PathBBox, (currently lines 2884–2993, search for “/PathBBox”), which does what pathbbox ought to have done.

First pass it computes the x (and then y) bounds, considering only the ends points of straight lines, and the endpoints of curves (ignores middle controls).

Second pass is for curves only. For those curves with any interior control points outside the already-computed limits (x or y or both), it computes for those axes the cubic coefficients, differentiates once, solves for 0 subject to 0 < t < 1, and then computes the values at those turning points. If these turning points expand the bounding box, the the bounding box is expanded.

A test:

0 0 moveto 1 0 1 1 0 1 curveto

then

pathbbox returns: 0.0 0.0 1.0 1.0, being the bounding box of the control points;

PathBBox returns: 0.0 0.0 0.75 1.0, being the bounding box of the path. Observe that Max[x]=¾.

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu