Understanding graphics (Transformation matrix cm)coordinate(parsing positions of graphics) system in pdf?

fascinating coder :

I gone through the content stream of different pdf's which contain graphics elements. Some pdf's contain normal CTM text coordinate system for graphics. Like below enter image description here Here CTM positions I am able to compare with my page coordinates.

But I found something strange in this pdf(the x and y transisitions are in thousands and my page coordinates are 576, 720. How I can compare with page coordinates? ). You can see below enter image description here. In this case how the CTM is calculation happening .

And I saw in rules like "A conforming reader or writer of a PDF content stream may change an arrangement of graphics state operators to any other arrangement that achieves the same values of the relevant graphics state parameters for each graphics object."

Can anyone please explain about other such cases where graphics parsing act like this and what considerations need to be taken to handle it in a generic manner ?

Please explain all ways of parsing available graphics coordinates.

mkl :

Please explain all ways of parsing available graphics coordinates.

There essentially is but one way to do that, the way implied by the PDF specification: When reading a content stream, update the current transformation matrix (CTM) according to the effects of the instructions you find.

Let's look at your second content stream.

Initial value

At the beginning the CTM maps the default user space to the device space. As we are interested in coordinates in the default user space itself, for us these spaces coincide and we start with the identity matrix. Furthermore, there are no saved graphics states and therefore no CTM values in saved states yet:

1 0 0        |
0 1 0        |
0 0 1        |

(0) q

The first instruction q saves the current graphics state; thus, we now have a copy of the CTM on the graphics stack:

1 0 0        |    1 0 0
0 1 0        |    0 1 0
0 0 1        |    0 0 1

(1) .1 0 0 .1 0 0 cm

The next instruction .1 0 0 .1 0 0 cm multiplies the CTM from the left:

.1 0  0     1 0 0     .1 0  0
0  .1 0  *  0 1 0  =  0  .1 0
0  0  1     0 0 1     0  0  1

Thus, we have

.1 0  0        |    1 0 0
0  .1 0        |    0 1 0
0  0  1        |    0 0 1

(2..6) ... re W n ... rg ... gs

These instructions don't change the CTM or the state stack.

(7) q

The next instruction q saves the current graphics state; thus

.1 0  0        |    1 0 0    .1 0  0
0  .1 0        |    0 1 0    0  .1 0
0  0  1        |    0 0 1    0  0  1

(I draw the top of the stack on the right side.)

(8) 1 0 0 1 3398 2608 cm

(For the sake of brevity I truncate the values a bit.)

The next instruction 1 0 0 1 3398 2608 cm multiplies the CTM from the left:

   1    0 0     .1 0  0        .1   0   0
   0    1 0  *  0  .1 0  =    0      .1 0
3398 2606 1     0  0  1     339.8 260.6 1

Thus, we now have

   .1   0   0        |    1 0 0    .1 0  0
  0      .1 0        |    0 1 0    0  .1 0
339.8 260.6 1        |    0 0 1    0  0  1

This is the first instruction you were unsure about because of the value in the thousands. After evaluating, though, you see the origin being pushed to fairly normal values 339.8 260.6.

(9..13) ... m ... l ... l h f*

These instructions don't change the CTM or the state stack.

(14) Q

The next instruction Q restores the most recently saved graphics state. Thus, we have

.1 0  0        |    1 0 0
0  .1 0        |    0 1 0
0  0  1        |    0 0 1

(15..17) ... RG ... w ... M

These instructions don't change the CTM or the state stack.

(18) q

The next instruction q saves the current graphics state; thus

.1 0  0        |    1 0 0    .1 0  0
0  .1 0        |    0 1 0    0  .1 0
0  0  1        |    0 0 1    0  0  1

(19) 1 0 0 1 3607 2339 cm

(For the sake of brevity I truncate the values a bit.)

The next instruction 1 0 0 1 3607 2339 cm multiplies the CTM from the left:

   1    0 0     .1 0  0        .1   0   0
   0    1 0  *  0  .1 0  =    0      .1 0
3607 2339 1     0  0  1     360.7 233.9 1

Thus, we now have

   .1   0   0        |    1 0 0    .1 0  0
  0      .1 0        |    0 1 0    0  .1 0
360.7 233.9 1        |    0 0 1    0  0  1

This is the second instruction you were unsure about because of the value in the thousands. After evaluating, though, you again see the origin being pushed to fairly normal values 360.7 233.9.

(20..) etc.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=358706&siteId=1