miterlimit is FIXED8 (float)

This commit is contained in:
Jindra Petřík
2015-12-26 23:28:32 +01:00
parent bc7b57c6fb
commit 09d4772eef
9 changed files with 259 additions and 215 deletions

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>");
}
}