diff --git a/src/main/java/de/neemann/digital/draw/graphics/Transform.java b/src/main/java/de/neemann/digital/draw/graphics/Transform.java index f839c0158..c73a56750 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/Transform.java +++ b/src/main/java/de/neemann/digital/draw/graphics/Transform.java @@ -46,12 +46,12 @@ public interface Transform { TransformMatrix m1 = t1.getMatrix(); TransformMatrix m2 = t2.getMatrix(); return new TransformMatrix( - m1.a * m2.a + m1.b * m2.c, - m1.c * m2.a + m1.d * m2.c, - m1.a * m2.b + m1.b * m2.d, - m1.c * m2.b + m1.d * m2.d, - m1.a * m2.x + m1.b * m2.y + m1.x, - m1.c * m2.x + m1.d * m2.y + m1.y); + m1.a * m2.a + m1.c * m2.b, + m1.b * m2.a + m1.d * m2.b, + m1.a * m2.c + m1.c * m2.d, + m1.b * m2.c + m1.d * m2.d, + m2.a * m1.x + m2.b * m1.y + m2.x, + m2.c * m1.x + m2.d * m1.y + m2.y); } diff --git a/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java b/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java index d159fce78..8abb5ca79 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java +++ b/src/main/java/de/neemann/digital/draw/graphics/TransformMatrix.java @@ -23,7 +23,7 @@ public class TransformMatrix implements Transform { final double phi = w / 180 * Math.PI; float cos = (float) Math.cos(phi); float sin = (float) Math.sin(phi); - return new TransformMatrix(cos, sin, -sin, cos, 0, 0); + return new TransformMatrix(cos, -sin, sin, cos, 0, 0); } /** diff --git a/src/main/java/de/neemann/digital/draw/shapes/custom/svg/Context.java b/src/main/java/de/neemann/digital/draw/shapes/custom/svg/Context.java index a563b3e91..a3a679a28 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/custom/svg/Context.java +++ b/src/main/java/de/neemann/digital/draw/shapes/custom/svg/Context.java @@ -152,7 +152,7 @@ class Context { private static void readTransform(Context c, String value) throws SvgException { StringTokenizer st = new StringTokenizer(value, "(),"); - Transform t = null; + Transform t; final String trans = st.nextToken(); switch (trans) { case "translate": @@ -170,10 +170,13 @@ class Context { t = new TransformMatrix(xs, 0, 0, ys, 0, 0); break; case "matrix": + final float ma = Float.parseFloat(st.nextToken()); + final float mb = Float.parseFloat(st.nextToken()); + final float mc = Float.parseFloat(st.nextToken()); t = new TransformMatrix( - Float.parseFloat(st.nextToken()), - Float.parseFloat(st.nextToken()), - Float.parseFloat(st.nextToken()), + ma, + mc, + mb, Float.parseFloat(st.nextToken()), Float.parseFloat(st.nextToken()), Float.parseFloat(st.nextToken())); @@ -184,15 +187,15 @@ class Context { t = TransformMatrix.rotate(w); float xc = Float.parseFloat(st.nextToken()); float yc = Float.parseFloat(st.nextToken()); - t = Transform.mul(new TransformTranslate(xc, yc), t); - t = Transform.mul(t, new TransformTranslate(-xc, -yc)); + t = Transform.mul(new TransformTranslate(-xc, -yc), t); + t = Transform.mul(t, new TransformTranslate(xc, yc)); } else t = TransformMatrix.rotate(w); break; default: throw new SvgException("unknown transform: " + value, null); } - c.tr = Transform.mul(c.tr, t); + c.tr = Transform.mul(t, c.tr); } private static Color getColorFromString(String v) { diff --git a/src/test/java/de/neemann/digital/draw/graphics/TransformMatrixTest.java b/src/test/java/de/neemann/digital/draw/graphics/TransformMatrixTest.java index 17c90bb84..fc11bb6c5 100644 --- a/src/test/java/de/neemann/digital/draw/graphics/TransformMatrixTest.java +++ b/src/test/java/de/neemann/digital/draw/graphics/TransformMatrixTest.java @@ -20,11 +20,11 @@ public class TransformMatrixTest extends TestCase { TransformMatrix tr = TransformMatrix.rotate(45); VectorInterface p = new VectorFloat(2, 0).transform(tr); assertEquals(Math.sqrt(2), p.getXFloat(), 1e-4); - assertEquals(-Math.sqrt(2), p.getYFloat(), 1e-4); + assertEquals(Math.sqrt(2), p.getYFloat(), 1e-4); } public void testRotateInverse() { - Transform tr = new TransformRotate(new Vector(2,3),1); + Transform tr = new TransformRotate(new Vector(2, 3), 1); VectorInterface p = new VectorFloat(7, 8); VectorInterface t = p.transform(tr).transform(tr.invert()); @@ -43,26 +43,52 @@ public class TransformMatrixTest extends TestCase { public void testUniform() { assertTrue(TransformMatrix.rotate(30).isUniform()); - assertTrue(new TransformRotate(new Vector(2,2),0).getMatrix().isUniform()); - assertTrue(new TransformRotate(new Vector(2,2),1).getMatrix().isUniform()); - assertTrue(new TransformRotate(new Vector(2,2),2).getMatrix().isUniform()); - assertTrue(new TransformRotate(new Vector(2,2),3).getMatrix().isUniform()); - assertTrue(new TransformTranslate(4,5).getMatrix().isUniform()); - assertTrue(TransformMatrix.scale(2,2).isUniform()); + assertTrue(new TransformRotate(new Vector(2, 2), 0).getMatrix().isUniform()); + assertTrue(new TransformRotate(new Vector(2, 2), 1).getMatrix().isUniform()); + assertTrue(new TransformRotate(new Vector(2, 2), 2).getMatrix().isUniform()); + assertTrue(new TransformRotate(new Vector(2, 2), 3).getMatrix().isUniform()); + assertTrue(new TransformTranslate(4, 5).getMatrix().isUniform()); + assertTrue(TransformMatrix.scale(2, 2).isUniform()); - assertFalse(TransformMatrix.scale(2,3).isUniform()); + assertFalse(TransformMatrix.scale(2, 3).isUniform()); } public void testNoRotation() { assertFalse(TransformMatrix.rotate(30).noRotation()); - assertTrue(new TransformRotate(new Vector(2,2),0).getMatrix().noRotation()); - assertFalse(new TransformRotate(new Vector(2,2),1).getMatrix().noRotation()); - assertTrue(new TransformRotate(new Vector(2,2),2).getMatrix().noRotation()); - assertFalse(new TransformRotate(new Vector(2,2),3).getMatrix().noRotation()); - assertTrue(new TransformTranslate(4,5).getMatrix().noRotation()); - assertTrue(TransformMatrix.scale(2,2).noRotation()); + assertTrue(new TransformRotate(new Vector(2, 2), 0).getMatrix().noRotation()); + assertFalse(new TransformRotate(new Vector(2, 2), 1).getMatrix().noRotation()); + assertTrue(new TransformRotate(new Vector(2, 2), 2).getMatrix().noRotation()); + assertFalse(new TransformRotate(new Vector(2, 2), 3).getMatrix().noRotation()); + assertTrue(new TransformTranslate(4, 5).getMatrix().noRotation()); + assertTrue(TransformMatrix.scale(2, 2).noRotation()); - assertTrue(TransformMatrix.scale(2,3).noRotation()); + assertTrue(TransformMatrix.scale(2, 3).noRotation()); + } + + public void testMul() { + final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix(); + final TransformMatrix t2 = new TransformTranslate(10, 10).getMatrix(); + final VectorFloat v = new VectorFloat(2, 3); + compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2))); + } + + public void testMul2() { + final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix(); + final TransformMatrix t2 = new TransformRotate(new Vector(10, 10), 1).getMatrix(); + final VectorFloat v = new VectorFloat(2, 3); + compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2))); + } + + public void testMul3() { + final TransformMatrix t1 = new TransformTranslate(10, 10).getMatrix(); + final TransformMatrix t2 = TransformMatrix.rotate(45); + final VectorFloat v = new VectorFloat(2, 3); + compare(v.transform(t1).transform(t2), v.transform(Transform.mul(t1, t2))); + } + + private void compare(VectorInterface v1, VectorInterface v2) { + assertEquals(v1.getXFloat(), v2.getXFloat(), 1e-4); + assertEquals(v1.getYFloat(), v2.getYFloat(), 1e-4); } } \ No newline at end of file diff --git a/src/test/java/de/neemann/digital/draw/shapes/custom/SvgImporterTest.java b/src/test/java/de/neemann/digital/draw/shapes/custom/SvgImporterTest.java index 35390c31a..501ebc3ce 100644 --- a/src/test/java/de/neemann/digital/draw/shapes/custom/SvgImporterTest.java +++ b/src/test/java/de/neemann/digital/draw/shapes/custom/SvgImporterTest.java @@ -424,6 +424,34 @@ public class SvgImporterTest extends TestCase { .check(); } + public void testInkscape7() throws IOException, SvgException, PolygonParser.ParserException, PinException { + CustomShapeDescription custom = new SvgImporter( + in("\n" + + "\n" + + "\n" + + " \n" + + "\n" + + "\n" + + "")).create(); + + new CSDChecker(custom) + .checkPolygon("M 100,43.431458 L 170.71068,114.142136 L 100,184.85281 L 29.289322,114.142136 Z") + .check(); + } + + public void testInkscape8() throws IOException, SvgException, PolygonParser.ParserException, PinException { + CustomShapeDescription custom = new SvgImporter( + in("\n" + + "\n" + + "")).create(); + + new CSDChecker(custom) + .checkPolygon("M 100,43.431458 L 170.71068,114.142136 L 100,184.85281 L 29.289322,114.142136 Z") + .check(); + } + //***************************************************************************************************** diff --git a/src/test/java/de/neemann/digital/draw/shapes/custom/svg/ContextTest.java b/src/test/java/de/neemann/digital/draw/shapes/custom/svg/ContextTest.java index c01d1e761..515d59bbb 100644 --- a/src/test/java/de/neemann/digital/draw/shapes/custom/svg/ContextTest.java +++ b/src/test/java/de/neemann/digital/draw/shapes/custom/svg/ContextTest.java @@ -13,4 +13,11 @@ public class ContextTest extends TestCase { assertEquals(new Color(63, 127, 191), Context.readStyle(new Context(), "stroke:rgb(25%,50%,75%)").getStroke()); } + public void testInkscape1() throws SvgException { + Context c = Context.readStyle(new Context(), "fill:#000000;fill-opacity:0.5;stroke:none"); + assertNull(c.getStroke()); + assertEquals(new Color(0, 0, 0, 127), c.getFilled()); + } + + } \ No newline at end of file