non static caches (separated cache for all SWFs)

This commit is contained in:
honfika@gmail.com
2015-07-12 15:14:41 +02:00
parent 0af75c9990
commit 904d1f64f1
22 changed files with 145 additions and 83 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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