summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam P. White <inkscapebrony@gmail.com>2014-11-09 02:12:39 +0000
committerLiam P. White <inkscapebrony@gmail.com>2014-11-09 02:12:39 +0000
commit263305034e9bb1f8958fa4eda523813d20b65941 (patch)
treeba82a92f188696cfec66f70700c44e9aeed7b5ca
parentexport dialog, small code cleanup, should be a noop. (check if pointer is nul... (diff)
downloadinkscape-263305034e9bb1f8958fa4eda523813d20b65941.tar.gz
inkscape-263305034e9bb1f8958fa4eda523813d20b65941.zip
Add specialized transforms
Fixed bugs: - https://launchpad.net/bugs/1207502 (bzr r13688)
-rw-r--r--src/svg/svg-affine-test.h2
-rw-r--r--src/svg/svg-affine.cpp157
2 files changed, 100 insertions, 59 deletions
diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h
index 11b9012a8..d44f2f714 100644
--- a/src/svg/svg-affine-test.h
+++ b/src/svg/svg-affine-test.h
@@ -247,7 +247,7 @@ SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[2] = {
SvgAffineTest::test_t const SvgAffineTest::write_skew_tests[3] = {
{"skewX(30)",Geom::Affine(1,0,tan(30.*DEGREE),1,0,0)},
{"skewX(-30)",Geom::Affine(1,0,tan(-30.*DEGREE),1,0,0)},
- {"skewY(390)",Geom::Affine(1,tan(30.*DEGREE),0,1,0,0)}};
+ {"skewY(30)",Geom::Affine(1,tan(30.*DEGREE),0,1,0,0)}};
/*
Local Variables:
diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp
index 44567a2bd..b2b8744db 100644
--- a/src/svg/svg-affine.cpp
+++ b/src/svg/svg-affine.cpp
@@ -162,65 +162,105 @@ sp_svg_transform_write(Geom::Affine const &transform)
int prec = prefs->getInt("/options/svgoutput/numericprecision", 8);
int min_exp = prefs->getInt("/options/svgoutput/minimumexponent", -8);
- /* fixme: We could use t1 * t1 + t2 * t2 here instead */
- if ( Geom::are_near(transform[1], 0.0, e) && Geom::are_near (transform[2], 0.0, e)) {
- if (Geom::are_near (transform[4], 0.0, e) && Geom::are_near (transform[5], 0.0, e)) {
- if (Geom::are_near (transform[0], 1.0, e) && Geom::are_near (transform[3], 1.0, e)) {
- /* We are more or less identity */
- return NULL;
- } else {
- /* We are more or less scale */
- gchar c[256];
- unsigned p = 0;
- strcpy (c + p, "scale(");
- p += 6;
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp );
- c[p++] = ')';
- c[p] = '\000';
- g_assert( p <= sizeof(c) );
- return g_strdup(c);
- }
+ // Special case: when all fields of the affine are zero,
+ // the optimized transformation is scale(0)
+ if (transform[0] == 0 && transform[1] == 0 && transform[2] == 0 &&
+ transform[3] == 0 && transform[4] == 0 && transform[5] == 0)
+ {
+ return g_strdup("scale(0)");
+ }
+
+ // FIXME legacy C code!
+ // the function sp_svg_number_write_de is stopping me from using a proper C++ string
+
+ gchar c[256]; // string buffer
+ unsigned p = 0; // position in the buffer
+
+ if (transform.isIdentity()) {
+ // We are more or less identity, so no transform attribute needed:
+ return NULL;
+ } else if (transform.isScale()) {
+ // We are more or less a uniform scale
+ strcpy (c + p, "scale(");
+ p += 6;
+ p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp );
+ if (Geom::are_near(transform[3], 0.0, e)) {
+ c[p++] = ')';
+ c[p] = '\000';
} else {
- if (Geom::are_near (transform[0], 1.0, e) && Geom::are_near (transform[3], 1.0, e)) {
- /* We are more or less translate */
- gchar c[256];
- unsigned p = 0;
- strcpy (c + p, "translate(");
- p += 10;
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp );
- c[p++] = ')';
- c[p] = '\000';
- g_assert( p <= sizeof(c) );
- return g_strdup(c);
- } else {
- gchar c[256];
- unsigned p = 0;
- strcpy (c + p, "matrix(");
- p += 7;
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[1], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[2], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp );
- c[p++] = ',';
- p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp );
- c[p++] = ')';
- c[p] = '\000';
- g_assert( p <= sizeof(c) );
- return g_strdup(c);
- }
+ c[p++] = ',';
+ p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[3], prec, min_exp );
+ c[p++] = ')';
+ c[p] = '\000';
}
+ } else if (transform.isTranslation()) {
+ // We are more or less a pure translation
+ strcpy (c + p, "translate(");
+ p += 10;
+ p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[4], prec, min_exp );
+ if (Geom::are_near(transform[5], 0.0, e)) {
+ c[p++] = ')';
+ c[p] = '\000';
+ } else {
+ c[p++] = ',';
+ p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp );
+ c[p++] = ')';
+ c[p] = '\000';
+ }
+ } else if (transform.isRotation()) {
+ // We are more or less a pure rotation
+ strcpy(c + p, "rotate(");
+ p += 7;
+
+ double angle = std::atan2(transform[1], transform[0]) * (180 / M_PI);
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp);
+
+ c[p++] = ')';
+ c[p] = '\000';
+ /* } else if (transform.withoutTranslation().isRotation()) {
+ // FIXME someone please figure out if this can actually be done
+ // The rotation angle is correct, the points are not
+ // Refer to the matrix in svg-affine-test.h
+
+ // We are a rotation about a special axis
+ strcpy(c + p, "rotate(");
+ p += 7;
+
+ Geom::Affine const sans_translate = transform.withoutTranslation();
+ double angle = std::atan2(sans_translate[1], sans_translate[0]) * (180 / M_PI);
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp);
+ c[p++] = ',';
+
+ Geom::Point pt = transform.translation();
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, pt[Geom::X], prec, min_exp);
+
+ c[p++] = ',';
+
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, pt[Geom::Y], prec, min_exp);
+
+ c[p++] = ')';
+ c[p] = '\000';*/
+ } else if (transform.isHShear()) {
+ // We are more or less a pure skewX
+ strcpy(c + p, "skewX(");
+ p += 6;
+
+ double angle = atan(transform[2]) * (180 / M_PI);
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp);
+
+ c[p++] = ')';
+ c[p] = '\000';
+ } else if (transform.isVShear()) {
+ // We are more or less a pure skewY
+ strcpy(c + p, "skewY(");
+ p += 6;
+
+ double angle = atan(transform[1]) * (180 / M_PI);
+ p += sp_svg_number_write_de(c + p, sizeof(c) - p, angle, prec, min_exp);
+
+ c[p++] = ')';
+ c[p] = '\000';
} else {
- gchar c[256];
- unsigned p = 0;
strcpy (c + p, "matrix(");
p += 7;
p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[0], prec, min_exp );
@@ -236,9 +276,10 @@ sp_svg_transform_write(Geom::Affine const &transform)
p += sp_svg_number_write_de( c + p, sizeof(c) - p, transform[5], prec, min_exp );
c[p++] = ')';
c[p] = '\000';
- g_assert( p <= sizeof(c) );
- return g_strdup(c);
}
+
+ assert(p <= sizeof(c));
+ return g_strdup(c);
}