diff options
| author | Liam P. White <inkscapebrony@gmail.com> | 2014-11-09 05:13:46 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebrony@gmail.com> | 2014-11-09 05:13:46 +0000 |
| commit | 4b236f3f1e3fe5374e18dac9e6c35567d9dc0995 (patch) | |
| tree | d6a8f361b37294feb8da05c2ce61271e5137a237 /src/svg | |
| parent | Remove FIXME from refactoring (diff) | |
| parent | Fix bug in previous commit. Add test against it (diff) | |
| download | inkscape-4b236f3f1e3fe5374e18dac9e6c35567d9dc0995.tar.gz inkscape-4b236f3f1e3fe5374e18dac9e6c35567d9dc0995.zip | |
Update to trunk r13690
(bzr r13341.5.22)
Diffstat (limited to 'src/svg')
| -rw-r--r-- | src/svg/svg-affine-test.h | 7 | ||||
| -rw-r--r-- | src/svg/svg-affine.cpp | 157 | ||||
| -rw-r--r-- | src/svg/svg-angle.cpp | 4 | ||||
| -rw-r--r-- | src/svg/svg-length-test.h | 14 |
4 files changed, 114 insertions, 68 deletions
diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h index 11b9012a8..6d8387328 100644 --- a/src/svg/svg-affine-test.h +++ b/src/svg/svg-affine-test.h @@ -34,7 +34,7 @@ private: static char const * const read_fail_tests[25]; static test_t const write_matrix_tests[2]; static test_t const write_translate_tests[3]; - static test_t const write_scale_tests[2]; + static test_t const write_scale_tests[3]; static test_t const write_rotate_tests[2]; static test_t const write_skew_tests[3]; public: @@ -238,8 +238,9 @@ SvgAffineTest::test_t const SvgAffineTest::write_translate_tests[3] = { {"translate(1,1)",Geom::Affine(1,0,0,1,1,1)}, {"translate(1)",Geom::Affine(1,0,0,1,1,0)}, {"translate(-1345,0.123)",Geom::Affine(1,0,0,1,-1.345e3,.123)}}; -SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[2] = { +SvgAffineTest::test_t const SvgAffineTest::write_scale_tests[3] = { {"scale(0)",Geom::Affine(0,0,0,0,0,0)}, + {"scale(7)",Geom::Affine(7,0,0,7,0,0)}, {"scale(2,3)",Geom::Affine(2,0,0,3,0,0)}}; SvgAffineTest::test_t const SvgAffineTest::write_rotate_tests[2] = { {"rotate(13)",Geom::Affine(cos(13.*DEGREE),sin(13.*DEGREE),-sin(13.*DEGREE),cos(13.*DEGREE),0,0)}, @@ -247,7 +248,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..af58c4544 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[0], transform[3], 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); } diff --git a/src/svg/svg-angle.cpp b/src/svg/svg-angle.cpp index 63152368e..ed5ccd45e 100644 --- a/src/svg/svg-angle.cpp +++ b/src/svg/svg-angle.cpp @@ -104,15 +104,19 @@ static bool sp_svg_angle_read_lff(gchar const *str, SVGAngle::Unit &unit, float } else { if (strncmp(e, "deg", 3) == 0) { unit = SVGAngle::DEG; + val = v; computed = v; } else if (strncmp(e, "grad", 4) == 0) { unit = SVGAngle::GRAD; + val = v; computed = Inkscape::Util::Quantity::convert(v, "grad", "°"); } else if (strncmp(e, "rad", 3) == 0) { unit = SVGAngle::RAD; + val = v; computed = Inkscape::Util::Quantity::convert(v, "rad", "°"); } else if (strncmp(e, "turn", 4) == 0) { unit = SVGAngle::TURN; + val = v; computed = Inkscape::Util::Quantity::convert(v, "turn", "°"); } else { return false; diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h index 81a28c9e7..fbdb7588d 100644 --- a/src/svg/svg-length-test.h +++ b/src/svg/svg-length-test.h @@ -164,13 +164,13 @@ SvgLengthTest::test_t const SvgLengthTest::absolute_tests[12] = { {"1.00001", SVGLength::NONE, 1.00001 , 1.00001}, {"1px", SVGLength::PX , 1 , 1}, {".1px", SVGLength::PX , 0.1 , 0.1}, - {"100pt", SVGLength::PT , 100 , 125}, - {"1e2pt", SVGLength::PT , 100 , 125}, - {"3pc", SVGLength::PC , 3 , 45}, - {"-3.5pc", SVGLength::PC , -3.5 , -3.5*15.}, - {"1.2345678mm", SVGLength::MM , 1.2345678, 1.2345678*3.543307}, // TODO: More precise constants? (a 7 digit constant when the default precision is 8 digits?) - {"123.45678cm", SVGLength::CM , 123.45678 , 123.45678*35.43307}, - {"73.162987in", SVGLength::INCH, 73.162987 , 73.162987*90}}; + {"100pt", SVGLength::PT , 100 , 400.0/3.0}, + {"1e2pt", SVGLength::PT , 100 , 400.0/3.0}, + {"3pc", SVGLength::PC , 3 , 48}, + {"-3.5pc", SVGLength::PC , -3.5 , -3.5*16.0}, + {"1.2345678mm", SVGLength::MM , 1.2345678, 1.2345678*96.0/25.4}, // TODO: More precise constants? (a 7 digit constant when the default precision is 8 digits?) + {"123.45678cm", SVGLength::CM , 123.45678 , 123.45678*96.0/2.54}, + {"73.162987in", SVGLength::INCH, 73.162987 , 73.162987*96}}; SvgLengthTest::test_t const SvgLengthTest::relative_tests[3] = { {"123em", SVGLength::EM, 123, 123. * 7.}, {"123ex", SVGLength::EX, 123, 123. * 13.}, |
