frame SVG export: export static texts

This commit is contained in:
Honfika
2014-04-19 21:43:01 +02:00
parent cd54dca644
commit 03d3e24a16
20 changed files with 188 additions and 240 deletions

View File

@@ -1872,7 +1872,7 @@ public final class SWF implements TreeItem, Timelined {
switch (mode) {
case SVG:
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(Utf8Helper.getBytes(st.toSVG(new SVGExporterContext(outdir, "assets_" + fcharacterID), -2, 0)));
fos.write(Utf8Helper.getBytes(st.toSVG(new SVGExporterContext(outdir, "assets_" + fcharacterID), -2, new CXFORMWITHALPHA(), 0)));
}
break;
case PNG:
@@ -1928,7 +1928,7 @@ public final class SWF implements TreeItem, Timelined {
switch (mode) {
case SVG:
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(Utf8Helper.getBytes(mst.toSVG(new SVGExporterContext(outdir, "assets_" + fcharacterID), -2, 0)));
fos.write(Utf8Helper.getBytes(mst.toSVG(new SVGExporterContext(outdir, "assets_" + fcharacterID), -2, new CXFORMWITHALPHA(), 0)));
}
break;
}
@@ -2588,7 +2588,7 @@ public final class SWF implements TreeItem, Timelined {
}
public static String frameToSvg(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporterContext exporterContext, RECT displayRect, ColorTransform colorTransform, Color backGroundColor, int level) throws IOException {
SVGExporter exporter = new SVGExporter(timeline.swf, new ExportRectangle(displayRect), colorTransform);
SVGExporter exporter = new SVGExporter(new ExportRectangle(displayRect), colorTransform);
if (backGroundColor != null) {
exporter.setBackGroundColor(backGroundColor);
}
@@ -2662,7 +2662,7 @@ public final class SWF implements TreeItem, Timelined {
exporterContext.exportedTags.put(drawableTag, assetFileName);
File file = new File(assetsDir + File.separator + assetFileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(Utf8Helper.getBytes(drawable.toSVG(exporterContext, layer.ratio, level + 1)));
fos.write(Utf8Helper.getBytes(drawable.toSVG(exporterContext, layer.ratio, clrTrans, level + 1)));
}
}
RECT boundRect = drawable.getRect();

View File

@@ -40,6 +40,7 @@ import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
*
@@ -53,16 +54,10 @@ public class SVGExporter {
protected Document _svg;
protected Element _svgDefs;
protected Element _svgG;
protected Element path;
protected List<Element> gradients;
public List<Element> gradients;
protected int lastPatternId;
private final SWF swf;
private double maxLineWidth;
private final ExportRectangle bounds;
public SVGExporter(SWF swf, ExportRectangle bounds, ColorTransform colorTransform) {
this.swf = swf;
this.bounds = bounds;
public SVGExporter(ExportRectangle bounds, ColorTransform colorTransform) {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try {
@@ -75,16 +70,47 @@ public class SVGExporter {
svgRoot.setAttribute("xmlns:xlink", xlinkNamespace);
_svgDefs = _svg.createElement("defs");
svgRoot.appendChild(_svgDefs);
_svgG = _svg.createElement("g");
_svgG.setAttribute("transform", "matrix(1, 0, 0, 1, "
+ roundPixels20(-bounds.xMin / (double) SWF.unitDivisor) + ", " + roundPixels20(-bounds.yMin / (double) SWF.unitDivisor) + ")");
svgRoot.appendChild(_svgG);
if (bounds != null) {
createNewGroup(bounds);
}
} catch (ParserConfigurationException ex) {
Logger.getLogger(SVGExporter.class.getName()).log(Level.SEVERE, null, ex);
}
gradients = new ArrayList<>();
}
public final void createNewGroup(ExportRectangle bounds) {
_svgG = _svg.createElement("g");
_svgG.setAttribute("transform", "matrix(1, 0, 0, 1, "
+ roundPixels20(-bounds.xMin / (double) SWF.unitDivisor) + ", " + roundPixels20(-bounds.yMin / (double) SWF.unitDivisor) + ")");
_svg.getDocumentElement().appendChild(_svgG);
}
public final void createNewGroup(Matrix transform) {
_svgG = _svg.createElement("g");
double translateX = roundPixels400(transform.translateX / SWF.unitDivisor);
double translateY = roundPixels400(transform.translateY / SWF.unitDivisor);
double rotateSkew0 = roundPixels400(transform.rotateSkew0);
double rotateSkew1 = roundPixels400(transform.rotateSkew1);
double scaleX = roundPixels400(transform.scaleX);
double scaleY = roundPixels400(transform.scaleY);
_svgG.setAttribute("transform", "matrix(" + scaleX + ", " + rotateSkew0
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
_svg.getDocumentElement().appendChild(_svgG);
}
public void addToGroup(Node newChild) {
_svgG.appendChild(newChild);
}
public void addToDefs(Node newChild) {
_svgDefs.appendChild(newChild);
}
public Element createElement(String tagName) {
return _svg.createElement(tagName);
}
public String getSVG() {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
StringWriter writer = new StringWriter();

View File

@@ -17,8 +17,8 @@
package com.jpexs.decompiler.flash.exporters.morphshape;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -35,26 +35,9 @@ import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
/**
@@ -63,71 +46,26 @@ import org.w3c.dom.Element;
*/
public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
protected static final String sNamespace = "http://www.w3.org/2000/svg";
protected static final String xlinkNamespace = "http://www.w3.org/1999/xlink";
protected Document _svg;
protected Element _svgDefs;
protected Element _svgG;
protected Element path;
protected List<Element> gradients;
protected int lastPatternId;
private final Color defaultColor;
private final SWF swf;
private double maxLineWidth;
private final ExportRectangle bounds;
private final SVGExporter exporter;
public SVGMorphShapeExporter(SWF swf, SHAPE shape, SHAPE endShape, ExportRectangle bounds, ColorTransform colorTransform) {
public SVGMorphShapeExporter(SWF swf, SHAPE shape, SHAPE endShape, SVGExporter exporter, Color defaultColor, ColorTransform colorTransform) {
super(shape, endShape, colorTransform);
this.swf = swf;
this.bounds = bounds;
}
public String getSVG() {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
StringWriter writer = new StringWriter();
try {
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(_svg);
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
} catch (TransformerException ex) {
Logger.getLogger(SVGMorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
return writer.toString();
}
@Override
public void beginShape() {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
DOMImplementation impl = docBuilder.getDOMImplementation();
DocumentType svgDocType = impl.createDocumentType("svg", "-//W3C//DTD SVG 1.0//EN",
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd");
_svg = impl.createDocument(sNamespace, "svg", svgDocType);
Element svgRoot = _svg.getDocumentElement();
svgRoot.setAttribute("xmlns:xlink", xlinkNamespace);
_svgDefs = _svg.createElement("defs");
svgRoot.appendChild(_svgDefs);
_svgG = _svg.createElement("g");
_svgG.setAttribute("transform", "matrix(1, 0, 0, 1, "
+ roundPixels20(-bounds.xMin / (double) SWF.unitDivisor) + ", " + roundPixels20(-bounds.yMin / (double) SWF.unitDivisor) + ")");
svgRoot.appendChild(_svgG);
} catch (ParserConfigurationException ex) {
Logger.getLogger(SVGMorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
gradients = new ArrayList<>();
this.defaultColor = defaultColor;
this.exporter = exporter;
}
@Override
public void beginFill(RGB color, RGB colorEnd) {
if (color == null) {
color = new RGB(Color.BLACK);
color = new RGB(defaultColor == null ? Color.BLACK : defaultColor);
}
if (colorEnd == null) {
colorEnd = new RGB(Color.BLACK);
colorEnd = new RGB(defaultColor == null ? Color.BLACK : defaultColor);
}
finalizePath();
path.setAttribute("stroke", "none");
@@ -148,20 +86,20 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
public void beginGradientFill(int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio) {
finalizePath();
Element gradient = (type == FILLSTYLE.LINEAR_GRADIENT)
? _svg.createElement("linearGradient")
: _svg.createElement("radialGradient");
? exporter.createElement("linearGradient")
: exporter.createElement("radialGradient");
populateGradientElement(gradient, type, gradientRecords, gradientRecordsEnd, matrix, matrixEnd, spreadMethod, interpolationMethod, focalPointRatio);
int id = gradients.indexOf(gradient);
int id = exporter.gradients.indexOf(gradient);
if (id < 0) {
// todo: filter same gradients
id = gradients.size();
gradients.add(gradient);
id = exporter.gradients.size();
exporter.gradients.add(gradient);
}
gradient.setAttribute("id", "gradient" + id);
path.setAttribute("stroke", "none");
path.setAttribute("fill", "url(#gradient" + id + ")");
path.setAttribute("fill-rule", "evenodd");
_svgDefs.appendChild(gradient);
exporter.addToDefs(gradient);
}
@Override
@@ -200,7 +138,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
}
String base64ImgData = DatatypeConverter.printBase64Binary(imageData);
path.setAttribute("style", "fill:url(#" + patternId + ")");
Element pattern = _svg.createElement("pattern");
Element pattern = exporter.createElement("pattern");
pattern.setAttribute("id", patternId);
pattern.setAttribute("patternUnits", "userSpaceOnUse");
pattern.setAttribute("overflow", "visible");
@@ -217,12 +155,12 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
pattern.setAttribute("patternTransform", "matrix(" + scaleX + ", " + rotateSkew0
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
}
Element imageElement = _svg.createElement("image");
Element imageElement = exporter.createElement("image");
imageElement.setAttribute("width", "" + width);
imageElement.setAttribute("height", "" + height);
imageElement.setAttribute("xlink:href", "data:image/" + format + ";base64," + base64ImgData);
pattern.appendChild(imageElement);
_svgG.appendChild(pattern);
exporter.addToGroup(pattern);
}
}
}
@@ -230,9 +168,6 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
@Override
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
finalizePath();
if (thickness > maxLineWidth) {
maxLineWidth = thickness;
}
thickness /= SWF.unitDivisor;
thicknessEnd /= SWF.unitDivisor;
path.setAttribute("fill", "none");
@@ -280,23 +215,23 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio) {
path.removeAttribute("stroke-opacity");
Element gradient = (type == FILLSTYLE.LINEAR_GRADIENT)
? _svg.createElement("linearGradient")
: _svg.createElement("radialGradient");
? exporter.createElement("linearGradient")
: exporter.createElement("radialGradient");
populateGradientElement(gradient, type, gradientRecords, gradientRecordsEnd, matrix, matrixEnd, spreadMethod, interpolationMethod, focalPointRatio);
int id = gradients.indexOf(gradient);
int id = exporter.gradients.indexOf(gradient);
if (id < 0) {
// todo: filter same gradients
id = gradients.size();
gradients.add(gradient);
id = exporter.gradients.size();
exporter.gradients.add(gradient);
}
gradient.setAttribute("id", "gradient" + id);
path.setAttribute("stroke", "url(#gradient" + id + ")");
path.setAttribute("fill", "none");
_svgDefs.appendChild(gradient);
exporter.addToDefs(gradient);
}
private Element createAnimateElement(String attributeName, Object startValue, Object endValue) {
Element animate = _svg.createElement("animate");
Element animate = exporter.createElement("animate");
animate.setAttribute("dur", "2s"); // todo
animate.setAttribute("repeatCount", "indefinite");
animate.setAttribute("attributeName", attributeName);
@@ -309,9 +244,9 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
if (path != null && !"".equals(pathData)) {
path.setAttribute("d", pathData.trim());
path.appendChild(createAnimateElement("d", pathData.trim(), pathDataEnd.trim()));
_svgG.appendChild(path);
exporter.addToGroup(path);
}
path = _svg.createElement("path");
path = exporter.createElement("path");
super.finalizePath();
}
@@ -364,7 +299,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
double scaleXEnd = Math.signum(a) * Math.sqrt(a * a + b * b);
double scaleYEnd = Math.signum(d) * Math.sqrt(c * c + d * d);
Element animateRotate = _svg.createElement("animateTransform");
Element animateRotate = exporter.createElement("animateTransform");
animateRotate.setAttribute("dur", "2s"); // todo
animateRotate.setAttribute("repeatCount", "indefinite");
animateRotate.setAttribute("attributeName", "gradientTransform");
@@ -373,7 +308,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
animateRotate.setAttribute("from", Double.toString(rotate));
animateRotate.setAttribute("to", Double.toString(rotateEnd));
Element animateScale = _svg.createElement("animateTransform");
Element animateScale = exporter.createElement("animateTransform");
animateScale.setAttribute("dur", "2s"); // todo
animateScale.setAttribute("repeatCount", "indefinite");
animateScale.setAttribute("attributeName", "gradientTransform");
@@ -382,7 +317,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
animateScale.setAttribute("from", scaleX + " " + scaleY);
animateScale.setAttribute("to", scaleXEnd + " " + scaleYEnd);
Element animateTranslate = _svg.createElement("animateTransform");
Element animateTranslate = exporter.createElement("animateTransform");
animateTranslate.setAttribute("dur", "2s"); // todo
animateTranslate.setAttribute("repeatCount", "indefinite");
animateTranslate.setAttribute("attributeName", "gradientTransform");
@@ -398,7 +333,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
for (int i = 0; i < gradientRecords.length; i++) {
GRADRECORD record = gradientRecords[i];
GRADRECORD recordEnd = gradientRecordsEnd[i];
Element gradientEntry = _svg.createElement("stop");
Element gradientEntry = exporter.createElement("stop");
gradientEntry.setAttribute("offset", Double.toString(record.ratio / 255.0));
gradientEntry.appendChild(createAnimateElement("offset", record.ratio / 255.0, recordEnd.ratio / 255.0));
RGB color = record.color;

View File

@@ -17,8 +17,8 @@
package com.jpexs.decompiler.flash.exporters.shape;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -35,26 +35,9 @@ import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
/**
@@ -63,74 +46,29 @@ import org.w3c.dom.Element;
*/
public class SVGShapeExporter extends DefaultSVGShapeExporter {
protected static final String sNamespace = "http://www.w3.org/2000/svg";
protected static final String xlinkNamespace = "http://www.w3.org/1999/xlink";
protected Document _svg;
protected Element _svgDefs;
protected Element _svgG;
protected Element path;
protected List<Element> gradients;
protected int lastPatternId;
private final Color defaultColor;
private final SWF swf;
private double maxLineWidth;
private final ExportRectangle bounds;
private final SVGExporter exporter;
private final String shapeId;
public SVGShapeExporter(SWF swf, SHAPE shape, ExportRectangle bounds, ColorTransform colorTransform) {
this(swf, shape, bounds, colorTransform, "");
public SVGShapeExporter(SWF swf, SHAPE shape, SVGExporter exporter, Color defaultColor, ColorTransform colorTransform) {
this(swf, shape, exporter, defaultColor, colorTransform, "");
}
public SVGShapeExporter(SWF swf, SHAPE shape, ExportRectangle bounds, ColorTransform colorTransform, String shapeId) {
public SVGShapeExporter(SWF swf, SHAPE shape, SVGExporter exporter, Color defaultColor, ColorTransform colorTransform, String shapeId) {
super(shape, colorTransform);
this.swf = swf;
this.bounds = bounds;
this.defaultColor = defaultColor;
this.exporter = exporter;
this.shapeId = shapeId;
}
public String getSVG() {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
StringWriter writer = new StringWriter();
try {
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(_svg);
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
} catch (TransformerException ex) {
Logger.getLogger(SVGShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
return writer.toString();
}
@Override
public void beginShape() {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
DOMImplementation impl = docBuilder.getDOMImplementation();
DocumentType svgDocType = impl.createDocumentType("svg", "-//W3C//DTD SVG 1.0//EN",
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd");
_svg = impl.createDocument(sNamespace, "svg", svgDocType);
Element svgRoot = _svg.getDocumentElement();
svgRoot.setAttribute("xmlns:xlink", xlinkNamespace);
_svgDefs = _svg.createElement("defs");
svgRoot.appendChild(_svgDefs);
_svgG = _svg.createElement("g");
_svgG.setAttribute("transform", "matrix(1, 0, 0, 1, "
+ roundPixels20(-bounds.xMin / (double) SWF.unitDivisor) + ", " + roundPixels20(-bounds.yMin / (double) SWF.unitDivisor) + ")");
svgRoot.appendChild(_svgG);
} catch (ParserConfigurationException ex) {
Logger.getLogger(SVGShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
gradients = new ArrayList<>();
}
@Override
public void beginFill(RGB color) {
if (color == null) {
color = new RGB(Color.BLACK);
color = new RGB(defaultColor == null ? Color.BLACK : defaultColor);
}
finalizePath();
path.setAttribute("stroke", "none");
@@ -148,21 +86,21 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
public void beginGradientFill(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
finalizePath();
Element gradient = (type == FILLSTYLE.LINEAR_GRADIENT)
? _svg.createElement("linearGradient")
: _svg.createElement("radialGradient");
? exporter.createElement("linearGradient")
: exporter.createElement("radialGradient");
populateGradientElement(gradient, type, gradientRecords, matrix, spreadMethod, interpolationMethod, focalPointRatio);
int id = gradients.indexOf(gradient);
int id = exporter.gradients.indexOf(gradient);
if (id < 0) {
// todo: filter same gradients
id = gradients.size();
gradients.add(gradient);
id = exporter.gradients.size();
exporter.gradients.add(gradient);
}
String gradientId = "gradient" + shapeId + id;
gradient.setAttribute("id", gradientId);
path.setAttribute("stroke", "none");
path.setAttribute("fill", "url(#" + gradientId + ")");
path.setAttribute("fill-rule", "evenodd");
_svgDefs.appendChild(gradient);
exporter.addToDefs(gradient);
}
@Override
@@ -205,7 +143,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
}
String base64ImgData = DatatypeConverter.printBase64Binary(imageData);
path.setAttribute("style", "fill:url(#" + patternId + ")");
Element pattern = _svg.createElement("pattern");
Element pattern = exporter.createElement("pattern");
pattern.setAttribute("id", patternId);
pattern.setAttribute("patternUnits", "userSpaceOnUse");
pattern.setAttribute("overflow", "visible");
@@ -222,12 +160,12 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
pattern.setAttribute("patternTransform", "matrix(" + scaleX + ", " + rotateSkew0
+ ", " + rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")");
}
Element imageElement = _svg.createElement("image");
Element imageElement = exporter.createElement("image");
imageElement.setAttribute("width", "" + width);
imageElement.setAttribute("height", "" + height);
imageElement.setAttribute("xlink:href", "data:image/" + format + ";base64," + base64ImgData);
pattern.appendChild(imageElement);
_svgG.appendChild(pattern);
exporter.addToGroup(pattern);
}
}
}
@@ -235,9 +173,6 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
@Override
public void lineStyle(double thickness, RGB color, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
finalizePath();
if (thickness > maxLineWidth) {
maxLineWidth = thickness;
}
thickness /= SWF.unitDivisor;
path.setAttribute("fill", "none");
path.setAttribute("stroke", color.toHexRGB());
@@ -279,28 +214,28 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) {
path.removeAttribute("stroke-opacity");
Element gradient = (type == FILLSTYLE.LINEAR_GRADIENT)
? _svg.createElement("linearGradient")
: _svg.createElement("radialGradient");
? exporter.createElement("linearGradient")
: exporter.createElement("radialGradient");
populateGradientElement(gradient, type, gradientRecords, matrix, spreadMethod, interpolationMethod, focalPointRatio);
int id = gradients.indexOf(gradient);
int id = exporter.gradients.indexOf(gradient);
if (id < 0) {
// todo: filter same gradients
id = gradients.size();
gradients.add(gradient);
id = exporter.gradients.size();
exporter.gradients.add(gradient);
}
gradient.setAttribute("id", "gradient" + id);
path.setAttribute("stroke", "url(#gradient" + id + ")");
path.setAttribute("fill", "none");
_svgDefs.appendChild(gradient);
exporter.addToDefs(gradient);
}
@Override
protected void finalizePath() {
if (path != null && !"".equals(pathData)) {
path.setAttribute("d", pathData.trim());
_svgG.appendChild(path);
exporter.addToGroup(path);
}
path = _svg.createElement("path");
path = exporter.createElement("path");
super.finalizePath();
}
@@ -344,7 +279,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
}
for (int i = 0; i < gradientRecords.length; i++) {
GRADRECORD record = gradientRecords[i];
Element gradientEntry = _svg.createElement("stop");
Element gradientEntry = exporter.createElement("stop");
gradientEntry.setAttribute("offset", Double.toString(record.ratio / 255.0));
RGB color = record.color;
//if(colors.get(i) != 0) {

View File

@@ -17,7 +17,6 @@
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.AppStrings;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
import java.awt.BorderLayout;
import java.awt.Color;

View File

@@ -87,7 +87,6 @@ import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

View File

@@ -939,7 +939,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
return "";
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.exporters.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.morphshape.SVGMorphShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
@@ -329,20 +330,20 @@ public class DefineMorphShape2Tag extends CharacterTag implements MorphShapeTag
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
if (ratio == -2) {
SHAPEWITHSTYLE beginShapes = getShapeAtRatio(0);
SHAPEWITHSTYLE endShapes = getShapeAtRatio(65535);
SVGMorphShapeExporter exporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, rect, new ColorTransform() /*FIXME?*/);
SVGMorphShapeExporter exporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
} else {
SHAPEWITHSTYLE shapes = getShapeAtRatio(ratio);
SVGShapeExporter exporter = new SVGShapeExporter(swf, shapes, rect, new ColorTransform() /*FIXME?*/);
SVGShapeExporter exporter = new SVGShapeExporter(swf, shapes, svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
}
return svgExporter.getSVG();
}
@Override

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.exporters.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.morphshape.SVGMorphShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
@@ -312,20 +313,20 @@ public class DefineMorphShapeTag extends CharacterTag implements MorphShapeTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
if (ratio == -2) {
SHAPEWITHSTYLE beginShapes = getShapeAtRatio(0);
SHAPEWITHSTYLE endShapes = getShapeAtRatio(65535);
SVGMorphShapeExporter exporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, rect, new ColorTransform() /*FIXME?*/);
SVGMorphShapeExporter exporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
} else {
SHAPEWITHSTYLE shapes = getShapeAtRatio(ratio);
SVGShapeExporter exporter = new SVGShapeExporter(swf, shapes, rect, new ColorTransform() /*FIXME?*/);
SVGShapeExporter exporter = new SVGShapeExporter(swf, shapes, svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
}
return svgExporter.getSVG();
}
@Override

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
@@ -61,11 +62,12 @@ public class DefineShape2Tag extends ShapeTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), rect, new ColorTransform() /*FIXME?*/);
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
return svgExporter.getSVG();
}
@Override

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
@@ -66,11 +67,12 @@ public class DefineShape3Tag extends ShapeTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), rect, new ColorTransform() /*FIXME?*/);
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
return svgExporter.getSVG();
}
/* @Override

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
@@ -69,11 +70,12 @@ public class DefineShape4Tag extends ShapeTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), rect, new ColorTransform() /*FIXME?*/);
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
return svgExporter.getSVG();
}
@Override

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.SVGExporterContext;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
@@ -94,11 +95,12 @@ public class DefineShapeTag extends ShapeTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
ExportRectangle rect = new ExportRectangle(getRect());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), rect, new ColorTransform() /*FIXME?*/);
SVGExporter svgExporter = new SVGExporter(rect, new ColorTransform());
SVGShapeExporter exporter = new SVGShapeExporter(swf, getShapes(), svgExporter, null, new ColorTransform() /*FIXME?*/);
exporter.export();
return exporter.getSVG();
return svgExporter.getSVG();
}
/* @Override

View File

@@ -290,7 +290,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, Drawable
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) throws IOException {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) throws IOException {
return SWF.frameToSvg(getTimeline(), 0, 0, null, 0, exporterContext, getRect(), new ColorTransform(), null, level + 1);
}

View File

@@ -494,9 +494,8 @@ public class DefineText2Tag extends TextTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
return "";
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
return staticTextToSVG(swf, textRecords, 2, getTextMatrix(), colorTransform);
}
@Override

View File

@@ -510,9 +510,8 @@ public class DefineTextTag extends TextTag {
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
return "";
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
return staticTextToSVG(swf, textRecords, 1, getTextMatrix(), colorTransform);
}
@Override

View File

@@ -59,7 +59,7 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
return "";
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

View File

@@ -33,7 +33,7 @@ public interface DrawableTag extends BoundedTag {
public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform);
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) throws IOException;
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) throws IOException;
public Point getImagePos(int frame);

View File

@@ -260,9 +260,8 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
@Override
public String toSVG(SVGExporterContext exporterContext, int ratio, int level) {
public String toSVG(SVGExporterContext exporterContext, int ratio, ColorTransform colorTransform, int level) {
return "";
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override

View File

@@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.SVGExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.text.ParseException;
import com.jpexs.decompiler.flash.timeline.DepthState;
@@ -264,7 +266,6 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
int textHeight = 12;
int x = 0;
int y = 0;
Graphics2D g = (Graphics2D) image.getGraphics();
List<SHAPE> glyphs = new ArrayList<>();
for (TEXTRECORD rec : textRecords) {
if (rec.styleFlagsHasColor) {
@@ -304,6 +305,52 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
}
}
public static String staticTextToSVG(SWF swf, List<TEXTRECORD> textRecords, int numText, MATRIX textMatrix, ColorTransform colorTransform) {
Color textColor = new Color(0, 0, 0);
FontTag font = null;
int textHeight = 12;
int x = 0;
int y = 0;
List<SHAPE> glyphs = new ArrayList<>();
SVGExporter svgExporter = new SVGExporter(null, new ColorTransform());
for (TEXTRECORD rec : textRecords) {
if (rec.styleFlagsHasColor) {
if (numText == 2) {
textColor = colorTransform.apply(rec.textColorA.toColor());
} else {
textColor = colorTransform.apply(rec.textColor.toColor());
}
}
if (rec.styleFlagsHasFont) {
font = (FontTag) swf.characters.get(rec.fontId);
glyphs = font.getGlyphShapeTable();
textHeight = rec.textHeight;
}
if (rec.styleFlagsHasXOffset) {
x = rec.xOffset;
}
if (rec.styleFlagsHasYOffset) {
y = rec.yOffset;
}
double rat = textHeight / 1024.0 / font.getDivider();
for (GLYPHENTRY entry : rec.glyphEntries) {
Matrix matTr = Matrix.getTranslateInstance(x, y);
Matrix mat = new Matrix(textMatrix).concatenate(matTr).concatenate(Matrix.getScaleInstance(rat));
if (entry.glyphIndex != -1) {
// shapeNum: 1
SHAPE shape = glyphs.get(entry.glyphIndex);
svgExporter.createNewGroup(mat);
SVGShapeExporter exporter = new SVGShapeExporter(swf, shape, svgExporter, textColor, new ColorTransform() /*FIXME?*/);
exporter.export();
x += entry.glyphAdvance;
}
}
}
return svgExporter.getSVG();
}
@Override
public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) {
RECT r = getBounds();