shear/skew transformation errors
Friedrich W. H. Kossebau
kossebau at kde.org
Thu Apr 5 14:45:42 BST 2012
Hi,
tl;dr There are unclear differences in skew transform handling in ODF and SVG,
at least loading SVG with skewX/Y is broken. Expert input needed.
I got pointed to the fact that there are problems with loading SVG files with
shearing transformations, e.g. seen with the coords-trans-03-t from the w3c
SVG test suite, from
http://dev.w3.org/SVG/profiles/1.1F2/test/svg/coords-trans-03-t.svg
But after a short look I am still a little puzzled and would like some
assistance.
For one the docs of QTransform::shear(...) are shitty because they do not tell
what kind of real value they take. From all code examples I found it seems to
be "tan(radian value of the angle)", as also is the value in the matrix.
>From the ODF and SVG specs I would have guessed the skewX/skewY attributes
take the same values with the same semantics. But the SVG attribute values are
handled with
tan(DEG2RAD(params[0].toDouble())) (SvgUtil.cpp)
and the ODF attribute values with
tan(-params[0].toDouble())" (KoShape.cpp)
So the ODF skew values are given in radian values, not degree values, and the
spec text is wrong about that? And is the angle in ODF clockwise, while it is
counter-clockwise in SVG (see the "-" for ODF)?
To complicate things more, the code for loading graphic styles does
tan(params[0].toDouble()) (KoOdfGraphicStyle.cpp)
(and also has an error for mixing up the parameters for skewY).
So what code is wrong, where is LO/OOo code ruling over the spec (and where to
discuss to fix this, to decrease spoiling of the ODF spec)?
Cheers
Friedrich
PS: Find below an overview of the relevant code/spec parts:
__ODF 1.2 spec, section 19.228 draw:transform___
* skewX(<skew-angle>), specifies a skew transformation by
<rotate-angle> degrees along the x-axis.
* skewY(<skew-angle>), specifies a skew transformation by
<rotate-angle> degrees along the y-axis.
[[the bad <rotate-angle>s have been reported to odf-comment ml by me]]
__SVG 1.1 spec, section 7.6 The transform attribute___
skewX(<skew-angle>), which specifies a skew transformation along the x-axis.
and referenced from this, section 7.4 Coordinate system transformations__
* A skew transformation along the x-axis is equivalent to [...]
[1 0 tan(a) 1 0 0], which has the effect of skewing X coordinates
by angle a.
* A skew transformation along the y-axis is equivalent to [...]
[1 tan(a) 0 1 0 0], which has the effect of skewing Y coordinates
by angle a.
SvgUtil.cpp:
} else if (subtransform[0].toLower() == "skewx") {
result.shear(tan(DEG2RAD(params[0].toDouble())), 0.0F);
} else if (subtransform[0].toLower() == "skewy") {
result.shear(0.0F, tan(DEG2RAD(params[0].toDouble())));
KoShape.cpp:
} else if (cmd == "skewx") {
QPointF p = absolutePosition(KoFlake::TopLeftCorner);
QTransform shearMatrix;
shearMatrix.translate(p.x(), p.y());
shearMatrix.shear(tan(-params[0].toDouble()), 0.0F);
shearMatrix.translate(-p.x(), -p.y());
matrix = matrix * shearMatrix;
} else if (cmd == "skewy") {
QPointF p = absolutePosition(KoFlake::TopLeftCorner);
QTransform shearMatrix;
shearMatrix.translate(p.x(), p.y());
shearMatrix.shear(0.0F, tan(-params[0].toDouble()));
shearMatrix.translate(-p.x(), -p.y());
matrix = matrix * shearMatrix;
KoOdfGraphicStyle.cpp:
} else if (subtransform[0] == "skewx")
transform.shear(tan(params[0].toDouble()), 0.0F);
else if (subtransform[0] == "skewy")
transform.shear(tan(params[0].toDouble()), 0.0F);
[[error! parameters switched in last line]]
qt.gitorious.org/qt/qtsvg/blobs/master/src/svg/qsvghandler.cpp:
} else if (state == SkewX) {
if (points.count() != 1)
goto error;
const qreal deg2rad = qreal(0.017453292519943295769);
matrix.shear(qTan(points[0]*deg2rad), 0);
} else if (state == SkewY) {
if (points.count() != 1)
goto error;
const qreal deg2rad = qreal(0.017453292519943295769);
matrix.shear(0, qTan(points[0]*deg2rad));
More information about the calligra-devel
mailing list