Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does PDF line width interact with the CTM in both horizontal and vertical dimensions?

Tags:

pdf

graphics

I'm trying to figure out exactly how line width affects a stroked line in PDF, given the current transformation matrix (CTM). Two questions...

First: how do I convert the line width to device space using the CTM? Page 208 in the PDF 1.7 Reference, which describes how to convert points using the CTM, assumes the input data is an (x, y) point. Line width is just a single value, so how do I convert it? Do I create a "dummy" point from it like (lineWidth, lineWidth)?

Second: once I make that calculation, I'll get another (x, y) point. If the CTM has different scaling factors for horizontal vs. vertical, that gives me two different line widths. How are these line widths actually applied? Does the first one (x) get applied only when drawing horizontal lines?

A concrete example for the second question: if I draw/stroke a horizontal line from (0, 0) to (4, 4) with line width (2, 1), what are the coordinates of the bounding box of the resulting rectangle (i.e., the rectangle that contains the line width)?

This is from Page 215 in the Reference, but it doesn't actually explain how the thickness of stroked lines will vary:

The effect produced in device space depends on the current transformation matrix (CTM) in effect at the time the path is stroked. If the CTM specifies scaling by different factors in the horizontal and vertical dimensions, the thickness of stroked lines in device space will vary according to their orientation.

like image 309
Adrian Holovaty Avatar asked Sep 29 '22 22:09

Adrian Holovaty


2 Answers

how do I convert the line width to device space using the CTM?

The line width essentially is the line size perpendicular to its direction. Thus, to calculate the width after transformation using the CTM, you choose a planar vector perpendicular to the original line whose length is the line width from the current graphics state, apply the CTM (without translation, i.e. setting e and f to 0) to that vector (embedded in the three dimensional space by setting the third coordinate to 1) and calculate the length of the resulting 2D vector (projecting on the first two coordinates).

E.g. you have a line from (0,0) to (1,4) in current user space coordinates with a width of 1. You have to find a vector perpendicular to it, e.g. (-4,1) by rotating 90° counter clockwise, and scale it to a length of 1, i.e. ( -4/sqrt(17), 1/sqrt(17) ) in that case.

If the CTM is the one from @Tikitu's answer

CTM has a horizontal scaling factor of 2 and a vertical scaling factor of 1

it would be

2 0 0
0 1 0
0 0 1

This matrix would make the line from the example above go from (0,0) to (2,4) and the "width vector" ( -4/sqrt(17), 1/sqrt(17) ) would be transformed to ( -8/sqrt(17), 1/sqrt(17) ) (the CTM already has no translation part) with a length of sqrt(65/17) which is about 1.955. I.e. the width of the resulting line (its size perpendicular to its direction) is nearly 2.

If the original line would instead have been (0,0) to (4,1) with width 1, a width vector choice would have been ( -1/sqrt(17), 4/sqrt(17) ). In that case the transformed line would go from (0,0) to (8,1) and the width vector would be transformed to ( -2/sqrt(17), 4/sqrt(17) ) with a length of sqrt(20/17) which is about 1.085. I.e. the width of the resulting line (perpendicular to its direction) is slightly more than 1.

You seem to be interested in the "corners" of the line. For this you have to take start and end of the transformed line and add or subtract half the transformed width vector. In the samples above:

  1. (original line from (0,0) to (1,4)): ( -4/sqrt(17), 1/(2*sqrt(17)) ), ( 4/sqrt(17), -1/(2*sqrt(17)) ), ( 2-4/sqrt(17), 4+1/(2*sqrt(17)) ), ( 2+4/sqrt(17), 4-1/(2*sqrt(17)) );

  2. (original line from (0,0) to (4,1)): ( -1/sqrt(17), 2/sqrt(17) ), ( 1/sqrt(17), -2/sqrt(17) ), ( 8-1/sqrt(17), 1+2/sqrt(17) ), ( 8+1/sqrt(17), 1-2/sqrt(17) ).

Don't forget, though, that PDF lines often are not cut off at the end but instead have some cap. And furthermore remember the special meaning of line width 0.

like image 156
mkl Avatar answered Oct 06 '22 18:10

mkl


I don't know anything about PDF internals, but I can make a guess at what that passage might mean, based on knowing a bit about using matrices to represent linear transformations.

If you imagine your stroked line as a rectangle (long and thin, but with a definite width) and apply the CTM to the four corner points, you'll see how the orientation of the line changes its width when the CTM has different horizontal and vertical scaling factors.

If your CTM has a horizontal scaling factor of 2 and a vertical scaling factor of 1, think about lines at various angles:

  • a horizontal line (a short-but-wide rectangle) gets its length doubled, and it's "height" (the width of the line) stays the same;
  • a vertical line (a tall-and-thin rectangle) gets it's width doubled (i.e., the line gets twice as thick), and it's length stays the same;
  • lines at various angles get thicker by different degrees, depending on the angle, because they get stretched horizontally but not verticallye.g.
  • the thickness of a line at 45 degrees is measured diagonally (45 degrees the other way), so it gets somewhat thicker (some horizontal stretching), but not twice as thick (the vertical component of the diagonal didn't get bigger). (You can figure out the thickness with two applications of the Pythagorean theorem; it's about 1.58 times greater, or sqrt(5)/sqrt(2).)

If this story is correct, you can't convert line width using the CTM: it is simply different case-by-case, depending on the orientation of the line. What you can convert is the width of a particular line, with a particular orientation, via the trick of thinking of the line as a solid area and running its corners individually through the CTM. (This also means that "the same" line, with the same thickness, will look different as you vary its orientation, if your CTM has different horizontal and vertical scaling factors.)

like image 33
Tikitu Avatar answered Oct 06 '22 20:10

Tikitu