package org.xmind.ui.internal.svgsupport;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.draw2d.Graphics;
/**
*
* @author Enki Xiong
*
*/
public class SVGTransform {
private static class Translate implements TransformElement {
private float dx, dy;
public Translate(float dx, float dy) {
this.dx = dx;
this.dy = dy;
}
public void transform(Graphics graphics) {
graphics.translate(dx, dy);
}
@Override
public String toString() {
return "translate:" + dx + "," + dy; //$NON-NLS-1$ //$NON-NLS-2$
}
}
private static class Scale implements TransformElement {
private float hScale = 1.0f;
private float vScale = 1.0f;
public Scale(float hScale) {
this(hScale, hScale);
}
public Scale(float hScale, float vScale) {
this.hScale = hScale;
this.vScale = vScale;
}
public void transform(Graphics graphics) {
graphics.scale(hScale, vScale);
}
@Override
public String toString() {
return "scale:" + hScale + "," + vScale; //$NON-NLS-1$ //$NON-NLS-2$
}
}
private static class Rotate implements TransformElement {
private float angle;
private float dx, dy;
public Rotate(float angle) {
this.angle = angle;
}
Rotate(float angle, float dx, float dy) {
this(angle);
this.dx = dx;
this.dy = dy;
}
public void transform(Graphics graphics) {
graphics.translate(dx, dy);
graphics.rotate(angle);
graphics.translate(-dx, -dy);
}
@Override
public String toString() {
return "rotate:" + angle; //$NON-NLS-1$
}
}
public static final Pattern pattern = Pattern
.compile("(translate)|(rotate)|(scale)|([+-]?\\d+(\\.\\d+)?)"); //$NON-NLS-1$
private LinkedList<TransformElement> list = new LinkedList<TransformElement>();
private float[] matrix = new float[] { 1, 0, 0, 1, 0, 0 };
private boolean isMatrix = false;
public void parseTransform(String transform) {
if (transform.startsWith("matrix")) { //$NON-NLS-1$
isMatrix = true;
parseTransformMatrix(transform);
} else {
parseTransformList(transform);
}
}
private void parseTransformList(String transform) {
final Matcher match = pattern.matcher(transform);
LinkedList<String> tokens = new LinkedList<String>();
while (match.find()) {
tokens.add(match.group());
}
while (!tokens.isEmpty()) {
String type = tokens.removeFirst();
if (type.equals(SVGDefinitionConstants.TRANSLATE)) {
list.add(new Translate(Float.valueOf(tokens.removeFirst()),
Float.valueOf(tokens.removeFirst())));
continue;
}
if (type.equals(SVGDefinitionConstants.ROTATE)) {
String angle = tokens.removeFirst();
if (tokens.isEmpty()) {
list.addLast(new Rotate(Float.valueOf(angle)));
break;
}
String tmp = tokens.getFirst();
if (tmp.equals(SVGDefinitionConstants.TRANSLATE)
|| tmp.equals(SVGDefinitionConstants.ROTATE)
|| tmp.equals(SVGDefinitionConstants.SCALE)) {
list.addLast(new Rotate(Float.valueOf(angle)));
} else {
list.addLast(new Rotate(Float.valueOf(angle),
Float.valueOf(tokens.removeFirst()),
Float.valueOf(tokens.removeFirst())));
}
continue;
}
if (type.equals(SVGDefinitionConstants.SCALE)) {
String hScale = tokens.removeFirst();
if (tokens.isEmpty()) {
list.addLast(new Scale(Float.valueOf(hScale)));
break;
}
String tmp = tokens.getFirst();
if (tmp.equals(SVGDefinitionConstants.TRANSLATE)
|| tmp.equals(SVGDefinitionConstants.ROTATE)
|| tmp.equals(SVGDefinitionConstants.SCALE)) {
list.addLast(new Scale(Float.valueOf(hScale)));
} else {
list.addLast(new Scale(Float.valueOf(hScale),
Float.valueOf(tokens.removeFirst())));
}
continue;
}
}
}
private void parseTransformMatrix(String transform) {
String[] strs = transform
.split(SVGDefinitionConstants.LEFT_BRACKET_REGEX)[1]
.split(SVGDefinitionConstants.RIGHT_BRACKET_REGEX)[0]
.split(" +"); //$NON-NLS-1$
matrix[0] = Float.valueOf(strs[0]);
matrix[1] = Float.valueOf(strs[1]);
matrix[2] = Float.valueOf(strs[2]);
matrix[3] = Float.valueOf(strs[3]);
matrix[4] = Float.valueOf(strs[4]);
matrix[5] = Float.valueOf(strs[5]);
}
public LinkedList<TransformElement> getList() {
return list;
}
public boolean isMatrix() {
return isMatrix;
}
}