From b9c2be102f5bf51873e229c7a76e457274be51cc Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Thu, 20 Nov 2014 19:54:50 +0100 Subject: [PATCH 1/3] Issue #723: saving swf with invalid referenced characters fixed --- libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java | 4 ++++ 1 file changed, 4 insertions(+) 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 b37f6bf3a..60375f4b2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -312,6 +312,10 @@ public final class SWF implements SWFContainerItem, Timelined { for (Integer id : needed) { if (!addedCharacterIds.contains(id)) { CharacterTag neededCharacter = characters.get(id); + if (neededCharacter == null) { + continue; + } + if (movedTags.contains(neededCharacter)) { logger.log(Level.SEVERE, "Fixing characters order failed, recursion detected."); return; From dec1380d13aeb4cfb100391ce26691e5ff6b43dc Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Fri, 21 Nov 2014 18:07:57 +0100 Subject: [PATCH 2/3] DefineCompactedFont paging fixed --- .../jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index 36b9cea96..de19c0b06 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -124,11 +124,6 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { shapeCache = fonts.get(0).getGlyphShapes(); } - @Override - public int getNumFrames() { - return 1; - } - @Override public String getFontNameIntag() { String ret = ""; From 13c894196c2b32d9b09e0df94429e0af78225206 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sat, 22 Nov 2014 03:16:30 +0100 Subject: [PATCH 3/3] Issue #288: less memory usage during FLA export, using stringbuilders --- .../flash/IdentifiersDeobfuscation.java | 24 +- .../src/com/jpexs/decompiler/flash/SWF.java | 95 +- .../flash}/abc/CachedDecompilation.java | 2 +- .../flash/abc/avm2/AVM2Deobfuscation.java | 10 +- .../decompiler/flash/abc/types/Multiname.java | 8 +- .../jpexs/decompiler/flash/action/Action.java | 2 - .../flash}/action/CachedScript.java | 72 +- .../morphshape/CanvasMorphShapeExporter.java | 24 +- .../flash/tags/DefineBitsJPEG2Tag.java | 4 +- .../flash/tags/DefineBitsJPEG3Tag.java | 4 +- .../flash/tags/DefineBitsJPEG4Tag.java | 3 +- .../flash/tags/DefineBitsLossless2Tag.java | 4 +- .../flash/tags/DefineBitsLosslessTag.java | 4 +- .../decompiler/flash/tags/DefineBitsTag.java | 4 +- .../decompiler/flash/tags/DefineFont2Tag.java | 6 +- .../decompiler/flash/tags/DefineFont3Tag.java | 6 +- .../decompiler/flash/tags/DefineFontTag.java | 8 +- .../decompiler/flash/tags/DefineText2Tag.java | 27 +- .../decompiler/flash/tags/DefineTextTag.java | 29 +- .../decompiler/flash/tags/base/ImageTag.java | 6 + .../flash/tags/gfx/DefineCompactedFont.java | 10 +- .../decompiler/flash/types/TEXTRECORD.java | 9 +- .../decompiler/flash/xfl/XFLConverter.java | 1444 +++++++++-------- .../decompiler/graph/GraphPartMulti.java | 15 +- .../src/com/jpexs/helpers/Helper.java | 36 +- .../jpexs/decompiler/flash/gui/FontPanel.java | 2 +- .../jpexs/decompiler/flash/gui/MainPanel.java | 36 +- .../decompiler/flash/gui/PreviewPanel.java | 5 +- .../jpexs/decompiler/flash/gui/TextPanel.java | 2 +- .../decompiler/flash/gui/abc/ABCPanel.java | 12 +- .../flash/gui/abc/DecompiledEditorPane.java | 54 +- .../flash/gui/action/ActionPanel.java | 47 +- .../flash/gui/tagtree/TagTreeContextMenu.java | 5 +- 33 files changed, 1024 insertions(+), 995 deletions(-) rename {src/com/jpexs/decompiler/flash/gui => libsrc/ffdec_lib/src/com/jpexs/decompiler/flash}/abc/CachedDecompilation.java (97%) rename {src/com/jpexs/decompiler/flash/gui => libsrc/ffdec_lib/src/com/jpexs/decompiler/flash}/action/CachedScript.java (90%) 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 6bfe4feb9..be80decbd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java @@ -163,23 +163,24 @@ public class IdentifiersDeobfuscation { } else { parts = new String[]{pkg}; } - String ret = ""; + StringBuilder ret = new StringBuilder(); boolean isChanged = false; for (int p = 0; p < parts.length; p++) { if (p > 0) { - ret += "."; + ret.append("."); } String partChanged = deobfuscateName(as3, parts[p], false, "package", namesMap, renameType, selected); if (partChanged != null) { - ret += partChanged; + ret.append(partChanged); isChanged = true; } else { - ret += parts[p]; + ret.append(parts[p]); } } if (isChanged) { - namesMap.put(pkg, ret); - return ret; + String retStr = ret.toString(); + namesMap.put(pkg, retStr); + return retStr; } return null; } @@ -328,15 +329,16 @@ public class IdentifiersDeobfuscation { } else { parts = new String[]{pkg}; } - String ret = ""; + StringBuilder ret = new StringBuilder(); for (int i = 0; i < parts.length; i++) { if (i > 0) { - ret += "."; + ret.append("."); } - ret += printIdentifier(as3, parts[i], validNameExceptions); + ret.append(printIdentifier(as3, parts[i], validNameExceptions)); } - nameCache.put(pkg, ret); - return ret; + String retStr = ret.toString(); + nameCache.put(pkg, retStr); + return retStr; } public static String escapeOIdentifier(String s) { 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 60375f4b2..e9a8c2a7c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -79,8 +79,14 @@ import com.jpexs.decompiler.flash.exporters.settings.ShapeExportSettings; import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings; import com.jpexs.decompiler.flash.exporters.settings.TextExportSettings; import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; +import com.jpexs.decompiler.flash.abc.CachedDecompilation; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; +import com.jpexs.decompiler.flash.action.CachedScript; +import com.jpexs.decompiler.flash.helpers.HighlightedText; +import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; @@ -271,6 +277,10 @@ public final class SWF implements SWFContainerItem, Timelined { public DumpInfoSwfNode dumpInfo; public DefineBinaryDataTag binaryData; + private static Cache frameCache = Cache.getInstance(false); + private final Cache as2Cache = Cache.getInstance(true); + private final Cache as3Cache = Cache.getInstance(true); + public void updateCharacters() { characters.clear(); parseCharacters(new ArrayList(tags)); @@ -637,6 +647,13 @@ public final class SWF implements SWFContainerItem, Timelined { throw new IOException("Invalid SWF file. No known tag found."); } } + + /* preload shape tags + for (Tag tag : tags) { + if (tag instanceof ShapeTag) { + ((ShapeTag) tag).getShapes(); + } + }*/ } @Override @@ -2065,10 +2082,12 @@ public final class SWF implements SWFContainerItem, Timelined { public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel, version); + clearAllCache(); } public void exportXfl(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException { XFLConverter.convertSWF(handler, this, swfName, outfile, false, generator, generatorVerName, generatorVersion, parallel, version); + clearAllCache(); } public static AffineTransform matrixToTransform(MATRIX mat) { @@ -2077,8 +2096,6 @@ public final class SWF implements SWFContainerItem, Timelined { mat.translateX, mat.translateY); } - private static Cache frameCache = Cache.getInstance(false); - public static SerializableImage getFromCache(String key) { if (frameCache.contains(key)) { return SWF.frameCache.get(key); @@ -2092,8 +2109,80 @@ public final class SWF implements SWFContainerItem, Timelined { } } - public static void clearImageCache() { + public void clearImageCache() { frameCache.clear(); + for (Tag tag : tags) { + if (tag instanceof ImageTag) { + ((ImageTag) tag).clearCache(); + } + } + } + + public void clearScriptCache() { + as2Cache.clear(); + as3Cache.clear(); + } + + public void clearAllCache() { + clearImageCache(); + clearScriptCache(); + Cache.clearAll(); + System.gc(); + } + + public static void uncache(ASMSource src) { + src.getSwf().as2Cache.remove(src); + } + + public static void uncache(ScriptPack pack) { + pack.getSwf().as3Cache.remove(pack); + } + + public static boolean isCached(ASMSource src) { + return src.getSwf().as2Cache.contains(src); + } + + public static boolean isCached(ScriptPack pack) { + return pack.getSwf().as3Cache.contains(pack); + } + + public static CachedScript getCached(ASMSource src, ActionList actions) throws InterruptedException { + SWF swf = src.getSwf(); + if (swf.as2Cache.contains(src)) { + return swf.as2Cache.get(src); + } + + if (actions == null) { + actions = src.getActions(); + } + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); + Action.actionsToSource(src, actions, src.toString()/*FIXME?*/, writer); + List hilights = writer.instructionHilights; + String srcNoHex = writer.toString(); + CachedScript res = new CachedScript(srcNoHex, hilights); + swf.as2Cache.put(src, res); + return res; + } + + public static CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { + SWF swf = pack.getSwf(); + if (swf.as3Cache.contains(pack)) { + return swf.as3Cache.get(pack); + } + + int scriptIndex = pack.scriptIndex; + ScriptInfo script = null; + if (scriptIndex > -1) { + script = pack.abc.script_info.get(scriptIndex); + } + boolean parallel = Configuration.parallelSpeedUp.get(); + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); + pack.toSource(writer, swf.abcList, script.traits.traits, ScriptExportMode.AS, parallel); + HighlightedText hilightedCode = new HighlightedText(writer); + CachedDecompilation res = new CachedDecompilation(hilightedCode); + swf.as3Cache.put(pack, res); + + return res; } public static RECT fixRect(RECT rect) { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/CachedDecompilation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/CachedDecompilation.java similarity index 97% rename from src/com/jpexs/decompiler/flash/gui/abc/CachedDecompilation.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/CachedDecompilation.java index 55a98f692..006d1b346 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/CachedDecompilation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/CachedDecompilation.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.gui.abc; +package com.jpexs.decompiler.flash.abc; import com.jpexs.decompiler.flash.helpers.HighlightedText; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java index ceb65690c..a1ad08132 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Deobfuscation.java @@ -174,18 +174,18 @@ public class AVM2Deobfuscation { } else { parts = new String[]{s}; } - String ret = ""; + StringBuilder ret = new StringBuilder(); for (int p = 0; p < parts.length; p++) { if (p > 0) { - ret += "."; + ret.append("."); } if (!isValidNSPart(parts[p])) { - ret += fooString(namesMap, parts[p], false, DEFAULT_FOO_SIZE, "package", renameType); + ret.append(fooString(namesMap, parts[p], false, DEFAULT_FOO_SIZE, "package", renameType)); } else { - ret += parts[p]; + ret.append(parts[p]); } } - newName = ret; + newName = ret.toString(); namesMap.put(s, newName); } if (stringUsages.contains(strIndex)) { 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 3124f7e6e..77db5fb25 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 @@ -269,16 +269,16 @@ public class Multiname { } public String getNameWithNamespace(AVM2ConstantPool constants, boolean raw) { - String ret = ""; + StringBuilder ret = new StringBuilder(); Namespace ns = getNamespace(constants); if (ns != null) { String nsname = ns.getName(constants, raw); if (nsname != null && !nsname.isEmpty()) { - ret += nsname + "."; + ret.append(nsname).append("."); } } - ret += getName(constants, null, raw); - return ret; + ret.append(getName(constants, null, raw)); + return ret.toString(); } public Namespace getNamespace(AVM2ConstantPool constants) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java index 8e2985a36..ea790c62b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java @@ -755,9 +755,7 @@ public class Action implements GraphSourceItem { * @throws java.lang.InterruptedException */ public static List actionsToTree(HashMap regNames, HashMap variables, HashMap functions, List actions, int version, int staticOperation, String path) throws InterruptedException { - //Stack stack = new Stack(); return ActionGraph.translateViaGraph(regNames, variables, functions, actions, version, staticOperation, path); - //return actionsToTree(regNames, stack, actions, 0, actions.size() - 1, version); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/action/CachedScript.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/CachedScript.java similarity index 90% rename from src/com/jpexs/decompiler/flash/gui/action/CachedScript.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/CachedScript.java index 360775e07..4655a7155 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/CachedScript.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/CachedScript.java @@ -1,36 +1,36 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.action; - -import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; -import java.io.Serializable; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class CachedScript implements Serializable { - - public String text; - List hilights; - - public CachedScript(String text, List hilights) { - this.text = text; - this.hilights = hilights; - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.action; + +import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; +import java.io.Serializable; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class CachedScript implements Serializable { + + public String text; + public List hilights; + + public CachedScript(String text, List hilights) { + this.text = text; + this.hilights = hilights; + } +} 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 3803ca8c7..1a783db83 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 @@ -82,20 +82,20 @@ public class CanvasMorphShapeExporter extends MorphShapeExporterBase { } public static String getJsSuffix(int width, int height) { - String ret = ""; - ret += "}\r\n"; + StringBuilder ret = new StringBuilder(); + ret.append("}\r\n"); int step = Math.round(65535 / 100); int rate = 10; - ret += "var step = " + step + ";\r\n"; - ret += "var ratio = -1;\r\n"; - ret += "function nextFrame(ctx){\r\n"; - ret += "\tctx.clearRect(0,0," + width + "," + height + ");\r\n"; - ret += "\tratio = (ratio+step)%65535;\r\n"; - ret += "\tmorphshape(ctx,ratio);\r\n"; - ret += "}\r\n"; - ret += "window.setInterval(function(){nextFrame(ctx)}," + rate + ");\r\n"; - ret += CanvasShapeExporter.getJsSuffix(); - return ret; + ret.append("var step = ").append(step).append(";\r\n"); + ret.append("var ratio = -1;\r\n"); + ret.append("function nextFrame(ctx){\r\n"); + ret.append("\tctx.clearRect(0,0,").append(width).append(",").append(height).append(");\r\n"); + ret.append("\tratio = (ratio+step)%65535;\r\n"); + ret.append("\tmorphshape(ctx,ratio);\r\n"); + ret.append("}\r\n"); + ret.append("window.setInterval(function(){nextFrame(ctx)},").append(rate).append(");\r\n"); + ret.append(CanvasShapeExporter.getJsSuffix()); + return ret.toString(); } public static String getJsPrefix() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java index 285fbedfe..efc28e024 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java @@ -43,8 +43,6 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { public static final int ID = 21; - private SerializableImage cachedImage; - @Override public int getCharacterId() { return characterID; @@ -104,7 +102,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { @Override public void setImage(byte[] data) { imageData = new ByteArrayRange(data); - cachedImage = null; + clearCache(); setModified(true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java index 1e9af5bf0..e65feee8c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java @@ -46,8 +46,6 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { public static final int ID = 35; - private SerializableImage cachedImage; - @Override public int getCharacterId() { return characterID; @@ -66,7 +64,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { bitmapAlphaData = new byte[0]; } imageData = new ByteArrayRange(data); - cachedImage = null; + clearCache(); setModified(true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java index fe7f79bc4..3359d6443 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java @@ -54,8 +54,6 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { public static final int ID = 90; - private SerializableImage cachedImage; - @Override public int getCharacterId() { return characterID; @@ -83,6 +81,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { } else { bitmapAlphaData = ByteArrayRange.EMPTY; } + clearCache(); setModified(true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java index 39c683516..90d6a526b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java @@ -66,8 +66,6 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { public static final int ID = 36; - private SerializableImage cachedImage; - @Override public int getCharacterId() { return characterID; @@ -129,7 +127,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { sos2.writeBytesZlib(bitmapDataOS.toByteArray()); zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray()); decompressed = false; - cachedImage = null; + clearCache(); setModified(true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java index 9939a2adf..a0b46aba2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java @@ -75,8 +75,6 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { public static final int ID = 20; - private SerializableImage cachedImage; - private byte[] createEmptyImage() { try { BITMAPDATA bitmapData = new BITMAPDATA(); @@ -128,7 +126,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { sos2.writeBytesZlib(bitmapDataOS.toByteArray()); zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray()); decompressed = false; - cachedImage = null; + clearCache(); setModified(true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java index b18be36f0..97fc37ff6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java @@ -41,8 +41,6 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { public static final int ID = 6; - private SerializableImage cachedImage; - @Override public void setImage(byte[] data) { throw new UnsupportedOperationException("Set image is not supported for DefineBits"); @@ -132,6 +130,6 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { @Override public void handleEvent(Tag tag) { - cachedImage = null; + clearCache(); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java index bb1916079..5e026016c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java @@ -432,11 +432,11 @@ public class DefineFont2Tag extends FontTag { @Override public String getCharacters(List tags) { - String ret = ""; + StringBuilder ret = new StringBuilder(); for (int i : codeTable) { - ret += (char) i; + ret.append((char) i); } - return ret; + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java index d6d27fcd0..bd45194f1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java @@ -435,11 +435,11 @@ public class DefineFont3Tag extends FontTag { @Override public String getCharacters(List tags) { - String ret = ""; + StringBuilder ret = new StringBuilder(); for (int i : codeTable) { - ret += (char) i; + ret.append((char) i); } - return ret; + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java index c0eb7ae7b..d7e2bea7e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java @@ -319,19 +319,19 @@ public class DefineFontTag extends FontTag { @Override public String getCharacters(List tags) { - String ret = ""; + StringBuilder ret = new StringBuilder(); ensureFontInfo(); if (fontInfoTag != null) { for (int i : fontInfoTag.codeTable) { - ret += (char) i; + ret.append((char) i); } } if (fontInfo2Tag != null) { for (int i : fontInfo2Tag.codeTable) { - ret += (char) i; + ret.append((char) i); } } - return ret; + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java index 42e48eed7..1856427d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java @@ -127,23 +127,26 @@ public class DefineText2Tag extends TextTag { @Override public String getFormattedText() { FontTag fnt = null; - String ret = ""; - ret += "[\r\nxmin " + textBounds.Xmin + "\r\nymin " + textBounds.Ymin + "\r\nxmax " + textBounds.Xmax + "\r\nymax " + textBounds.Ymax; + StringBuilder ret = new StringBuilder(); + ret.append("[\r\nxmin ").append(textBounds.Xmin). + append("\r\nymin ").append(textBounds.Ymin). + append("\r\nxmax ").append(textBounds.Xmax). + append("\r\nymax ").append(textBounds.Ymax); if (textMatrix.translateX != 0) { - ret += "\r\ntranslatex " + textMatrix.translateX; + ret.append("\r\ntranslatex ").append(textMatrix.translateX); } if (textMatrix.translateY != 0) { - ret += "\r\ntranslatey " + textMatrix.translateY; + ret.append("\r\ntranslatey ").append(textMatrix.translateY); } if (textMatrix.hasScale) { - ret += "\r\nscalex " + textMatrix.scaleX; - ret += "\r\nscaley " + textMatrix.scaleY; + ret.append("\r\nscalex ").append(textMatrix.scaleX); + ret.append("\r\nscaley ").append(textMatrix.scaleY); } if (textMatrix.hasRotate) { - ret += "\r\nrotateskew0 " + textMatrix.rotateSkew0; - ret += "\r\nrotateskew1 " + textMatrix.rotateSkew1; + ret.append("\r\nrotateskew0 ").append(textMatrix.rotateSkew0); + ret.append("\r\nrotateskew1 ").append(textMatrix.rotateSkew1); } - ret += "\r\n]"; + ret.append("\r\n]"); for (TEXTRECORD rec : textRecords) { String params = ""; if (rec.styleFlagsHasFont) { @@ -167,11 +170,11 @@ public class DefineText2Tag extends TextTag { params += "\r\ny " + rec.yOffset; } if (params.length() > 0) { - ret += "[" + params + "\r\n]"; + ret.append("[").append(params).append("\r\n]"); } - ret += Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]"); + ret.append(Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]")); } - return ret; + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java index fbb58b5b5..524c59b3c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java @@ -128,23 +128,26 @@ public class DefineTextTag extends TextTag { @Override public String getFormattedText() { FontTag fnt = null; - String ret = ""; - ret += "[\r\nxmin " + textBounds.Xmin + "\r\nymin " + textBounds.Ymin + "\r\nxmax " + textBounds.Xmax + "\r\nymax " + textBounds.Ymax; + StringBuilder ret = new StringBuilder(); + ret.append("[\r\nxmin ").append(textBounds.Xmin). + append("\r\nymin ").append(textBounds.Ymin). + append("\r\nxmax ").append(textBounds.Xmax). + append("\r\nymax ").append(textBounds.Ymax); if (textMatrix.translateX != 0) { - ret += "\r\ntranslatex " + textMatrix.translateX; + ret.append("\r\ntranslatex ").append(textMatrix.translateX); } if (textMatrix.translateY != 0) { - ret += "\r\ntranslatey " + textMatrix.translateY; + ret.append("\r\ntranslatey ").append(textMatrix.translateY); } if (textMatrix.hasScale) { - ret += "\r\nscalex " + textMatrix.scaleX; - ret += "\r\nscaley " + textMatrix.scaleY; + ret.append("\r\nscalex ").append(textMatrix.scaleX); + ret.append("\r\nscaley ").append(textMatrix.scaleY); } if (textMatrix.hasRotate) { - ret += "\r\nrotateskew0 " + textMatrix.rotateSkew0; - ret += "\r\nrotateskew1 " + textMatrix.rotateSkew1; + ret.append("\r\nrotateskew0 ").append(textMatrix.rotateSkew0); + ret.append("\r\nrotateskew1 ").append(textMatrix.rotateSkew1); } - ret += "\r\n]"; + ret.append("\r\n]"); for (TEXTRECORD rec : textRecords) { String params = ""; if (rec.styleFlagsHasFont) { @@ -168,16 +171,16 @@ public class DefineTextTag extends TextTag { params += "\r\ny " + rec.yOffset; } if (params.length() > 0) { - ret += "[" + params + "\r\n]"; + ret.append("[").append(params).append("\r\n]"); } if (fnt == null) { - ret += AppResources.translate("fontNotFound").replace("%fontId%", Integer.toString(rec.fontId)); + ret.append(AppResources.translate("fontNotFound").replace("%fontId%", Integer.toString(rec.fontId))); } else { - ret += Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]"); + ret.append(Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]")); } } - return ret; + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index 5c9309c53..ad396fa96 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -50,6 +50,8 @@ import java.util.Set; */ public abstract class ImageTag extends CharacterTag implements DrawableTag { + protected SerializableImage cachedImage; + public ImageTag(SWF swf, int id, String name, ByteArrayRange data) { super(swf, id, name, data); } @@ -210,4 +212,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { return transformation.toTransform().createTransformedShape(getShape().getOutline()); } + + public void clearCache() { + cachedImage = null; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index de19c0b06..624db6b37 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -126,14 +126,14 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { @Override public String getFontNameIntag() { - String ret = ""; + StringBuilder ret = new StringBuilder(); for (int i = 0; i < fonts.size(); i++) { if (i > 0) { - ret += ", "; + ret.append(", "); } - ret += fonts.get(i).fontName; + ret.append(fonts.get(i).fontName); } - return ret; + return ret.toString(); } @Override @@ -192,7 +192,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { } setModified(true); - SWF.clearImageCache(); + getSwf().clearImageCache(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java index f644244ff..d3b084081 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java @@ -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.types; import com.jpexs.decompiler.flash.tags.DefineText2Tag; @@ -60,10 +61,10 @@ public class TEXTRECORD implements Serializable { public GLYPHENTRY[] glyphEntries; public String getText(FontTag font) { - String ret = ""; + StringBuilder ret = new StringBuilder(); for (GLYPHENTRY ge : glyphEntries) { - ret += font.glyphToChar(ge.glyphIndex); + ret.append(font.glyphToChar(ge.glyphIndex)); } - return ret; + return ret.toString(); } } 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 59917a4d8..540137cd3 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 @@ -153,12 +153,13 @@ public class XFLConverter { public static final int KEY_MODE_SHAPE_TWEEN = 17922; public static final int KEY_MODE_MOTION_TWEEN = 8195; public static final int KEY_MODE_SHAPE_LAYERS = 8192; + + private static final Random random = new Random(123); // predictable random private XFLConverter() { } public static String convertShapeEdge(MATRIX mat, SHAPERECORD record, int x, int y) { - String ret = ""; if (record instanceof StyleChangeRecord) { StyleChangeRecord scr = (StyleChangeRecord) record; Point p = new Point(scr.moveDeltaX, scr.moveDeltaY); @@ -192,20 +193,20 @@ public class XFLConverter { //anchor = mat.apply(anchor); return "[ " + control.x + " " + control.y + " " + anchor.x + " " + anchor.y; } - return ret; + return ""; } public static String convertShapeEdges(int startX, int startY, MATRIX mat, List records) { - String ret = ""; + StringBuilder ret = new StringBuilder(); int x = startX; int y = startY; - ret += "!" + startX + " " + startY; + ret.append("!").append(startX).append(" ").append(startY); for (SHAPERECORD rec : records) { - ret += convertShapeEdge(mat, rec, x, y); + ret.append(convertShapeEdge(mat, rec, x, y)); x = rec.changeX(x); y = rec.changeY(y); } - return ret; + return ret.toString(); } public static String convertLineStyle(LINESTYLE ls, int shapeNum) { @@ -219,59 +220,59 @@ public class XFLConverter { } public static String convertLineStyle(HashMap characters, LINESTYLE2 ls, int shapeNum) { - String ret = ""; - String params = ""; + StringBuilder ret = new StringBuilder(); + StringBuilder params = new StringBuilder(); if (ls.pixelHintingFlag) { - params += " pixelHinting=\"true\""; + params.append(" pixelHinting=\"true\""); } if (ls.width == 1) { - params += " solidStyle=\"hairline\""; + params.append(" solidStyle=\"hairline\""); } if ((!ls.noHScaleFlag) && (!ls.noVScaleFlag)) { - params += " scaleMode=\"normal\""; + params.append(" scaleMode=\"normal\""); } else if ((!ls.noHScaleFlag) && ls.noVScaleFlag) { - params += " scaleMode=\"horizontal\""; + params.append(" scaleMode=\"horizontal\""); } else if (ls.noHScaleFlag && (!ls.noVScaleFlag)) { - params += " scaleMode=\"vertical\""; + params.append(" scaleMode=\"vertical\""); } switch (ls.endCapStyle) { //What about endCapStyle? case LINESTYLE2.NO_CAP: - params += " caps=\"none\""; + params.append(" caps=\"none\""); break; case LINESTYLE2.SQUARE_CAP: - params += " caps=\"square\""; + params.append(" caps=\"square\""); break; } switch (ls.joinStyle) { case LINESTYLE2.BEVEL_JOIN: - params += " joints=\"bevel\""; + params.append(" joints=\"bevel\""); break; case LINESTYLE2.MITER_JOIN: - params += " joints=\"miter\""; + params.append(" joints=\"miter\""); float miterLimitFactor = toFloat(ls.miterLimitFactor); if (miterLimitFactor != 3.0f) { - params += " miterLimit=\"" + miterLimitFactor + "\""; + params.append(" miterLimit=\"").append(miterLimitFactor).append("\""); } break; } - ret += ""); + ret.append(""); if (!ls.hasFillFlag) { RGBA color = (RGBA) ls.color; - ret += ""; + ret.append(""); } else { - ret += convertFillStyle(null/* FIXME */, characters, ls.fillType, shapeNum); + ret.append(convertFillStyle(null/* FIXME */, characters, ls.fillType, shapeNum)); } - ret += ""; - ret += ""; - return ret; + ret.append(""); + ret.append(""); + return ret.toString(); } private static float toFloat(int i) { @@ -279,62 +280,63 @@ public class XFLConverter { } public static String convertFillStyle(MATRIX mat, HashMap characters, FILLSTYLE fs, int shapeNum) { + /* todo: use matrix if (mat == null) { mat = new MATRIX(); - } - String ret = ""; + }*/ + StringBuilder ret = new StringBuilder(); //ret += ""; switch (fs.fillStyleType) { case FILLSTYLE.SOLID: - ret += "= 3) { - ret += " alpha=\"" + ((RGBA) fs.color).getAlphaFloat() + "\""; + ret.append(" alpha=\"").append(((RGBA) fs.color).getAlphaFloat()).append("\""); } - ret += " />"; + ret.append(" />"); break; case FILLSTYLE.REPEATING_BITMAP: case FILLSTYLE.CLIPPED_BITMAP: case FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP: case FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP: - ret += ""; } - ret += "\""; + ret.append("\""); if ((fs.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) || (fs.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) { - ret += " bitmapIsClipped=\"true\""; + ret.append(" bitmapIsClipped=\"true\""); } - ret += ">"; - ret += "" + convertMatrix(fs.bitmapMatrix) + ""; - ret += ""; + ret.append(">"); + ret.append("").append(convertMatrix(fs.bitmapMatrix)).append(""); + ret.append(""); break; case FILLSTYLE.LINEAR_GRADIENT: case FILLSTYLE.RADIAL_GRADIENT: case FILLSTYLE.FOCAL_RADIAL_GRADIENT: if (fs.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) { - ret += ""); - ret += "" + convertMatrix(fs.gradientMatrix) + ""; + ret.append("").append(convertMatrix(fs.gradientMatrix)).append(""); GRADRECORD[] records; if (fs.fillStyleType == FILLSTYLE.FOCAL_RADIAL_GRADIENT) { records = fs.gradient.gradientRecords; @@ -374,24 +376,23 @@ public class XFLConverter { records = fs.gradient.gradientRecords; } for (GRADRECORD rec : records) { - ret += "= 3 ? rec.color.toHexRGB() : rec.color.toHexRGB()) + "\""; + ret.append("= 3) { - ret += " alpha=\"" + ((RGBA) rec.color).getAlphaFloat() + "\""; + ret.append(" alpha=\"").append(((RGBA) rec.color).getAlphaFloat()).append("\""); } - ret += " ratio=\"" + rec.getRatioFloat() + "\""; - ret += " />"; + ret.append(" ratio=\"").append(rec.getRatioFloat()).append("\""); + ret.append(" />"); } if (fs.fillStyleType == FILLSTYLE.LINEAR_GRADIENT) { - ret += ""; + ret.append(""); } else { - ret += ""; + ret.append(""); } break; } //ret += ""; - return ret; - + return ret.toString(); } public static String convertMatrix(MATRIX m) { @@ -399,23 +400,23 @@ public class XFLConverter { } public static String convertMatrix(Matrix m) { - String ret = ""; + StringBuilder ret = new StringBuilder(); if (m == null) { m = new Matrix(); } - ret += ""); + return ret.toString(); } /* public static String convertShape(HashMap characters, MATRIX mat, int shapeNum, SHAPE shape) { @@ -440,25 +441,25 @@ public class XFLConverter { } public static String convertShape(HashMap characters, MATRIX mat, int shapeNum, List shapeRecords, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, boolean morphshape, boolean useLayers) { - String ret = ""; + StringBuilder ret = new StringBuilder(); List layers = getShapeLayers(characters, mat, shapeNum, shapeRecords, fillStyles, lineStyles, morphshape); if (layers.size() == 1 && !useLayers) { - ret += layers.get(0); + ret.append(layers.get(0)); } else { int layer = 1; for (int l = layers.size() - 1; l >= 0; l--) { - ret += ""; //color=\"#4FFF4F\" - ret += ""; - ret += ""; - ret += ""; - ret += layers.get(l); - ret += ""; - ret += ""; - ret += ""; - ret += ""; + ret.append(""); //color=\"#4FFF4F\" + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(layers.get(l)); + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(""); } } - return ret; + return ret.toString(); } /** @@ -901,149 +902,149 @@ public class XFLConverter { } public static String convertFilter(FILTER filter) { - String ret = ""; + StringBuilder ret = new StringBuilder(); if (filter instanceof DROPSHADOWFILTER) { DROPSHADOWFILTER dsf = (DROPSHADOWFILTER) filter; - ret += ""); } else if (filter instanceof BLURFILTER) { BLURFILTER bf = (BLURFILTER) filter; - ret += ""); } else if (filter instanceof GLOWFILTER) { GLOWFILTER gf = (GLOWFILTER) filter; - ret += ""); } else if (filter instanceof BEVELFILTER) { BEVELFILTER bf = (BEVELFILTER) filter; - ret += ""); } else if (filter instanceof GRADIENTGLOWFILTER) { GRADIENTGLOWFILTER ggf = (GRADIENTGLOWFILTER) filter; - ret += ""); for (int g = 0; g < ggf.gradientColors.length; g++) { RGBA gc = ggf.gradientColors[g]; - ret += ""); } - ret += ""; + ret.append(""); } else if (filter instanceof GRADIENTBEVELFILTER) { GRADIENTBEVELFILTER gbf = (GRADIENTBEVELFILTER) filter; - ret += ""); for (int g = 0; g < gbf.gradientColors.length; g++) { RGBA gc = gbf.gradientColors[g]; - ret += ""); } - ret += ""; + ret.append(""); } else if (filter instanceof COLORMATRIXFILTER) { COLORMATRIXFILTER cmf = (COLORMATRIXFILTER) filter; - ret += convertAdjustColorFilter(cmf); + ret.append(convertAdjustColorFilter(cmf)); } - return ret; + 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) { - String ret = ""; + StringBuilder ret = new StringBuilder(); if (matrix == null) { matrix = new MATRIX(); } @@ -1059,110 +1060,110 @@ public class XFLConverter { } } - ret += "()); double centerPoint3DX = twipToPixel(matrix.translateX + spriteRect.getWidth() / 2); double centerPoint3DY = twipToPixel(matrix.translateY + spriteRect.getHeight() / 2); - ret += " centerPoint3DX=\"" + centerPoint3DX + "\" centerPoint3DY=\"" + centerPoint3DY + "\""; + ret.append(" centerPoint3DX=\"").append(centerPoint3DX).append("\" centerPoint3DY=\"").append(centerPoint3DY).append("\""); } else if (tag instanceof ButtonTag) { - ret += " symbolType=\"button\""; + ret.append(" symbolType=\"button\""); } if (cacheAsBitmap) { - ret += " cacheAsBitmap=\"true\""; + ret.append(" cacheAsBitmap=\"true\""); } if (!isVisible && flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) { - ret += " isVisible=\"false\""; + ret.append(" isVisible=\"false\""); } - ret += ">"; - ret += ""; - ret += convertMatrix(matrix); - ret += ""; - ret += ""; + ret.append(">"); + ret.append(""); + ret.append(convertMatrix(matrix)); + ret.append(""); + ret.append(""); if (backgroundColor != null) { - ret += ""); } if (colorTransform != null) { - ret += ""); } if (filters != null) { - ret += ""; + ret.append(""); for (FILTER f : filters) { - ret += convertFilter(f); + ret.append(convertFilter(f)); } - ret += ""; + ret.append(""); } if (tag instanceof DefineButtonTag) { - ret += ""; + ret.append(""); } if (tag instanceof DefineButton2Tag) { DefineButton2Tag db2 = (DefineButton2Tag) tag; if (!db2.actions.isEmpty()) { - ret += ""; + ret.append("]]>"); } } if (clipActions != null) { - ret += ""; + ret.append("]]>"); } - ret += ""; - return ret; + ret.append(""); + return ret.toString(); } private static String convertActionScript(ASMSource as) { @@ -1183,7 +1184,7 @@ public class XFLConverter { //TODO: Imported assets //linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf" - String ret = ""; + StringBuilder ret = new StringBuilder(); List media = new ArrayList<>(); List symbols = new ArrayList<>(); for (int ch : characters.keySet()) { @@ -1192,40 +1193,39 @@ public class XFLConverter { continue; //shapes with 1 ocurrence and single layer are not added to library } if ((symbol instanceof ShapeTag) || (symbol instanceof DefineSpriteTag) || (symbol instanceof ButtonTag)) { - String symbolStr = ""; + StringBuilder symbolStr = new StringBuilder(); - symbolStr += ""); + symbolStr.append(""); String itemIcon = null; if (symbol instanceof ButtonTag) { itemIcon = "0"; - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); ButtonTag button = (ButtonTag) symbol; List records = button.getRecords(); - String[] frames = {"", "", "", ""}; int maxDepth = 0; for (BUTTONRECORD rec : records) { @@ -1234,12 +1234,12 @@ public class XFLConverter { } } for (int i = maxDepth; i >= 1; i--) { - symbolStr += ""; - symbolStr += ""; + symbolStr.append(" color=\"").append(randomOutlineColor()).append("\">"); + symbolStr.append(""); int lastFrame = 0; loopframes: for (int frame = 1; frame <= 4; frame++) { @@ -1277,7 +1277,7 @@ public class XFLConverter { } CharacterTag character = characters.get(rec.characterId); MATRIX matrix = rec.placeMatrix; - String recCharStr = ""; + String recCharStr; if (character instanceof TextTag) { recCharStr = convertText(null, tags, (TextTag) character, matrix, filters, null); } else if (character instanceof DefineVideoStreamTag) { @@ -1289,52 +1289,52 @@ public class XFLConverter { lastFrame = frame; if (duration > 0) { if (duration > 1) { - symbolStr += ""; - symbolStr += ""; - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); + symbolStr.append(""); + symbolStr.append(""); } - symbolStr += ""; - symbolStr += ""; - symbolStr += recCharStr; - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); + symbolStr.append(recCharStr); + symbolStr.append(""); + symbolStr.append(""); } } } } - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); } - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); } else if (symbol instanceof DefineSpriteTag) { DefineSpriteTag sprite = (DefineSpriteTag) symbol; if (sprite.subTags.isEmpty()) { //probably AS2 class continue; } - symbolStr += convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getSubTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files); + symbolStr.append(convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getSubTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files)); } else if (symbol instanceof ShapeTag) { itemIcon = "1"; ShapeTag shape = (ShapeTag) symbol; - symbolStr += ""; - symbolStr += ""; - symbolStr += convertShape(characters, null, shape.getShapeNum(), shape.getShapes().shapeRecords, shape.getShapes().fillStyles, shape.getShapes().lineStyles, false, true); - symbolStr += ""; - symbolStr += ""; + symbolStr.append(""); + symbolStr.append(""); + symbolStr.append(convertShape(characters, null, shape.getShapeNum(), shape.getShapes().shapeRecords, shape.getShapes().fillStyles, shape.getShapes().lineStyles, false, true)); + symbolStr.append(""); + symbolStr.append(""); } - symbolStr += ""; - symbolStr += ""; - symbolStr = prettyFormatXML(symbolStr); + symbolStr.append(""); + symbolStr.append(""); + String symbolStr2 = prettyFormatXML(symbolStr.toString()); String symbolFile = "Symbol " + symbol.getCharacterId() + ".xml"; - files.put(symbolFile, Utf8Helper.getBytes(symbolStr)); + files.put(symbolFile, Utf8Helper.getBytes(symbolStr2)); String symbLinkStr = ""; symbLinkStr += ""); for (String m : media) { - ret += m; + ret.append(m); } - ret += ""; + ret.append(""); } if (!symbols.isEmpty()) { - ret += ""; + ret.append(""); for (String s : symbols) { - ret += s; + ret.append(s); } - ret += ""; + ret.append(""); } - return ret; + return ret.toString(); } private static String prettyFormatXML(String input) { @@ -1653,7 +1655,7 @@ public class XFLConverter { } private static String convertFrame(boolean shapeTween, HashMap characters, List tags, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, int duration, String actionScript, String elements, HashMap files) { - String ret = ""; + StringBuilder ret = new StringBuilder(); DefineSoundTag sound = null; if (startSound != null) { for (Tag t : tags) { @@ -1667,79 +1669,80 @@ public class XFLConverter { } } - ret += " 1) { - ret += " duration=\"" + duration + "\""; + ret.append(" duration=\"").append(duration).append("\""); } if (shapeTween) { - ret += " tweenType=\"shape\" keyMode=\"" + KEY_MODE_SHAPE_TWEEN + "\""; + ret.append(" tweenType=\"shape\" keyMode=\"").append(KEY_MODE_SHAPE_TWEEN).append("\""); } else { - ret += " keyMode=\"" + KEY_MODE_NORMAL + "\""; + ret.append(" keyMode=\"").append(KEY_MODE_NORMAL).append("\""); } String soundEnvelopeStr = ""; if (soundStreamHead != null && startSound == null) { String soundName = "sound" + soundStreamHead.getCharacterId() + "." + soundStreamHead.getExportFormat(); - ret += " soundName=\"" + soundName + "\""; - ret += " soundSync=\"stream\""; + ret.append(" soundName=\"").append(soundName).append("\""); + ret.append(" soundSync=\"stream\""); soundEnvelopeStr += ""; soundEnvelopeStr += ""; soundEnvelopeStr += ""; } if (startSound != null && sound != null) { String soundName = "sound" + sound.soundId + "." + sound.getExportFormat(); - ret += " soundName=\"" + soundName + "\""; + ret.append(" soundName=\"").append(soundName).append("\""); if (startSound.soundInfo.hasInPoint) { - ret += " inPoint44=\"" + startSound.soundInfo.inPoint + "\""; + ret.append(" inPoint44=\"").append(startSound.soundInfo.inPoint).append("\""); } if (startSound.soundInfo.hasOutPoint) { - ret += " outPoint44=\"" + startSound.soundInfo.outPoint + "\""; + ret.append(" outPoint44=\"").append(startSound.soundInfo.outPoint).append("\""); } if (startSound.soundInfo.hasLoops) { if (startSound.soundInfo.loopCount == 32767) { - ret += " soundLoopMode=\"loop\""; + ret.append(" soundLoopMode=\"loop\""); } - ret += " soundLoop=\"" + startSound.soundInfo.loopCount + "\""; + ret.append(" soundLoop=\"").append(startSound.soundInfo.loopCount).append("\""); } if (startSound.soundInfo.syncStop) { - ret += " soundSync=\"stop\""; + ret.append(" soundSync=\"stop\""); } else if (startSound.soundInfo.syncNoMultiple) { - ret += " soundSync=\"start\""; + ret.append(" soundSync=\"start\""); } soundEnvelopeStr += ""; if (startSound.soundInfo.hasEnvelope) { - for (SOUNDENVELOPE env : startSound.soundInfo.envelopeRecords) { + SOUNDENVELOPE[] envelopeRecords = startSound.soundInfo.envelopeRecords; + for (SOUNDENVELOPE env : envelopeRecords) { soundEnvelopeStr += ""; } - if (startSound.soundInfo.envelopeRecords.length == 1 - && startSound.soundInfo.envelopeRecords[0].leftLevel == 32768 - && startSound.soundInfo.envelopeRecords[0].pos44 == 0 - && startSound.soundInfo.envelopeRecords[0].rightLevel == 0) { - ret += " soundEffect=\"left channel\""; - } else if (startSound.soundInfo.envelopeRecords.length == 1 - && startSound.soundInfo.envelopeRecords[0].leftLevel == 0 - && startSound.soundInfo.envelopeRecords[0].pos44 == 0 - && startSound.soundInfo.envelopeRecords[0].rightLevel == 32768) { - ret += " soundEffect=\"right channel\""; - } else if (startSound.soundInfo.envelopeRecords.length == 2 - && startSound.soundInfo.envelopeRecords[0].leftLevel == 32768 - && startSound.soundInfo.envelopeRecords[0].pos44 == 0 - && startSound.soundInfo.envelopeRecords[0].rightLevel == 0 - && startSound.soundInfo.envelopeRecords[1].leftLevel == 0 - && startSound.soundInfo.envelopeRecords[1].pos44 == sound.soundSampleCount - && startSound.soundInfo.envelopeRecords[1].rightLevel == 32768) { - ret += " soundEffect=\"fade left to right\""; - } else if (startSound.soundInfo.envelopeRecords.length == 2 - && startSound.soundInfo.envelopeRecords[0].leftLevel == 0 - && startSound.soundInfo.envelopeRecords[0].pos44 == 0 - && startSound.soundInfo.envelopeRecords[0].rightLevel == 32768 - && startSound.soundInfo.envelopeRecords[1].leftLevel == 32768 - && startSound.soundInfo.envelopeRecords[1].pos44 == sound.soundSampleCount - && startSound.soundInfo.envelopeRecords[1].rightLevel == 0) { - ret += " soundEffect=\"fade right to left\""; + if (envelopeRecords.length == 1 + && envelopeRecords[0].leftLevel == 32768 + && envelopeRecords[0].pos44 == 0 + && envelopeRecords[0].rightLevel == 0) { + ret.append(" soundEffect=\"left channel\""); + } else if (envelopeRecords.length == 1 + && envelopeRecords[0].leftLevel == 0 + && envelopeRecords[0].pos44 == 0 + && envelopeRecords[0].rightLevel == 32768) { + ret.append(" soundEffect=\"right channel\""); + } else if (envelopeRecords.length == 2 + && envelopeRecords[0].leftLevel == 32768 + && envelopeRecords[0].pos44 == 0 + && envelopeRecords[0].rightLevel == 0 + && envelopeRecords[1].leftLevel == 0 + && envelopeRecords[1].pos44 == sound.soundSampleCount + && envelopeRecords[1].rightLevel == 32768) { + ret.append(" soundEffect=\"fade left to right\""); + } else if (envelopeRecords.length == 2 + && envelopeRecords[0].leftLevel == 0 + && envelopeRecords[0].pos44 == 0 + && envelopeRecords[0].rightLevel == 32768 + && envelopeRecords[1].leftLevel == 32768 + && envelopeRecords[1].pos44 == sound.soundSampleCount + && envelopeRecords[1].rightLevel == 0) { + ret.append(" soundEffect=\"fade right to left\""); } else { - ret += " soundEffect=\"custom\""; + ret.append(" soundEffect=\"custom\""); } //TODO: fade in, fade out @@ -1748,39 +1751,40 @@ public class XFLConverter { } soundEnvelopeStr += ""; } - ret += ">"; + ret.append(">"); - ret += soundEnvelopeStr; + ret.append(soundEnvelopeStr); if (!actionScript.isEmpty()) { - ret += ""; + ret.append(""); } - ret += ""; - ret += elements; - ret += ""; - ret += ""; - return ret; + ret.append(""); + ret.append(elements); + ret.append(""); + ret.append(""); + return ret.toString(); } private static String convertVideoInstance(String instanceName, MATRIX matrix, DefineVideoStreamTag video, CLIPACTIONS clipActions) { - String ret = ""); + ret.append(""); + ret.append(convertMatrix(matrix)); + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(""); + return ret.toString(); } private static String convertFrames(String prevStr, String afterStr, List nonLibraryShapes, List tags, List timelineTags, HashMap characters, int depth, FLAVersion flaVersion, HashMap files) { - String ret = ""; + StringBuilder ret = new StringBuilder(); prevStr += ""; int frame = -1; String elements = ""; @@ -1912,7 +1916,7 @@ public class XFLConverter { frame++; if (!elements.equals(lastElements) && frame > 0) { - ret += convertFrame(lastShapeTween, characters, tags, null, null, frame - duration, duration, "", lastElements, files); + ret.append(convertFrame(lastShapeTween, characters, tags, null, null, frame - duration, duration, "", lastElements, files)); duration = 1; } else if (frame == 0) { duration = 1; @@ -1926,17 +1930,18 @@ public class XFLConverter { } if (!lastElements.isEmpty()) { frame++; - ret += convertFrame(lastShapeTween, characters, tags, null, null, (frame - duration < 0 ? 0 : frame - duration), duration, "", lastElements, files); + ret.append(convertFrame(lastShapeTween, characters, tags, null, null, (frame - duration < 0 ? 0 : frame - duration), duration, "", lastElements, files)); } afterStr = "" + afterStr; - if (!ret.isEmpty()) { - ret = prevStr + ret + afterStr; + String retStr = ret.toString(); + if (!retStr.isEmpty()) { + retStr = prevStr + retStr + afterStr; } - return ret; + return retStr; } public static String convertFonts(List tags) { - String ret = ""; + StringBuilder ret = new StringBuilder(); for (Tag t : tags) { if (t instanceof FontTag) { FontTag font = (FontTag) t; @@ -1992,20 +1997,21 @@ public class XFLConverter { if (hasAllRanges) { embedRanges = "9999"; } - ret += ""; + ret.append(""); } } - if (!"".equals(ret)) { - ret = "" + ret + ""; + String retStr = ret.toString(); + if (!retStr.isEmpty()) { + retStr = "" + retStr + ""; } - return ret; + return retStr; } public static String convertActionScriptLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { - String ret = ""; + StringBuilder ret = new StringBuilder(); String script = ""; int duration = 0; @@ -2032,41 +2038,42 @@ public class XFLConverter { duration++; } else { if (duration > 0) { - ret += " 1) { - ret += " duration=\"" + duration + "\""; + ret.append(" duration=\"").append(duration).append("\""); } - ret += " keyMode=\"" + KEY_MODE_NORMAL + "\">"; - ret += ""; - ret += ""; - ret += ""; + ret.append(" keyMode=\"").append(KEY_MODE_NORMAL).append("\">"); + ret.append(""); + ret.append(""); + ret.append(""); } - ret += ""; - ret += ""; - ret += ""; - ret += ""; - ret += ""; + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(""); + ret.append(""); script = ""; duration = 0; } frame++; } } - if (!ret.isEmpty()) { - ret = "" + String retStr = ret.toString(); + if (!retStr.isEmpty()) { + retStr = "" + "" - + ret + + retStr + "" + ""; } - return ret; + return retStr; } public static String convertLabelsLayer(int spriteId, List tags, List timeLineTags, String backgroundColor) { - String ret = ""; + StringBuilder ret = new StringBuilder(); int duration = 0; int frame = 0; String frameLabel = ""; @@ -2083,45 +2090,46 @@ public class XFLConverter { duration++; } else { if (duration > 0) { - ret += " 1) { - ret += " duration=\"" + duration + "\""; + ret.append(" duration=\"").append(duration).append("\""); } - ret += " keyMode=\"" + KEY_MODE_NORMAL + "\">"; - ret += ""; - ret += ""; - ret += ""; + ret.append(" keyMode=\"").append(KEY_MODE_NORMAL).append("\">"); + ret.append(""); + ret.append(""); + ret.append(""); } - ret += ""); + ret.append(""); + ret.append(""); + ret.append(""); frameLabel = ""; duration = 0; } frame++; } } - if (!ret.isEmpty()) { - ret = "" + String retStr = ret.toString(); + if (!retStr.isEmpty()) { + retStr = "" + "" - + ret + + retStr + "" + ""; } - return ret; + return retStr; } public static String convertSoundLayer(int layerIndex, String backgroundColor, HashMap characters, List tags, List timeLineTags, HashMap files) { - String ret = ""; + StringBuilder ret = new StringBuilder(); StartSoundTag lastStartSound = null; SoundStreamHeadTypeTag lastSoundStreamHead = null; StartSoundTag startSound = null; @@ -2154,7 +2162,7 @@ public class XFLConverter { if (t instanceof ShowFrameTag) { if (soundStreamHead != null || startSound != null) { if (lastSoundStreamHead != null || lastStartSound != null) { - ret += convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files); + ret.append(convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files)); } frame += duration; duration = 1; @@ -2172,36 +2180,36 @@ public class XFLConverter { frame = 0; duration = 1; } - ret += convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files); + ret.append(convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files)); } - if (!ret.isEmpty()) { - ret = "" - + "" + ret + "" + String retStr = ret.toString(); + if (!retStr.isEmpty()) { + retStr = "" + + "" + retStr + "" + ""; } - return ret; + return retStr; } private static String randomOutlineColor() { RGB outlineColor = new RGB(); - Random rnd = new Random(); do { - outlineColor.red = rnd.nextInt(256); - outlineColor.green = rnd.nextInt(256); - outlineColor.blue = rnd.nextInt(256); + outlineColor.red = random.nextInt(256); + outlineColor.green = random.nextInt(256); + outlineColor.blue = random.nextInt(256); } while ((outlineColor.red + outlineColor.green + outlineColor.blue) / 3 < 128); 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) { - String ret = ""; - ret += ""; - ret += ""; + StringBuilder ret = new StringBuilder(); + ret.append(""); + ret.append(""); String labelsLayer = convertLabelsLayer(spriteId, tags, timelineTags, backgroundColor); - ret += labelsLayer; + ret.append(labelsLayer); String scriptLayer = convertActionScriptLayer(spriteId, tags, timelineTags, backgroundColor); - ret += scriptLayer; + ret.append(scriptLayer); int index = 0; @@ -2225,11 +2233,11 @@ public class XFLConverter { parentLayers.push(index); } - ret += ""); + ret.append(convertFrames("", "", nonLibraryShapes, tags, timelineTags, characters, po.getDepth(), flaVersion, files)); + ret.append(""); index++; break; } @@ -2273,15 +2281,15 @@ public class XFLConverter { if (cf.isEmpty()) { index--; } - ret += cf; + ret.append(cf); } int soundLayerIndex = layerCount; layerCount++; - ret += convertSoundLayer(soundLayerIndex, backgroundColor, characters, tags, timelineTags, files); - ret += ""; - ret += ""; - return ret; + ret.append(convertSoundLayer(soundLayerIndex, backgroundColor, characters, tags, timelineTags, files)); + ret.append(""); + ret.append(""); + return ret.toString(); } private static void writeFile(AbortRetryIgnoreHandler handler, final byte[] data, final String file) throws IOException { @@ -2326,7 +2334,7 @@ public class XFLConverter { } public static String convertText(String instanceName, List tags, TextTag tag, MATRIX m, List filters, CLIPACTIONS clipActions) { - String ret = ""; + StringBuilder ret = new StringBuilder(); if (m == null) { m = new MATRIX(); @@ -2396,21 +2404,21 @@ public class XFLConverter { } } - ret += " attrs = TextTag.getTextRecordsAttributes(textRecords, tags); - ret += " width=\"" + tag.getBounds().getWidth() / 2 + "\" height=\"" + tag.getBounds().getHeight() + "\" autoExpand=\"true\" isSelectable=\"false\">"; - ret += matStr; + ret.append(" width=\"").append(tag.getBounds().getWidth() / 2).append("\" height=\"").append(tag.getBounds().getHeight()).append("\" autoExpand=\"true\" isSelectable=\"false\">"); + ret.append(matStr); - ret += ""; + ret.append(""); int fontId = -1; FontTag font = null; String fontName = null; @@ -2470,32 +2478,32 @@ public class XFLConverter { } firstRun = false; if (font != null) { - ret += ""; - ret += "" + xmlString((newline ? "\r" : "") + rec.getText(font)) + ""; - ret += ""; + ret.append(""); + ret.append("").append(xmlString((newline ? "\r" : "") + rec.getText(font))).append(""); + ret.append(""); - ret += ""); - ret += ""; - ret += ""; + ret.append(""); + ret.append(""); } } - ret += ""; - ret += filterStr; - ret += ""; + ret.append(""); + ret.append(filterStr); + ret.append(""); } else if (tag instanceof DefineEditTextTag) { DefineEditTextTag det = (DefineEditTextTag) tag; String tagName; @@ -2520,14 +2528,14 @@ public class XFLConverter { } else { tagName = "DOMInputText"; } - ret += "<" + tagName; + ret.append("<").append(tagName); if (fontRenderingMode != null) { - ret += " fontRenderingMode=\"" + fontRenderingMode + "\""; + ret.append(" fontRenderingMode=\"").append(fontRenderingMode).append("\""); } if (instanceName != null) { - ret += " name=\"" + xmlString(instanceName) + "\""; + ret.append(" name=\"").append(xmlString(instanceName)).append("\""); } - ret += antiAlias; + ret.append(antiAlias); double width = twipToPixel(bounds.getWidth()); double height = twipToPixel(bounds.getHeight()); //There is usually 4px difference between width/height and XML width/height @@ -2539,43 +2547,43 @@ public class XFLConverter { width -= twipToPixel(det.rightMargin); width -= twipToPixel(det.leftMargin); } - ret += " width=\"" + width + "\""; - ret += " height=\"" + height + "\""; + ret.append(" width=\"").append(width).append("\""); + ret.append(" height=\"").append(height).append("\""); if (det.border) { - ret += " border=\"true\""; + ret.append(" border=\"true\""); } if (det.html) { - ret += " renderAsHTML=\"true\""; + ret.append(" renderAsHTML=\"true\""); } if (det.noSelect) { - ret += " isSelectable=\"false\""; + ret.append(" isSelectable=\"false\""); } if (det.multiline && det.wordWrap) { - ret += " lineType=\"multiline\""; + ret.append(" lineType=\"multiline\""); } else if (det.multiline && (!det.wordWrap)) { - ret += " lineType=\"multiline no wrap\""; + ret.append(" lineType=\"multiline no wrap\""); } else if (det.password) { - ret += " lineType=\"password\""; + ret.append(" lineType=\"password\""); } if (det.hasMaxLength) { - ret += " maxCharacters=\"" + det.maxLength + "\""; + ret.append(" maxCharacters=\"").append(det.maxLength).append("\""); } if (!det.variableName.isEmpty()) { - ret += " variableName=\"" + det.variableName + "\""; + ret.append(" variableName=\"").append(det.variableName).append("\""); } - ret += ">"; - ret += matStr; - ret += ""; + ret.append(">"); + ret.append(matStr); + ret.append(""); String txt = ""; if (det.hasText) { txt = det.initialText; } if (det.html) { - ret += convertHTMLText(tags, det, txt); + ret.append(convertHTMLText(tags, det, txt)); } else { - ret += ""; - ret += "" + xmlString(txt) + ""; + ret.append(""); + ret.append("").append(xmlString(txt)).append(""); int leftMargin = -1; int rightMargin = -1; int indent = -1; @@ -2635,53 +2643,48 @@ public class XFLConverter { alignment = "unknown"; } } - ret += ""; - ret += ""); + ret.append(" -1) { - ret += " indent=\"" + twipToPixel(indent) + "\""; + ret.append(" indent=\"").append(twipToPixel(indent)).append("\""); } if (leftMargin > -1) { - ret += " leftMargin=\"" + twipToPixel(leftMargin) + "\""; + ret.append(" leftMargin=\"").append(twipToPixel(leftMargin)).append("\""); } if (lineSpacing > -1) { - ret += " lineSpacing=\"" + twipToPixel(lineSpacing) + "\""; + ret.append(" lineSpacing=\"").append(twipToPixel(lineSpacing)).append("\""); } if (rightMargin > -1) { - ret += " rightMargin=\"" + twipToPixel(rightMargin) + "\""; + ret.append(" rightMargin=\"").append(twipToPixel(rightMargin)).append("\""); } if (size > -1) { - ret += " size=\"" + twipToPixel(size) + "\""; - ret += " bitmapSize=\"" + size + "\""; + ret.append(" size=\"").append(twipToPixel(size)).append("\""); + ret.append(" bitmapSize=\"").append(size).append("\""); } if (fontFace != null) { - ret += " face=\"" + fontFace + "\""; + ret.append(" face=\"").append(fontFace).append("\""); } if (textColor != null) { - ret += " fillColor=\"" + textColor.toHexRGB() + "\" alpha=\"" + textColor.getAlphaFloat() + "\""; + ret.append(" fillColor=\"").append(textColor.toHexRGB()).append("\" alpha=\"").append(textColor.getAlphaFloat()).append("\""); } - ret += "/>"; - ret += ""; - ret += ""; + ret.append("/>"); + ret.append(""); + ret.append(""); } - ret += ""; - ret += filterStr; - ret += ""; + ret.append(""); + ret.append(filterStr); + ret.append(""); } - return ret; + return ret.toString(); } public static void convertSWF(AbortRetryIgnoreHandler handler, SWF swf, String swfFileName, String outfile, boolean compressed, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion flaVersion) throws IOException { - FileAttributesTag fa = null; - for (Tag t : swf.tags) { - if (t instanceof FileAttributesTag) { - fa = (FileAttributesTag) t; - } - } + FileAttributesTag fa = swf.fileAttributes; boolean useAS3 = false; boolean useNetwork = false; @@ -2702,7 +2705,7 @@ public class XFLConverter { } } } - String domDocument = ""; + StringBuilder domDocument = new StringBuilder(); String baseName = swfFileName; File f = new File(baseName); baseName = f.getName(); @@ -2723,26 +2726,26 @@ public class XFLConverter { backgroundColor = sbc.backgroundColor.toHexRGB(); } } - domDocument += ""); + domDocument.append(convertFonts(swf.tags)); + domDocument.append(convertLibrary(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, swf.tags, characters, files, datfiles, flaVersion)); + domDocument.append(""); + domDocument.append(convertTimeline(0, nonLibraryShapes, backgroundColor, swf.tags, swf.tags, characters, "Scene 1", flaVersion, files)); + domDocument.append(""); + domDocument.append(""); + String domDocumentStr = prettyFormatXML(domDocument.toString()); for (Tag t : swf.tags) { if (t instanceof DoInitActionTag) { @@ -2780,235 +2783,242 @@ public class XFLConverter { } int flaSwfVersion = swf.version > flaVersion.maxSwfVersion() ? flaVersion.maxSwfVersion() : swf.version; - String publishSettings = "\n" - + "\n" - + " \n" - + " 1\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 0\n" - + (flaVersion.ordinal() >= FLAVersion.CC.ordinal() ? " 0\n" : " 0\n") - + " 0\n" - + " 0\n" - + " 1\n" - + " 1\n" - + " 1\n" - + " 1\n" - + " 1\n" - + " 1\n" - + " 1\n" - + (flaVersion.ordinal() >= FLAVersion.CC.ordinal() ? " 1\n" : " 1\n") - + " 1\n" - + " 1\n" - + " " + baseName + ".swf\n" - + " " + baseName + ".exe\n" - + " " + baseName + ".app\n" - + " " + baseName + ".html\n" - + " " + baseName + ".gif\n" - + " " + baseName + ".jpg\n" - + " " + baseName + ".png\n" - + (flaVersion.ordinal() >= FLAVersion.CC.ordinal() ? " 1\n" : " 1\n") - + " " + baseName + ".smil\n" - + " " + baseName + ".swc\n" - + " \n" - + " \n" - + " 0\n" - + " 12,0,0,0;11,2,0,0;11,1,0,0;10,3,0,0;10,2,153,0;10,1,52,0;9,0,124,0;8,0,24,0;7,0,14,0;6,0,79,0;5,0,58,0;4,0,32,0;3,0,8,0;2,0,1,12;1,0,0,1;\n" - + " 1\n" - + " 1\n" - + " " + baseName + "_content.html\n" - + " " + baseName + "_alternate.html\n" - + " 0\n" - + " \n" - + " " + width + "\n" - + " " + height + "\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " 1\n" - + " 4\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " \n" - + " 1\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 80\n" - + " 0\n" - + " 0\n" - + " 7\n" - + " 0\n" - + " 7\n" - + " 0\n" - + " " + flaSwfVersion + "\n" - + " " + FLAVersion.swfVersionToPlayer(flaSwfVersion) + "\n" - + " " + (useAS3 ? "3" : "2") + "\n" - + " 1\n" - + " \n" - + " .\n" - + " CONFIG::FLASH_AUTHORING="true";\n" - + " 0\n" - + " \n" - + " " + (swf.compression == SWFCompression.NONE ? "0" : "1") + "\n" - + " " + (swf.compression == SWFCompression.LZMA ? "1" : "0") + "\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " " + (useNetwork ? 1 : 0) + "\n" - + " " + xmlString(characterClasses.containsKey(0) ? characterClasses.get(0) : "") + "\n" - + " 2\n" - + " 4\n" - + " 4096\n" - + " AS3\n" - + " 1\n" - + " 1\n" - + " 0\n" - + " 15\n" - + " 1\n" - + " 0\n" - + " 4102\n" - + " rsl\n" - + " wrap\n" - + " $(AppConfig)/ActionScript 3.0/rsls/loader_animation.swf\n" - + ((flaVersion.ordinal() >= FLAVersion.CC.ordinal()) ? (" \n" - + " \n" - + " $(AppConfig)/ActionScript 3.0/libs\n" - + " merge\n" - + " \n" - + " \n" - + " $(FlexSDK)/frameworks/libs/flex.swc\n" - + " merge\n" - + " textLayout_2.0.0.232.swz\n" - + " \n" - + " \n" - + " $(FlexSDK)/frameworks/libs/core.swc\n" - + " merge\n" - + " textLayout_2.0.0.232.swz\n" - + " \n" - + " \n" - + " \n" - + " ") - : " \n" - + " \n" - + " $(AppConfig)/ActionScript 3.0/libs\n" - + " merge\n" - + " \n" - + " \n" - + " $(AppConfig)/ActionScript 3.0/libs/11.0/textLayout.swc\n" - + " rsl\n" - + " http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz\n" - + " http://fpdownload.adobe.com/pub/swz/crossdomain.xml\n" - + " textLayout_2.0.0.232.swz\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " $(AppConfig)/ActionScript 3.0/libs/11.0/textLayout.swc\n" - + " \n" - + " http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz\n" - + " http://fpdownload.adobe.com/pub/swz/crossdomain.xml\n" - + " textLayout_2.0.0.232.swz\n" - + " \n" - + " \n") - + " \n" - + " \n" - + " " + width + "\n" - + " " + height + "\n" - + " 0\n" - + " 4718592\n" - + " 0\n" - + " 80\n" - + " 1\n" - + " \n" - + " \n" - + " 1\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 100000\n" - + " 1\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " \n" - + " \n" - + " " + width + "\n" - + " " + height + "\n" - + " 0\n" - + " 1\n" - + " 1\n" - + " \n" - + " 1\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " \n" - + " 128\n" - + " \n" - + " \n" - + " 255\n" - + " \n" - + " \n" - + " \n" - + " " + width + "\n" - + " " + height + "\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " \n" - + " \n" - + " \n" - + " 24-bit with Alpha\n" - + " 255\n" - + " \n" - + " \n" - + ((flaVersion.ordinal() >= FLAVersion.CC.ordinal()) ? "" - : (" \n" - + " " + width + "\n" - + " " + height + "\n" - + " 1\n" - + " 0\n" - + " \n" - + " \n" - + " 00000000\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 0\n" - + " 1\n" - + " \n")) - + "\n" - + ""; + boolean greaterThanCC = flaVersion.ordinal() >= FLAVersion.CC.ordinal(); + StringBuilder publishSettings = new StringBuilder(); + publishSettings.append("\n"); + publishSettings.append("\n"); + publishSettings.append(" \n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(greaterThanCC ? " 0\n" : " 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(greaterThanCC ? " 1\n" : " 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" ").append(baseName).append(".swf\n"); + publishSettings.append(" ").append(baseName).append(".exe\n"); + publishSettings.append(" ").append(baseName).append(".app\n"); + publishSettings.append(" ").append(baseName).append(".html\n"); + publishSettings.append(" ").append(baseName).append(".gif\n"); + publishSettings.append(" ").append(baseName).append(".jpg\n"); + publishSettings.append(" ").append(baseName).append(".png\n"); + publishSettings.append(greaterThanCC ? " 1\n" : " 1\n"); + publishSettings.append(" ").append(baseName).append(".smil\n"); + publishSettings.append(" ").append(baseName).append(".swc\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 12,0,0,0;11,2,0,0;11,1,0,0;10,3,0,0;10,2,153,0;10,1,52,0;9,0,124,0;8,0,24,0;7,0,14,0;6,0,79,0;5,0,58,0;4,0,32,0;3,0,8,0;2,0,1,12;1,0,0,1;\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" ").append(baseName).append("_content.html\n"); + publishSettings.append(" ").append(baseName).append("_alternate.html\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" \n"); + publishSettings.append(" ").append(width).append("\n"); + publishSettings.append(" ").append(height).append("\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 4\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" \n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 80\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 7\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 7\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" ").append(flaSwfVersion).append("\n"); + publishSettings.append(" ").append(FLAVersion.swfVersionToPlayer(flaSwfVersion)).append("\n"); + publishSettings.append(" ").append(useAS3 ? "3" : "2").append("\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" .\n"); + publishSettings.append(" CONFIG::FLASH_AUTHORING="true";\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" \n"); + publishSettings.append(" ").append(swf.compression == SWFCompression.NONE ? "0" : "1").append("\n"); + publishSettings.append(" ").append(swf.compression == SWFCompression.LZMA ? "1" : "0").append("\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" ").append(useNetwork ? 1 : 0).append("\n"); + publishSettings.append(" ").append(xmlString(characterClasses.containsKey(0) ? characterClasses.get(0) : "")).append("\n"); + publishSettings.append(" 2\n"); + publishSettings.append(" 4\n"); + publishSettings.append(" 4096\n"); + publishSettings.append(" AS3\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 15\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 4102\n"); + publishSettings.append(" rsl\n"); + publishSettings.append(" wrap\n"); + publishSettings.append(" $(AppConfig)/ActionScript 3.0/rsls/loader_animation.swf\n"); + if (greaterThanCC) { + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(AppConfig)/ActionScript 3.0/libs\n"); + publishSettings.append(" merge\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(FlexSDK)/frameworks/libs/flex.swc\n"); + publishSettings.append(" merge\n"); + publishSettings.append(" textLayout_2.0.0.232.swz\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(FlexSDK)/frameworks/libs/core.swc\n"); + publishSettings.append(" merge\n"); + publishSettings.append(" textLayout_2.0.0.232.swz\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" "); + } else { + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(AppConfig)/ActionScript 3.0/libs\n"); + publishSettings.append(" merge\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(AppConfig)/ActionScript 3.0/libs/11.0/textLayout.swc\n"); + publishSettings.append(" rsl\n"); + publishSettings.append(" http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz\n"); + publishSettings.append(" http://fpdownload.adobe.com/pub/swz/crossdomain.xml\n"); + publishSettings.append(" textLayout_2.0.0.232.swz\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" $(AppConfig)/ActionScript 3.0/libs/11.0/textLayout.swc\n"); + publishSettings.append(" \n"); + publishSettings.append(" http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz\n"); + publishSettings.append(" http://fpdownload.adobe.com/pub/swz/crossdomain.xml\n"); + publishSettings.append(" textLayout_2.0.0.232.swz\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + } + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" ").append(width).append("\n"); + publishSettings.append(" ").append(height).append("\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 4718592\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 80\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 100000\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" ").append(width).append("\n"); + publishSettings.append(" ").append(height).append("\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" \n"); + publishSettings.append(" 128\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 255\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" ").append(width).append("\n"); + publishSettings.append(" ").append(height).append("\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 24-bit with Alpha\n"); + publishSettings.append(" 255\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + if (!greaterThanCC) { + publishSettings.append(" \n"); + publishSettings.append(" ").append(width).append("\n"); + publishSettings.append(" ").append(height).append("\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" \n"); + publishSettings.append(" \n"); + publishSettings.append(" 00000000\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 0\n"); + publishSettings.append(" 1\n"); + publishSettings.append(" \n"); + } + publishSettings.append("\n"); + publishSettings.append(""); + String publishSettingsStr = publishSettings.toString(); if (compressed) { - final String domDocumentF = domDocument; - final String publishSettingsF = publishSettings; + final String domDocumentF = domDocumentStr; + final String publishSettingsF = publishSettingsStr; final String outfileF = outfile; new RetryTask(new RunnableIOEx() { @Override @@ -3039,8 +3049,8 @@ public class XFLConverter { } } } - writeFile(handler, Utf8Helper.getBytes(domDocument), outDir.getAbsolutePath() + File.separator + "DOMDocument.xml"); - writeFile(handler, Utf8Helper.getBytes(publishSettings), outDir.getAbsolutePath() + File.separator + "PublishSettings.xml"); + writeFile(handler, Utf8Helper.getBytes(domDocumentStr), outDir.getAbsolutePath() + File.separator + "DOMDocument.xml"); + writeFile(handler, Utf8Helper.getBytes(publishSettingsStr), outDir.getAbsolutePath() + File.separator + "PublishSettings.xml"); File libraryDir = new File(outDir.getAbsolutePath() + File.separator + "LIBRARY"); libraryDir.mkdir(); File binDir = new File(outDir.getAbsolutePath() + File.separator + "bin"); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java index a86e3543e..0d81464c5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java @@ -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.graph; import java.util.Collections; @@ -34,19 +35,19 @@ public class GraphPartMulti extends GraphPart { @Override public String toString() { - String ret = ""; - ret += "[multi "; + StringBuilder ret = new StringBuilder(); + ret.append("[multi "); boolean first = true; for (GraphPart g : parts) { if (first) { first = false; } else { - ret += ", "; + ret.append(", "); } - ret += g.toString(); + ret.append(g.toString()); } - ret += "]"; - return ret; + ret.append("]"); + return ret.toString(); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java index 10c20e415..8b674fe3f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/Helper.java @@ -277,7 +277,7 @@ public class Helper { } public static String padZeros(long number, int length) { - String ret = "" + number; + String ret = Long.toString(number); while (ret.length() < length) { ret = "0" + ret; } @@ -330,59 +330,59 @@ public class Helper { } public static String joinStrings(List arr, String glue) { - String ret = ""; + StringBuilder ret = new StringBuilder(); boolean first = true; for (String s : arr) { if (!first) { - ret += glue; + ret.append(glue); } else { first = false; } - ret += s; + ret.append(s); } - return ret; + return ret.toString(); } public static String joinStrings(String[] arr, String glue) { - String ret = ""; + StringBuilder ret = new StringBuilder(); boolean first = true; for (String s : arr) { if (!first) { - ret += glue; + ret.append(glue); } else { first = false; } - ret += s; + ret.append(s); } - return ret; + return ret.toString(); } public static String joinStrings(List arr, String formatString, String glue) { - String ret = ""; + StringBuilder ret = new StringBuilder(); boolean first = true; for (String s : arr) { if (!first) { - ret += glue; + ret.append(glue); } else { first = false; } - ret += String.format(formatString, s); + ret.append(String.format(formatString, s)); } - return ret; + return ret.toString(); } public static String joinStrings(String[] arr, String formatString, String glue) { - String ret = ""; + StringBuilder ret = new StringBuilder(); boolean first = true; for (String s : arr) { if (!first) { - ret += glue; + ret.append(glue); } else { first = false; } - ret += String.format(formatString, s); + ret.append(String.format(formatString, s)); } - return ret; + return ret.toString(); } @SuppressWarnings("unchecked") @@ -866,7 +866,7 @@ public class Helper { * @return String */ public static String doubleStr(double d) { - String ret = "" + d; + String ret = Double.toString(d); if (ret.endsWith(".0")) { ret = ret.substring(0, ret.length() - 2); } diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index abb56512e..46677cee4 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -178,7 +178,7 @@ public class FontPanel extends javax.swing.JPanel { } } ft.setModified(true); - SWF.clearImageCache(); + ft.getSwf().clearImageCache(); } public void showFontTag(FontTag ft) { diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index b96cf1e9d..c5228bc06 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -575,7 +575,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec try { swf.deobfuscateIdentifiers(RenameType.TYPENUMBER); swf.assignClassesToSymbols(); - clearCache(); + swf.clearScriptCache(); if (abcPanel != null) { abcPanel.reload(); } @@ -1037,15 +1037,6 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return null; } - private void clearCache() { - if (abcPanel != null) { - abcPanel.decompiledTextArea.clearScriptCache(); - } - if (actionPanel != null) { - actionPanel.clearCache(); - } - } - public void gotoFrame(int frame) { TreeItem treeItem = (TreeItem) tagTree.getLastSelectedPathComponent(); if (treeItem == null) { @@ -1087,7 +1078,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } public void disableDecompilationChanged() { - clearCache(); + clearAllScriptCache(); + if (abcPanel != null) { abcPanel.reload(); } @@ -1095,6 +1087,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec updateClassesList(); } + private void clearAllScriptCache() { + for (SWFList swfList : swfs) { + for (SWF swf : swfList) { + swf.clearScriptCache(); + } + } + } + public void searchAs() { if (searchDialog == null) { searchDialog = new SearchDialog(getMainFrame().getWindow()); @@ -1204,7 +1204,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec public void autoDeobfuscateChanged() { Helper.decompilationErrorAdd = AppStrings.translate(Configuration.autoDeobfuscate.get() ? "deobfuscation.comment.failed" : "deobfuscation.comment.tryenable"); - clearCache(); + clearAllScriptCache(); if (abcPanel != null) { abcPanel.reload(); } @@ -1507,7 +1507,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } - SWF.clearImageCache(); + swf.clearImageCache(); reload(true); } } @@ -1672,7 +1672,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec Main.stopWork(); View.showMessageDialog(null, translate("message.rename.renamed").replace("%count%", Integer.toString(cnt))); swf.assignClassesToSymbols(); - clearCache(); + swf.clearScriptCache(); if (abcPanel != null) { abcPanel.reload(); } @@ -1743,7 +1743,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec @Override public void run() { - clearCache(); + clearAllScriptCache(); getABCPanel().reload(); updateClassesList(); } @@ -1792,7 +1792,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } public void refreshDecompiled() { - clearCache(); + clearAllScriptCache(); if (abcPanel != null) { abcPanel.reload(); } @@ -1881,7 +1881,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec refreshTree(); setTagTreeSelectedNode(newTag); } - SWF.clearImageCache(); + it.getSwf().clearImageCache(); } catch (IOException ex) { logger.log(Level.SEVERE, "Invalid image", ex); View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); @@ -1903,7 +1903,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec refreshTree(); setTagTreeSelectedNode(newTag); } - SWF.clearImageCache(); + st.getSwf().clearImageCache(); } catch (IOException ex) { logger.log(Level.SEVERE, "Invalid image", ex); View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 364bab7de..6db92b079 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -966,9 +966,10 @@ public class PreviewPanel extends JSplitPane implements ActionListener { break; case ACTION_SAVE_GENERIC_TAG: { genericTagPanel.save(); - SWF.clearImageCache(); Tag tag = genericTagPanel.getTag(); - tag.getSwf().updateCharacters(); + SWF swf = tag.getSwf(); + swf.clearImageCache(); + swf.updateCharacters(); tag.getTimelined().getTimeline().reset(); mainPanel.refreshTree(); mainPanel.setTagTreeSelectedNode(tag); diff --git a/src/com/jpexs/decompiler/flash/gui/TextPanel.java b/src/com/jpexs/decompiler/flash/gui/TextPanel.java index e1a6e274f..197ece5a5 100644 --- a/src/com/jpexs/decompiler/flash/gui/TextPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/TextPanel.java @@ -131,7 +131,7 @@ public class TextPanel extends JPanel implements ActionListener { setEditText(false); mainPanel.reload(true); } - SWF.clearImageCache(); + item.getSwf().clearImageCache(); } break; } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 675af4320..902dbefa0 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -167,7 +167,8 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se pos++; String workText = AppStrings.translate("work.searching"); String decAdd = ""; - if (!decompiledTextArea.isCached(item.getValue())) { + final ScriptPack pack = item.getValue(); + if (!SWF.isCached(pack)) { decAdd = ", " + AppStrings.translate("work.decompiling"); } @@ -176,10 +177,9 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se @Override public Void doInBackground() throws Exception { - decompiledTextArea.cacheScriptPack(item.getValue(), swf.abcList); - if (pat.matcher(decompiledTextArea.getCachedText(item.getValue())).find()) { + if (pat.matcher(SWF.getCached(pack).text).find()) { ABCPanelSearchResult searchResult = new ABCPanelSearchResult(); - searchResult.scriptPack = item.getValue(); + searchResult.scriptPack = pack; searchResult.classPath = item.getKey(); found.add(searchResult); } @@ -644,7 +644,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se public void reload() { lastDecompiled = ""; - decompiledTextArea.clearScriptCache(); + swf.clearScriptCache(); decompiledTextArea.reloadClass(); detailPanel.methodTraitPanel.methodCodePanel.clear(); } @@ -781,7 +781,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se case ACTION_SAVE_DECOMPILED: ScriptPack pack = decompiledTextArea.getScriptLeaf(); int oldIndex = pack.scriptIndex; - decompiledTextArea.uncache(pack); + SWF.uncache(pack); try { String oldSp = null; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 804ebf904..8001a22e9 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -16,7 +16,9 @@ */ package com.jpexs.decompiler.flash.gui.abc; +import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.CachedDecompilation; import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -32,17 +34,12 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.View; -import com.jpexs.decompiler.flash.helpers.HighlightedText; -import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightData; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.helpers.Cache; import java.awt.Point; import java.util.ArrayList; import java.util.List; @@ -72,7 +69,6 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private final ABCPanel abcPanel; private int classIndex = -1; private boolean isStatic = false; - private final Cache cache = Cache.getInstance(true); private final List scriptListeners = new ArrayList<>(); @@ -583,25 +579,6 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } } - public void uncache(ScriptPack pack) { - cache.remove(pack); - } - - public boolean isCached(ScriptPack pack) { - return cache.contains(pack); - } - - private CachedDecompilation getCached(ScriptPack pack) throws InterruptedException { - if (!cache.contains(pack)) { - cacheScriptPack(pack, abcList); - } - return (CachedDecompilation) cache.get(pack); - } - - public String getCachedText(ScriptPack pack) throws InterruptedException { - return getCached(pack).text; - } - public void gotoLastTrait() { gotoTrait(lastTraitIndex); } @@ -647,27 +624,6 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } private List abcList; - public void clearScriptCache() { - cache.clear(); - } - - public void cacheScriptPack(ScriptPack scriptLeaf, List abcList) throws InterruptedException { - int maxCacheSize = 50; - int scriptIndex = scriptLeaf.scriptIndex; - ScriptInfo script = null; - ABC abc = scriptLeaf.abc; - if (scriptIndex > -1) { - script = abc.script_info.get(scriptIndex); - } - if (!cache.contains(scriptLeaf)) { - boolean parallel = Configuration.parallelSpeedUp.get(); - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); - scriptLeaf.toSource(writer, abcList, script.traits.traits, ScriptExportMode.AS, parallel); - HighlightedText hilightedCode = new HighlightedText(writer); - cache.put(scriptLeaf, new CachedDecompilation(hilightedCode)); - } - } - public void setScript(ScriptPack scriptLeaf, List abcList) { abcPanel.scriptNameLabel.setText(scriptLeaf.getClassPath().toString()); int scriptIndex = scriptLeaf.scriptIndex; @@ -691,8 +647,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL this.script = scriptLeaf; CachedDecompilation cd = null; try { - cacheScriptPack(scriptLeaf, abcList); - cd = getCached(scriptLeaf); + cd = SWF.getCached(scriptLeaf); } catch (InterruptedException ex) { } if (cd != null) { @@ -710,7 +665,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL public void reloadClass() { int ci = classIndex; - uncache(script); + SWF.uncache(script); if ((script != null) && (abc != null)) { setScript(script, abcList); } @@ -724,7 +679,6 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL public void setABC(ABC abc) { this.abc = abc; - cache.clear(); setText(""); } diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 887997d4f..c64c14ed6 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionGraph; import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.CachedScript; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer; @@ -48,7 +49,6 @@ import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.helpers.Cache; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import java.awt.BorderLayout; @@ -129,7 +129,6 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene private String lastDecompiled = ""; private ASMSource lastASM; public SearchPanel searchPanel; - private Cache cache = Cache.getInstance(true); private CancellableWorker setSourceWorker; public void clearSource() { @@ -143,10 +142,6 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene srcHexOnly = null; } - public void clearCache() { - cache.clear(); - } - public String getStringUnderCursor() { int pos = decompiledEditor.getCaretPosition(); @@ -213,27 +208,6 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene return null; } - private CachedScript getCached(ASMSource pack) { - return (CachedScript) cache.get(pack); - } - - private boolean isCached(ASMSource src) { - return cache.contains(src); - } - - private void cacheScript(ASMSource src, List actions) throws InterruptedException { - if (!cache.contains(src)) { - if (actions == null) { - actions = src.getActions(); - } - HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true); - Action.actionsToSource(src, actions, src.toString()/*FIXME?*/, writer); - List hilights = writer.instructionHilights; - String srcNoHex = writer.toString(); - cache.put(src, new CachedScript(srcNoHex, hilights)); - } - } - public boolean search(final String txt, boolean ignoreCase, boolean regexp) { if ((txt != null) && (!txt.isEmpty())) { searchPanel.setOptions(ignoreCase, regexp); @@ -251,18 +225,18 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene pos++; String workText = AppStrings.translate("work.searching"); String decAdd = ""; - if (!isCached(item.getValue())) { + ASMSource asm = item.getValue(); + if (!SWF.isCached(asm)) { decAdd = ", " + AppStrings.translate("work.decompiling"); } Main.startWork(workText + " \"" + txt + "\"" + decAdd + " - (" + pos + "/" + asms.size() + ") " + item.getKey() + "... "); try { - cacheScript(item.getValue(), null); + if (pat.matcher(SWF.getCached(asm, null).text).find()) { + found.add(new ActionSearchResult(asm, item.getKey())); + } } catch (InterruptedException ex) { break; } - if (pat.matcher(getCached(item.getValue()).text).find()) { - found.add(new ActionSearchResult(item.getValue(), item.getKey())); - } } Main.stopWork(); @@ -434,10 +408,9 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene if (Configuration.decompile.get()) { setDecompiledText("//" + AppStrings.translate("work.decompiling") + "..."); if (!useCache) { - uncache(asm); + SWF.uncache(asm); } - cacheScript(asm, actions); - CachedScript sc = getCached(asm); + CachedScript sc = SWF.getCached(asm, actions); decompiledHilights = sc.hilights; lastDecompiled = sc.text; lastASM = asm; @@ -830,8 +803,4 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene } }); } - - private void uncache(ASMSource pack) { - cache.remove(pack); - } } diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 52397137e..437c8de78 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -288,10 +288,13 @@ public class TagTreeContextMenu extends JPopupMenu implements ActionListener { @Override public void actionPerformed(ActionEvent ae) { - tag.getSwf().tags.remove(tag); + SWF sourceSwf = tag.getSwf(); + sourceSwf.tags.remove(tag); tag.setSwf(targetSwf); targetSwf.tags.add(tag); tag.setModified(true); + sourceSwf.clearImageCache(); + targetSwf.clearImageCache(); mainPanel.refreshTree(); } });