mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-25 10:36:30 +00:00
miterlimit is FIXED8 (float)
This commit is contained in:
@@ -245,7 +245,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, float miterLimit) {
|
||||
finalizePath();
|
||||
thickness /= SWF.unitDivisor;
|
||||
thicknessEnd /= SWF.unitDivisor;
|
||||
|
||||
@@ -92,7 +92,7 @@ public abstract class DefaultSVGMorphShapeExporter extends MorphShapeExporterBas
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, int miterLimit) {
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, float miterLimit) {
|
||||
finalizePath();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.morphshape;
|
||||
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
@@ -46,7 +47,7 @@ public interface IMorphShapeExporter {
|
||||
|
||||
public void endFill();
|
||||
|
||||
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, float miterLimit);
|
||||
|
||||
public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio, float focalPointRatioEnd);
|
||||
|
||||
|
||||
@@ -199,12 +199,10 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
|
||||
if (straightEdgeRecord.generalLineFlag) {
|
||||
xPos += straightEdgeRecord.deltaX;
|
||||
yPos += straightEdgeRecord.deltaY;
|
||||
} else if (straightEdgeRecord.vertLineFlag) {
|
||||
yPos += straightEdgeRecord.deltaY;
|
||||
} else {
|
||||
if (straightEdgeRecord.vertLineFlag) {
|
||||
yPos += straightEdgeRecord.deltaY;
|
||||
} else {
|
||||
xPos += straightEdgeRecord.deltaX;
|
||||
}
|
||||
xPos += straightEdgeRecord.deltaX;
|
||||
}
|
||||
|
||||
StraightEdgeRecord straightEdgeRecordEnd = (StraightEdgeRecord) shapeRecordEnd;
|
||||
@@ -213,12 +211,10 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
|
||||
if (straightEdgeRecordEnd.generalLineFlag) {
|
||||
xPosEnd += straightEdgeRecordEnd.deltaX;
|
||||
yPosEnd += straightEdgeRecordEnd.deltaY;
|
||||
} else if (straightEdgeRecordEnd.vertLineFlag) {
|
||||
yPosEnd += straightEdgeRecordEnd.deltaY;
|
||||
} else {
|
||||
if (straightEdgeRecordEnd.vertLineFlag) {
|
||||
yPosEnd += straightEdgeRecordEnd.deltaY;
|
||||
} else {
|
||||
xPosEnd += straightEdgeRecordEnd.deltaX;
|
||||
}
|
||||
xPosEnd += straightEdgeRecordEnd.deltaX;
|
||||
}
|
||||
|
||||
subPath.add(new StraightMorphEdge(xPosFrom, yPosFrom, xPos, yPos, xPosEndFrom, yPosEndFrom, xPosEnd, yPosEnd, currentLineStyleIdx, currentFillStyleIdx1));
|
||||
@@ -397,7 +393,7 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
|
||||
int startCapStyle = LINESTYLE2.ROUND_CAP;
|
||||
int endCapStyle = LINESTYLE2.ROUND_CAP;
|
||||
int joinStyle = LINESTYLE2.ROUND_JOIN;
|
||||
int miterLimitFactor = 3;
|
||||
float miterLimitFactor = 3f;
|
||||
boolean hasFillFlag = false;
|
||||
if (lineStyle instanceof LINESTYLE2) {
|
||||
LINESTYLE2 lineStyle2 = (LINESTYLE2) lineStyle;
|
||||
|
||||
@@ -147,7 +147,7 @@ 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) {
|
||||
public void lineStyle(double thickness, double thicknessEnd, RGB color, RGB colorEnd, boolean pixelHinting, String scaleMode, int startCaps, int endCaps, int joints, float miterLimit) {
|
||||
finalizePath();
|
||||
thickness *= zoom / SWF.unitDivisor;
|
||||
thicknessEnd *= zoom / SWF.unitDivisor;
|
||||
@@ -187,8 +187,8 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
|
||||
break;
|
||||
default:
|
||||
path.setAttribute("stroke-linejoin", "miter");
|
||||
if (miterLimit >= 1 && miterLimit != 4) {
|
||||
path.setAttribute("stroke-miterlimit", Integer.toString(miterLimit));
|
||||
if (miterLimit >= 1 && miterLimit != 4f) {
|
||||
path.setAttribute("stroke-miterlimit", Double.toString(miterLimit));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,10 @@ public class SWFDecompilerPlugin {
|
||||
|
||||
private static final List<SWFDecompilerListener> listeners = new ArrayList<>();
|
||||
|
||||
public static void loadPlugins() {
|
||||
public static File getPluginsDir() {
|
||||
File pluginPath = null;
|
||||
|
||||
try {
|
||||
File pluginPath = null;
|
||||
String pluginPathConfig = Configuration.pluginPath.get();
|
||||
if (pluginPathConfig != null && !pluginPathConfig.isEmpty()) {
|
||||
pluginPath = new File(pluginPathConfig);
|
||||
@@ -65,20 +66,25 @@ public class SWFDecompilerPlugin {
|
||||
File dir = f.getAbsoluteFile().getParentFile().getParentFile();
|
||||
pluginPath = new File(Path.combine(dir.getPath(), "plugins")).getCanonicalFile();
|
||||
}
|
||||
|
||||
if (pluginPath.exists()) {
|
||||
System.out.println("Loading plugins from " + pluginPath.getPath());
|
||||
File[] files = pluginPath.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
System.out.println("Loading plugin: " + file.getPath());
|
||||
loadPlugin(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException ex) {
|
||||
Logger.getLogger(SWFDecompilerPlugin.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return pluginPath;
|
||||
}
|
||||
|
||||
public static void loadPlugins() {
|
||||
File pluginPath = getPluginsDir();
|
||||
if (pluginPath != null && pluginPath.exists()) {
|
||||
System.out.println("Loading plugins from " + pluginPath.getPath());
|
||||
File[] files = pluginPath.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
System.out.println("Loading plugin: " + file.getPath());
|
||||
loadPlugin(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void loadPlugin(String path) {
|
||||
|
||||
@@ -870,6 +870,9 @@ public class ShapeImporter {
|
||||
}
|
||||
|
||||
private void processRect(int shapeNum, SHAPEWITHSTYLE shapes, Element childElement, Matrix transform, SvgStyle style) {
|
||||
|
||||
Point startPoint = new Point(0, 0);
|
||||
|
||||
String attr = childElement.getAttribute("x");
|
||||
double x = attr.length() > 0 ? Double.parseDouble(attr) : 0;
|
||||
|
||||
@@ -909,6 +912,8 @@ public class ShapeImporter {
|
||||
scr.command = 'M';
|
||||
scr.params = new double[]{x + width, y + ry};
|
||||
pathCommands.add(scr);
|
||||
startPoint.x = x + width;
|
||||
startPoint.y = y + ry;
|
||||
|
||||
double sqrt2RXHalf = Math.sqrt(2) * rx / 2;
|
||||
double sqrt2Minus1RX = (Math.sqrt(2) - 1) * rx;
|
||||
@@ -956,6 +961,8 @@ public class ShapeImporter {
|
||||
PathCommand scr = new PathCommand();
|
||||
scr.command = 'M';
|
||||
scr.params = new double[]{x, y};
|
||||
startPoint.x = x;
|
||||
startPoint.y = y;
|
||||
pathCommands.add(scr);
|
||||
|
||||
double[] points = new double[]{
|
||||
@@ -973,6 +980,11 @@ public class ShapeImporter {
|
||||
}
|
||||
}
|
||||
|
||||
PathCommand serz = new PathCommand();
|
||||
serz.command = 'Z';
|
||||
serz.params = new double[]{startPoint.x, startPoint.y};
|
||||
pathCommands.add(serz);
|
||||
|
||||
processCommands(shapeNum, shapes, pathCommands, transform, style);
|
||||
}
|
||||
|
||||
@@ -1093,183 +1105,194 @@ public class ShapeImporter {
|
||||
//Test for SVG
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
//svgTest("pservers-grad-01-b");
|
||||
svgTest("pservers-grad-05-b");
|
||||
svgTest("pservers-grad-07-b");
|
||||
}
|
||||
|
||||
private void applyFillGradients(SvgFill fill, FILLSTYLE fillStyle, RECT bounds, StyleChangeRecord scr, Matrix transform, int shapeNum, SvgStyle style) {
|
||||
if (fill == null || fillStyle == null) {
|
||||
return;
|
||||
}
|
||||
if (fill instanceof SvgGradient) {
|
||||
SvgGradient gfill = (SvgGradient) fill;
|
||||
Matrix gradientMatrix = Matrix.parseSvgMatrix(gfill.gradientTransform, SWF.unitDivisor, 1);
|
||||
gradientMatrix = transform.concatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).concatenate(gradientMatrix);
|
||||
fillStyle.gradientMatrix = gradientMatrix.toMATRIX();
|
||||
if (fill instanceof SvgLinearGradient) {
|
||||
SvgLinearGradient lgfill = (SvgLinearGradient) fill;
|
||||
fillStyle.fillStyleType = FILLSTYLE.LINEAR_GRADIENT;
|
||||
fillStyle.gradient = new GRADIENT();
|
||||
double x1;
|
||||
if (lgfill.x1.endsWith("%")) {
|
||||
x1 = Double.parseDouble(lgfill.x1.substring(0, lgfill.x1.length() - 1)) / 100;
|
||||
} else {
|
||||
x1 = Double.parseDouble(lgfill.x1);
|
||||
}
|
||||
//x1 = x1 - (-819.2);
|
||||
|
||||
double y1;
|
||||
if (lgfill.y1.endsWith("%")) {
|
||||
y1 = Double.parseDouble(lgfill.y1.substring(0, lgfill.y1.length() - 1)) / 100;
|
||||
} else {
|
||||
y1 = Double.parseDouble(lgfill.y1);
|
||||
}
|
||||
double x2;
|
||||
if (lgfill.x2.endsWith("%")) {
|
||||
x2 = Double.parseDouble(lgfill.x2.substring(0, lgfill.x2.length() - 1)) / 100;
|
||||
} else {
|
||||
x2 = Double.parseDouble(lgfill.x2);
|
||||
}
|
||||
//x2 = x2 - 819.2;
|
||||
double y2;
|
||||
if (lgfill.y2.endsWith("%")) {
|
||||
y2 = Double.parseDouble(lgfill.y2.substring(0, lgfill.y2.length() - 1)) / 100;
|
||||
} else {
|
||||
y2 = Double.parseDouble(lgfill.y2);
|
||||
}
|
||||
x1 = x1 * SWF.unitDivisor;
|
||||
y1 = y1 * SWF.unitDivisor;
|
||||
x2 = x2 * SWF.unitDivisor;
|
||||
y2 = y2 * SWF.unitDivisor;
|
||||
|
||||
Matrix boundingBoxMatrix = new Matrix();
|
||||
if (lgfill.gradientUnits == SvgGradientUnits.OBJECT_BOUNDING_BOX) {
|
||||
boundingBoxMatrix.scaleX = (bounds.Xmax - bounds.Xmin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.rotateSkew0 = 0;
|
||||
boundingBoxMatrix.rotateSkew1 = 0;
|
||||
boundingBoxMatrix.scaleY = (bounds.Ymax - bounds.Ymin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.translateX = bounds.Xmin;
|
||||
boundingBoxMatrix.translateY = bounds.Ymin;
|
||||
}
|
||||
|
||||
Matrix xyMatrix = new Matrix();
|
||||
xyMatrix.scaleX = x2 - x1;
|
||||
xyMatrix.rotateSkew0 = y2 - y1;
|
||||
xyMatrix.rotateSkew1 = -xyMatrix.rotateSkew0;
|
||||
xyMatrix.scaleY = xyMatrix.scaleX;
|
||||
|
||||
xyMatrix = xyMatrix.preConcatenate(boundingBoxMatrix);
|
||||
|
||||
Matrix zeroStartMatrix = Matrix.getTranslateInstance(0.5, 0);
|
||||
|
||||
Matrix scaleMatrix = Matrix.getScaleInstance(1 / 16384.0 / 2);
|
||||
Matrix transMatrix = Matrix.getTranslateInstance(x1, y1);
|
||||
|
||||
Matrix tMatrix = new Matrix();
|
||||
tMatrix = tMatrix.preConcatenate(scaleMatrix);
|
||||
tMatrix = tMatrix.preConcatenate(zeroStartMatrix);
|
||||
tMatrix = tMatrix.preConcatenate(xyMatrix);
|
||||
|
||||
tMatrix = tMatrix.preConcatenate(transMatrix);
|
||||
Point p1 = tMatrix.transform(new Point(-16384, 0));
|
||||
Point p2 = tMatrix.transform(new Point(16384, 0));
|
||||
|
||||
tMatrix = tMatrix.preConcatenate(new Matrix(fillStyle.gradientMatrix));
|
||||
fillStyle.gradientMatrix = tMatrix.toMATRIX();
|
||||
} else if (fill instanceof SvgRadialGradient) {
|
||||
SvgRadialGradient rgfill = (SvgRadialGradient) fill;
|
||||
double cx;
|
||||
if (rgfill.cx.endsWith("%")) {
|
||||
cx = Double.parseDouble(rgfill.cx.substring(0, rgfill.cx.length() - 1)) / 100;
|
||||
} else {
|
||||
cx = Double.parseDouble(rgfill.cx);
|
||||
}
|
||||
double cy;
|
||||
if (rgfill.cy.endsWith("%")) {
|
||||
cy = Double.parseDouble(rgfill.cy.substring(0, rgfill.cy.length() - 1)) / 100;
|
||||
} else {
|
||||
cy = Double.parseDouble(rgfill.cy);
|
||||
}
|
||||
|
||||
double r;
|
||||
if (rgfill.r.endsWith("%")) {
|
||||
r = Double.parseDouble(rgfill.r.substring(0, rgfill.r.length() - 1)) / 100;
|
||||
} else {
|
||||
r = Double.parseDouble(rgfill.r);
|
||||
}
|
||||
|
||||
Matrix boundingBoxMatrix = new Matrix();
|
||||
if (rgfill.gradientUnits == SvgGradientUnits.OBJECT_BOUNDING_BOX) {
|
||||
boundingBoxMatrix.scaleX = (bounds.Xmax - bounds.Xmin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.rotateSkew0 = 0;
|
||||
boundingBoxMatrix.rotateSkew1 = 0;
|
||||
boundingBoxMatrix.scaleY = (bounds.Ymax - bounds.Ymin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.translateX = bounds.Xmin;
|
||||
boundingBoxMatrix.translateY = bounds.Ymin;
|
||||
}
|
||||
|
||||
fillStyle.gradientMatrix = Matrix.getTranslateInstance(SWF.unitDivisor * cx, SWF.unitDivisor * cy).concatenate(new Matrix(fillStyle.gradientMatrix)).concatenate(Matrix.getScaleInstance(r / 819.2)).preConcatenate(boundingBoxMatrix).toMATRIX();
|
||||
|
||||
double fx;
|
||||
if (rgfill.fx.endsWith("%")) {
|
||||
fx = Double.parseDouble(rgfill.fx.substring(0, rgfill.fx.length() - 1)) / 100;
|
||||
} else {
|
||||
fx = Double.parseDouble(rgfill.fx);
|
||||
}
|
||||
double fy;
|
||||
if (rgfill.fy.endsWith("%")) {
|
||||
fy = Double.parseDouble(rgfill.fy.substring(0, rgfill.fy.length() - 1)) / 100;
|
||||
} else {
|
||||
fy = Double.parseDouble(rgfill.fy);
|
||||
}
|
||||
if (!rgfill.fx.equals(rgfill.cx) || !rgfill.fy.equals(rgfill.cy)) {
|
||||
fillStyle.fillStyleType = FILLSTYLE.FOCAL_RADIAL_GRADIENT;
|
||||
fillStyle.gradient = new FOCALGRADIENT();
|
||||
FOCALGRADIENT fg = (FOCALGRADIENT) fillStyle.gradient;
|
||||
double f = Math.sqrt((fx - cx) * (fx - cx) + (fy - cy) * (fy - cy)) / 819.2;
|
||||
fg.focalPoint = (float) f;
|
||||
} else {
|
||||
fillStyle.fillStyleType = FILLSTYLE.RADIAL_GRADIENT;
|
||||
fillStyle.gradient = new GRADIENT();
|
||||
}
|
||||
}
|
||||
switch (gfill.spreadMethod) {
|
||||
case PAD:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_PAD_MODE;
|
||||
break;
|
||||
case REFLECT:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_REFLECT_MODE;
|
||||
break;
|
||||
case REPEAT:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_REPEAT_MODE;
|
||||
break;
|
||||
}
|
||||
switch (gfill.interpolation) {
|
||||
case LINEAR_RGB:
|
||||
fillStyle.gradient.interpolationMode = GRADIENT.INTERPOLATION_LINEAR_RGB_MODE;
|
||||
break;
|
||||
case SRGB:
|
||||
fillStyle.gradient.interpolationMode = GRADIENT.INTERPOLATION_RGB_MODE;
|
||||
break;
|
||||
}
|
||||
|
||||
fillStyle.gradient.gradientRecords = new GRADRECORD[gfill.stops.size()];
|
||||
for (int i = 0; i < gfill.stops.size(); i++) {
|
||||
SvgStop stop = gfill.stops.get(i);
|
||||
Color color = stop.color;
|
||||
color = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) Math.round(color.getAlpha() * style.opacity));
|
||||
fillStyle.gradient.gradientRecords[i] = new GRADRECORD();
|
||||
fillStyle.gradient.gradientRecords[i].inShape3 = shapeNum >= 3;
|
||||
fillStyle.gradient.gradientRecords[i].color = getRGB(shapeNum, color);
|
||||
fillStyle.gradient.gradientRecords[i].ratio = (int) Math.round(stop.offset * 255);
|
||||
}
|
||||
} else if (fill instanceof SvgBitmapFill) {
|
||||
SvgBitmapFill bfill = (SvgBitmapFill) fill;
|
||||
fillStyle.fillStyleType = FILLSTYLE.REPEATING_BITMAP;
|
||||
fillStyle.bitmapId = bfill.characterId;
|
||||
Matrix fillMatrix = Matrix.parseSvgMatrix(bfill.patternTransform, SWF.unitDivisor, SWF.unitDivisor);
|
||||
fillMatrix = transform.concatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).concatenate(fillMatrix);
|
||||
fillStyle.bitmapMatrix = fillMatrix.toMATRIX();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyStyleGradients(RECT bounds, StyleChangeRecord scr, Matrix transform, int shapeNum, SvgStyle style) {
|
||||
SvgFill fill = style.getFillWithOpacity();
|
||||
if (fill != null) {
|
||||
if (fill instanceof SvgGradient) {
|
||||
FILLSTYLE fillStyle = scr.fillStyles.fillStyles[0];
|
||||
SvgGradient gfill = (SvgGradient) fill;
|
||||
Matrix gradientMatrix = Matrix.parseSvgMatrix(gfill.gradientTransform, SWF.unitDivisor, 1);
|
||||
gradientMatrix = transform.concatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).concatenate(gradientMatrix);
|
||||
fillStyle.gradientMatrix = gradientMatrix.toMATRIX();
|
||||
if (fill instanceof SvgLinearGradient) {
|
||||
SvgLinearGradient lgfill = (SvgLinearGradient) fill;
|
||||
fillStyle.fillStyleType = FILLSTYLE.LINEAR_GRADIENT;
|
||||
fillStyle.gradient = new GRADIENT();
|
||||
double x1;
|
||||
if (lgfill.x1.endsWith("%")) {
|
||||
x1 = Double.parseDouble(lgfill.x1.substring(0, lgfill.x1.length() - 1)) / 100;
|
||||
} else {
|
||||
x1 = Double.parseDouble(lgfill.x1);
|
||||
}
|
||||
//x1 = x1 - (-819.2);
|
||||
|
||||
double y1;
|
||||
if (lgfill.y1.endsWith("%")) {
|
||||
y1 = Double.parseDouble(lgfill.y1.substring(0, lgfill.y1.length() - 1)) / 100;
|
||||
} else {
|
||||
y1 = Double.parseDouble(lgfill.y1);
|
||||
}
|
||||
double x2;
|
||||
if (lgfill.x2.endsWith("%")) {
|
||||
x2 = Double.parseDouble(lgfill.x2.substring(0, lgfill.x2.length() - 1)) / 100;
|
||||
} else {
|
||||
x2 = Double.parseDouble(lgfill.x2);
|
||||
}
|
||||
//x2 = x2 - 819.2;
|
||||
double y2;
|
||||
if (lgfill.y2.endsWith("%")) {
|
||||
y2 = Double.parseDouble(lgfill.y2.substring(0, lgfill.y2.length() - 1)) / 100;
|
||||
} else {
|
||||
y2 = Double.parseDouble(lgfill.y2);
|
||||
}
|
||||
x1 = x1 * SWF.unitDivisor;
|
||||
y1 = y1 * SWF.unitDivisor;
|
||||
x2 = x2 * SWF.unitDivisor;
|
||||
y2 = y2 * SWF.unitDivisor;
|
||||
|
||||
Matrix boundingBoxMatrix = new Matrix();
|
||||
if (lgfill.gradientUnits == SvgGradientUnits.OBJECT_BOUNDING_BOX) {
|
||||
boundingBoxMatrix.scaleX = (bounds.Xmax - bounds.Xmin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.rotateSkew0 = 0;
|
||||
boundingBoxMatrix.rotateSkew1 = 0;
|
||||
boundingBoxMatrix.scaleY = (bounds.Ymax - bounds.Ymin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.translateX = bounds.Xmin;
|
||||
boundingBoxMatrix.translateY = bounds.Ymin;
|
||||
}
|
||||
|
||||
Matrix xyMatrix = new Matrix();
|
||||
xyMatrix.scaleX = x2 - x1;
|
||||
xyMatrix.rotateSkew0 = y2 - y1;
|
||||
xyMatrix.rotateSkew1 = -xyMatrix.rotateSkew0;
|
||||
xyMatrix.scaleY = xyMatrix.scaleX;
|
||||
|
||||
xyMatrix = xyMatrix.preConcatenate(boundingBoxMatrix);
|
||||
|
||||
Matrix zeroStartMatrix = Matrix.getTranslateInstance(0.5, 0);
|
||||
|
||||
Matrix scaleMatrix = Matrix.getScaleInstance(1 / 16384.0 / 2);
|
||||
Matrix transMatrix = Matrix.getTranslateInstance(x1, y1);
|
||||
|
||||
Matrix tMatrix = new Matrix();
|
||||
tMatrix = tMatrix.preConcatenate(scaleMatrix);
|
||||
tMatrix = tMatrix.preConcatenate(zeroStartMatrix);
|
||||
tMatrix = tMatrix.preConcatenate(xyMatrix);
|
||||
|
||||
tMatrix = tMatrix.preConcatenate(transMatrix);
|
||||
Point p1 = tMatrix.transform(new Point(-16384, 0));
|
||||
Point p2 = tMatrix.transform(new Point(16384, 0));
|
||||
|
||||
tMatrix = tMatrix.preConcatenate(new Matrix(fillStyle.gradientMatrix));
|
||||
fillStyle.gradientMatrix = tMatrix.toMATRIX();
|
||||
} else if (fill instanceof SvgRadialGradient) {
|
||||
SvgRadialGradient rgfill = (SvgRadialGradient) fill;
|
||||
double cx;
|
||||
if (rgfill.cx.endsWith("%")) {
|
||||
cx = Double.parseDouble(rgfill.cx.substring(0, rgfill.cx.length() - 1)) / 100;
|
||||
} else {
|
||||
cx = Double.parseDouble(rgfill.cx);
|
||||
}
|
||||
double cy;
|
||||
if (rgfill.cy.endsWith("%")) {
|
||||
cy = Double.parseDouble(rgfill.cy.substring(0, rgfill.cy.length() - 1)) / 100;
|
||||
} else {
|
||||
cy = Double.parseDouble(rgfill.cy);
|
||||
}
|
||||
|
||||
double r;
|
||||
if (rgfill.r.endsWith("%")) {
|
||||
r = Double.parseDouble(rgfill.r.substring(0, rgfill.r.length() - 1)) / 100;
|
||||
} else {
|
||||
r = Double.parseDouble(rgfill.r);
|
||||
}
|
||||
|
||||
Matrix boundingBoxMatrix = new Matrix();
|
||||
if (rgfill.gradientUnits == SvgGradientUnits.OBJECT_BOUNDING_BOX) {
|
||||
boundingBoxMatrix.scaleX = (bounds.Xmax - bounds.Xmin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.rotateSkew0 = 0;
|
||||
boundingBoxMatrix.rotateSkew1 = 0;
|
||||
boundingBoxMatrix.scaleY = (bounds.Ymax - bounds.Ymin) / SWF.unitDivisor;
|
||||
boundingBoxMatrix.translateX = bounds.Xmin;
|
||||
boundingBoxMatrix.translateY = bounds.Ymin;
|
||||
}
|
||||
|
||||
fillStyle.gradientMatrix = Matrix.getTranslateInstance(SWF.unitDivisor * cx, SWF.unitDivisor * cy).concatenate(new Matrix(fillStyle.gradientMatrix)).concatenate(Matrix.getScaleInstance(r / 819.2)).preConcatenate(boundingBoxMatrix).toMATRIX();
|
||||
|
||||
double fx;
|
||||
if (rgfill.fx.endsWith("%")) {
|
||||
fx = Double.parseDouble(rgfill.fx.substring(0, rgfill.fx.length() - 1)) / 100;
|
||||
} else {
|
||||
fx = Double.parseDouble(rgfill.fx);
|
||||
}
|
||||
double fy;
|
||||
if (rgfill.fy.endsWith("%")) {
|
||||
fy = Double.parseDouble(rgfill.fy.substring(0, rgfill.fy.length() - 1)) / 100;
|
||||
} else {
|
||||
fy = Double.parseDouble(rgfill.fy);
|
||||
}
|
||||
if (!rgfill.fx.equals(rgfill.cx) || !rgfill.fy.equals(rgfill.cy)) {
|
||||
fillStyle.fillStyleType = FILLSTYLE.FOCAL_RADIAL_GRADIENT;
|
||||
fillStyle.gradient = new FOCALGRADIENT();
|
||||
FOCALGRADIENT fg = (FOCALGRADIENT) fillStyle.gradient;
|
||||
double f = Math.sqrt((fx - cx) * (fx - cx) + (fy - cy) * (fy - cy)) / 819.2;
|
||||
fg.focalPoint = (float) f;
|
||||
} else {
|
||||
fillStyle.fillStyleType = FILLSTYLE.RADIAL_GRADIENT;
|
||||
fillStyle.gradient = new GRADIENT();
|
||||
}
|
||||
}
|
||||
switch (gfill.spreadMethod) {
|
||||
case PAD:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_PAD_MODE;
|
||||
break;
|
||||
case REFLECT:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_REFLECT_MODE;
|
||||
break;
|
||||
case REPEAT:
|
||||
fillStyle.gradient.spreadMode = GRADIENT.SPREAD_REPEAT_MODE;
|
||||
break;
|
||||
}
|
||||
switch (gfill.interpolation) {
|
||||
case LINEAR_RGB:
|
||||
fillStyle.gradient.interpolationMode = GRADIENT.INTERPOLATION_LINEAR_RGB_MODE;
|
||||
break;
|
||||
case SRGB:
|
||||
fillStyle.gradient.interpolationMode = GRADIENT.INTERPOLATION_RGB_MODE;
|
||||
break;
|
||||
}
|
||||
|
||||
fillStyle.gradient.gradientRecords = new GRADRECORD[gfill.stops.size()];
|
||||
for (int i = 0; i < gfill.stops.size(); i++) {
|
||||
SvgStop stop = gfill.stops.get(i);
|
||||
Color color = stop.color;
|
||||
color = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) Math.round(color.getAlpha() * style.opacity));
|
||||
fillStyle.gradient.gradientRecords[i] = new GRADRECORD();
|
||||
fillStyle.gradient.gradientRecords[i].inShape3 = shapeNum >= 3;
|
||||
fillStyle.gradient.gradientRecords[i].color = getRGB(shapeNum, color);
|
||||
fillStyle.gradient.gradientRecords[i].ratio = (int) Math.round(stop.offset * 255);
|
||||
}
|
||||
} else if (fill instanceof SvgBitmapFill) {
|
||||
FILLSTYLE fillStyle = scr.fillStyles.fillStyles[0];
|
||||
SvgBitmapFill bfill = (SvgBitmapFill) fill;
|
||||
fillStyle.fillStyleType = FILLSTYLE.REPEATING_BITMAP;
|
||||
fillStyle.bitmapId = bfill.characterId;
|
||||
Matrix fillMatrix = Matrix.parseSvgMatrix(bfill.patternTransform, SWF.unitDivisor, SWF.unitDivisor);
|
||||
fillMatrix = transform.concatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).concatenate(fillMatrix);
|
||||
fillStyle.bitmapMatrix = fillMatrix.toMATRIX();
|
||||
applyFillGradients(fill, scr.fillStyles.fillStyles[0], bounds, scr, transform, shapeNum, style);
|
||||
}
|
||||
SvgFill strokeFill = style.getStrokeFillWithOpacity();
|
||||
if (strokeFill != null) {
|
||||
if (scr.lineStyles.lineStyles.length > 0 && scr.lineStyles.lineStyles[0] instanceof LINESTYLE2) {
|
||||
applyFillGradients(strokeFill, ((LINESTYLE2) scr.lineStyles.lineStyles[0]).fillType, bounds, scr, transform, shapeNum, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1300,7 +1323,7 @@ public class ShapeImporter {
|
||||
}
|
||||
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
SvgFill strokeFill = style.getStrokeColorWithOpacity();
|
||||
SvgFill strokeFill = style.getStrokeFillWithOpacity();
|
||||
if (strokeFill != null) {
|
||||
Color lineColor = strokeFill.toColor();
|
||||
|
||||
@@ -1317,12 +1340,17 @@ public class ShapeImporter {
|
||||
: lineCap == SvgLineCap.SQUARE ? LINESTYLE2.SQUARE_CAP : 0;
|
||||
lineStyle2.startCapStyle = swfCap;
|
||||
lineStyle2.endCapStyle = swfCap;
|
||||
if (!(strokeFill instanceof SvgColor)) {
|
||||
lineStyle2.hasFillFlag = true;
|
||||
lineStyle2.fillType = new FILLSTYLE();
|
||||
//...apply in second step - applyStyleGradients
|
||||
}//Single color does not need fillType attribute
|
||||
|
||||
int swfJoin = lineJoin == SvgLineJoin.MITER ? LINESTYLE2.MITER_JOIN
|
||||
: lineJoin == SvgLineJoin.ROUND ? LINESTYLE2.ROUND_JOIN
|
||||
: lineJoin == SvgLineJoin.BEVEL ? LINESTYLE2.BEVEL_JOIN : 0;
|
||||
lineStyle2.joinStyle = swfJoin;
|
||||
lineStyle2.miterLimitFactor = (int) Math.round(style.strokeMiterLimit * 256);
|
||||
lineStyle2.miterLimitFactor = (float) style.strokeMiterLimit;
|
||||
} else {
|
||||
if (lineCap != SvgLineCap.ROUND) {
|
||||
showWarning("lineCapNotSupported", "LineCap style not supported in shape " + shapeNum);
|
||||
@@ -2185,6 +2213,23 @@ public class ShapeImporter {
|
||||
return new SvgColor(fillColor.getRed(), fillColor.getGreen(), fillColor.getBlue(), opacity);
|
||||
}
|
||||
|
||||
public SvgFill getStrokeFillWithOpacity() {
|
||||
if (strokeFill == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(strokeFill instanceof SvgColor)) {
|
||||
return strokeFill;
|
||||
}
|
||||
Color strokeFillColor = ((SvgColor) strokeFill).color;
|
||||
|
||||
int opacity = (int) Math.round(this.opacity * strokeOpacity * 255);
|
||||
if (opacity == 255) {
|
||||
return strokeFill;
|
||||
}
|
||||
|
||||
return new SvgColor(strokeFillColor.getRed(), strokeFillColor.getGreen(), strokeFillColor.getBlue(), opacity);
|
||||
}
|
||||
|
||||
public SvgFill getStrokeColorWithOpacity() {
|
||||
if (strokeFill == null) {
|
||||
return null;
|
||||
|
||||
@@ -63,9 +63,9 @@ public class LINESTYLE2 extends LINESTYLE implements Serializable {
|
||||
@SWFType(value = BasicType.UB, count = 2)
|
||||
public int endCapStyle;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
@SWFType(BasicType.FIXED8)
|
||||
@Conditional(value = "joinStyle", options = MITER_JOIN)
|
||||
public int miterLimitFactor;
|
||||
public float miterLimitFactor;
|
||||
|
||||
public FILLSTYLE fillType;
|
||||
|
||||
|
||||
@@ -216,8 +216,8 @@ public class XFLConverter {
|
||||
+ "<SolidColor color=\"")
|
||||
.append(ls.color.toHexRGB()).append("\"")
|
||||
.append(shapeNum == 3 ? " alpha=\"" + ((RGBA) ls.color).getAlphaFloat() + "\"" : "").append(" />"
|
||||
+ "</fill>"
|
||||
+ "</SolidStroke>");
|
||||
+ "</fill>"
|
||||
+ "</SolidStroke>");
|
||||
}
|
||||
|
||||
private static void convertLineStyle(HashMap<Integer, CharacterTag> characters, LINESTYLE2 ls, int shapeNum, StringBuilder ret) {
|
||||
@@ -250,7 +250,7 @@ public class XFLConverter {
|
||||
break;
|
||||
case LINESTYLE2.MITER_JOIN:
|
||||
params.append(" joints=\"miter\"");
|
||||
float miterLimitFactor = toFloat(ls.miterLimitFactor);
|
||||
float miterLimitFactor = ls.miterLimitFactor;
|
||||
if (miterLimitFactor != 3.0f) {
|
||||
params.append(" miterLimit=\"").append(miterLimitFactor).append("\"");
|
||||
}
|
||||
@@ -274,10 +274,6 @@ public class XFLConverter {
|
||||
ret.append("</SolidStroke>");
|
||||
}
|
||||
|
||||
private static float toFloat(int i) {
|
||||
return ((float) i) / (1 << 16);
|
||||
}
|
||||
|
||||
private static void convertFillStyle(MATRIX mat, HashMap<Integer, CharacterTag> characters, FILLSTYLE fs, int shapeNum, StringBuilder ret) {
|
||||
/* todo: use matrix
|
||||
if (mat == null) {
|
||||
@@ -2183,7 +2179,7 @@ public class XFLConverter {
|
||||
if (ret2.length() > 0) {
|
||||
ret.append("<DOMLayer name=\"Layer ").append(layerIndex).append("\" color=\"").append(randomOutlineColor()).append("\">"
|
||||
+ "<frames>").append(ret2).append("</frames>"
|
||||
+ "</DOMLayer>");
|
||||
+ "</DOMLayer>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user