Q: I have several questions relating to Matrix2D.

1) I do not see a way to apply a rotation via an api method. I am

currently applying a rotation in a manner such as:

Matrix2D mtx = ...;

Matrix2D rotation = Matrix2D.RotationMatrix(30 *PI/180);

mtx = rotation*mtx;

Is this the preferred way to perform this?

2) I do not see a way to apply a skew via an api method. I assume that

I would create a matrix as described in the PDF Spec like [1, tan a,

tan b, 1, 0, 0]. I would then multiply this by my matrix containing my

translation, rotation and scale data. Is this the preferred way to do

this?

3) It was my understanding from the PDF spec that all transformations

are multiplicative. However, the scale method in Matrix2D only

multiplies the a and d values, and does not actually do a matrix

multiplication. Is this by design? I thought that is was a bug at

first, but then i re-read the PDFNet documentation and it verified

this. For instance if I do a rotation of 30deg on an identity matrix,

i get :

0.866025403784439, b=-0.5, c=0.5, d=0.866025403784439, h=0, v=0.

If I then multiply a scale matrix (a=5, b=0, c=0, d=10, h=0, v=0) by

hand (ie row*column) then I get:

a=4.33012701892219, b=-5, c=2.5, d=8.66025403784439, h=0, v=0.

However, using the matrix.scale(5,10) method I get:

a=4.33012701892219, b=-0.5, c=0.5, d=8.66025403784439, h=0, v=0

------

A: Regarding #1, you are on the right track. To apply rotation

transformation, create a rotation matrix (using

Matrix2D.RotationMatrix(rad_angle)) and then pre multiply it to

another matrix.

Regarding #2: you are also on the right track. You could create skew

matrix as follows:

Matrix2D skew = new Matrix2D(1, scwx, scwy, 1, 0, 0);

Now if you also want to translate, scale, and rotate content you could

create additional matrices:

const double deg2rad = 3.1415926535 / 180.0;

Matrix2D rotate = Matrix2D.RotationMatrix(30 * deg2rad);

Matrix2D scale = Matrix2D (scx, 0, 0, scy, 0, 0);

Matrix2D translate = Matrix2D (1, 0, 0, 1, offset_x, offset_y);

The final matrix will depend on the desired order of transforms. For

example if you want first to skew the element, followed by rotation,

followed by scaling, followed by translation, you would multiply

matrices as follows:

Matrix2D mtx = translate * scale * rotate * skew;

Alternatively if you would like to first translate the element,

followed by other transforms you would multiply matrices as follows:

Matrix2D mtx = scale * rotate * skew * translate;

This is similar to the convention used in OpenGL, where the rightmost

matrix is the topmost matrix on the stack, whereas the leftmost matrix

is the first matrix on the stack.

The transforms are applied from right to left:

<--4--<---3----<--2---<-----1----

Matrix2D mtx = scale * rotate * skew * translate;

Re #3, the Scale method in Matrix2D simple multiplies a and d entries

by a given value. To create a scale matrix use the steps described

above.