diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java index c527037a9..859992f8b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java @@ -386,7 +386,7 @@ public class IdentifiersDeobfuscation { } else if (c == '\u00A7') { ret.append("\\\u00A7"); } else if (c < 32) { - ret.append("\\x").append(Helper.padZeros(Integer.toHexString((int) c), 2)); + ret.append("\\x").append(Helper.byteToHex((byte) c)); } else { ret.append(c); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index a5f097df0..48a2f2466 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -155,6 +155,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; @@ -978,6 +979,23 @@ public final class SWF implements SWFContainerItem, Timelined { fileTitle = null; } + public Date getFileModificationDate() { + try { + if (swfList != null && swfList.sourceInfo != null) { + String fileName = swfList.sourceInfo.getFile(); + if (fileName != null) { + long lastModified = new File(fileName).lastModified(); + if (lastModified > 0) { + return new Date(lastModified); + } + } + } + } catch (SecurityException sex) { + } + + return new Date(); + } + private static void getAbcTags(List list, List actionScripts) { for (Tag t : list) { if (t instanceof DefineSpriteTag) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 895ab324a..d8008d263 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -282,7 +282,6 @@ import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.ScriptEndItem; import com.jpexs.helpers.Helper; import java.io.ByteArrayInputStream; @@ -859,24 +858,13 @@ public class AVM2Code implements Cloneable { StringBuilder s = new StringBuilder(); for (AVM2Instruction instruction : code) { s.append(instruction.toString()); - s.append("\r\n"); + s.append(Helper.newLine); } return s.toString(); } - public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { - int i = 0; - for (AVM2Instruction instruction : code) { - writer.appendNoHilight(Helper.formatAddress(i)); - writer.appendNoHilight(" "); - instruction.toString(writer, localData).newLine(); - i++; - } - return writer; - } - public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ScriptExportMode exportMode, GraphTextWriter writer) { - return toASMSource(constants, trait, info, body, new ArrayList(), exportMode, writer); + return toASMSource(constants, trait, info, body, new ArrayList<>(), exportMode, writer); } public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List outputMap, ScriptExportMode exportMode, GraphTextWriter writer) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java index 1781e0fbe..4c9835f7d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/AVM2Instruction.java @@ -284,7 +284,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem { } public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) { - writer.appendNoHilight(Helper.formatAddress(offset) + " " + Helper.padSpaceRight(Helper.byteArrToString(getBytes()), 30) + definition.instructionName); + writer.appendNoHilight(Helper.formatAddress(offset) + " " + String.format("%-30s", Helper.byteArrToString(getBytes())) + definition.instructionName); writer.appendNoHilight(getParams(localData.constantsAvm2, localData.fullyQualifiedNames) + getComment()); return writer; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java index 1cfb355b5..9a13c6499 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java @@ -226,17 +226,25 @@ public class MethodInfo { @Override public String toString() { - String optionalStr = "["; + StringBuilder ret = new StringBuilder(); + ret.append("MethodInfo: param_types="); + Helper.intArrToStringBuilder(param_types, ret); + ret.append(" ret_type=").append(ret_type) + .append(" name_index=").append(name_index) + .append(" flags=").append(flags) + .append(" optional=["); if (optional != null) { for (int i = 0; i < optional.length; i++) { if (i > 0) { - optionalStr += ","; + ret.append(","); } - optionalStr += optional[i].toString(); + ret.append(optional[i].toString()); } } - optionalStr += "]"; - return "MethodInfo: param_types=" + Helper.intArrToString(param_types) + " ret_type=" + ret_type + " name_index=" + name_index + " flags=" + flags + " optional=" + optionalStr + " paramNames=" + Helper.intArrToString(paramNames); + ret.append("]"); + ret.append(" paramNames="); + Helper.intArrToStringBuilder(paramNames, ret); + return ret.toString(); } public String toString(AVM2ConstantPool constants, List fullyQualifiedNames) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java index 0da3a9766..1e72a52de 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java @@ -198,16 +198,17 @@ public class Multiname { if (index == 0) { return "null"; } - String ret = "["; + StringBuilder ret = new StringBuilder(); + ret.append("["); for (int n = 0; n < constants.getNamespaceSet(index).namespaces.length; n++) { if (n > 0) { - ret += ","; + ret.append(","); } int ns = constants.getNamespaceSet(index).namespaces[n]; - ret += namespaceToString(constants, ns); + ret.append(namespaceToString(constants, ns)); } - ret += "]"; - return ret; + ret.append("]"); + return ret.toString(); } private static String multinameToString(AVM2ConstantPool constants, int index, List fullyQualifiedNames) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java index a75cf932b..c2bd1ffce 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java @@ -139,25 +139,20 @@ public class ActionTry extends Action implements GraphSourceItemContainer { @Override public String getASMSourceBetween(int pos) { - String ret = ""; if (pos == 0) { if (catchBlockFlag) { - ret += "Catch"; - ret += " {\r\n"; - return ret; + return "Catch {\r\n"; } if (finallyBlockFlag) { - ret += "Finally {\r\n"; - return ret; + return "Finally {\r\n"; } } if (pos == 1) { if (catchBlockFlag && finallyBlockFlag) { - ret += "Finally {\r\n"; - return ret; + return "Finally {\r\n"; } } - return ret; + return ""; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index cffdeca97..1216008c4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -47,6 +47,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; +/** + * + * @author JPEXS + */ public class Configuration { private static final String CONFIG_NAME = "config.bin"; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/SwfSpecificConfiguration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/SwfSpecificConfiguration.java new file mode 100644 index 000000000..a55b91eb6 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/SwfSpecificConfiguration.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.configuration; + +/** + * + * @author JPEXS + */ +public class SwfSpecificConfiguration { +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java index da3252b16..8b065160e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java @@ -155,13 +155,10 @@ public class FontExporter { f.setVersion("1.0"); SWF swf = t.getSwf(); - if (swf != null && swf.swfList != null && swf.swfList.sourceInfo != null) { - String fileName = swf.swfList.sourceInfo.getFile(); - if (fileName != null) { - Date date = new Date(new File(fileName).lastModified()); - f.setCreationDate(date); - f.setModificationDate(date); - } + if (swf != null) { + Date date = swf.getFileModificationDate(); + f.setCreationDate(date); + f.setModificationDate(date); } int ascent = t.getAscent(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java index 05b7fa4b0..cf8257ffc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java @@ -564,15 +564,15 @@ public class FrameExporter { for (FILTER filter : layer.filters) { if (filter instanceof COLORMATRIXFILTER) { COLORMATRIXFILTER cmf = (COLORMATRIXFILTER) filter; - String mat = "["; + sb.append("\t\t\tfcanvas = Filters.colorMatrix(fcanvas,fcanvas.getContext(\"2d\"),["); for (int k = 0; k < cmf.matrix.length; k++) { if (k > 0) { - mat += ","; + sb.append(","); } - mat += cmf.matrix[k]; + sb.append(cmf.matrix[k]); } - mat += "]"; - sb.append("\t\t\tfcanvas = Filters.colorMatrix(fcanvas,fcanvas.getContext(\"2d\"),").append(mat).append(");\r\n"); + sb.append("]"); + sb.append(");\r\n"); } if (filter instanceof CONVOLUTIONFILTER) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java index af0484046..5bfbb62b0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java @@ -72,7 +72,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { protected SWF swf; - protected String lineFillData = null; + protected StringBuilder lineFillData = null; protected String lineLastRadColor = null; @@ -281,7 +281,7 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { @Override public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, GRADRECORD[] gradientRecordsEnd, Matrix matrix, Matrix matrixEnd, int spreadMethod, int interpolationMethod, float focalPointRatio, float focalPointRatioEnd) { - lineFillData = ""; + lineFillData = new StringBuilder(); //TODO: How many repeats is ideal? final int REPEAT_CNT = 5; @@ -302,11 +302,11 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { start2.y += deltaY; end2.x += deltaX; end2.y += deltaY; - lineFillData += "\tvar grd=ctx.createLinearGradient(" + useRatioPos(start.x, start2.x) + "," + useRatioPos(start.y, start2.y) + "," + useRatioPos(end.x, end2.x) + "," + useRatioPos(end.y, end2.y) + ");\r\n"; + lineFillData.append("\tvar grd=ctx.createLinearGradient(").append(useRatioPos(start.x, start2.x)).append(",").append(useRatioPos(start.y, start2.y)).append(",").append(useRatioPos(end.x, end2.x)).append(",").append(useRatioPos(end.y, end2.y)).append(");\r\n"); } else { lineFillMatrix = matrix; lineFillMatrixEnd = matrixEnd; - lineFillData += "\tvar grd=ctx.createRadialGradient(" + useRatioDouble(focalPointRatio * 16384, focalPointRatioEnd * 16384) + ",0,0,0,0," + (16384 + 32768 * repeatCnt) + ");\r\n"; + lineFillData.append("\tvar grd=ctx.createRadialGradient(").append(useRatioDouble(focalPointRatio * 16384, focalPointRatioEnd * 16384)).append(",0,0,0,0,").append(16384 + 32768 * repeatCnt).append(");\r\n"); } int repeatTotal = lineRepeatCnt * 2 + 1; double oneHeight = 1.0 / repeatTotal; @@ -322,14 +322,14 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { for (int j = 0; j < gradientRecords.length; j++) { GRADRECORD r = gradientRecords[j]; GRADRECORD r2 = gradientRecordsEnd[j]; - lineFillData += "\tvar s=" + useRatioDouble(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0), pos + (oneHeight * (revert ? 255 - r2.ratio : r2.ratio) / 255.0)) + ";\r\n"; - lineFillData += "\tif(s<0) s = 0;\r\n\tif(s>1) s = 1;\r\n"; - lineFillData += "\tgrd.addColorStop(s," + useRatioColor(r.color, r2.color) + ");\r\n"; + lineFillData.append("\tvar s=").append(useRatioDouble(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0), pos + (oneHeight * (revert ? 255 - r2.ratio : r2.ratio) / 255.0))).append(";\r\n"); + lineFillData.append("\tif(s<0) s = 0;\r\n\tif(s>1) s = 1;\r\n"); + lineFillData.append("\tgrd.addColorStop(s,").append(useRatioColor(r.color, r2.color)).append(");\r\n"); lineLastRadColor = useRatioColor(r.color, r2.color); } pos += oneHeight; } - lineFillData += "\tctx.fillStyle = grd;\r\n"; + lineFillData.append("\tctx.fillStyle = grd;\r\n"); String preStrokeData = ""; @@ -406,34 +406,37 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { String drawFill = "\tdrawMorphPath(ctx,pathData,ratio,false);\r\n";; pathData = new StringBuilder(); if (lineFillData != null) { - String preLineFillData = ""; - preLineFillData += "\tvar oldctx = ctx;\r\n"; - preLineFillData += "\tctx.save();\r\n"; - preLineFillData += strokeData; - preLineFillData += drawStroke; - preLineFillData += "\tvar lfcanvas = document.createElement(\"canvas\");\r\n"; - preLineFillData += "\tlfcanvas.width = canvas.width;\r\n"; - preLineFillData += "\tlfcanvas.height = canvas.height;\r\n"; - preLineFillData += "\tvar lfctx = lfcanvas.getContext(\"2d\");\r\n"; - preLineFillData += "\tenhanceContext(lfctx);\r\n"; - preLineFillData += "\tlfctx.applyTransforms(ctx._matrix);\r\n"; - preLineFillData += "\tctx = lfctx;"; + StringBuilder preLineFillData = new StringBuilder(); + preLineFillData.append("\tvar oldctx = ctx;\r\n"); + preLineFillData.append("\tctx.save();\r\n"); + preLineFillData.append(strokeData); + preLineFillData.append(drawStroke); + preLineFillData.append("\tvar lfcanvas = document.createElement(\"canvas\");\r\n"); + preLineFillData.append("\tlfcanvas.width = canvas.width;\r\n"); + preLineFillData.append("\tlfcanvas.height = canvas.height;\r\n"); + preLineFillData.append("\tvar lfctx = lfcanvas.getContext(\"2d\");\r\n"); + preLineFillData.append("\tenhanceContext(lfctx);\r\n"); + preLineFillData.append("\tlfctx.applyTransforms(ctx._matrix);\r\n"); + preLineFillData.append("\tctx = lfctx;"); if (lineLastRadColor != null) { - preLineFillData += "\tctx.fillStyle=" + lineLastRadColor + ";\r\n ctx.fill(\"evenodd\");\r\n"; + preLineFillData.append("\tctx.fillStyle=").append(lineLastRadColor).append(";\r\n ctx.fill(\"evenodd\");\r\n"); } - preLineFillData += "\tctx.transform(" + useRatioDouble(lineFillMatrix.scaleX / unitDivisor, lineFillMatrixEnd.scaleX / unitDivisor) - + "," + useRatioDouble(lineFillMatrix.rotateSkew0 / unitDivisor, lineFillMatrixEnd.rotateSkew0 / unitDivisor) - + "," + useRatioDouble(lineFillMatrix.rotateSkew1 / unitDivisor, lineFillMatrixEnd.rotateSkew1 / unitDivisor) - + "," + useRatioDouble(lineFillMatrix.scaleY / unitDivisor, lineFillMatrixEnd.scaleY / unitDivisor) - + "," + useRatioDouble((lineFillMatrix.translateX + deltaX) / unitDivisor, (lineFillMatrixEnd.translateX + deltaX) / unitDivisor) - + "," + useRatioDouble((lineFillMatrix.translateY + deltaY) / unitDivisor, (lineFillMatrixEnd.translateY + deltaY) / unitDivisor) + ");\r\n"; - lineFillData = preLineFillData + lineFillData; - lineFillData += "\tctx.fillRect(" + (-16384 - 32768 * lineRepeatCnt) + "," + (-16384 - 32768 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + ");\r\n"; - lineFillData += "\tctx = oldctx;\r\n"; + preLineFillData.append("\tctx.transform(").append(useRatioDouble(lineFillMatrix.scaleX / unitDivisor, lineFillMatrixEnd.scaleX / unitDivisor)) + .append(",").append(useRatioDouble(lineFillMatrix.rotateSkew0 / unitDivisor, lineFillMatrixEnd.rotateSkew0 / unitDivisor)) + .append(",").append(useRatioDouble(lineFillMatrix.rotateSkew1 / unitDivisor, lineFillMatrixEnd.rotateSkew1 / unitDivisor)) + .append(",").append(useRatioDouble(lineFillMatrix.scaleY / unitDivisor, lineFillMatrixEnd.scaleY / unitDivisor)) + .append(",").append(useRatioDouble((lineFillMatrix.translateX + deltaX) / unitDivisor, (lineFillMatrixEnd.translateX + deltaX) / unitDivisor)) + .append(",").append(useRatioDouble((lineFillMatrix.translateY + deltaY) / unitDivisor, (lineFillMatrixEnd.translateY + deltaY) / unitDivisor)).append(");\r\n"); + lineFillData.insert(0, preLineFillData); + lineFillData.append("\tctx.fillRect(").append(-16384 - 32768 * lineRepeatCnt) + .append(",").append(-16384 - 32768 * lineRepeatCnt) + .append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt) + .append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt).append(");\r\n"); + lineFillData.append("\tctx = oldctx;\r\n"); //lcanvas - stroke //lfcanvas - stroke background - lineFillData += "\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n" + lineFillData.append("\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n" + "\tvar lpix = limgd.data;\r\n" + "\tvar lfimgd = lfctx.getImageData(0, 0, lfcanvas.width, lfcanvas.height);\r\n" + "\tvar lfpix = lfimgd.data;\r\n" @@ -442,8 +445,8 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { + "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n" + "\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n" + "\t}\r\n" - + "\tctx.putImageData(imgd, 0, 0);\r\n"; - lineFillData += "\tctx.restore();\r\n"; + + "\tctx.putImageData(imgd, 0, 0);\r\n"); + lineFillData.append("\tctx.restore();\r\n"); strokeData = new StringBuilder(); } else { pathData.append(strokeData); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CanvasShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CanvasShapeExporter.java index 43f09bd4a..6032a5026 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CanvasShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/CanvasShapeExporter.java @@ -70,7 +70,7 @@ public class CanvasShapeExporter extends ShapeExporterBase { protected RGB basicFill; - protected String lineFillData = null; + protected StringBuilder lineFillData = null; protected String lineLastRadColor = null; @@ -311,7 +311,7 @@ public class CanvasShapeExporter extends ShapeExporterBase { @Override public void lineGradientStyle(int type, GRADRECORD[] gradientRecords, Matrix matrix, int spreadMethod, int interpolationMethod, float focalPointRatio) { - lineFillData = ""; + lineFillData = new StringBuilder(); //TODO: How many repeats is ideal? final int REPEAT_CNT = 5; @@ -325,10 +325,10 @@ public class CanvasShapeExporter extends ShapeExporterBase { start.y += deltaY; end.x += deltaX; end.y += deltaY; - lineFillData += "\tvar grd=ctx.createLinearGradient(" + Double.toString(start.x / unitDivisor) + "," + Double.toString(start.y / unitDivisor) + "," + Double.toString(end.x / unitDivisor) + "," + Double.toString(end.y / unitDivisor) + ");\r\n"; + lineFillData.append("\tvar grd=ctx.createLinearGradient(").append(Double.toString(start.x / unitDivisor)).append(",").append(Double.toString(start.y / unitDivisor)).append(",").append(Double.toString(end.x / unitDivisor)).append(",").append(Double.toString(end.y / unitDivisor)).append(");\r\n"); } else { lineFillMatrix = matrix; - lineFillData += "\tvar grd=ctx.createRadialGradient(" + focalPointRatio * 16384 + ",0,0,0,0," + (16384 + 32768 * lineRepeatCnt) + ");\r\n"; + lineFillData.append("\tvar grd=ctx.createRadialGradient(").append(focalPointRatio * 16384).append(",0,0,0,0,").append(16384 + 32768 * lineRepeatCnt).append(");\r\n"); } int repeatTotal = lineRepeatCnt * 2 + 1; double oneHeight = 1.0 / repeatTotal; @@ -342,12 +342,12 @@ public class CanvasShapeExporter extends ShapeExporterBase { revert = !revert; } for (GRADRECORD r : gradientRecords) { - lineFillData += "\tgrd.addColorStop(" + Double.toString(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0)) + "," + color(r.color) + ");\r\n"; + lineFillData.append("\tgrd.addColorStop(").append(Double.toString(pos + (oneHeight * (revert ? 255 - r.ratio : r.ratio) / 255.0))).append(",").append(color(r.color)).append(");\r\n"); lineLastRadColor = color(r.color); } pos += oneHeight; } - lineFillData += "\tctx.fillStyle = grd;\r\n"; + lineFillData.append("\tctx.fillStyle = grd;\r\n"); String preStrokeData = ""; @@ -406,33 +406,36 @@ public class CanvasShapeExporter extends ShapeExporterBase { String drawFill = "\tdrawPath(ctx,pathData,false);\r\n";; pathData = new StringBuilder(); if (lineFillData != null) { - String preLineFillData = ""; - preLineFillData += "\tvar oldctx = ctx;\r\n"; - preLineFillData += "\tctx.save();\r\n"; - preLineFillData += strokeData; - preLineFillData += drawStroke; - preLineFillData += "\tvar lfcanvas = document.createElement(\"canvas\");\r\n"; - preLineFillData += "\tlfcanvas.width = canvas.width;\r\n"; - preLineFillData += "\tlfcanvas.height=canvas.height;\r\n"; - preLineFillData += "\tvar lfctx = lfcanvas.getContext(\"2d\");\r\n"; - preLineFillData += "\tenhanceContext(lfctx);\r\n"; - preLineFillData += "\tlfctx.applyTransforms(ctx._matrix);\r\n"; - preLineFillData += "\tctx = lfctx;"; + StringBuilder preLineFillData = new StringBuilder(); + preLineFillData.append("\tvar oldctx = ctx;\r\n"); + preLineFillData.append("\tctx.save();\r\n"); + preLineFillData.append(strokeData); + preLineFillData.append(drawStroke); + preLineFillData.append("\tvar lfcanvas = document.createElement(\"canvas\");\r\n"); + preLineFillData.append("\tlfcanvas.width = canvas.width;\r\n"); + preLineFillData.append("\tlfcanvas.height=canvas.height;\r\n"); + preLineFillData.append("\tvar lfctx = lfcanvas.getContext(\"2d\");\r\n"); + preLineFillData.append("\tenhanceContext(lfctx);\r\n"); + preLineFillData.append("\tlfctx.applyTransforms(ctx._matrix);\r\n"); + preLineFillData.append("\tctx = lfctx;"); if (lineLastRadColor != null) { - preLineFillData += "\tctx.fillStyle=" + lineLastRadColor + ";\r\n\tctx.fill(\"evenodd\");\r\n"; + preLineFillData.append("\tctx.fillStyle=").append(lineLastRadColor).append(";\r\n\tctx.fill(\"evenodd\");\r\n"); } - preLineFillData += "\tctx.transform(" + Helper.doubleStr(lineFillMatrix.scaleX / unitDivisor) + "," + Helper.doubleStr(lineFillMatrix.rotateSkew0 / unitDivisor) - + "," + Helper.doubleStr(lineFillMatrix.rotateSkew1 / unitDivisor) + "," + Helper.doubleStr(lineFillMatrix.scaleY / unitDivisor) - + "," + Helper.doubleStr((lineFillMatrix.translateX + deltaX) / unitDivisor) + "," + Helper.doubleStr((lineFillMatrix.translateY + deltaY) / unitDivisor) + ");\r\n"; - lineFillData = preLineFillData + lineFillData; - lineFillData += "\tctx.fillRect(" + (-16384 - 32768 * lineRepeatCnt) + "," + (-16384 - 32768 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + "," + (2 * 16384 + 32768 * 2 * lineRepeatCnt) + ");\r\n"; + preLineFillData.append("\tctx.transform(").append(Helper.doubleStr(lineFillMatrix.scaleX / unitDivisor)) + .append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew0 / unitDivisor)) + .append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew1 / unitDivisor)) + .append(",").append(Helper.doubleStr(lineFillMatrix.scaleY / unitDivisor)) + .append(",").append(Helper.doubleStr((lineFillMatrix.translateX + deltaX) / unitDivisor)) + .append(",").append(Helper.doubleStr((lineFillMatrix.translateY + deltaY) / unitDivisor)).append(");\r\n"); + lineFillData.insert(0, preLineFillData); + lineFillData.append("\tctx.fillRect(").append(-16384 - 32768 * lineRepeatCnt).append(",").append(-16384 - 32768 * lineRepeatCnt).append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt).append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt).append(");\r\n"); - lineFillData += "\tctx = oldctx;\r\n"; + lineFillData.append("\tctx = oldctx;\r\n"); //lcanvas - stroke //lfcanvas - stroke background - lineFillData += "\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n" + lineFillData.append("\tvar limgd = lctx.getImageData(0, 0, lcanvas.width, lcanvas.height);\r\n" + "\tvar lpix = limgd.data;\r\n" + "\tvar lfimgd = lfctx.getImageData(0, 0, lfcanvas.width, lfcanvas.height);\r\n" + "\tvar lfpix = lfimgd.data;\r\n" @@ -441,8 +444,8 @@ public class CanvasShapeExporter extends ShapeExporterBase { + "\tfor (var i = 0; i < lpix.length; i += 4) {\r\n" + "\t\tif(lpix[i+3]>0){ pix[i] = lfpix[i]; pix[i+1] = lfpix[i+1]; pix[i+2] = lfpix[i+2]; pix[i+3] = lfpix[i+3];}\r\n" + "\t}\r\n" - + "\tctx.putImageData(imgd, 0, 0);\r\n"; - lineFillData += "\tctx.restore();\r\n"; + + "\tctx.putImageData(imgd, 0, 0);\r\n"); + lineFillData.append("\tctx.restore();\r\n"); strokeData = new StringBuilder(); } else { pathData.append(strokeData); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index b4f8d020e..3e052ed44 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -163,17 +163,16 @@ public class XFLConverter { private XFLConverter() { } - public static String convertShapeEdge(MATRIX mat, SHAPERECORD record, int x, int y) { + private static void convertShapeEdge(MATRIX mat, SHAPERECORD record, int x, int y, StringBuilder ret) { if (record instanceof StyleChangeRecord) { StyleChangeRecord scr = (StyleChangeRecord) record; Point p = new Point(scr.moveDeltaX, scr.moveDeltaY); //p = mat.apply(p); if (scr.stateMoveTo) { - return "! " + p.x + " " + p.y; + ret.append("! ").append(p.x).append(" ").append(p.y); + return; } - return ""; - } - if (record instanceof StraightEdgeRecord) { + } else if (record instanceof StraightEdgeRecord) { StraightEdgeRecord ser = (StraightEdgeRecord) record; if (ser.generalLineFlag || ser.vertLineFlag) { y += ser.deltaY; @@ -183,9 +182,8 @@ public class XFLConverter { } Point p = new Point(x, y); //p = mat.apply(p); - return "| " + p.x + " " + p.y; - } - if (record instanceof CurvedEdgeRecord) { + ret.append("| ").append(p.x).append(" ").append(p.y); + } else if (record instanceof CurvedEdgeRecord) { CurvedEdgeRecord cer = (CurvedEdgeRecord) record; int controlX = cer.controlDeltaX + x; int controlY = cer.controlDeltaY + y; @@ -195,36 +193,33 @@ public class XFLConverter { //control = mat.apply(control); Point anchor = new Point(anchorX, anchorY); //anchor = mat.apply(anchor); - return "[ " + control.x + " " + control.y + " " + anchor.x + " " + anchor.y; + ret.append("[ ").append(control.x).append(" ").append(control.y).append(" ").append(anchor.x).append(" ").append(anchor.y); } - return ""; } - public static String convertShapeEdges(int startX, int startY, MATRIX mat, List records) { - StringBuilder ret = new StringBuilder(); + private static void convertShapeEdges(int startX, int startY, MATRIX mat, List records, StringBuilder ret) { int x = startX; int y = startY; ret.append("!").append(startX).append(" ").append(startY); for (SHAPERECORD rec : records) { - ret.append(convertShapeEdge(mat, rec, x, y)); + convertShapeEdge(mat, rec, x, y, ret); x = rec.changeX(x); y = rec.changeY(y); } - return ret.toString(); } - public static String convertLineStyle(LINESTYLE ls, int shapeNum) { - return "" - + "" - + "" - + "" - + ""; + private static void convertLineStyle(LINESTYLE ls, int shapeNum, StringBuilder ret) { + ret.append("" + + "" + + "" + + "" + + ""); } - public static String convertLineStyle(HashMap characters, LINESTYLE2 ls, int shapeNum) { - StringBuilder ret = new StringBuilder(); + private static void convertLineStyle(HashMap characters, LINESTYLE2 ls, int shapeNum, StringBuilder ret) { StringBuilder params = new StringBuilder(); if (ls.pixelHintingFlag) { params.append(" pixelHinting=\"true\""); @@ -272,24 +267,22 @@ public class XFLConverter { append(color.getAlphaFloat() != 1 ? " alpha=\"" + color.getAlphaFloat() + "\"" : ""). append(" />"); } else { - ret.append(convertFillStyle(null/* FIXME */, characters, ls.fillType, shapeNum)); + convertFillStyle(null/* FIXME */, characters, ls.fillType, shapeNum, ret); } ret.append(""); ret.append(""); - return ret.toString(); } private static float toFloat(int i) { return ((float) i) / (1 << 16); } - public static String convertFillStyle(MATRIX mat, HashMap characters, FILLSTYLE fs, int shapeNum) { + private static void convertFillStyle(MATRIX mat, HashMap characters, FILLSTYLE fs, int shapeNum, StringBuilder ret) { /* todo: use matrix if (mat == null) { mat = new MATRIX(); }*/ - StringBuilder ret = new StringBuilder(); - //ret += ""; + //ret.append(""); switch (fs.fillStyleType) { case FILLSTYLE.SOLID: ret.append(""; + ret.append(""); + return; } ret.append("\""); @@ -395,15 +389,14 @@ public class XFLConverter { } break; } - //ret += ""; - return ret.toString(); + //ret.append(""); } - public static String convertMatrix(MATRIX m) { + private static String convertMatrix(MATRIX m) { return convertMatrix(new Matrix(m)); } - public static String convertMatrix(Matrix m) { + private static String convertMatrix(Matrix m) { StringBuilder ret = new StringBuilder(); if (m == null) { m = new Matrix(); @@ -444,7 +437,7 @@ public class XFLConverter { return layers.size() > 1; } - public static String convertShape(HashMap characters, MATRIX mat, int shapeNum, List shapeRecords, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, boolean morphshape, boolean useLayers) { + private static String convertShape(HashMap characters, MATRIX mat, int shapeNum, List shapeRecords, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, boolean morphshape, boolean useLayers) { StringBuilder ret = new StringBuilder(); List layers = getShapeLayers(characters, mat, shapeNum, shapeRecords, fillStyles, lineStyles, morphshape); if (layers.size() == 1 && !useLayers) { @@ -524,7 +517,7 @@ public class XFLConverter { return ret; } - public static List getShapeLayers(HashMap characters, MATRIX mat, int shapeNum, List shapeRecords, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, boolean morphshape) { + private static List getShapeLayers(HashMap characters, MATRIX mat, int shapeNum, List shapeRecords, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, boolean morphshape) { if (mat == null) { mat = new MATRIX(); } @@ -534,50 +527,50 @@ public class XFLConverter { int fillStyle0 = -1; int fillStyle1 = -1; int strokeStyle = -1; - String fillsStr = ""; - String strokesStr = ""; - fillsStr += ""; - strokesStr += ""; + StringBuilder fillsStr = new StringBuilder(); + StringBuilder strokesStr = new StringBuilder(); + fillsStr.append(""); + strokesStr.append(""); List layers = new ArrayList<>(); - String currentLayer = ""; + StringBuilder currentLayer = new StringBuilder(); int fillStyleCount = 0; if (fillStyles != null) { for (FILLSTYLE fs : fillStyles.fillStyles) { - fillsStr += ""; - fillsStr += convertFillStyle(mat, characters, fs, shapeNum); - fillsStr += ""; + fillsStr.append(""); + convertFillStyle(mat, characters, fs, shapeNum, fillsStr); + fillsStr.append(""); fillStyleCount++; } } if (lineStyles != null) { if (shapeNum <= 3 && lineStyles.lineStyles != null) { for (int l = 0; l < lineStyles.lineStyles.length; l++) { - strokesStr += ""; - strokesStr += convertLineStyle(lineStyles.lineStyles[l], shapeNum); - strokesStr += ""; + strokesStr.append(""); + convertLineStyle(lineStyles.lineStyles[l], shapeNum, strokesStr); + strokesStr.append(""); lineStyleCount++; } } else if (lineStyles.lineStyles != null) { for (int l = 0; l < lineStyles.lineStyles.length; l++) { - strokesStr += ""; - strokesStr += convertLineStyle(characters, (LINESTYLE2) lineStyles.lineStyles[l], shapeNum); - strokesStr += ""; + strokesStr.append(""); + convertLineStyle(characters, (LINESTYLE2) lineStyles.lineStyles[l], shapeNum, strokesStr); + strokesStr.append(""); lineStyleCount++; } } } - fillsStr += ""; - strokesStr += ""; + fillsStr.append(""); + strokesStr.append(""); int layer = 1; if ((fillStyleCount > 0) || (lineStyleCount > 0)) { - currentLayer += ""; - currentLayer += fillsStr; - currentLayer += strokesStr; - currentLayer += ""; + currentLayer.append(""); + currentLayer.append(fillsStr); + currentLayer.append(strokesStr); + currentLayer.append(""); } int x = 0; int y = 0; @@ -595,8 +588,10 @@ public class XFLConverter { int lastFillStyle0 = fillStyle0; int lastStrokeStyle = strokeStyle; if (scr.stateNewStyles) { - fillsStr = ""; - strokesStr = ""; + fillsStr.setLength(0); + strokesStr.setLength(0); + fillsStr.append(""); + strokesStr.append(""); if (fillStyleCount > 0 || lineStyleCount > 0) { if ((fillStyle0 > 0) || (fillStyle1 > 0) || (strokeStyle > 0)) { @@ -615,58 +610,61 @@ public class XFLConverter { } } if (!empty) { - currentLayer += " -1) { - currentLayer += " fillStyle0=\"" + fillStyle0 + "\""; + currentLayer.append(" fillStyle0=\"").append(fillStyle0).append("\""); } if (fillStyle1 > -1) { - currentLayer += " fillStyle1=\"" + fillStyle1 + "\""; + currentLayer.append(" fillStyle1=\"").append(fillStyle1).append("\""); } if (strokeStyle > -1) { - currentLayer += " strokeStyle=\"" + strokeStyle + "\""; + currentLayer.append(" strokeStyle=\"").append(strokeStyle).append("\""); } - currentLayer += " edges=\"" + convertShapeEdges(startEdgeX, startEdgeY, mat, edges) + "\" />"; + currentLayer.append(" edges=\""); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); + currentLayer.append("\" />"); } } - currentLayer += ""; - currentLayer += ""; - if (!currentLayer.contains("")) { //no empty layers, TODO:handle this better - layers.add(currentLayer); + currentLayer.append(""); + currentLayer.append(""); + String currentLayerString = currentLayer.toString(); + if (!currentLayerString.contains("")) { //no empty layers, TODO:handle this better + layers.add(currentLayerString); } - currentLayer = ""; + currentLayer.setLength(0); } - currentLayer += ""; + currentLayer.append(""); //ret += convertShape(characters, null, shape); for (int f = 0; f < scr.fillStyles.fillStyles.length; f++) { - fillsStr += ""; - fillsStr += convertFillStyle(mat, characters, scr.fillStyles.fillStyles[f], shapeNum); - fillsStr += ""; + fillsStr.append(""); + convertFillStyle(mat, characters, scr.fillStyles.fillStyles[f], shapeNum, fillsStr); + fillsStr.append(""); fillStyleCount++; } lineStyleCount = 0; if (shapeNum <= 3) { for (int l = 0; l < scr.lineStyles.lineStyles.length; l++) { - strokesStr += ""; - strokesStr += convertLineStyle(scr.lineStyles.lineStyles[l], shapeNum); - strokesStr += ""; + strokesStr.append(""); + convertLineStyle(scr.lineStyles.lineStyles[l], shapeNum, strokesStr); + strokesStr.append(""); lineStyleCount++; } } else { for (int l = 0; l < scr.lineStyles.lineStyles.length; l++) { - strokesStr += ""; - strokesStr += convertLineStyle(characters, (LINESTYLE2) scr.lineStyles.lineStyles[l], shapeNum); - strokesStr += ""; + strokesStr.append(""); + convertLineStyle(characters, (LINESTYLE2) scr.lineStyles.lineStyles[l], shapeNum, strokesStr); + strokesStr.append(""); lineStyleCount++; } } - fillsStr += ""; - strokesStr += ""; - currentLayer += fillsStr; - currentLayer += strokesStr; - currentLayer += ""; + fillsStr.append(""); + strokesStr.append(""); + currentLayer.append(fillsStr); + currentLayer.append(strokesStr); + currentLayer.append(""); actualLinestyles = scr.lineStyles; } if (scr.stateFillStyle0) { @@ -708,17 +706,19 @@ public class XFLConverter { } } if (!empty) { - currentLayer += " -1) { - currentLayer += " fillStyle0=\"" + lastFillStyle0 + "\""; + currentLayer.append(" fillStyle0=\"").append(lastFillStyle0).append("\""); } if (fillStyle1 > -1) { - currentLayer += " fillStyle1=\"" + lastFillStyle1 + "\""; + currentLayer.append(" fillStyle1=\"").append(lastFillStyle1).append("\""); } if (strokeStyle > -1) { - currentLayer += " strokeStyle=\"" + lastStrokeStyle + "\""; + currentLayer.append(" strokeStyle=\"").append(lastStrokeStyle).append("\""); } - currentLayer += " edges=\"" + convertShapeEdges(startEdgeX, startEdgeY, mat, edges) + "\" />"; + currentLayer.append(" edges=\""); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); + currentLayer.append("\" />"); } startEdgeX = x; @@ -748,29 +748,32 @@ public class XFLConverter { } } if (!empty) { - currentLayer += " -1) { - currentLayer += " fillStyle0=\"" + fillStyle0 + "\""; + currentLayer.append(" fillStyle0=\"").append(fillStyle0).append("\""); } if (fillStyle1 > -1) { - currentLayer += " fillStyle1=\"" + fillStyle1 + "\""; + currentLayer.append(" fillStyle1=\"").append(fillStyle1).append("\""); } if (strokeStyle > -1) { - currentLayer += " strokeStyle=\"" + strokeStyle + "\""; + currentLayer.append(" strokeStyle=\"").append(strokeStyle).append("\""); } - currentLayer += " edges=\"" + convertShapeEdges(startEdgeX, startEdgeY, mat, edges) + "\" />"; + currentLayer.append(" edges=\""); + convertShapeEdges(startEdgeX, startEdgeY, mat, edges, currentLayer); + currentLayer.append("\" />"); } } } edges.clear(); - fillsStr += ""; - strokesStr += ""; - if (!currentLayer.isEmpty()) { - currentLayer += ""; - currentLayer += ""; + fillsStr.append(""); + strokesStr.append(""); // todo: these fillsStr and strokeStr are not used, why? + if (currentLayer.length() > 0) { + currentLayer.append(""); + currentLayer.append(""); - if (!currentLayer.contains("")) { //no empty layers, TODO:handle this better - layers.add(currentLayer); + String currentLayerString = currentLayer.toString(); + if (!currentLayerString.contains("")) { //no empty layers, TODO:handle this better + layers.add(currentLayerString); } } return layers; @@ -906,7 +909,7 @@ public class XFLConverter { return ds; } - public static String convertFilter(FILTER filter) { + private static String convertFilter(FILTER filter) { StringBuilder ret = new StringBuilder(); if (filter instanceof DROPSHADOWFILTER) { DROPSHADOWFILTER dsf = (DROPSHADOWFILTER) filter; @@ -1048,7 +1051,7 @@ public class XFLConverter { return ret.toString(); } - public static String convertSymbolInstance(String name, MATRIX matrix, ColorTransform colorTransform, boolean cacheAsBitmap, int blendMode, List filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap characters, List tags, FLAVersion flaVersion) { + private static String convertSymbolInstance(String name, MATRIX matrix, ColorTransform colorTransform, boolean cacheAsBitmap, int blendMode, List filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap characters, List tags, FLAVersion flaVersion) { StringBuilder ret = new StringBuilder(); if (matrix == null) { matrix = new MATRIX(); @@ -1181,11 +1184,12 @@ public class XFLConverter { return writer.toString(); } - private static long getTimestamp() { - return new Date().getTime() / 1000; + private static long getTimestamp(SWF swf) { + Date date = swf.getFileModificationDate(); + return date.getTime() / 1000; } - public static String convertLibrary(SWF swf, Map characterVariables, Map characterClasses, List nonLibraryShapes, String backgroundColor, List tags, HashMap characters, HashMap files, HashMap datfiles, FLAVersion flaVersion) { + private static String convertLibrary(SWF swf, Map characterVariables, Map characterClasses, List nonLibraryShapes, String backgroundColor, List tags, HashMap characters, HashMap files, HashMap datfiles, FLAVersion flaVersion) { //TODO: Imported assets //linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf" @@ -1200,7 +1204,7 @@ public class XFLConverter { if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) { StringBuilder symbolStr = new StringBuilder(); - symbolStr.append("= FLAVersion.CS5_5.ordinal()) { - symbLinkStr += " lastModified=\"" + getTimestamp() + "\""; + symbLinkStr += " lastModified=\"" + getTimestamp(swf) + "\""; //TODO: itemID=\"518de416-00000341\" } symbLinkStr += "/>"; @@ -1362,7 +1366,7 @@ public class XFLConverter { ImageHelper.write(image.getBufferedImage(), format, baos); String symbolFile = "bitmap" + symbol.getCharacterId() + "." + imageTag.getImageFormat(); files.put(symbolFile, baos.toByteArray()); - String mediaLinkStr = "\n"; + mediaLinkStr += " quality=\"50\" href=\"" + symbolFile + "\" bitmapDataHRef=\"M " + (media.size() + 1) + " " + getTimestamp(swf) + ".dat\" frameRight=\"" + image.getWidth() + "\" frameBottom=\"" + image.getHeight() + "\"/>\n"; media.add(mediaLinkStr); } else if ((symbol instanceof SoundStreamHeadTypeTag) || (symbol instanceof DefineSoundTag)) { @@ -1518,7 +1522,7 @@ public class XFLConverter { String symbolFile = "sound" + symbol.getCharacterId() + "." + exportFormat; files.put(symbolFile, data); - String mediaLinkStr = ""; //Use the dat file, otherwise it does not work @@ -1592,7 +1596,7 @@ public class XFLConverter { }); } else { files.put(symbolFile, data); - mediaLinkStr = " tags) { + private static String convertFonts(List tags) { StringBuilder ret = new StringBuilder(); for (Tag t : tags) { if (t instanceof FontTag) { @@ -2011,7 +2015,7 @@ public class XFLConverter { return retStr; } - public static String convertActionScriptLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { + private static String convertActionScriptLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { StringBuilder ret = new StringBuilder(); String script = ""; @@ -2073,7 +2077,7 @@ public class XFLConverter { return retStr; } - public static String convertLabelsLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { + private static String convertLabelsLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { StringBuilder ret = new StringBuilder(); int duration = 0; int frame = 0; @@ -2129,7 +2133,7 @@ public class XFLConverter { return retStr; } - public static String convertSoundLayer(int layerIndex, String backgroundColor, HashMap characters, List tags, List timeLineTags, HashMap files) { + private static String convertSoundLayer(int layerIndex, String backgroundColor, HashMap characters, List tags, List timeLineTags, HashMap files) { StringBuilder ret = new StringBuilder(); StartSoundTag lastStartSound = null; SoundStreamHeadTypeTag lastSoundStreamHead = null; @@ -2202,7 +2206,7 @@ public class XFLConverter { return outlineColor.toHexRGB(); } - public static String convertTimeline(int spriteId, List nonLibraryShapes, String backgroundColor, List tags, List timelineTags, HashMap characters, String name, FLAVersion flaVersion, HashMap files) { + private static String convertTimeline(int spriteId, List nonLibraryShapes, String backgroundColor, List tags, List timelineTags, HashMap characters, String name, FLAVersion flaVersion, HashMap files) { StringBuilder ret = new StringBuilder(); ret.append(""); ret.append(""); @@ -2331,7 +2335,7 @@ public class XFLConverter { return ret; } - public static String convertText(String instanceName, TextTag tag, MATRIX m, List filters, CLIPACTIONS clipActions) { + private static String convertText(String instanceName, TextTag tag, MATRIX m, List filters, CLIPACTIONS clipActions) { StringBuilder ret = new StringBuilder(); if (m == null) { @@ -3095,7 +3099,7 @@ public class XFLConverter { return a == b ? true : Math.abs(a - b) < EPSILON; } - public static String convertAdjustColorFilter(COLORMATRIXFILTER filter) { + private static String convertAdjustColorFilter(COLORMATRIXFILTER filter) { float[][] matrix = new float[5][5]; int index = 0; for (int i = 0; i < 4; i++) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java index b9900862a..594cddb62 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java @@ -90,15 +90,20 @@ public class Helper { * @return String representation of the array */ public static String intArrToString(int[] array) { - String s = "["; + StringBuilder sb = new StringBuilder(); + intArrToStringBuilder(array, sb); + return sb.toString(); + } + + public static void intArrToStringBuilder(int[] array, StringBuilder sb) { + sb.append("["); for (int i = 0; i < array.length; i++) { if (i > 0) { - s += ","; + sb.append(","); } - s += array[i]; + sb.append(array[i]); } - s += "]"; - return s; + sb.append("]"); } /** @@ -108,15 +113,16 @@ public class Helper { * @return String representation of the array */ public static String byteArrToString(byte[] array) { - String s = "["; + StringBuilder sb = new StringBuilder(); + sb.append("["); for (int i = 0; i < array.length; i++) { if (i > 0) { - s += " "; + sb.append(" "); } - s += padZeros(Integer.toHexString(array[i] & 0xff), 2); + sb.append(hexStringCache[array[i] & 0xff]); } - s += "]"; - return s; + sb.append("]"); + return sb.toString(); } /** @@ -137,30 +143,28 @@ public class Helper { /** * Formats specified address to four numbers xxxx + * (or five numbers when showing decimal addresses) * * @param number Address to format * @return String representation of the address */ public static String formatAddress(long number) { - if (Configuration.decimalAddress.get()) { - return padZeros(Long.toString(number), 4); - } - return padZeros(Long.toHexString(number), 4); + return formatAddress(number, Configuration.decimalAddress.get()); } /** - * Adds space to text to fill specified width + * Formats specified address to four numbers xxxx + * (or five numbers when showing decimal addresses) * - * @param text Text to add spaces to - * @param width New width - * @return Text with appended spaces + * @param number Address to format + * @param decimal Use decimal format + * @return String representation of the address */ - public static String padSpaceRight(String text, int width) { - int oldLen = text.length(); - for (int i = oldLen; i < width; i++) { - text += " "; + public static String formatAddress(long number, boolean decimal) { + if (decimal) { + return String.format("%05d", number); } - return text; + return String.format("%04x", number); } /** @@ -186,7 +190,7 @@ public class Helper { } else if (c == '\\') { ret.append("\\\\"); } else if (c < 32) { - ret.append("\\x").append(padZeros(Integer.toHexString((int) c), 2)); + ret.append("\\x").append(byteToHex((byte) c)); } else { ret.append(c); } @@ -222,7 +226,7 @@ public class Helper { } else if (c == '\'') { ret.append("\\'"); } else if (c < 32) { - ret.append("\\x").append(padZeros(Integer.toHexString((int) c), 2)); + ret.append("\\x").append(byteToHex((byte) c)); } else { ret.append(c); } @@ -256,7 +260,8 @@ public class Helper { } else if (c == '"') { ret.append("\\\""); } else if (c < 32) { - ret.append("\\u").append(padZeros(Integer.toHexString((int) c), 4)); + // \\x is not available in Java string, we should use \\u instead + ret.append("\\u00").append(byteToHex((byte) c)); } else { ret.append(c); } diff --git a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java index 5931c4fca..181003a6e 100644 --- a/src/com/jpexs/decompiler/flash/gui/ExportDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/ExportDialog.java @@ -157,20 +157,20 @@ public class ExportDialog extends AppDialog { } private void saveConfig() { - String cfg = ""; + StringBuilder cfg = new StringBuilder(); for (int i = 0; i < optionNames.length; i++) { int selIndex = combos[i].getSelectedIndex(); Class c = optionClasses[i]; Object vals[] = c.getEnumConstants(); String key = optionNames[i] + "." + vals[selIndex].toString().toLowerCase(); if (i > 0) { - cfg += ","; + cfg.append(","); } - cfg += key; + cfg.append(key); } Configuration.lastSelectedExportZoom.set(Double.parseDouble(zoomTextField.getText()) / 100); - Configuration.lastSelectedExportFormats.set(cfg); + Configuration.lastSelectedExportFormats.set(cfg.toString()); } public ExportDialog(List exportables) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java index bdda325b2..2c77bc711 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java @@ -28,8 +28,6 @@ import java.awt.FontFormatException; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; import java.util.HashSet; @@ -49,6 +47,8 @@ import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; /** @@ -278,17 +278,24 @@ public class FontEmbedDialog extends AppDialog { updateCheckboxes(); } }); - faceSelection.addItemListener(new ItemListener() { - - @Override - public void itemStateChanged(ItemEvent e) { - updateCheckboxes(); - } + faceSelection.addItemListener((ItemEvent e) -> { + updateCheckboxes(); }); updateCheckboxes(); - individualCharsField.addKeyListener(new KeyAdapter() { + individualCharsField.getDocument().addDocumentListener(new DocumentListener() { + @Override - public void keyTyped(KeyEvent e) { + public void insertUpdate(DocumentEvent e) { + updateIndividual(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updateIndividual(); + } + + @Override + public void changedUpdate(DocumentEvent e) { updateIndividual(); } }); @@ -297,13 +304,13 @@ public class FontEmbedDialog extends AppDialog { private void updateIndividual() { String chars = individualCharsField.getText(); Font f = getSelectedFont(); - String visibleChars = ""; + StringBuilder visibleChars = new StringBuilder(); for (int i = 0; i < chars.length(); i++) { if (f.canDisplay(chars.codePointAt(i))) { - visibleChars += "" + chars.charAt(i); + visibleChars.append(chars.charAt(i)); } } - individialSample.setText(visibleChars); + individialSample.setText(visibleChars.toString()); } private void updateCheckboxes() { diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index c775f8592..894b4dbab 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -220,8 +220,8 @@ public class FontPanel extends JPanel { selectedFont = swf.sourceFontNamesMap.get(ft.getFontId()); } else if (Configuration.getFontToNameMap().containsKey(key)) { selectedFont = Configuration.getFontToNameMap().get(key); - } else if (Configuration.getFontToNameMap().containsKey(ft.getFontName())) { - selectedFont = Configuration.getFontToNameMap().get(ft.getFontName()); + } else if (Configuration.getFontToNameMap().containsKey(ft.getFontNameIntag())) { + selectedFont = Configuration.getFontToNameMap().get(ft.getFontNameIntag()); } else { selectedFont = FontTag.findInstalledFontName(ft.getFontName()); } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 43b31100e..1c274fb87 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -280,7 +280,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { Point p = lastMouseEvent == null ? null : lastMouseEvent.getPoint(); List objs = new ArrayList<>(); - String ret = ""; + StringBuilder ret = new StringBuilder(); synchronized (ImagePanel.class) { if (timer == thisTimer) { @@ -290,7 +290,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { int y = p.y; objs = iconPanel.getObjectsUnderPoint(p); - ret += " [" + x + "," + y + "] : "; + ret.append(" [").append(x).append(",").append(y).append("] : "); } } } @@ -299,7 +299,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { for (int i = 0; i < objs.size(); i++) { DepthState ds = objs.get(i); if (!first) { - ret += ", "; + ret.append(", "); } first = false; CharacterTag c = tim.swf.getCharacter(ds.characterId); @@ -307,18 +307,18 @@ public final class ImagePanel extends JPanel implements MediaDisplay { newStateUnderCursor = ds; handCursor = true; } - ret += c.toString(); + ret.append(c.toString()); if (timelined instanceof ButtonTag) { handCursor = true; } } if (first) { - ret += " - "; + ret.append(" - "); } synchronized (ImagePanel.class) { if (timer == thisTimer) { - debugLabel.setText(ret); + debugLabel.setText(ret.toString()); if (handCursor) { iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); diff --git a/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java b/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java index 399ba0862..39da0dae9 100644 --- a/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/NewVersionDialog.java @@ -54,7 +54,6 @@ public class NewVersionDialog extends AppDialog { JEditorPane changesText = new JEditorPane(); changesText.setEditable(false); changesText.setFont(UIManager.getFont("TextField.font")); - String changesStr = ""; SimpleDateFormat serverFormatter = new SimpleDateFormat("MM/dd/yyyy"); DateFormat formatter; String customFormat = translate("customDateFormat"); @@ -63,13 +62,17 @@ public class NewVersionDialog extends AppDialog { } else { formatter = new SimpleDateFormat(customFormat); } + + StringBuilder changesStr = new StringBuilder(); + changesStr.append(""); + boolean first = true; for (Version v : versions) { if (!first) { - changesStr += "
"; + changesStr.append("
"); } first = false; - changesStr += "" + translate("version") + " " + v.versionName + "
"; + changesStr.append("").append(translate("version")).append(" ").append(v.versionName).append("
"); String releaseDate = v.releaseDate; try { Date date = serverFormatter.parse(releaseDate); @@ -77,25 +80,27 @@ public class NewVersionDialog extends AppDialog { } catch (ParseException ex) { Logger.getLogger(NewVersionDialog.class.getName()).log(Level.SEVERE, null, ex); } - changesStr += translate("releasedate") + " " + releaseDate; + changesStr.append(translate("releasedate")).append(" ").append(releaseDate); if (!v.changes.isEmpty()) { - changesStr += "
"; - changesStr += "
";
+                changesStr.append("
"); + changesStr.append("
");
                 for (String type : v.changes.keySet()) {
-                    changesStr += type + ":" + "
"; + changesStr.append(type).append(":" + "
"); for (String ch : v.changes.get(type)) { - changesStr += " - " + ch + "
"; + changesStr.append(" - ").append(ch).append("
"); } } - changesStr += "
"; + changesStr.append("
"); } } + + changesStr.append(""); latestVersion = null; if (!versions.isEmpty()) { latestVersion = versions.get(0); } changesText.setContentType("text/html"); - changesText.setText("" + changesStr + ""); + changesText.setText(changesStr.toString()); if (latestVersion != null) { JLabel newAvailableLabel = new JLabel("
" + translate("newversionavailable") + " " + latestVersion.appName + " " + translate("version") + " " + latestVersion.versionName + "
", SwingConstants.CENTER); newAvailableLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java index 4612fc367..297e36cb1 100644 --- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java @@ -124,11 +124,12 @@ public class DumpViewPanel extends JPanel { if (address != -1) { int b2 = b & 0xff; - selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8) - + " Hex: " + Helper.padZeros(Integer.toHexString(b2), 2) + selectedByteInfo.setText("Addr: " + String.format("%08X", address) + + " Hex: " + String.format("%02X", b) + " Dec: " + b2 + " Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8) - + " Ascii: " + (char) b2); + + " Ascii: " + (char) b2 + ); } else { selectedByteInfo.setText("-"); }