# Tutorial: iText by Example

## Coordinate Systems

The coordinate system:
See PDF Reference Manual (version 1.6) p169:

> Coordinate systems define the canvas on which all painting occurs. They determine the position, orientation, and size of the text, graphics, and images that appear on a page.

If you start a new page in PDF, the CTM (current transformation matrix) maps positions from user coordinates to device coordinates. The origin of the coordinate system is in the lower left corner of the page by default. The x-axis is oriented horizontally to the right, the y-axis vertically to the upper left corner. All measurements are done in points. This is not an iText specific choice. All this is documented in the PDF Reference Manual, section 4.2 Coordinate Systems.
Example: java com.lowagie.examples.directcontent.coordinates.XandYcoordinates
Puts some marks at specific X and Y coordinates; connects the marks with a line and puts some text next to the marks: see XandY.pdf
If you print the resulting PDF of the example and measure the locations on the page, you will see that the distances measured from the bottom or the left side of the page are not always correct. Adobe's print dialog has several options (like "fit to paper") that change the printed result, so be careful!
Go to top of the page
Transformations:
There are different ways to change the CTM.
You can use the method concatCTM(float, float, float, float, float, float). For instance, if you want to shift the origin to the upper left corner and change the orientation of the y-axis, you can use this statement right after getting the PdfContentByte:

    cb.concatCTM(1f, 0f, 0f, -1f, 0f, PageSize.A4.height());

If we take the same code as in the first example, but apply this new transformation matrix, we see that everything is upside-down now and all text is mirrored.
Example: java com.lowagie.examples.directcontent.coordinates.UpsideDown
Same example as above, but now the origin is in the upper left corner: see upsidedown.pdf
These transformations are called affine transformations and you should have learnt about them at school when you were about 17 years old. If you want to freshen up your memory, I've got some algebra for you:
if you want to translate, scale or rotate images or text, you need to use a Transformation Matrix. Most iText methods involving transformations ask you for the parameters a, b, c, d, e and f. Those parameters are elements of the Transformation Matrix:

[ | a | b | 0 | ]
c | d | 0
e | f | 1

The third column is fixed because we are only interested in 2D transformations, we are not discussing 3D here. With the parameters e and f, you can specify a translation. The following matrix moves everything e pixels in x-direction and f pixels in y-direction.

[ | 1 | 0 | 0 | ]
0 | 1 | 0
e | f | 1

You can use the a and d parameter to scale. The following matrix doubles everything in x-direction and triples everything in y-direction:

[ | 2 | 0 | 0 | ]
0 | 3 | 0
0 | 0 | 1

If you want to rotate something, you have to change a, b, c and d. With angle equals to the rotation angle in radians, you have a matrix like this:

[ | Math.cos(angle) | Math.sin(angle) | 0 | ]
-Math.sin(angle) | Math.cos(angle) | 0
0 | 0 | 1

There is one serious caveat when you rotate an object: the coordinate of the rotation pivot is (0, 0). If you rotate something, you have to watch out that it is not rotated 'off' your page. you may have to perform a translation to keep the object on the page. Of course you can combine translation (tX, tY), scaling (sX, sY) rotation (angle) in one matrix:

[ | sX * Math.cos(angle) | sY * Math.sin(angle) | 0 | ]
-sX * Math.sin(angle) | sY * Math.cos(angle) | 0
tX | tY | 1

So you will have to use these parameters:

- a = sX * Math.cos(angle);
- b = sY * Math.sin(angle);
- c = -sX * Math.sin(angle);
- d = sY * Math.cos(angle)
- e = tX;
- f = tY;

Another way to change the CTM is by using transform(java.awt.geom.AffineTransform) As you can see AffineTransform is an object in the JDK. It comes with some getInstance methods that are easier to understand. If you want a scale coordinate system, just get a 'scale instance':

    cb.transform(AffineTransform.getScaleInstance(1.2, 0.75));

Check SUN's API for more information.
Example: java com.lowagie.examples.directcontent.coordinates.AffineTransformation
Same example as above, but now the X and Y coordinates are scaled: see affinetransformation.pdf
Go to top of the page
Adding PdfTemplates:
The stuff above probably seems rather theoretical, but it was a necessary introduction to this part: if you are using PdfTemplates, you are going to need a transformation matrix. Up till now, we only have used this method to add a PdfTemplate: PdfContentByte.addTemplate(com.lowagie.text.pdf.PdfTemplate, float, float). This method performs a translation, using this matrix:

[ | 1 | 0 | 0 | ]
0 | 1 | 0
x | y | 1

In fact, the method just calls the more sophisticated method: addTemplate(com.lowagie.text.pdf.PdfTemplate, float, float, float, float, float, float).
Instead of cb.addTemplate(template, x, y), you could call cb.addTemplate(template, 1, 0, 0, 1, x, y) (that's exactly what happens internally in iText). The parameters in this method are the (a, b, c, d, e, f) values as explained above.
Example: java com.lowagie.examples.directcontent.coordinates.Transformations
Add a template using different transformation matrices: see transformations.pdf
Go to top of the page
Adding Images:
What was explained for PdfTemplate objects also goes for Image objects. There's a method addImage(com.lowagie.text.Image) that adds the Image at an absolute position (provided that you used setAbsolutePosition(float, float) first). But there's also addImage(com.lowagie.text.Image, float, float, float, float, float, float) that allows you to transform the Image.
Example: java com.lowagie.examples.directcontent.coordinates.TransformImage
Add an image using different transformation matrices: see transformimage.pdf
External resources for this example: hitchcock.png
This is very tricky stuff. It's doable for PdfTemplates, but if you want to transform Images, you'd better trust on iText to construct the transformation matrix. Class Image has sufficient methods to perform most of the Image transformations you are going to need.
Go to top of the page
Amazon books:
amazon.co.uk-link