mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-25 01:25:33 +00:00
frame SVG export: export static texts
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user