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("")).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("")).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