mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-26 20:10:45 +00:00
#369: SVG export fix
This commit is contained in:
@@ -63,7 +63,7 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa
|
||||
|
||||
@Override
|
||||
public String toSVG() {
|
||||
return shapes.toSVG(2, swf.tags);
|
||||
return shapes.toSVG(2, swf.tags, shapeBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -68,7 +68,7 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa
|
||||
|
||||
@Override
|
||||
public String toSVG() {
|
||||
return shapes.toSVG(3, swf.tags);
|
||||
return shapes.toSVG(3, swf.tags, shapeBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa
|
||||
|
||||
@Override
|
||||
public String toSVG() {
|
||||
return shapes.toSVG(4, swf.tags);
|
||||
return shapes.toSVG(4, swf.tags, shapeBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -76,7 +76,7 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag
|
||||
|
||||
@Override
|
||||
public String toSVG() {
|
||||
return shapes.toSVG(1, swf.tags);
|
||||
return shapes.toSVG(1, swf.tags, shapeBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,7 +51,7 @@ public class SHAPE implements NeedsCharacters {
|
||||
* @return String with XML representation of this shape (SVG)
|
||||
*/
|
||||
public String toSVG(int shapeNum, List<Tag> tags) {
|
||||
return SHAPERECORD.shapeToSVG(tags, shapeNum, null, null, numFillBits, numLineBits, shapeRecords);
|
||||
return SHAPERECORD.shapeToSVG(tags, shapeNum, null, null, numFillBits, numLineBits, shapeRecords, new RECT());
|
||||
}
|
||||
|
||||
public BufferedImage toImage(int shapeNum, List<Tag> tags, Color defaultColor, boolean putToCache) {
|
||||
|
||||
@@ -50,10 +50,12 @@ public class SHAPEWITHSTYLE implements NeedsCharacters {
|
||||
* Converts shape to SVG
|
||||
*
|
||||
* @param shapeNum Type of DefineShape
|
||||
* @param tags
|
||||
* @param bounds
|
||||
* @return String with XML representation of this shape (SVG)
|
||||
*/
|
||||
public String toSVG(int shapeNum, List<Tag> tags) {
|
||||
return SHAPERECORD.shapeToSVG(tags, shapeNum, fillStyles, lineStyles, numFillBits, numLineBits, shapeRecords);
|
||||
public String toSVG(int shapeNum, List<Tag> tags, RECT bounds) {
|
||||
return SHAPERECORD.shapeToSVG(tags, shapeNum, fillStyles, lineStyles, numFillBits, numLineBits, shapeRecords, bounds);
|
||||
}
|
||||
|
||||
public BufferedImage toImage(int shapeNum, List<Tag> tags) {
|
||||
|
||||
@@ -39,8 +39,12 @@ public class CurvedEdgeRecord extends SHAPERECORD {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSWG(int oldX, int oldY) {
|
||||
return "Q " + SWF.twipToPixel(oldX + controlDeltaX) + " " + SWF.twipToPixel(oldY + controlDeltaY) + " " + SWF.twipToPixel(oldX + controlDeltaX + anchorDeltaX) + " " + SWF.twipToPixel(oldY + controlDeltaY + anchorDeltaY);
|
||||
public String toSVG(int oldX, int oldY, SVGRenderingContext context) {
|
||||
String result = "";
|
||||
if (!context.wasMoveTo) {
|
||||
result = "M " + SWF.twipToPixel(oldX) + " " + SWF.twipToPixel(oldY) + " ";
|
||||
}
|
||||
return result + "Q " + SWF.twipToPixel(oldX + controlDeltaX) + " " + SWF.twipToPixel(oldY + controlDeltaY) + " " + SWF.twipToPixel(oldX + controlDeltaX + anchorDeltaX) + " " + SWF.twipToPixel(oldY + controlDeltaY + anchorDeltaY);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class EndShapeRecord extends SHAPERECORD {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSWG(int oldX, int oldY) {
|
||||
public String toSVG(int oldX, int oldY, SVGRenderingContext context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
@@ -101,7 +102,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
public Point start;
|
||||
public Point end;
|
||||
|
||||
public void draw(int startX, int startY, Graphics2D g, int shapeNum) {
|
||||
private void draw(int startX, int startY, Graphics2D g, int shapeNum) {
|
||||
AffineTransform oldAf = g.getTransform();
|
||||
AffineTransform trans20 = AffineTransform.getScaleInstance(1 / DESCALE, 1 / DESCALE);
|
||||
boolean ok = false;
|
||||
@@ -161,7 +162,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
g.setClip(null);
|
||||
}
|
||||
|
||||
public void fill(List<Tag> tags, int startX, int startY, Graphics2D g, int shapeNum) {
|
||||
private void fill(List<Tag> tags, int startX, int startY, Graphics2D g, int shapeNum) {
|
||||
if (fillStyle0 == null) {
|
||||
return;
|
||||
}
|
||||
@@ -480,8 +481,9 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
String points = "";
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
context.wasMoveTo = false;
|
||||
for (SHAPERECORD r : edges) {
|
||||
points += " " + r.toSWG(x, y);
|
||||
points += " " + r.toSVG(x, y, context);
|
||||
x = r.changeX(x);
|
||||
y = r.changeY(y);
|
||||
}
|
||||
@@ -490,7 +492,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
}
|
||||
}
|
||||
|
||||
public abstract String toSWG(int oldX, int oldY);
|
||||
public abstract String toSVG(int oldX, int oldY, SVGRenderingContext context);
|
||||
|
||||
public abstract int changeX(int x);
|
||||
|
||||
@@ -849,22 +851,25 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
|
||||
* @param records
|
||||
* @return Shape converted to SVG
|
||||
*/
|
||||
public static String shapeToSVG(List<Tag> tags, int shapeNum, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStylesList, int numFillBits, int numLineBits, List<SHAPERECORD> records) {
|
||||
public static String shapeToSVG(List<Tag> tags, int shapeNum, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStylesList, int numFillBits, int numLineBits, List<SHAPERECORD> records, RECT bounds) {
|
||||
String ret = "";
|
||||
RECT bounds = new RECT();
|
||||
List<Path> paths = getPaths(bounds, shapeNum, fillStyles, lineStylesList, /*numFillBits, numLineBits,*/ records);
|
||||
RECT rect = new RECT();
|
||||
List<Path> paths = getPaths(rect, shapeNum, fillStyles, lineStylesList, /*numFillBits, numLineBits,*/ records);
|
||||
ret = "";
|
||||
SVGRenderingContext context = new SVGRenderingContext();
|
||||
ret += "<g id=\"1\" transform=\"matrix(1, 0, 0, 1, "
|
||||
+ SWF.twipToPixel(-bounds.Xmin) + ", " + SWF.twipToPixel(-bounds.Ymin) + ")\">\n";
|
||||
for (Path p : paths) {
|
||||
ret += p.toSVG(tags, shapeNum, context);
|
||||
ret += p.toSVG(tags, shapeNum, context) + "\n";
|
||||
}
|
||||
ret += "</g>\n";
|
||||
ret = "<?xml version='1.0' encoding='UTF-8' ?> \n"
|
||||
+ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
|
||||
+ "<svg width=\"" + (int) Math.ceil(SWF.twipToPixel(bounds.Xmax)) + "\"\n"
|
||||
+ " height=\"" + (int) Math.ceil(SWF.twipToPixel(bounds.Ymax)) + "\"\n"
|
||||
+ " viewBox=\"0 0 " + (int) Math.ceil(SWF.twipToPixel(bounds.Xmax)) + " " + (int) Math.ceil(SWF.twipToPixel(bounds.Ymax) + 50) + "\"\n"
|
||||
+ "<svg width=\"" + (int) Math.ceil(SWF.twipToPixel(bounds.Xmax - bounds.Xmin)) + "\"\n"
|
||||
+ " height=\"" + (int) Math.ceil(SWF.twipToPixel(bounds.Ymax - bounds.Ymin)) + "\"\n"
|
||||
+ " viewBox=\"0 0 " + (int) Math.ceil(SWF.twipToPixel(bounds.Xmax - bounds.Xmin)) + " " + (int) Math.ceil(SWF.twipToPixel(bounds.Ymax - bounds.Ymin)) + "\"\n"
|
||||
+ " xmlns=\"http://www.w3.org/2000/svg\"\n"
|
||||
+ " xmlns:xlink=\"http://www.w3.org/1999/xlink\">" + ret + ""
|
||||
+ " xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" + ret + ""
|
||||
+ "</svg>";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -24,4 +24,5 @@ package com.jpexs.decompiler.flash.types.shaperecords;
|
||||
public class SVGRenderingContext {
|
||||
|
||||
public int patternCount = 0;
|
||||
public boolean wasMoveTo;
|
||||
}
|
||||
|
||||
@@ -39,13 +39,17 @@ public class StraightEdgeRecord extends SHAPERECORD {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSWG(int oldX, int oldY) {
|
||||
public String toSVG(int oldX, int oldY, SVGRenderingContext context) {
|
||||
String result = "";
|
||||
if (!context.wasMoveTo) {
|
||||
result = "M " + SWF.twipToPixel(oldX) + " " + SWF.twipToPixel(oldY) + " ";
|
||||
}
|
||||
if (generalLineFlag) {
|
||||
return "L " + SWF.twipToPixel(oldX + deltaX) + " " + SWF.twipToPixel(oldY + deltaY);
|
||||
return result + "L " + SWF.twipToPixel(oldX + deltaX) + " " + SWF.twipToPixel(oldY + deltaY);
|
||||
} else if (vertLineFlag) {
|
||||
return "V " + SWF.twipToPixel(oldY + deltaY);
|
||||
return result + "V " + SWF.twipToPixel(oldY + deltaY);
|
||||
} else {
|
||||
return "H " + SWF.twipToPixel(oldX + deltaX);
|
||||
return result + "H " + SWF.twipToPixel(oldX + deltaX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,9 +64,12 @@ public class StyleChangeRecord extends SHAPERECORD implements Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSWG(int oldX, int oldY) {
|
||||
public String toSVG(int oldX, int oldY, SVGRenderingContext context) {
|
||||
if (stateMoveTo) {
|
||||
return "M " + SWF.twipToPixel(moveDeltaX) + " " + SWF.twipToPixel(moveDeltaY);
|
||||
if ((!context.wasMoveTo) || ((moveDeltaX != oldX) || (moveDeltaY != oldY))) {
|
||||
context.wasMoveTo = true;
|
||||
return "M " + SWF.twipToPixel(moveDeltaX) + " " + SWF.twipToPixel(moveDeltaY);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user