Hi Maruan,

> On 28 Dec 2014, at 02:54, Maruan Sahyoun <sahy...@fileaffairs.de> wrote:
> 
> 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.
> 

Yes.

> Now getShearX, getShearY and create AffineTransform in Matrix are wrong IMHO 
> as they have the extraction flipped between sx and sy.

That’s what was puzzling me. I think what we’re doing is fine based on 
AffineTransform’s definition of shear x/y, but that the terminology is simply 
different from PDF, i.e. an x-skew is described in terms of a y-factor, so it’s 
easy to see how the naming could be ambiguous.

> e.g. printing the values of
> 
> AffineTransform transform = AffineTransform.getShearInstance(0, 0.5);

Ok, so that’s hx = 0, hy = 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);

Element (1,0) is hx, so you’re doing hx = 0.5, hy = 0, which is the opposite of 
your example above.

> 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]]

Which would make sense for hx = 0.5 but what you wanted was:

    matrix.setValue(0, 1, 0.5f)

which produces the expected result:

    AffineTransform[[1.0, 0.0, 0.0], [0.5, 1.0, 0.0]]

So I think we’re ok.

— John

> 
> 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
>>>> 
>>> 
>> 
> 

Reply via email to