OK - I think the Matrix code is wrong in getting the shear values compared to the description in the PDF spec.
eg. using a text matrix to produce an 'italic' text AffineTransform transform = AffineTransform.getShearInstance(0, 0.5); contentStream.setTextMatrix(transform); produces the same result as contentStream.setTextMatrix(1, 0, 0.5, 1, 0, 0); Which is inline with the spec as c is the sy value. Now getShearX, getShearY and createAffineTransform in Matrix are wrong IMHO as they have the extraction flipped between sx and sy. e.g. printing the values of AffineTransform transform = AffineTransform.getShearInstance(0, 0.5); produces AffineTransform[[1.0, 0.0, 0.0], [0.5, 1.0, 0.0]] where printing the values of Matrix matrix = new Matrix(); matrix.setValue(1, 0, 0.5f); produces AffineTransform[[1.0, 0.5, 0.0], [0.0, 1.0, 0.0]] which is wrong as it should produce AffineTransform[[1.0, 0.0, 0.0], [0.5, 1.0, 0.0]] BR Maruan Am 27.12.2014 um 23:47 schrieb John Hewson <j...@jahewson.com>: > Yes, the pure matrix code seems to work fine. As do the examples which Tilman > mentioned. I can’t find any issue with the code itself. However, we make use > the following Matrix method: > > public AffineTransform createAffineTransform() > { > AffineTransform retval = new AffineTransform( > single[0], single[1], // m00 m10 = scaleX shearY > single[3], single[4], // m01 m11 = shearX scaleY > single[6], single[7] ); // m02 m12 = tx ty > return retval; > } > > Recall that single[] is the array: > > | sx hy 0 | > | hx sy 0 | > | tx ty 1 | > > Which is fine, except that shear-x and shear-y are flipped vs. the wording in > the PDF spec, namely: > > "Skew shall be specified by [1 tan a tan b 1 0 0], which skews the x axis by > an angle a and the y axis by > an angle b.” > > But the AffineTransform constructor uses the following parameters: > > "m00 - the X coordinate scaling element of the 3x3 matrix > m10 - the Y coordinate shearing element of the 3x3 matrix > m01 - the X coordinate shearing element of the 3x3 matrix > m11 - the Y coordinate scaling element of the 3x3 matrix > m02 - the X coordinate translation element of the 3x3 matrix > m12 - the Y coordinate translation element of the 3x3 matrix" > > At this point I’m left thinking that Java and PDF have chosen different > meanings of “x” and “y” when talking about skew, indeed this appears to be > the case, as the PDF spec defines the x-coordinate transform on p120 as: > > x’ = a*x + c*y + e > > while the AffineTransform documentation defines the same transform as: > > x' = [ m00*x + m01*y + m02 ] > > which might seem different until one realises that m00 = a, m01 = c, m02 = e. > The only difference appears to be the description that c "skews the y axis” > in PDF and m01 is "the X coordinate shearing" in AffineTransform. It seems > like PDF is weird in this regard? > > -- John > >> On 27 Dec 2014, at 16:51, Maruan Sahyoun <sahy...@fileaffairs.de> wrote: >> >> Hi, >> >> I tried the following with skew being [1 tan a tan b 1 0 0] according to the >> spec. >> >> Matrix matrix = new Matrix(); >> >> which gives me [1.0,0.0,0.0,1.0,0.0,0.0] >> >> then >> >> matrix.setValue(0, 1, 0.5f); >> matrix.setValue(1, 0, 0.7f); >> >> which shall set the tan a and tan b values >> >> which gave me >> >> [1.0,0.5,0.7,1.0,0.0,0.0] >> >> then >> >> Matrix matrix2 = new Matrix() >> >> again being [1.0,0.0,0.0,1.0,0.0,0.0] >> >> then >> >> matrix.concatenate(matrix2) >> >> resulting in [1.0,0.5,0.7,1.0,0.0,0.0] >> >> To me that indicates that the pure matrix class is fine for that case. What >> are the arguments to the Concatenate operator in your case? Could it be that >> reading the values is not OK? >> >> BR >> >> Maruan >> >> Am 27.12.2014 um 14:16 schrieb John Hewson <j...@jahewson.com>: >> >>> Hi All, >>> >>> I’ve been looking at the Matrix class and trying to understand if it has >>> some problems. The Matrix class >>> in PDFBox uses the following matrix: >>> >>> | sx hy 0 | >>> | hx sy 0 | >>> | tx ty 1 | >>> >>> In a PDF file this matrix is represented as the 6-element array [a, b, c, >>> d, e, f] where the meaning of >>> the values comes from p118 and is [sx, hx, hy, sy, tx, ty]. Note that h is >>> used to mean shear/skew. >>> >>> The Concatenate operator class populates the Matrix as follows: >>> PDFBox PDF Spec >>> newMatrix.setValue(0, 0, a.floatValue()); sx a = sx >>> newMatrix.setValue(0, 1, b.floatValue()); hy c = hx <- Flipped? >>> newMatrix.setValue(1, 0, c.floatValue()); hx b = hy <- Flipped? >>> newMatrix.setValue(1, 1, d.floatValue()); sy d = sy >>> newMatrix.setValue(2, 0, e.floatValue()); tx e = tx >>> newMatrix.setValue(2, 1, f.floatValue()); ty f = ty >>> >>> I’ve annotated what PDFBox does on the left, compared to the PDF spec, the >>> x and y skew elements >>> (hx and hy) are flipped in PDFBox. This flip matches the order in which >>> AWT’s AffineTransform’s >>> constructor expects its elements but does not match the arrays used in the >>> PDF spec. >>> >>> Are we accidentally flipping skew-x and skew-y in the Concatenate operator? >>> >>> -- John >>> >> >