mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-22 01:38:31 +00:00
non static caches (separated cache for all SWFs)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
@@ -44,6 +45,10 @@ public class IdentifiersDeobfuscation {
|
||||
|
||||
private final HashMap<String, Integer> typeCounts = new HashMap<>();
|
||||
|
||||
private static final Cache<String, String> as2NameCache = Cache.getInstance(false, true, "as2_ident");
|
||||
|
||||
private static final Cache<String, String> as3NameCache = Cache.getInstance(false, true, "as3_ident");
|
||||
|
||||
public static final String VALID_FIRST_CHARACTERS = "\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}_$";
|
||||
|
||||
public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}";
|
||||
@@ -296,14 +301,12 @@ public class IdentifiersDeobfuscation {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String makeObfuscatedIdentifier(String s) {
|
||||
return "\u00A7" + escapeOIdentifier(s) + "\u00A7";
|
||||
public static GraphTextWriter appendObfuscatedIdentifier(String s, GraphTextWriter writer) {
|
||||
writer.append("\u00A7");
|
||||
escapeOIdentifier(s, writer);
|
||||
return writer.append("\u00A7");
|
||||
}
|
||||
|
||||
private static final Cache<String, String> as3NameCache = Cache.getInstance(false, true, "as3_ident");
|
||||
|
||||
private static final Cache<String, String> as2NameCache = Cache.getInstance(false, true, "as2_ident");
|
||||
|
||||
/**
|
||||
* Ensures identifier is valid and if not, uses paragraph syntax
|
||||
*
|
||||
@@ -323,17 +326,19 @@ public class IdentifiersDeobfuscation {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
Cache<String, String> nameCache = as3 ? as3NameCache : as2NameCache;
|
||||
|
||||
if (nameCache.contains(s)) {
|
||||
return nameCache.get(s);
|
||||
}
|
||||
|
||||
if (isValidName(as3, s, validExceptions)) {
|
||||
if (isValidName(as3, s)) {
|
||||
nameCache.put(s, s);
|
||||
return s;
|
||||
}
|
||||
String ret = makeObfuscatedIdentifier(s);
|
||||
|
||||
String ret = "\u00A7" + escapeOIdentifier(s) + "\u00A7";
|
||||
nameCache.put(s, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -343,28 +348,62 @@ public class IdentifiersDeobfuscation {
|
||||
if (nameCache.contains(pkg)) {
|
||||
return nameCache.get(pkg);
|
||||
}
|
||||
|
||||
if (pkg.isEmpty()) {
|
||||
nameCache.put(pkg, pkg);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
String[] parts;
|
||||
if (pkg.contains(".")) {
|
||||
parts = pkg.split("\\.");
|
||||
} else {
|
||||
parts = new String[]{pkg};
|
||||
}
|
||||
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
if (i > 0) {
|
||||
ret.append(".");
|
||||
}
|
||||
|
||||
ret.append(printIdentifier(as3, parts[i], validNameExceptions));
|
||||
}
|
||||
|
||||
String retStr = ret.toString();
|
||||
nameCache.put(pkg, retStr);
|
||||
return retStr;
|
||||
}
|
||||
|
||||
public static GraphTextWriter escapeOIdentifier(String s, GraphTextWriter writer) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '\n') {
|
||||
writer.append("\\n");
|
||||
} else if (c == '\r') {
|
||||
writer.append("\\r");
|
||||
} else if (c == '\t') {
|
||||
writer.append("\\t");
|
||||
} else if (c == '\b') {
|
||||
writer.append("\\b");
|
||||
} else if (c == '\t') {
|
||||
writer.append("\\t");
|
||||
} else if (c == '\f') {
|
||||
writer.append("\\f");
|
||||
} else if (c == '\\') {
|
||||
writer.append("\\\\");
|
||||
} else if (c == '\u00A7') {
|
||||
writer.append("\\\u00A7");
|
||||
} else if (c < 32) {
|
||||
writer.append("\\x").append(Helper.byteToHex((byte) c));
|
||||
} else {
|
||||
writer.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
public static String escapeOIdentifier(String s) {
|
||||
StringBuilder ret = new StringBuilder(s.length());
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
@@ -394,4 +433,9 @@ public class IdentifiersDeobfuscation {
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
as2NameCache.clear();
|
||||
as3NameCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.ShapeExportData;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
@@ -75,8 +76,6 @@ 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.DefineButton2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
@@ -120,6 +119,7 @@ import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
@@ -290,10 +290,16 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
private final IdentifiersDeobfuscation deobfuscation = new IdentifiersDeobfuscation();
|
||||
|
||||
@Internal
|
||||
private Cache<String, SerializableImage> frameCache = Cache.getInstance(false, false, "frame");
|
||||
private final Cache<String, SerializableImage> frameCache = Cache.getInstance(false, false, "frame");
|
||||
|
||||
@Internal
|
||||
private Cache<SoundTag, byte[]> soundCache = Cache.getInstance(false, false, "sound");
|
||||
private final Cache<CharacterTag, RECT> rectCache = Cache.getInstance(true, true, "rect");
|
||||
|
||||
@Internal
|
||||
private final Cache<SHAPE, ShapeExportData> shapeExportDataCache = Cache.getInstance(true, true, "shapeExportData");
|
||||
|
||||
@Internal
|
||||
private final Cache<SoundTag, byte[]> soundCache = Cache.getInstance(false, false, "sound");
|
||||
|
||||
@Internal
|
||||
private final Cache<ASMSource, CachedScript> as2Cache = Cache.getInstance(true, false, "as2");
|
||||
@@ -2127,6 +2133,10 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public IdentifiersDeobfuscation getDeobfuscation() {
|
||||
return deobfuscation;
|
||||
}
|
||||
|
||||
public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException, InterruptedException {
|
||||
XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel, version);
|
||||
clearAllCache();
|
||||
@@ -2169,9 +2179,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public void clearImageCache() {
|
||||
frameCache.clear();
|
||||
DefineSpriteTag.clearCache();
|
||||
DefineButtonTag.clearCache();
|
||||
DefineButton2Tag.clearCache();
|
||||
rectCache.clear();
|
||||
for (Tag tag : tags) {
|
||||
if (tag instanceof ImageTag) {
|
||||
((ImageTag) tag).clearCache();
|
||||
@@ -2182,6 +2190,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
public void clearScriptCache() {
|
||||
as2Cache.clear();
|
||||
as3Cache.clear();
|
||||
IdentifiersDeobfuscation.clearCache();
|
||||
}
|
||||
|
||||
public void clearAllCache() {
|
||||
@@ -2255,6 +2264,14 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return res;
|
||||
}
|
||||
|
||||
public Cache<CharacterTag, RECT> getRectCache() {
|
||||
return rectCache;
|
||||
}
|
||||
|
||||
public Cache<SHAPE, ShapeExportData> getShapeExportDataCache() {
|
||||
return shapeExportDataCache;
|
||||
}
|
||||
|
||||
public static RECT fixRect(RECT rect) {
|
||||
RECT ret = new RECT();
|
||||
ret.Xmin = rect.Xmin;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class DefineLocalActionItem extends ActionItem implements SetTypeActionIt
|
||||
writer.append("var ");
|
||||
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData)));
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
|
||||
} else {
|
||||
stripQuotes(name, localData, writer);
|
||||
}
|
||||
|
||||
@@ -96,14 +96,14 @@ public class FunctionActionItem extends ActionItem {
|
||||
writer.append(" ");
|
||||
String fname = calculatedFunctionName.toStringNoQuotes(localData);
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, fname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(fname));
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(fname, writer);
|
||||
} else {
|
||||
calculatedFunctionName.appendToNoQuotes(writer, localData);
|
||||
}
|
||||
} else if (!functionName.isEmpty()) {
|
||||
writer.append(" ");
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, functionName)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(functionName));
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(functionName, writer);
|
||||
} else {
|
||||
writer.append(functionName);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class FunctionActionItem extends ActionItem {
|
||||
pname = new RegisterNumber(regStart + p).translate();
|
||||
}
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, pname)) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(pname));
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(pname, writer);
|
||||
}
|
||||
writer.append(pname);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class GetVariableActionItem extends ActionItem {
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
|
||||
return writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData)));
|
||||
return IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
|
||||
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
|
||||
writer.append("eval(");
|
||||
name.appendTo(writer, localData);
|
||||
|
||||
@@ -74,7 +74,7 @@ public class SetVariableActionItem extends ActionItem implements SetTypeActionIt
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
|
||||
writer.append(IdentifiersDeobfuscation.makeObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData)));
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
|
||||
writer.append(" = ");
|
||||
return value.toString(writer, localData);
|
||||
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
|
||||
|
||||
@@ -179,7 +179,7 @@ public class FontExporter {
|
||||
for (int i = 0; i < shapes.size(); i++) {
|
||||
SHAPE s = shapes.get(i);
|
||||
final List<FPoint[]> contours = new ArrayList<>();
|
||||
PathExporter seb = new PathExporter(s, new ColorTransform()) {
|
||||
PathExporter seb = new PathExporter(swf, s, new ColorTransform()) {
|
||||
|
||||
private double transformX(double x) {
|
||||
return Math.ceil((double) (x / divider));
|
||||
|
||||
@@ -144,7 +144,7 @@ public class BitmapExporter extends ShapeExporterBase {
|
||||
}
|
||||
|
||||
private BitmapExporter(SWF swf, SHAPE shape, Color defaultColor, ColorTransform colorTransform) {
|
||||
super(shape, colorTransform);
|
||||
super(swf, shape, colorTransform);
|
||||
this.swf = swf;
|
||||
this.defaultColor = defaultColor;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class CanvasShapeExporter extends ShapeExporterBase {
|
||||
}
|
||||
|
||||
public CanvasShapeExporter(RGB basicFill, double unitDivisor, SWF swf, SHAPE shape, ColorTransform colorTransform, int deltaX, int deltaY) {
|
||||
super(shape, colorTransform);
|
||||
super(swf, shape, colorTransform);
|
||||
this.swf = swf;
|
||||
this.unitDivisor = unitDivisor;
|
||||
this.basicFill = basicFill;
|
||||
|
||||
@@ -39,8 +39,8 @@ public abstract class DefaultSVGShapeExporter extends ShapeExporterBase {
|
||||
|
||||
protected double zoom;
|
||||
|
||||
public DefaultSVGShapeExporter(SHAPE shape, ColorTransform colorTransform, double zoom) {
|
||||
super(shape, colorTransform);
|
||||
public DefaultSVGShapeExporter(SWF swf, SHAPE shape, ColorTransform colorTransform, double zoom) {
|
||||
super(swf, shape, colorTransform);
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.shape;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.GRADRECORD;
|
||||
@@ -35,14 +36,14 @@ public class PathExporter extends ShapeExporterBase {
|
||||
|
||||
private GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
|
||||
|
||||
public static List<GeneralPath> export(SHAPE shape) {
|
||||
PathExporter exporter = new PathExporter(shape, new ColorTransform());
|
||||
public static List<GeneralPath> export(SWF swf, SHAPE shape) {
|
||||
PathExporter exporter = new PathExporter(swf, shape, new ColorTransform());
|
||||
exporter.export();
|
||||
return exporter.paths;
|
||||
}
|
||||
|
||||
protected PathExporter(SHAPE shape, ColorTransform colorTransform) {
|
||||
super(shape, colorTransform);
|
||||
protected PathExporter(SWF swf, SHAPE shape, ColorTransform colorTransform) {
|
||||
super(swf, shape, colorTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,7 +51,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
|
||||
private final SVGExporter exporter;
|
||||
|
||||
public SVGShapeExporter(SWF swf, SHAPE shape, SVGExporter exporter, Color defaultColor, ColorTransform colorTransform, double zoom) {
|
||||
super(shape, colorTransform, zoom);
|
||||
super(swf, shape, colorTransform, zoom);
|
||||
this.swf = swf;
|
||||
this.defaultColor = defaultColor;
|
||||
this.exporter = exporter;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.shape;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.FillStyle;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.LineStyle;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
@@ -57,13 +58,12 @@ public abstract class ShapeExporterBase implements IShapeExporter {
|
||||
|
||||
private final ColorTransform colorTransform;
|
||||
|
||||
private static final Cache<SHAPE, ShapeExportData> exportDataCache = Cache.getInstance(true, true, "shapeExportDataCache");
|
||||
|
||||
public ShapeExporterBase(SHAPE shape, ColorTransform colorTransform) {
|
||||
public ShapeExporterBase(SWF swf, SHAPE shape, ColorTransform colorTransform) {
|
||||
this.shape = shape;
|
||||
this.colorTransform = colorTransform;
|
||||
|
||||
ShapeExportData cachedData = exportDataCache.get(shape);
|
||||
Cache<SHAPE, ShapeExportData> cache = swf.getShapeExportDataCache();
|
||||
ShapeExportData cachedData = cache.get(shape);
|
||||
if (cachedData == null) {
|
||||
List<FillStyle> fillStyles = new ArrayList<>();
|
||||
List<LineStyle> lineStyles = new ArrayList<>();
|
||||
@@ -95,7 +95,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
|
||||
cachedData.linePaths = linePaths;
|
||||
cachedData.fillStyles = fillStyles;
|
||||
cachedData.lineStyles = lineStyles;
|
||||
exportDataCache.put(shape, cachedData);
|
||||
cache.put(shape, cachedData);
|
||||
}
|
||||
|
||||
_fillStyles = cachedData.fillStyles;
|
||||
@@ -519,8 +519,4 @@ public abstract class ShapeExporterBase implements IShapeExporter {
|
||||
v1.add(v2.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
exportDataCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ public class HighlightedTextWriter extends GraphTextWriter {
|
||||
|
||||
@Override
|
||||
public HighlightedTextWriter append(String str) {
|
||||
return appendWithData(str, new HighlightData());
|
||||
return appendWithData(str, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,8 +84,6 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButton2Tag, RECT> rectCache = Cache.getInstance(true, true, "rect_button2");
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -213,9 +211,12 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
Cache<CharacterTag, RECT> cache = swf == null ? null : swf.getRectCache();
|
||||
RECT ret = cache == null ? null : cache.get(this);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
@@ -236,12 +237,12 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
}
|
||||
}
|
||||
}
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
if (cache != null) {
|
||||
cache.put(this, ret);
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,8 +84,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineButtonTag, RECT> rectCache = Cache.getInstance(true, true, "rect_button");
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -269,9 +267,12 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
Cache<CharacterTag, RECT> cache = swf == null ? null : swf.getRectCache();
|
||||
RECT ret = cache == null ? null : cache.get(this);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
RECT rect = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
for (BUTTONRECORD r : characters) {
|
||||
CharacterTag ch = swf.getCharacter(r.characterId);
|
||||
@@ -293,12 +294,11 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
}
|
||||
}
|
||||
|
||||
rectCache.put(this, rect);
|
||||
return rect;
|
||||
}
|
||||
if (cache != null) {
|
||||
cache.put(this, ret);
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
return rect;
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@@ -82,8 +82,6 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private static final Cache<DefineSpriteTag, RECT> rectCache = Cache.getInstance(true, true, "rect_sprite");
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -199,10 +197,13 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
|
||||
@Override
|
||||
public RECT getRect(Set<BoundedTag> added) {
|
||||
if (rectCache.contains(this)) {
|
||||
return rectCache.get(this);
|
||||
Cache<CharacterTag, RECT> cache = swf == null ? null : swf.getRectCache();
|
||||
RECT ret = cache == null ? null : cache.get(this);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
RECT ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
|
||||
ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
HashMap<Integer, Integer> depthMap = new HashMap<>();
|
||||
boolean foundSomething = false;
|
||||
for (Tag t : subTags) {
|
||||
@@ -253,10 +254,15 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
|
||||
foundSomething = true;
|
||||
}
|
||||
|
||||
if (!foundSomething) {
|
||||
ret = new RECT();
|
||||
}
|
||||
rectCache.put(this, ret);
|
||||
|
||||
if (cache != null) {
|
||||
cache.put(this, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -283,10 +289,6 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (Tag t : subTags) {
|
||||
|
||||
@@ -244,7 +244,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShape().getOutline());
|
||||
return transformation.toTransform().createTransformedShape(getShape().getOutline(swf));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -315,7 +315,7 @@ public abstract class MorphShapeTag extends CharacterTag implements DrawableTag
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline());
|
||||
return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline(swf));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -128,14 +128,14 @@ public abstract class ShapeTag extends CharacterTag implements DrawableTag, Lazy
|
||||
|
||||
@Override
|
||||
public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) {
|
||||
return transformation.toTransform().createTransformedShape(getShapes().getOutline());
|
||||
return transformation.toTransform().createTransformedShape(getShapes().getOutline(swf));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
|
||||
BitmapExporter.export(swf, getShapes(), null, image, transformation, colorTransform);
|
||||
if (Configuration.debugMode.get()) { // show control points
|
||||
List<GeneralPath> paths = PathExporter.export(getShapes());
|
||||
List<GeneralPath> paths = PathExporter.export(swf, getShapes());
|
||||
double[] coords = new double[6];
|
||||
AffineTransform at = transformation.toTransform();
|
||||
at.preConcatenate(AffineTransform.getScaleInstance(1 / SWF.unitDivisor, 1 / SWF.unitDivisor));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.PathExporter;
|
||||
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
@@ -74,12 +75,12 @@ public class SHAPE implements NeedsCharacters, Serializable {
|
||||
return SHAPERECORD.getBounds(shapeRecords);
|
||||
}
|
||||
|
||||
public Shape getOutline() {
|
||||
public Shape getOutline(SWF swf) {
|
||||
if (cachedOutline != null) {
|
||||
return cachedOutline;
|
||||
}
|
||||
|
||||
List<GeneralPath> paths = PathExporter.export(this);
|
||||
List<GeneralPath> paths = PathExporter.export(swf, this);
|
||||
Area area = new Area();
|
||||
for (GeneralPath path : paths) {
|
||||
area.add(new Area(path));
|
||||
|
||||
@@ -56,26 +56,26 @@ public class DottedChain {
|
||||
}
|
||||
|
||||
public String toPrintableString() {
|
||||
String ret = "";
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret += ".";
|
||||
ret.append(".");
|
||||
}
|
||||
ret += IdentifiersDeobfuscation.printIdentifier(true, parts.get(0));
|
||||
ret.append(IdentifiersDeobfuscation.printIdentifier(true, parts.get(0)));
|
||||
}
|
||||
return ret;
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String ret = "";
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
if (i > 0) {
|
||||
ret += ".";
|
||||
ret.append(".");
|
||||
}
|
||||
ret += parts.get(i);
|
||||
ret.append(parts.get(i));
|
||||
}
|
||||
return ret;
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user