added combined transforms

This commit is contained in:
hneemann 2018-12-03 22:00:44 +01:00
parent 402a38387f
commit bff8d7ea43

View File

@ -11,6 +11,9 @@ import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import java.awt.*; import java.awt.*;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -151,51 +154,96 @@ class Context {
} }
private static void readTransform(Context c, String value) throws SvgException { private static void readTransform(Context c, String value) throws SvgException {
StringTokenizer st = new StringTokenizer(value, "(),"); StreamTokenizer tokenzer = new StreamTokenizer(new StringReader(value));
Transform t; try {
final String trans = st.nextToken(); Transform t;
switch (trans) { while (true) {
case "translate": final int tok = tokenzer.nextToken();
final float x = Float.parseFloat(st.nextToken()); if (tok == StreamTokenizer.TT_EOF)
float y = 0; break;
if (st.hasMoreTokens()) if (tok != StreamTokenizer.TT_WORD)
y = Float.parseFloat(st.nextToken()); throw new SvgException("invalid transform", null);
t = new TransformTranslate(new VectorFloat(x, y)); switch (tokenzer.sval) {
break; case "translate":
case "scale": consume(tokenzer, '(');
final float xs = Float.parseFloat(st.nextToken()); final float x = readFloat(tokenzer);
float ys = xs; float y = 0;
if (st.hasMoreTokens()) if (isComma(tokenzer))
ys = Float.parseFloat(st.nextToken()); y = readFloat(tokenzer);
t = new TransformMatrix(xs, 0, 0, ys, 0, 0); consume(tokenzer, ')');
break; t = new TransformTranslate(new VectorFloat(x, y));
case "matrix": break;
final float ma = Float.parseFloat(st.nextToken()); case "scale":
final float mb = Float.parseFloat(st.nextToken()); consume(tokenzer, '(');
final float mc = Float.parseFloat(st.nextToken()); final float xs = readFloat(tokenzer);
t = new TransformMatrix( float ys = xs;
ma, if (isComma(tokenzer))
mc, ys = readFloat(tokenzer);
mb, consume(tokenzer, ')');
Float.parseFloat(st.nextToken()), t = new TransformMatrix(xs, 0, 0, ys, 0, 0);
Float.parseFloat(st.nextToken()), break;
Float.parseFloat(st.nextToken())); case "matrix":
break; consume(tokenzer, '(');
case "rotate": final float ma = readFloat(tokenzer);
float w = Float.parseFloat(st.nextToken()); consume(tokenzer, ',');
if (st.hasMoreTokens()) { final float mb = readFloat(tokenzer);
t = TransformMatrix.rotate(w); consume(tokenzer, ',');
float xc = Float.parseFloat(st.nextToken()); final float mc = readFloat(tokenzer);
float yc = Float.parseFloat(st.nextToken()); consume(tokenzer, ',');
t = Transform.mul(new TransformTranslate(-xc, -yc), t); final float md = readFloat(tokenzer);
t = Transform.mul(t, new TransformTranslate(xc, yc)); consume(tokenzer, ',');
} else final float mx = readFloat(tokenzer);
t = TransformMatrix.rotate(w); consume(tokenzer, ',');
break; final float my = readFloat(tokenzer);
default: consume(tokenzer, ')');
throw new SvgException("unknown transform: " + value, null); t = new TransformMatrix(
ma,
mc,
mb,
md,
mx,
my);
break;
case "rotate":
consume(tokenzer, '(');
float w = readFloat(tokenzer);
if (isComma(tokenzer)) {
t = TransformMatrix.rotate(w);
float xc = readFloat(tokenzer);
consume(tokenzer, ',');
float yc = readFloat(tokenzer);
t = Transform.mul(new TransformTranslate(-xc, -yc), t);
t = Transform.mul(t, new TransformTranslate(xc, yc));
} else
t = TransformMatrix.rotate(w);
consume(tokenzer, ')');
break;
default:
throw new SvgException("unknown transform: " + value, null);
}
c.tr = Transform.mul(t, c.tr);
}
} catch (IOException e) {
// can never happen
} }
c.tr = Transform.mul(t, c.tr); }
private static boolean isComma(StreamTokenizer tokenzer) throws IOException {
if (tokenzer.nextToken() == ',')
return true;
tokenzer.pushBack();
return false;
}
private static void consume(StreamTokenizer tokenzer, char c) throws IOException, SvgException {
if (tokenzer.nextToken() != c)
throw new SvgException("expected " + c, null);
}
private static float readFloat(StreamTokenizer tokenzer) throws IOException, SvgException {
if (tokenzer.nextToken() != StreamTokenizer.TT_NUMBER)
throw new SvgException("number expected", null);
return (float) tokenzer.nval;
} }
private static Color getColorFromString(String v) { private static Color getColorFromString(String v) {