Merge origin/master

This commit is contained in:
Jindra Petřík
2016-03-26 20:17:37 +01:00
43 changed files with 429 additions and 358 deletions

View File

@@ -90,6 +90,7 @@ import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DebugIDTag;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.EnableDebugger2Tag;
@@ -439,6 +440,21 @@ public final class SWF implements SWFContainerItem, Timelined {
return characterIdTags.get(characterId);
}
public CharacterIdTag getCharacterIdTag(int characterId, int tagId) {
List<CharacterIdTag> characterIdTags = getCharacterIdTags(characterId);
if (characterIdTags != null) {
for (CharacterIdTag t : characterIdTags) {
if (((Tag) t).getId() == tagId) {
if (t.getCharacterId() == characterId) {
return t;
}
}
}
}
return null;
}
public Map<Integer, Set<Integer>> getDependentCharacters() {
if (dependentCharacters == null) {
synchronized (this) {
@@ -554,6 +570,19 @@ public final class SWF implements SWFContainerItem, Timelined {
return null;
}
public DefineSoundTag getSound(int soundId) {
CharacterTag characterTag = getCharacters().get(soundId);
if (characterTag instanceof DefineSoundTag) {
return (DefineSoundTag) characterTag;
}
if (characterTag != null) {
logger.log(Level.SEVERE, "CharacterTag should be a DefineSoundTag. characterId: {0}", soundId);
}
return null;
}
public TextTag getText(int textId) {
CharacterTag characterTag = getCharacters().get(textId);
if (characterTag instanceof TextTag) {
@@ -2497,6 +2526,12 @@ public final class SWF implements SWFContainerItem, Timelined {
}
}
public static void clearAllStaticCache() {
Cache.clearAll();
Helper.clearShapeCache();
System.gc();
}
public void clearAllCache() {
characters = null;
characterIdTags = null;
@@ -2505,9 +2540,7 @@ public final class SWF implements SWFContainerItem, Timelined {
clearReadOnlyListCache();
clearImageCache();
clearScriptCache();
Cache.clearAll();
Helper.clearShapeCache();
System.gc();
clearAllStaticCache();
}
public static void uncache(ASMSource src) {
@@ -2664,7 +2697,7 @@ public final class SWF implements SWFContainerItem, Timelined {
return ret;
}
public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, Point cursorPosition, int mouseButton, RECT displayRect, Matrix transformation, Matrix absoluteTransformation, ColorTransform colorTransform, Color backGroundColor, double zoom) {
public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, Point cursorPosition, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, double zoom) {
if (timeline.getFrameCount() == 0) {
return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB);
}
@@ -2687,7 +2720,7 @@ public final class SWF implements SWFContainerItem, Timelined {
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = cursorPosition;
renderContext.mouseButton = mouseButton;
timeline.toImage(frame, time, renderContext, image, false, m, transformation, absoluteTransformation, colorTransform);
timeline.toImage(frame, time, renderContext, image, false, m, transformation, m, colorTransform);
return image;
}

View File

@@ -16,9 +16,11 @@
*/
package com.jpexs.decompiler.flash.dumpview;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.TagStub;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -31,7 +33,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
public class DumpInfo {
public class DumpInfo implements TreeItem {
public String name;
@@ -145,4 +147,18 @@ public class DumpInfo {
return resolvedTag;
}
@Override
public SWF getSwf() {
Tag tag = getTag();
if (tag != null) {
return tag.getSwf();
}
return null;
}
@Override
public boolean isModified() {
return false;
}
}

View File

@@ -196,12 +196,12 @@ public class FrameExporter {
rect.yMax *= settings.zoom;
rect.xMin *= settings.zoom;
rect.yMin *= settings.zoom;
SVGExporter exporter = new SVGExporter(rect);
SVGExporter exporter = new SVGExporter(rect, settings.zoom);
if (fbackgroundColor != null) {
exporter.setBackGroundColor(fbackgroundColor);
}
tim.toSVG(frame, 0, null, 0, exporter, null, 0, settings.zoom);
tim.toSVG(frame, 0, null, 0, exporter, null, 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
ret.add(f);
@@ -360,7 +360,7 @@ public class FrameExporter {
}
int fframe = fframes.get(pos++);
BufferedImage result = SWF.frameToImageGet(ftim, fframe, fframe, null, 0, ftim.displayRect, new Matrix(), new Matrix(), null, fbackgroundColor, settings.zoom).getBufferedImage();
BufferedImage result = SWF.frameToImageGet(ftim, fframe, fframe, null, 0, ftim.displayRect, new Matrix(), null, fbackgroundColor, settings.zoom).getBufferedImage();
if (evl != null) {
evl.handleExportedEvent("frame", pos, fframes.size(), tagName);

View File

@@ -96,8 +96,8 @@ public class MorphShapeExporter {
rect.yMax *= settings.zoom;
rect.xMin *= settings.zoom;
rect.yMin *= settings.zoom;
SVGExporter exporter = new SVGExporter(rect);
mst.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0, settings.zoom);
SVGExporter exporter = new SVGExporter(rect, settings.zoom);
mst.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
break;

View File

@@ -107,8 +107,8 @@ public class ShapeExporter {
rect.yMax *= settings.zoom;
rect.xMin *= settings.zoom;
rect.yMin *= settings.zoom;
SVGExporter exporter = new SVGExporter(rect);
st.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0, settings.zoom);
SVGExporter exporter = new SVGExporter(rect, settings.zoom);
st.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
break;
@@ -119,8 +119,7 @@ public class ShapeExporter {
int newHeight = (int) (rect.getHeight() * settings.zoom / SWF.unitDivisor) + 1;
SerializableImage img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB);
img.fillTransparent();
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
Matrix m = Matrix.getTranslateInstance(-rect.Xmin, -rect.Ymin);
m.scale(settings.zoom);
st.toImage(0, 0, 0, new RenderContext(), img, false, m, m, m, new CXFORMWITHALPHA());
if (settings.mode == ShapeExportMode.PNG) {

View File

@@ -82,8 +82,8 @@ public class TextExporter {
new RetryTask(() -> {
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) {
ExportRectangle rect = new ExportRectangle(textTag.getRect());
SVGExporter exporter = new SVGExporter(rect);
textTag.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0, settings.zoom);
SVGExporter exporter = new SVGExporter(rect, settings.zoom);
textTag.toSVG(exporter, -2, new CXFORMWITHALPHA(), 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
}, handler).run();

View File

@@ -189,8 +189,8 @@ public final class Matrix implements Cloneable {
}
public void translate(double x, double y) {
translateX += x;
translateY += y;
translateX = scaleX * x + rotateSkew1 * y + translateX;
translateY = rotateSkew0 * x + scaleY * y + translateY;
}
public void scale(double factor) {

View File

@@ -80,11 +80,9 @@ public class SVGExporter {
private final HashSet<String> fontFaces = new HashSet<>();
private String clip;
public boolean useTextTag = Configuration.textExportExportFontFace.get();
public SVGExporter(ExportRectangle bounds) {
public SVGExporter(ExportRectangle bounds, double zoom) {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
try {
@@ -98,7 +96,7 @@ public class SVGExporter {
if (bounds != null) {
svgRoot.setAttribute("width", (bounds.getWidth() / SWF.unitDivisor) + "px");
svgRoot.setAttribute("height", (bounds.getHeight() / SWF.unitDivisor) + "px");
createDefGroup(bounds, null);
createDefGroup(bounds, null, zoom);
}
} catch (ParserConfigurationException ex) {
Logger.getLogger(SVGExporter.class.getName()).log(Level.SEVERE, null, ex);
@@ -125,10 +123,15 @@ public class SVGExporter {
}
public final void createDefGroup(ExportRectangle bounds, String id) {
createDefGroup(bounds, id, 1);
}
public final void createDefGroup(ExportRectangle bounds, String id, double zoom) {
Element g = _svg.createElement("g");
if (bounds != null) {
g.setAttribute("transform", "matrix(1, 0, 0, 1, "
+ roundPixels20(-bounds.xMin / (double) SWF.unitDivisor) + ", " + roundPixels20(-bounds.yMin / (double) SWF.unitDivisor) + ")");
Matrix mat = Matrix.getTranslateInstance(-bounds.xMin, -bounds.yMin);
mat.scale(zoom);
g.setAttribute("transform", mat.getSvgTransformationString(SWF.unitDivisor, 1));
}
if (id != null) {
g.setAttribute("id", id);
@@ -150,7 +153,10 @@ public class SVGExporter {
public final Element createSubGroup(Matrix transform, String id) {
Element group = createSubGroup(id, "g");
group.setAttribute("transform", transform.getSvgTransformationString(SWF.unitDivisor, 1));
if (transform != null) {
group.setAttribute("transform", transform.getSvgTransformationString(SWF.unitDivisor, 1));
}
return group;
}
@@ -218,9 +224,6 @@ public class SVGExporter {
image.setAttribute("id", instanceName);
}
image.setAttribute("xlink:href", "#" + href);
if (clip != null) {
image.setAttribute("clip-path", "url(#" + clip + ")");
}
_svgGs.peek().appendChild(image);
return image;
}
@@ -257,14 +260,6 @@ public class SVGExporter {
return prefix + lastId;
}
public void setClip(String clip) {
this.clip = clip;
}
public String getClip() {
return clip;
}
protected static double roundPixels20(double pixels) {
return Math.round(pixels * 100) / 100.0;
}

View File

@@ -429,12 +429,15 @@ public class CanvasShapeExporter extends ShapeExporterBase {
preLineFillData.append("\tctx.fillStyle=").append(lineLastRadColor).append(";\r\n\tctx.fill(\"evenodd\");\r\n");
}
preLineFillData.append("\tctx.transform(").append(Helper.doubleStr(lineFillMatrix.scaleX / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew0 / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew1 / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.scaleY / unitDivisor))
.append(",").append(Helper.doubleStr((lineFillMatrix.translateX + deltaX) / unitDivisor))
.append(",").append(Helper.doubleStr((lineFillMatrix.translateY + deltaY) / unitDivisor)).append(");\r\n");
if (lineFillMatrix != null) {
preLineFillData.append("\tctx.transform(").append(Helper.doubleStr(lineFillMatrix.scaleX / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew0 / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.rotateSkew1 / unitDivisor))
.append(",").append(Helper.doubleStr(lineFillMatrix.scaleY / unitDivisor))
.append(",").append(Helper.doubleStr((lineFillMatrix.translateX + deltaX) / unitDivisor))
.append(",").append(Helper.doubleStr((lineFillMatrix.translateY + deltaY) / unitDivisor)).append(");\r\n");
}
lineFillData.insert(0, preLineFillData);
lineFillData.append("\tctx.fillRect(").append(-16384 - 32768 * lineRepeatCnt).append(",").append(-16384 - 32768 * lineRepeatCnt).append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt).append(",").append(2 * 16384 + 32768 * 2 * lineRepeatCnt).append(");\r\n");

View File

@@ -117,7 +117,6 @@ public class ImageImporter extends TagImporter {
int alpha = (imgData[y * width + x] >> 24) & 0xff;
data[y * width + x] = (byte) alpha;
}
}
newData = data;

View File

@@ -128,7 +128,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(ba));
} else {
bitmapAlphaData = ByteArrayRange.EMPTY;
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(new byte[0]));
}
imageData = new ByteArrayRange(data);

View File

@@ -133,7 +133,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(ba));
} else {
bitmapAlphaData = ByteArrayRange.EMPTY;
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(new byte[0]));
}
imageData = new ByteArrayRange(data);

View File

@@ -43,22 +43,22 @@ public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
public int buttonId;
@SWFType(BasicType.UI16)
public int buttonSoundChar0;
public int buttonSoundChar0; // OverUpToIdle
public SOUNDINFO buttonSoundInfo0;
@SWFType(BasicType.UI16)
public int buttonSoundChar1;
public int buttonSoundChar1; // IdleToOverUp
public SOUNDINFO buttonSoundInfo1;
@SWFType(BasicType.UI16)
public int buttonSoundChar2;
public int buttonSoundChar2; // OverUpToOverDown
public SOUNDINFO buttonSoundInfo2;
@SWFType(BasicType.UI16)
public int buttonSoundChar3;
public int buttonSoundChar3; // OverDownToOverUp
public SOUNDINFO buttonSoundInfo3;

View File

@@ -233,13 +233,8 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
@Override
protected void initTimeline(Timeline timeline) {
ColorTransform clrTrans = null;
for (Tag t : swf.getTags()) {
if (t instanceof DefineButtonCxformTag) {
DefineButtonCxformTag cx = (DefineButtonCxformTag) t;
clrTrans = cx.buttonColorTransform;
}
}
DefineButtonCxformTag cxformTag = (DefineButtonCxformTag) swf.getCharacterIdTag(buttonId, DefineButtonCxformTag.ID);
ColorTransform clrTrans = cxformTag == null ? null : cxformTag.buttonColorTransform;
int maxDepth = 0;
Frame frameUp = new Frame(timeline, 0);
Frame frameDown = new Frame(timeline, 0);

View File

@@ -934,8 +934,8 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) {
render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) {
render(TextRenderMode.SVG, null, exporter, null, new Matrix(), colorTransform, 1);
}
@Override

View File

@@ -187,11 +187,13 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
}
}
if (r != null) {
foundSomething = true;
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
if (r.Xmin < r.Xmax && r.Ymin < r.Ymax) {
foundSomething = true;
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
ret.Ymax = Math.max(r.Ymax, ret.Ymax);
}
}
}
if (!foundSomething) {
@@ -256,8 +258,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
r.Ymin = (int) Math.min(Math.min(Math.min(topleft.y, topright.y), bottomleft.y), bottomright.y);
r.Xmax = (int) Math.max(Math.max(Math.max(topleft.x, topright.x), bottomleft.x), bottomright.x);
r.Ymax = (int) Math.max(Math.max(Math.max(topleft.y, topright.y), bottomleft.y), bottomright.y);
}
ret.Xmin = Math.min(r.Xmin, ret.Xmin);
ret.Ymin = Math.min(r.Ymin, ret.Ymin);
ret.Xmax = Math.max(r.Xmax, ret.Xmax);
@@ -371,8 +373,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1);
}
@Override

View File

@@ -97,24 +97,12 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
getTimeline().toSVG(0, 0, null, 0, exporter, colorTransform, level + 1);
}
public DefineButtonSoundTag getSounds() {
List<CharacterIdTag> characterIdTags = swf.getCharacterIdTags(getCharacterId());
if (characterIdTags != null) {
for (CharacterIdTag t : characterIdTags) {
if (t instanceof DefineButtonSoundTag) {
DefineButtonSoundTag st = (DefineButtonSoundTag) t;
if (st.buttonId == getCharacterId()) {
return st;
}
}
}
}
return null;
return (DefineButtonSoundTag) swf.getCharacterIdTag(getCharacterId(), DefineButtonSoundTag.ID);
}
@Override

View File

@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.DefineScalingGridTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.helpers.ByteArrayRange;
import java.util.List;
/**
*
@@ -78,12 +77,6 @@ public abstract class CharacterTag extends Tag implements CharacterIdTag {
}
public DefineScalingGridTag getScalingGridTag() {
List<CharacterIdTag> mtags = swf.getCharacterIdTags(getCharacterId());
for (CharacterIdTag ct : mtags) {
if (ct instanceof DefineScalingGridTag) {
return (DefineScalingGridTag) ct;
}
}
return null;
return (DefineScalingGridTag) swf.getCharacterIdTag(getCharacterId(), DefineScalingGridTag.ID);
}
}

View File

@@ -41,7 +41,7 @@ public interface DrawableTag extends BoundedTag {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, ColorTransform colorTransform);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException;
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException;
public void toHtmlCanvas(StringBuilder result, double unitDivisor);

View File

@@ -331,7 +331,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) {
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) {
}
@Override

View File

@@ -290,8 +290,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShape(), exporter, null, colorTransform, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShape(), exporter, null, colorTransform, 1);
shapeExporter.export();
}

View File

@@ -289,15 +289,15 @@ public abstract class MorphShapeTag extends CharacterTag implements DrawableTag
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) {
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) {
if (ratio == -2) {
SHAPEWITHSTYLE beginShapes = getShapeAtRatio(0);
SHAPEWITHSTYLE endShapes = getShapeAtRatio(65535);
SVGMorphShapeExporter shapeExporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, exporter, null, colorTransform, zoom);
SVGMorphShapeExporter shapeExporter = new SVGMorphShapeExporter(swf, beginShapes, endShapes, exporter, null, colorTransform, 1);
shapeExporter.export();
} else {
SHAPEWITHSTYLE shapes = getShapeAtRatio(ratio);
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, shapes, exporter, null, colorTransform, zoom);
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, shapes, exporter, null, colorTransform, 1);
shapeExporter.export();
}
}

View File

@@ -179,8 +179,8 @@ public abstract class ShapeTag extends CharacterTag implements DrawableTag, Lazy
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShapes(), exporter, null, colorTransform, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException {
SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, getShapes(), exporter, null, colorTransform, 1);
shapeExporter.export();
}

View File

@@ -666,8 +666,8 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) {
staticTextToSVG(swf, textRecords, getTextNum(), exporter, getRect(), textMatrix, colorTransform, zoom);
public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) {
staticTextToSVG(swf, textRecords, getTextNum(), exporter, getRect(), textMatrix, colorTransform, 1);
}
@Override

View File

@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.helpers.FontHelper;
import com.jpexs.decompiler.flash.helpers.HighlightedText;
import com.jpexs.decompiler.flash.importers.TextImportResizeTextBoundsMode;
import com.jpexs.decompiler.flash.tags.text.JustifyAlignGlyphEntry;
@@ -451,6 +450,8 @@ public abstract class TextTag extends CharacterTag implements DrawableTag {
int x = 0;
int y = 0;
List<SHAPE> glyphs = null;
Matrix mat0 = transformation.clone();
mat0 = mat0.concatenate(new Matrix(textMatrix));
for (TEXTRECORD rec : textRecords) {
if (rec.styleFlagsHasColor) {
if (numText == 2) {
@@ -481,13 +482,13 @@ public abstract class TextTag extends CharacterTag implements DrawableTag {
double divider = font == null ? 1 : font.getDivider();
double rat = textHeight / 1024.0 / divider;
Matrix matScale = Matrix.getScaleInstance(rat);
Color textColor2 = new Color(textColor, true);
for (GLYPHENTRY entry : rec.glyphEntries) {
Matrix mat = transformation.clone();
mat = mat.concatenate(new Matrix(textMatrix));
Matrix matTr = Matrix.getTranslateInstance(x, y);
mat = mat.concatenate(matTr);
mat = mat.concatenate(Matrix.getScaleInstance(rat));
matScale.translateX = x;
matScale.translateY = y;
Matrix mat = mat0.concatenate(matScale);
SHAPE shape = null;
if (entry.glyphIndex != -1 && glyphs != null) {
// shapeNum: 1

View File

@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.exporters.FrameExporter;
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.Point;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.tags.DefineScalingGridTag;
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
@@ -66,7 +65,6 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -74,9 +72,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.w3c.dom.Element;
/**
*
@@ -557,47 +553,47 @@ public class Timeline {
}
/*public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, ColorTransform colorTransform) {
ExportRectangle scalingGrid = null;
if (timelined instanceof CharacterTag) {
DefineScalingGridTag sgt = ((CharacterTag) timelined).getScalingGridTag();
if (sgt != null) {
scalingGrid = new ExportRectangle(sgt.splitter);
}
}
ExportRectangle scalingGrid = null;
if (timelined instanceof CharacterTag) {
DefineScalingGridTag sgt = ((CharacterTag) timelined).getScalingGridTag();
if (sgt != null) {
scalingGrid = new ExportRectangle(sgt.splitter);
}
}
if (scalingGrid == null || transformation.rotateSkew0 != 0 || transformation.rotateSkew1 != 0) {
toImage(frame, time, renderContext, image, isClip, transformation, absoluteTransformation, colorTransform, null);
return;
}
if (scalingGrid == null || transformation.rotateSkew0 != 0 || transformation.rotateSkew1 != 0) {
toImage(frame, time, renderContext, image, isClip, transformation, absoluteTransformation, colorTransform, null);
return;
}
//9-slice scaling using DefineScalingGrid
Matrix diffTransform = prevTransformation.inverse().preConcatenate(transformation);
transformation = diffTransform;
//9-slice scaling using DefineScalingGrid
Matrix diffTransform = prevTransformation.inverse().preConcatenate(transformation);
transformation = diffTransform;
Matrix prevScale = new Matrix();
prevScale.scaleX = prevTransformation.scaleX;
prevScale.scaleY = prevTransformation.scaleY;
Matrix prevScale = new Matrix();
prevScale.scaleX = prevTransformation.scaleX;
prevScale.scaleY = prevTransformation.scaleY;
ExportRectangle boundsRect = new ExportRectangle(timelined.getRect());
ExportRectangle boundsRect = new ExportRectangle(timelined.getRect());
0 | 1 | 2
------------
3 | 4 | 5
------------
6 | 7 | 8
0 | 1 | 2
------------
3 | 4 | 5
------------
6 | 7 | 8
ExportRectangle targetRect[] = new ExportRectangle[9];
ExportRectangle sourceRect[] = new ExportRectangle[9];
Matrix transforms[] = new Matrix[9];
ExportRectangle targetRect[] = new ExportRectangle[9];
ExportRectangle sourceRect[] = new ExportRectangle[9];
Matrix transforms[] = new Matrix[9];
DefineScalingGridTag.getSlices(transformation, prevScale, boundsRect, scalingGrid, sourceRect, targetRect, transforms);
DefineScalingGridTag.getSlices(transformation, prevScale, boundsRect, scalingGrid, sourceRect, targetRect, transforms);
for (int i = 0; i < targetRect.length; i++) {
toImage(frame, time, renderContext, image, isClip, transforms[i], absoluteTransformation, colorTransform, targetRect[i]);
}
}*/
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, List<Shape> prevClips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans) {
for (int i = 0; i < targetRect.length; i++) {
toImage(frame, time, renderContext, image, isClip, transforms[i], absoluteTransformation, colorTransform, targetRect[i]);
}
}*/
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans) {
Matrix drawMatrix = new Matrix();
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
@@ -642,7 +638,7 @@ public class Timeline {
return;
}
m.translate(-rect.xMin, -rect.yMin);
m = m.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
//strokeTransform = strokeTransform.clone();
//strokeTransform.translate(-rect.xMin, -rect.yMin);
drawMatrix.translate(rect.xMin, rect.yMin);
@@ -764,9 +760,6 @@ public class Timeline {
gm.drawImage(img.getBufferedImage(), 0, 0, null);
Clip clip = new Clip(Helper.imageToShape(mask), clipDepth); // Maybe we can get current outline instead converting from image (?)
clips.add(clip);
prevClips.add(g.getClip());
g.setTransform(AffineTransform.getTranslateInstance(0, 0));
g.setClip(clip.shape);
} else {
if (renderContext.cursorPosition != null) {
if (drawable instanceof DefineSpriteTag) {
@@ -812,17 +805,44 @@ public class Timeline {
g.setTransform(transformation.toTransform());
List<Clip> clips = new ArrayList<>();
List<Shape> prevClips = new ArrayList<>();
int maxDepth = getMaxDepth();
int clipCount = 0;
for (int i = 1; i <= maxDepth; i++) {
boolean clipChanged = clipCount != clips.size();
for (int c = 0; c < clips.size(); c++) {
if (clips.get(c).depth == i) {
g.setClip(prevClips.get(c));
prevClips.remove(c);
if (clips.get(c).depth < i) {
clips.remove(c);
clipChanged = true;
}
}
if (clipChanged) {
if (clips.size() > 0) {
Area clip = null;
for (Clip clip1 : clips) {
Shape shape = clip1.shape;
if (clip == null) {
clip = new Area(shape);
} else {
clip.intersect(new Area(shape));
}
}
g.setTransform(new AffineTransform());
g.setClip(clip);
// draw clip border
//g.setPaint(Color.red);
//g.setStroke(new BasicStroke(2));
//g.draw(clip);
} else {
g.setClip(null);
}
clipCount = clips.size();
}
if (!frameObj.layers.containsKey(i)) {
continue;
}
@@ -873,25 +893,25 @@ public class Timeline {
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setClip(r);
drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, prevClips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
}
g.setClip(c);
/*
for (int s = 0; s < 9; s++) {
g.setTransform(new AffineTransform());
ExportRectangle p1 = transformation.transform(targetRect[s]);
g.setClip(c);
for (int s = 0; s < 9; s++) {
g.setTransform(new AffineTransform());
ExportRectangle p1 = transformation.transform(targetRect[s]);
g.setClip(c);
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setColor(Color.blue);
g.draw(r);
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setColor(Color.blue);
g.draw(r);
}*/
}*/
g.setTransform(origTransform);
} else {
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, prevClips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans);
}
} else if (character instanceof BoundedTag) {
showPlaceholder = true;
@@ -929,28 +949,44 @@ public class Timeline {
}
}
g.setTransform(AffineTransform.getScaleInstance(1, 1));
g.setTransform(new AffineTransform());
g.setClip(prevClip);
}
public void toSVG(int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level, double zoom) throws IOException {
public void toSVG(int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level) throws IOException {
if (getFrameCount() <= frame) {
return;
}
Frame frameObj = getFrame(frame);
List<SvgClip> clips = new ArrayList<>();
List<String> prevClips = new ArrayList<>();
int maxDepth = getMaxDepth();
int clipCount = 0;
Element clipGroup = null;
for (int i = 1; i <= maxDepth; i++) {
boolean clipChanged = clipCount != clips.size();
for (int c = 0; c < clips.size(); c++) {
if (clips.get(c).depth == i) {
exporter.setClip(prevClips.get(c));
prevClips.remove(c);
if (clips.get(c).depth < i) {
clips.remove(c);
clipChanged = true;
}
}
if (clipChanged) {
if (clipGroup != null) {
exporter.endGroup();
}
if (clips.size() > 0) {
String clip = clips.get(clips.size() - 1).shape; // todo: merge clip areas
clipGroup = exporter.createSubGroup(null, null);
clipGroup.setAttribute("clip-path", "url(#" + clip + ")");
}
clipCount = clips.size();
}
if (!frameObj.layers.containsKey(i)) {
continue;
}
@@ -981,7 +1017,7 @@ public class Timeline {
assetName = getTagIdPrefix(drawableTag, exporter);
exporter.exportedTags.put(drawableTag, assetName);
exporter.createDefGroup(new ExportRectangle(boundRect), assetName);
drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1, zoom);
drawable.toSVG(exporter, layer.ratio, clrTrans, level + 1);
exporter.endGroup();
}
ExportRectangle rect = new ExportRectangle(boundRect);
@@ -993,10 +1029,8 @@ public class Timeline {
exporter.createClipPath(new Matrix(), clipName);
SvgClip clip = new SvgClip(clipName, layer.clipDepth);
clips.add(clip);
prevClips.add(exporter.getClip());
Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix));
exporter.addUse(mat, boundRect, assetName, layer.instanceName);
exporter.setClip(clip.shape);
exporter.endGroup();
} else {
Matrix mat = Matrix.getTranslateInstance(rect.xMin, rect.yMin).preConcatenate(new Matrix(layer.matrix));
@@ -1005,6 +1039,9 @@ public class Timeline {
}
}
if (clipGroup != null) {
exporter.endGroup();
}
}
private static String getTagIdPrefix(Tag tag, SVGExporter exporter) {

View File

@@ -28,7 +28,7 @@ import java.awt.image.RescaleOp;
public class ColorTransform implements Cloneable {
public RescaleOp toRescaleOp() {
return new RescaleOp(new float[]{getRedMulti() / 255f, getGreenMulti() / 255f, getBlueMulti() / 255f, getAlphaMulti() / 255f},
return new RescaleOp(new float[]{getRedMulti() / 256f, getGreenMulti() / 256f, getBlueMulti() / 256f, getAlphaMulti() / 256f},
new float[]{getRedAdd(), getGreenAdd(), getBlueAdd(), getAlphaAdd()}, null);
}

View File

@@ -217,9 +217,8 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
double px = x * w2 + w2 / 2 - w / 2 - minXMin * ratio;
double py = y * h2 - minYMin * ratio;
Matrix transformation = new Matrix();
transformation.translate(px, py);
transformation = transformation.concatenate(Matrix.getScaleInstance(ratio));
Matrix transformation = Matrix.getTranslateInstance(px, py);
transformation.scale(ratio);
BitmapExporter.export(swf, shape, color, image, transformation, transformation, colorTransform);
// draw bounding boxes

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag;
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
import com.jpexs.decompiler.flash.tags.DefineButtonCxformTag;
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
import com.jpexs.decompiler.flash.tags.DefineButtonTag;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFontNameTag;
@@ -1063,13 +1064,9 @@ public class XFLConverter {
}
if (tag instanceof DefineButtonTag) {
DefineButtonTag bt = (DefineButtonTag) tag;
for (Tag t : tags) {
if (t instanceof DefineButtonCxformTag) {
DefineButtonCxformTag bcx = (DefineButtonCxformTag) t;
if (bcx.buttonId == bt.buttonId) {
colorTransform = bcx.buttonColorTransform;
}
}
DefineButtonCxformTag bcx = (DefineButtonCxformTag) bt.getSwf().getCharacterIdTag(bt.buttonId, DefineButtonCxformTag.ID);
if (bcx != null) {
colorTransform = bcx.buttonColorTransform;
}
}
@@ -1120,17 +1117,17 @@ public class XFLConverter {
if (colorTransform != null) {
writer.writeStartElement("color");
writer.writeStartElement("Color");
if (colorTransform.getRedMulti() != 255) {
writer.writeAttribute("redMultiplier", ((float) colorTransform.getRedMulti()) / 255.0f);
if (colorTransform.getRedMulti() != 256) {
writer.writeAttribute("redMultiplier", ((float) colorTransform.getRedMulti()) / 256.0f);
}
if (colorTransform.getGreenMulti() != 255) {
writer.writeAttribute("greenMultiplier", ((float) colorTransform.getGreenMulti()) / 255.0f);
if (colorTransform.getGreenMulti() != 256) {
writer.writeAttribute("greenMultiplier", ((float) colorTransform.getGreenMulti()) / 256.0f);
}
if (colorTransform.getBlueMulti() != 255) {
writer.writeAttribute("blueMultiplier", ((float) colorTransform.getBlueMulti()) / 255.0f);
if (colorTransform.getBlueMulti() != 256) {
writer.writeAttribute("blueMultiplier", ((float) colorTransform.getBlueMulti()) / 256.0f);
}
if (colorTransform.getAlphaMulti() != 255) {
writer.writeAttribute("alphaMultiplier", ((float) colorTransform.getAlphaMulti()) / 255.0f);
if (colorTransform.getAlphaMulti() != 256) {
writer.writeAttribute("alphaMultiplier", ((float) colorTransform.getAlphaMulti()) / 256.0f);
}
if (colorTransform.getRedAdd() != 0) {
@@ -1275,8 +1272,21 @@ public class XFLConverter {
symbolStr.writeAttribute("color", randomOutlineColor());
symbolStr.writeStartElement("frames");
int lastFrame = 0;
DefineButtonSoundTag sound = button.getSounds();
loopframes:
for (int frame = 1; frame <= 4; frame++) {
if (sound != null) {
switch (frame) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
}
}
for (BUTTONRECORD rec : records) {
if (rec.placeDepth == i) {
boolean ok = false;
@@ -1765,18 +1775,11 @@ public class XFLConverter {
}
}
private static void convertFrame(boolean shapeTween, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, int duration, String actionScript, String elements, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
private static void convertFrame(boolean shapeTween, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, int duration, String actionScript, String elements, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
DefineSoundTag sound = null;
if (startSound != null) {
for (Tag t : tags) {
if (t instanceof DefineSoundTag) {
DefineSoundTag s = (DefineSoundTag) t;
if (s.soundId == startSound.soundId) {
sound = s;
break;
}
}
}
SWF swf = startSound.getSwf();
sound = swf.getSound(startSound.soundId);
}
writer.writeStartElement("DOMFrame");
@@ -2046,7 +2049,7 @@ public class XFLConverter {
frame++;
String elements = elementsWriter.toString();
if (!elements.equals(lastElements) && frame > 0) {
convertFrame(lastShapeTween, characters, tags, null, null, frame - duration, duration, "", lastElements, files, writer2);
convertFrame(lastShapeTween, null, null, frame - duration, duration, "", lastElements, files, writer2);
duration = 1;
} else if (frame == 0) {
duration = 1;
@@ -2060,7 +2063,7 @@ public class XFLConverter {
}
if (!lastElements.isEmpty()) {
frame++;
convertFrame(lastShapeTween, characters, tags, null, null, (frame - duration < 0 ? 0 : frame - duration), duration, "", lastElements, files, writer2);
convertFrame(lastShapeTween, null, null, (frame - duration < 0 ? 0 : frame - duration), duration, "", lastElements, files, writer2);
}
afterStr = "</frames>" + afterStr;
@@ -2091,16 +2094,11 @@ public class XFLConverter {
for (Tag t : tags) {
if (t instanceof FontTag) {
SWF swf = t.getSwf();
FontTag font = (FontTag) t;
int fontId = font.getFontId();
String fontName = null;
for (Tag t2 : tags) {
if (t2 instanceof DefineFontNameTag) {
if (((DefineFontNameTag) t2).fontId == fontId) {
fontName = ((DefineFontNameTag) t2).fontName;
}
}
}
DefineFontNameTag fontNameTag = (DefineFontNameTag) swf.getCharacterIdTag(fontId, DefineFontNameTag.ID);
String fontName = fontNameTag == null ? null : fontNameTag.fontName;
if (fontName == null) {
fontName = font.getFontNameIntag();
}
@@ -2300,65 +2298,74 @@ public class XFLConverter {
return hasLabel;
}
private void convertSoundLayer(int layerIndex, String backgroundColor, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
private void convertSoundLayer(int layerIndex, ReadOnlyTagList timeLineTags, HashMap<String, byte[]> files, XFLXmlWriter writer) throws XMLStreamException {
int soundLayerIndex = 0;
XFLXmlWriter writer2 = new XFLXmlWriter();
StartSoundTag lastStartSound = null;
SoundStreamHeadTypeTag lastSoundStreamHead = null;
StartSoundTag startSound = null;
SoundStreamHeadTypeTag soundStreamHead = null;
int duration = 1;
List<StartSoundTag> startSounds = new ArrayList<>();
List<Integer> startSoundFrameNumbers = new ArrayList<>();
List<SoundStreamHeadTypeTag> soundStreamHeads = new ArrayList<>();
List<Integer> soundStreamHeadFrameNumbers = new ArrayList<>();
int frame = 0;
for (Tag t : timeLineTags) {
if (t instanceof StartSoundTag) {
startSound = (StartSoundTag) t;
for (Tag ta : tags) {
if (ta instanceof DefineSoundTag) {
DefineSoundTag s = (DefineSoundTag) ta;
if (s.soundId == startSound.soundId) {
if (!files.containsKey("sound" + s.soundId + "." + s.getExportFormat().toString().toLowerCase())) { //Sound was not exported
startSound = null; // ignore
}
break;
}
}
StartSoundTag startSound = (StartSoundTag) t;
SWF swf = startSound.getSwf();
DefineSoundTag s = swf.getSound(startSound.soundId);
if (!files.containsKey("sound" + s.soundId + "." + s.getExportFormat().toString().toLowerCase())) { //Sound was not exported
startSound = null; // ignore
}
}
if (t instanceof SoundStreamHeadTypeTag) {
soundStreamHead = (SoundStreamHeadTypeTag) t;
if (startSound != null) {
startSounds.add(startSound);
startSoundFrameNumbers.add(frame);
}
} else if (t instanceof SoundStreamHeadTypeTag) {
SoundStreamHeadTypeTag soundStreamHead = (SoundStreamHeadTypeTag) t;
if (!files.containsKey("sound" + soundStreamHead.getCharacterId() + "." + soundStreamHead.getExportFormat().toString().toLowerCase())) { //Sound was not exported
soundStreamHead = null; // ignore
}
}
if (t instanceof ShowFrameTag) {
if (soundStreamHead != null || startSound != null) {
if (lastSoundStreamHead != null || lastStartSound != null) {
convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files, writer2);
}
frame += duration;
duration = 1;
lastSoundStreamHead = soundStreamHead;
lastStartSound = startSound;
soundStreamHead = null;
startSound = null;
} else {
duration++;
if (soundStreamHead != null) {
soundStreamHeads.add(soundStreamHead);
soundStreamHeadFrameNumbers.add(frame);
}
} else if (t instanceof ShowFrameTag) {
frame++;
}
}
if (lastSoundStreamHead != null || lastStartSound != null) {
if (frame < 0) {
frame = 0;
duration = 1;
}
convertFrame(false, characters, tags, lastSoundStreamHead, lastStartSound, frame, duration, "", "", files, writer2);
}
if (writer2.length() > 0) {
writer.writeStartElement("DOMLayer", new String[]{"name", "Layer " + layerIndex, "color", randomOutlineColor()});
for (int i = 0; i < soundStreamHeads.size(); i++) {
writer.writeStartElement("DOMLayer", new String[]{"name", "Sound Layer " + (soundLayerIndex++), "color", randomOutlineColor()});
writer.writeStartElement("frames");
writer.writeCharactersRaw(writer2.toString());
int startFrame = soundStreamHeadFrameNumbers.get(i);
int duration = frame - startFrame;
if (startFrame != 0) {
// empty frames should be added
convertFrame(false, null, null, 0, startFrame, "", "", files, writer);
}
convertFrame(false, soundStreamHeads.get(i), null, startFrame, duration, "", "", files, writer);
writer.writeEndElement();
writer.writeEndElement();
}
for (int i = 0; i < startSounds.size(); i++) {
writer.writeStartElement("DOMLayer", new String[]{"name", "Sound Layer " + (soundLayerIndex++), "color", randomOutlineColor()});
writer.writeStartElement("frames");
int startFrame = startSoundFrameNumbers.get(i);
int duration = frame - startFrame;
if (startFrame != 0) {
// empty frames should be added
convertFrame(false, null, null, 0, startFrame, "", "", files, writer);
}
convertFrame(false, null, startSounds.get(i), startFrame, duration, "", "", files, writer);
writer.writeEndElement();
writer.writeEndElement();
}
@@ -2463,7 +2470,7 @@ public class XFLConverter {
int soundLayerIndex = layerCount;
layerCount++;
convertSoundLayer(soundLayerIndex, backgroundColor, characters, tags, timelineTags, files, writer);
convertSoundLayer(soundLayerIndex, timelineTags, files, writer);
writer.writeEndElement();
writer.writeEndElement();
}

View File

@@ -73,7 +73,7 @@ public class Helper {
public static String decompilationErrorAdd = null;
private static final Map<String, Area> shapeCache = new HashMap<>();
private static final Map<BitSet, Area> shapeCache = new HashMap<>();
private static final String[] hexStringCache;
@@ -1180,9 +1180,8 @@ public class Helper {
}
}
String key = byteArrayToBase64String(bs.toByteArray());
if (shapeCache.containsKey(key)) {
return shapeCache.get(key);
if (shapeCache.containsKey(bs)) {
return shapeCache.get(bs);
}
for (int x = 0; x < width; x++) {
@@ -1210,7 +1209,7 @@ public class Helper {
}
}
shapeCache.put(key, area);
shapeCache.put(bs, area);
return area;
}
@@ -1229,18 +1228,15 @@ public class Helper {
BitSet bs = new BitSet(width * height);
bs.set(type);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int idx = width * y + x;
if ((imgData[idx] >>> 24) > 0) {
bs.set(idx);
}
int pixelCount = width * height;
for (int i = 0; i < pixelCount; i++) {
if ((imgData[i] >>> 24) > 0) {
bs.set(i);
}
}
String key = byteArrayToBase64String(bs.toByteArray());
if (shapeCache.containsKey(key)) {
return shapeCache.get(key);
if (shapeCache.containsKey(bs)) {
return shapeCache.get(bs);
}
BitSet bsArea = new BitSet(width * height);
@@ -1321,7 +1317,7 @@ public class Helper {
}
}
shapeCache.put(key, area);
shapeCache.put(bs, area);
return area;
}