Long overdue but I got side tracked a little…
Before we get any further, it’s time to discuss the coordinate system used. The origin is at the lower left corner, with positive x and positive y are directions going left and upwards. Coordinates do not have to be integers. The user space is device independent and ever increment represents 1/72th of an inch.
The Images can be manipulated by a Transformation Matrix which can be used for ‘translation’, ‘rotation’, ‘scaling’ and ‘skew’.
In a PDF, the transformation matrix consists of 6 numbers [a b c d e f] which represent the following 3×3 matrix.
|x'| | a b 0| |x| |y'| = | c d 0| |y| |1 | | e f 1| |1|
- Translations are specified as [ 1 0 0 1 tx ty ], where tx and ty are the distances to translate the origin of the coordinate system in the horizontal and vertical dimensions, respectively.
- Scaling is obtained by [sx 0 0 sy 0 0]. This scales the coordinates so that 1 unit in the horizontal and vertical dimensions of the new coordinate system is the same size as sx and sy units, respectively, in the previous coordinate system.
- Rotations are produced by [cos θ sin θ −sin θ cos θ 0 0], which has the effect of rotating the coordinate system axes by an angle θ counterclockwise.
- Skew is specified by [1 tan α tan β 1 0 0], which skews the x axis by an angle α and the y axis by an angle β.
Matrix operations are not commutative, which means that the order of operations matters. In the PDF in question, the only rotation is 90 degrees clockwise, and no skew. Which means that the rotation matrix is expressed as [ 0 -1 1 0 0 0]
• The q operator pushes a copy of the entire graphics state onto the stack.
• The Q operator restores the entire graphics state to its former value by popping it from the stack.
q Q – Push and Pop
q – Save state
18 14.40002 576 763.2 re W n – Specifies a rectangular clipping path starting at (0.25”, 0.2”) and ending at (8.25”, 10.8”), effectively adding a top and bottom clipping are of 0.2” and a left and right clipping area of 0.25”
q – Save state
0 -792.96 612.48 0 -0.24 792.48 cm /Im1 Do – cm indicates a coordinate transformation matrix, /Im1 is the first image (jpeg background) and Do paints the object
So what happens here.Remember that the MediaBox is 612 by 792.
The image is scaled by 792.92 and 612.48 (after the rotation, the coordinates are swapped), thus making the picture 0.92 too large in the y direction and .48 in the x direction. This is corrected by the translation, centering the picture.
The image is rotated clockwise by 90 degrees. (sin 90 = 1, cos 90 = 0)
Finally the object is moved by translations (-0.24, 792.48).
The /Im1 object is a 150 DPI object, which means that the translation in pixels is (-0.5 and 1651). A little explanation is helpful here. The JPEG image has a size of 1652 and 1276 which means that it is 2 pixels to large in the x and 1 pixels too large in the y direction. This is because the JPEG is aligned to 8 pixels and some extra padding was necessary. Note that the JPEG is rotated 90 degrees in the stream, means that the x and y sizes are reversed. This will be corrected by rotating the picture, followed by a translation to its proper position. This will properly center the JPEG.
Q – Restore state
/Cs1 cs – Set the color space to /Cs1
0.1059 0.17650 0.1216 sc – Set the non-stroking color to (27,45,31) in RGB space or #1B2D1F which is a dark green. Verification shows that this is indeed the color of the ‘text’ layer.
0 -348.96 436.56 0 89.28 581.28 cm /Im2 Do
/Im2 is the main foreground text. Remember that all the other images are 300 dpi. The dimensions are (1819 x 1454)
The scaling is (348,96*300/72, 436.56*300/72) or (1453, 1819). The image is moved to (89.28, 581,28) or pixels (186, 1211) in JPEG space
More later but at least Obj 4 with the strange text strings should make a little more sense. You can of course also look at the PDF version 1.3 specification