diff --git a/trunk/src/com/jpexs/decompiler/flash/FrameInfo.java b/trunk/src/com/jpexs/decompiler/flash/FrameInfo.java
deleted file mode 100644
index f05817aab..000000000
--- a/trunk/src/com/jpexs/decompiler/flash/FrameInfo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010-2014 JPEXS
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package com.jpexs.decompiler.flash;
-
-import com.jpexs.decompiler.flash.tags.base.CharacterTag;
-import java.awt.Color;
-import java.util.Map;
-
-/**
- *
- * @author JPEXS
- */
-public class FrameInfo {
-
- public int maxDepth;
- public Map layers;
- public Color backgroundColor;
- public Map characters;
- public int frame;
-}
diff --git a/trunk/src/com/jpexs/decompiler/flash/Layer.java b/trunk/src/com/jpexs/decompiler/flash/Layer.java
deleted file mode 100644
index 399f972f0..000000000
--- a/trunk/src/com/jpexs/decompiler/flash/Layer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010-2014 JPEXS
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package com.jpexs.decompiler.flash;
-
-import com.jpexs.decompiler.flash.types.ColorTransform;
-import com.jpexs.decompiler.flash.types.MATRIX;
-import com.jpexs.decompiler.flash.types.RGBA;
-import com.jpexs.decompiler.flash.types.filters.FILTER;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- *
- * @author JPEXS
- */
-public class Layer implements Serializable {
-
- public MATRIX matrix;
- public String instanceName = null;
- public ColorTransform colorTransForm = null;
- public boolean cacheAsBitmap = false;
- public int blendMode = 0;
- public List filters = null;
- public boolean isVisible = true;
- public RGBA backGroundColor = null;
- public int characterId = -1;
- public int ratio = -1;
- public int time = 0;
- public boolean visible = true;
- public int clipDepth = -1;
-}
diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java
index b0c288fc6..1af376a19 100644
--- a/trunk/src/com/jpexs/decompiler/flash/SWF.java
+++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java
@@ -91,6 +91,9 @@ import com.jpexs.decompiler.flash.tags.base.RemoveTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
+import com.jpexs.decompiler.flash.timeline.DepthState;
+import com.jpexs.decompiler.flash.timeline.Frame;
+import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.treeitems.AS2PackageNodeItem;
import com.jpexs.decompiler.flash.treeitems.AS3PackageNodeItem;
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
@@ -160,13 +163,14 @@ import java.util.logging.Logger;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import javax.imageio.ImageIO;
+import com.jpexs.decompiler.flash.timeline.Timelined;
/**
* Class representing SWF file
*
* @author JPEXS
*/
-public final class SWF implements TreeItem {
+public final class SWF implements TreeItem,Timelined {
/**
* Default version of SWF file format
@@ -229,6 +233,16 @@ public final class SWF implements TreeItem {
public Map sourceFontsMap = new HashMap<>();
public static final double unitDivisor = 20;
+ private Timeline timeline;
+
+ @Override
+ public Timeline getTimeline(){
+ if(timeline == null){
+ timeline = new Timeline(this);
+ }
+ return timeline;
+ }
+
/**
* Gets all tags with specified id
*
@@ -2206,20 +2220,18 @@ public final class SWF implements TreeItem {
return ret;
}
- public static SerializableImage frameToImage(int containerId, int frame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform) {
- String key = "frame_" + frame + "_" + containerId + "_" + allTags.get(0).getSwf().hashCode();
+ public static SerializableImage frameToImageGet(Timeline timeline,int frame, RECT displayRect, Stack visited, Matrix transformation, ColorTransform colorTransform) {
+ String key = "frame_" + frame + "_" + timeline.id + "_" + timeline.swf.hashCode();
SerializableImage image = getFromCache(key);
if (image != null) {
return image;
}
- List frameInfos = getFrameInfo(frame, frame, allTags, controlTags, totalFrameCount);
- if (frameInfos.isEmpty()) {
+
+ if (timeline.frames.isEmpty()) {
return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB);
}
- FrameInfo fi = frameInfos.get(0);
-
RECT rect = displayRect;
image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
@@ -2230,143 +2242,16 @@ public final class SWF implements TreeItem {
g.fillRect(0, 0, image.getWidth(), image.getHeight());
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
- frameToImage(containerId, fi.maxDepth, fi.layers, fi.backgroundColor, fi.characters, fi.frame, allTags, controlTags, displayRect, visited, image, m, colorTransform);
+ frameToImage(timeline, frame, displayRect, visited, image, m, colorTransform);
putToCache(key, image);
return image;
}
- private static List getFrameInfo(int startFrame, int stopFrame, List allTags, List controlTags, int totalFrameCount) {
- List ret = new ArrayList<>();
- if (startFrame > stopFrame) {
- return ret;
- }
- if (totalFrameCount == 0) {
- return ret;
- }
+
- while (startFrame >= totalFrameCount) {
- startFrame -= totalFrameCount;
- }
-
- while (stopFrame >= totalFrameCount) {
- stopFrame -= totalFrameCount;
- }
-
- Map characters = new HashMap<>();
- for (Tag t : allTags) {
- if (t instanceof CharacterTag) {
- CharacterTag ch = (CharacterTag) t;
- characters.put(ch.getCharacterId(), ch);
- }
- }
-
- Map layers = new HashMap<>();
-
- int maxDepth = 0;
- int f = 0;
- Color backgroundColor = new Color(0, 0, 0, 0);
- for (Tag t : controlTags) {
- if (t instanceof SetBackgroundColorTag) {
- SetBackgroundColorTag c = (SetBackgroundColorTag) t;
- backgroundColor = new Color(c.backgroundColor.red, c.backgroundColor.green, c.backgroundColor.blue);
- }
-
- if (t instanceof PlaceObjectTypeTag) {
- PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
- int depth = po.getDepth();
- if (depth > maxDepth) {
- maxDepth = depth;
- }
-
- if (!layers.containsKey(depth)) {
- layers.put(depth, new Layer());
- }
- Layer layer = layers.get(depth);
- int characterId = po.getCharacterId();
- if (characterId != -1) {
- layer.characterId = characterId;
- }
- layer.visible = po.isVisible();
- if (po.flagMove()) {
- MATRIX matrix2 = po.getMatrix();
- if (matrix2 != null) {
- layer.matrix = matrix2;
- }
- String instanceName = po.getInstanceName();
- if (instanceName != null) {
- layer.instanceName = instanceName;
- }
- ColorTransform colorTransForm = po.getColorTransform();
- if (colorTransForm != null) {
- layer.colorTransForm = colorTransForm;
- }
- if (po.cacheAsBitmap()) {
- layer.cacheAsBitmap = true;
- }
- int blendMode = po.getBlendMode();
- if (blendMode != 0) {
- layer.blendMode = blendMode;
- }
- List filters = po.getFilters();
- if (filters != null) {
- layer.filters = filters;
- }
- int ratio = po.getRatio();
- if (ratio != -1) {
- layer.ratio = ratio;
- }
- int clipDepth = po.getClipDepth();
- if (clipDepth != -1) {
- layer.clipDepth = clipDepth;
- }
- } else {
- layer.matrix = po.getMatrix();
- layer.instanceName = po.getInstanceName();
- layer.colorTransForm = po.getColorTransform();
- layer.cacheAsBitmap = po.cacheAsBitmap();
- layer.blendMode = po.getBlendMode();
- layer.filters = po.getFilters();
- layer.ratio = po.getRatio();
- layer.clipDepth = po.getClipDepth();
- layer.time = 0;
- }
- }
-
- if (t instanceof RemoveTag) {
- RemoveTag rt = (RemoveTag) t;
- layers.remove(rt.getDepth());
-
- }
- if (t instanceof ShowFrameTag) {
- for (Layer l : layers.values()) {
- l.time++;
- }
- if ((f >= startFrame) && (f <= stopFrame)) {
- FrameInfo fi = new FrameInfo();
- fi.maxDepth = maxDepth;
- fi.layers = layers;
- fi.backgroundColor = backgroundColor;
- fi.characters = characters;
- fi.frame = f;
- ret.add(fi);
- if (f < stopFrame) {
- layers = Helper.deepCopy(layers);
- }
- }
- f++;
- if (f > stopFrame) {
- break;
- }
- }
- }
-
- return ret;
- }
-
- public static void framesToImage(int containerId, List ret, int startFrame, int stopFrame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform) {
- List frameInfos = getFrameInfo(startFrame, stopFrame, allTags, controlTags, totalFrameCount);
+ public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform) {
RECT rect = displayRect;
- for (FrameInfo fi : frameInfos) {
+ for (int f=0;f layers, Color backgroundColor, Map characters, int frame, List allTags, List controlTags, RECT displayRect, Stack visited, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
+ public static void frameToImage(Timeline timeline, int frame,RECT displayRect, Stack visited, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
float unzoom = (float) SWF.unitDivisor;
-
+ Frame frameObj = timeline.frames.get(frame);
Graphics2D g = (Graphics2D) image.getGraphics();
- g.setPaint(backgroundColor);
+ g.setPaint(frameObj.backgroundColor.toColor());
g.fill(new Rectangle(image.getWidth(), image.getHeight()));
g.setTransform(transformation.toTransform());
List clips = new ArrayList<>();
List prevClips = new ArrayList<>();
+
- for (int i = 1; i <= maxDepth; i++) {
-
+ for (int i = 1; i <= timeline.getMaxDepth(); i++) {
for (int c = 0; c < clips.size(); c++) {
if (clips.get(c).clipDepth == i) {
g.setClip(prevClips.get(c));
@@ -2412,17 +2297,17 @@ public final class SWF implements TreeItem {
clips.remove(c);
}
}
- if (!layers.containsKey(i)) {
+ if (!frameObj.layers.containsKey(i)) {
continue;
}
- Layer layer = layers.get(i);
- if (!characters.containsKey(layer.characterId)) {
+ DepthState layer = frameObj.layers.get(i);
+ if (!timeline.characters.containsKey(layer.characterId)) {
continue;
}
- if (!layer.visible) {
+ if (!layer.isVisible) {
continue;
}
- CharacterTag character = characters.get(layer.characterId);
+ CharacterTag character = timeline.characters.get(layer.characterId);
Matrix mat = new Matrix(layer.matrix);
mat = mat.preConcatenate(transformation);
@@ -2440,10 +2325,10 @@ public final class SWF implements TreeItem {
DrawableTag drawable = (DrawableTag) character;
SerializableImage img;
Matrix drawMatrix = new Matrix();
- int dframe = 1 + layer.time % drawable.getNumFrames();
+ int dframe = 0 + layer.time % drawable.getNumFrames();
if (drawable instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) drawable;
- RECT boundRect = bounded.getRect(characters, new Stack());
+ RECT boundRect = bounded.getRect(timeline.characters, new Stack());
ExportRectangle rect = new ExportRectangle(boundRect);
rect = mat.transform(rect);
Matrix m = mat.clone();
@@ -2486,11 +2371,11 @@ public final class SWF implements TreeItem {
gr.setComposite(AlphaComposite.Src);
gr.setColor(new Color(0, 0, 0, 0f));
gr.fillRect(0, 0, img.getWidth(), img.getHeight());
- drawable.toImage(dframe, layer.ratio, allTags, characters, visited, img, m, clrTrans);
+ drawable.toImage(dframe, layer.ratio, timeline.swf.tags, timeline.characters, visited, img, m, clrTrans);
} else if (drawable instanceof FontTag) {
// only DefineFont tags
- FontTag fontTag = (FontTag) drawable;
- img = fontTag.toImage(dframe, layer.ratio, allTags, characters, visited, transformation, clrTrans);
+ FontTag fontTag = (FontTag) drawable;
+ img = fontTag.toImage(dframe, layer.ratio, timeline.swf.tags, timeline.characters, visited, transformation, clrTrans);
} else {
throw new Error("Unsupported drawable.");
}
@@ -2508,7 +2393,7 @@ public final class SWF implements TreeItem {
drawMatrix.translateX /= unzoom;
drawMatrix.translateY /= unzoom;
AffineTransform trans = drawMatrix.toTransform();
-
+
switch (layer.blendMode) {
case 0:
case 1:
@@ -2590,7 +2475,7 @@ public final class SWF implements TreeItem {
BoundedTag b = (BoundedTag) character;
g.setPaint(new Color(255, 255, 255, 128));
g.setComposite(BlendComposite.Invert);
- RECT r = b.getRect(characters, visited);
+ RECT r = b.getRect(timeline.characters, visited);
int div = (int) unzoom;
g.drawString(character.toString(), r.Xmin / div + 3, r.Ymin / div + 15);
g.draw(new Rectangle(r.Xmin / div, r.Ymin / div, r.getWidth() / div, r.getHeight() / div));
@@ -2602,14 +2487,6 @@ public final class SWF implements TreeItem {
g.setTransform(AffineTransform.getScaleInstance(1, 1));
}
- public static void frameToImage(int containerId, int frame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited, SerializableImage image, Matrix transformation, ColorTransform colorTransform) {
- List frameInfos = getFrameInfo(frame, frame, allTags, controlTags, totalFrameCount);
- if (!frameInfos.isEmpty()) {
- FrameInfo fi = frameInfos.get(0);
- frameToImage(containerId, fi.maxDepth, fi.layers, fi.backgroundColor, fi.characters, fi.frame, allTags, controlTags, displayRect, visited, image, transformation, colorTransform);
- }
- }
-
public void removeTagFromTimeline(Tag toRemove, List timeline) {
int characterId = 0;
if (toRemove instanceof CharacterTag) {
diff --git a/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java
index d97cbcee5..1866f2362 100644
--- a/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java
+++ b/trunk/src/com/jpexs/decompiler/flash/configuration/Configuration.java
@@ -168,7 +168,7 @@ public class Configuration {
public static final ConfigurationItem locale = null;
@ConfigurationDefaultString("_loc%d_")
public static final ConfigurationItem registerNameFormat = null;
- @ConfigurationDefaultInt(10)
+ @ConfigurationDefaultInt(8)
public static final ConfigurationItem maxRecentFileCount = null;
public static final ConfigurationItem recentFiles = null;
public static final ConfigurationItem fontPairing = null;
@@ -338,7 +338,7 @@ public class Configuration {
recentFilesArray.remove(idx);
}
recentFilesArray.add(path);
- while (recentFilesArray.size() > maxRecentFileCount.get()) {
+ while (recentFilesArray.size() >= maxRecentFileCount.get()) {
recentFilesArray.remove(0);
}
recentFiles.set(Helper.joinStrings(recentFilesArray, "::"));
diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
index 893e49520..34bd20a74 100644
--- a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
+++ b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java
@@ -36,9 +36,11 @@ import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
+import java.util.Map;
import java.util.Stack;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
@@ -61,7 +63,7 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
private SWF swf;
private HashMap characters;
private boolean loaded;
-
+
@Override
public void setBackground(Color bg) {
if (label != null) {
@@ -162,7 +164,7 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
setImage(img);
}
return;
- }
+ }
play();
}
@@ -212,19 +214,16 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
}
}
- private void drawFrame() {
- if (drawable == null) {
- return;
- }
- Matrix mat = new Matrix();
- mat.translateX = swf.displayRect.Xmin;
- mat.translateY = swf.displayRect.Ymin;
+ private static SerializableImage getFrame(SWF swf,int frame,DrawableTag drawable,Map characters){
String key = "drawable_" + frame + "_" + drawable.hashCode();
SerializableImage img = SWF.getFromCache(key);
if (img == null) {
if (drawable instanceof BoundedTag) {
BoundedTag bounded = (BoundedTag) drawable;
RECT rect = bounded.getRect(characters, new Stack());
+ if(rect == null){ //??? Why?
+ rect = new RECT(0,0,1,1);
+ }
SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1,
(int) (rect.getHeight() / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
//Make all pixels transparent
@@ -243,7 +242,17 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis
}
SWF.putToCache(key, img);
}
- ImageIcon icon = new ImageIcon(img.getBufferedImage());
+ return img;
+ }
+
+ private void drawFrame() {
+ if (drawable == null) {
+ return;
+ }
+ Matrix mat = new Matrix();
+ mat.translateX = swf.displayRect.Xmin;
+ mat.translateY = swf.displayRect.Ymin;
+ ImageIcon icon = new ImageIcon(getFrame(swf,frame,drawable,characters).getBufferedImage());
label.setIcon(icon);
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java
index 9e094fbc9..80fe94e03 100644
--- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java
+++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java
@@ -94,6 +94,7 @@ import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
import com.jpexs.decompiler.flash.tags.text.ParseException;
+import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.treeitems.FrameNodeItem;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.treenodes.ContainerNode;
@@ -2466,13 +2467,15 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
int containerId = 0;
RECT rect = swf.displayRect;
int totalFrameCount = swf.frameCount;
+ Timeline timeline=swf.getTimeline();
if (fn.getParent() instanceof DefineSpriteTag) {
controlTags = ((DefineSpriteTag) fn.getParent()).subTags;
containerId = ((DefineSpriteTag) fn.getParent()).spriteId;
rect = ((DefineSpriteTag) fn.getParent()).getRect(swf.characters, new Stack());
totalFrameCount = ((DefineSpriteTag) fn.getParent()).frameCount;
+ timeline = ((DefineSpriteTag)fn.getParent()).getTimeline();
}
- previewImagePanel.setImage(SWF.frameToImage(containerId, fn.getFrame() - 1, swf.tags, controlTags, rect, totalFrameCount, new Stack(), Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform()));
+ previewImagePanel.setImage(SWF.frameToImageGet(timeline, fn.getFrame() - 1, rect, new Stack(), Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform()));
} else if (((tagObj instanceof FrameNodeItem) && ((FrameNodeItem) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag)) {
((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD);
createAndShowTempSwf(tagObj);
diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviewPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviewPanel.java
index 8e395dc44..31112d45f 100644
--- a/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviewPanel.java
+++ b/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviewPanel.java
@@ -71,7 +71,7 @@ public class SWFPreviewPanel extends JPanel implements FlashDisplay {
@Override
public void run() {
buffering.setVisible(true);
- SWF.framesToImage(0, frameImages, 0, swf.frameCount - 1, swf.tags, swf.tags, swf.displayRect, swf.frameCount, new Stack(), Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform());
+ SWF.framesToImage(swf.getTimeline(), frameImages, 0, swf.frameCount - 1, swf.displayRect, swf.frameCount, new Stack(), Matrix.getScaleInstance(1 / SWF.unitDivisor), new ColorTransform());
buffering.setVisible(false);
}
}.start();
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java
index 751e5c0d9..c95c9985b 100644
--- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java
@@ -16,7 +16,6 @@
*/
package com.jpexs.decompiler.flash.tags;
-import com.jpexs.decompiler.flash.Layer;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
@@ -29,6 +28,10 @@ import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
+import com.jpexs.decompiler.flash.timeline.DepthState;
+import com.jpexs.decompiler.flash.timeline.Frame;
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -60,7 +63,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
-public class DefineButton2Tag extends CharacterTag implements Container, BoundedTag, ButtonTag {
+public class DefineButton2Tag extends CharacterTag implements Container, BoundedTag, ButtonTag, Timelined {
/**
* ID for this character
@@ -86,6 +89,8 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
public List actions = new ArrayList<>();
public static final int ID = 34;
+ private Timeline timeline;
+
@Override
public int getCharacterId() {
return buttonId;
@@ -258,26 +263,10 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
return;
}
visited.push(buttonId);
- HashMap layers = new HashMap<>();
- int maxDepth = 0;
- for (BUTTONRECORD r : this.characters) {
- if (r.buttonStateUp) {
- Layer layer = new Layer();
- layer.colorTransForm = r.colorTransform;
- layer.blendMode = r.blendMode;
- layer.filters = r.filterList;
- layer.matrix = r.placeMatrix;
- layer.characterId = r.characterId;
- if (r.placeDepth > maxDepth) {
- maxDepth = r.placeDepth;
- }
- layers.put(r.placeDepth, layer);
- }
- }
visited.pop();
RECT displayRect = getRect(characters, visited);
visited.push(buttonId);
- SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, image, transformation, colorTransform);
+ SWF.frameToImage(getTimeline(), frame, displayRect, visited, image, transformation, colorTransform);
}
@Override
@@ -290,4 +279,31 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
public int getNumFrames() {
return 1;
}
+
+ @Override
+ public Timeline getTimeline() {
+ if (timeline != null) {
+ return timeline;
+ }
+ timeline = new Timeline(swf, new ArrayList(), buttonId);
+
+ int maxDepth = 0;
+ Frame fr = new Frame();
+ for (BUTTONRECORD r : this.characters) {
+ if (r.buttonStateUp) {
+ DepthState layer = new DepthState();
+ layer.colorTransForm = r.colorTransform;
+ layer.blendMode = r.blendMode;
+ layer.filters = r.filterList;
+ layer.matrix = r.placeMatrix;
+ layer.characterId = r.characterId;
+ if (r.placeDepth > maxDepth) {
+ maxDepth = r.placeDepth;
+ }
+ fr.layers.put(r.placeDepth, layer);
+ }
+ }
+ timeline.frames.add(fr);
+ return timeline;
+ }
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java
index 1fa905ed9..66d3b1317 100644
--- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java
@@ -1,23 +1,22 @@
/*
* Copyright (C) 2010-2014 JPEXS
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.DisassemblyListener;
-import com.jpexs.decompiler.flash.Layer;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
@@ -32,6 +31,10 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
+import com.jpexs.decompiler.flash.timeline.DepthState;
+import com.jpexs.decompiler.flash.timeline.Frame;
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
@@ -64,7 +67,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
-public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedTag, ButtonTag {
+public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedTag, ButtonTag, Timelined {
/**
* ID for this character
@@ -89,6 +92,8 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
private final long hdrSize;
+ private Timeline timeline;
+
@Override
public List getRecords() {
return characters;
@@ -279,26 +284,11 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
return;
}
visited.push(buttonId);
- HashMap layers = new HashMap<>();
- int maxDepth = 0;
- for (BUTTONRECORD r : this.characters) {
- if (r.buttonStateUp) {
- Layer layer = new Layer();
- layer.colorTransForm = r.colorTransform;
- layer.blendMode = r.blendMode;
- layer.filters = r.filterList;
- layer.matrix = r.placeMatrix;
- layer.characterId = r.characterId;
- if (r.placeDepth > maxDepth) {
- maxDepth = r.placeDepth;
- }
- layers.put(r.placeDepth, layer);
- }
- }
+
visited.pop();
RECT displayRect = getRect(characters, visited);
visited.push(buttonId);
- SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited, image, transformation, colorTransform);
+ SWF.frameToImage(getTimeline(), frame, displayRect, visited, image, transformation, colorTransform);
visited.pop();
}
@@ -332,4 +322,32 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
public String removePrefixAndSuffix(String source) {
return source;
}
+
+ @Override
+ public Timeline getTimeline() {
+ if (timeline != null) {
+ return timeline;
+ }
+ timeline = new Timeline(swf, new ArrayList(), buttonId);
+
+ int maxDepth = 0;
+ Frame fr = new Frame();
+ for (BUTTONRECORD r : this.characters) {
+ if (r.buttonStateUp) {
+ DepthState layer = new DepthState();
+ layer.colorTransForm = r.colorTransform;
+ layer.blendMode = r.blendMode;
+ layer.filters = r.filterList;
+ layer.matrix = r.placeMatrix;
+ layer.characterId = r.characterId;
+ if (r.placeDepth > maxDepth) {
+ maxDepth = r.placeDepth;
+ }
+ fr.layers.put(r.placeDepth, layer);
+ }
+ }
+ timeline.frames.add(fr);
+ return timeline;
+ }
+
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java
index 8197fb262..c32d59a97 100644
--- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java
+++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java
@@ -29,6 +29,8 @@ import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.MATRIX;
@@ -52,7 +54,7 @@ import java.util.Stack;
/**
* Defines a sprite character
*/
-public class DefineSpriteTag extends CharacterTag implements Container, BoundedTag, DrawableTag {
+public class DefineSpriteTag extends CharacterTag implements Container, BoundedTag, DrawableTag, Timelined {
/**
* Character ID of sprite
@@ -71,6 +73,16 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
public static final int ID = 39;
+ private Timeline timeline;
+
+ @Override
+ public Timeline getTimeline() {
+ if (timeline == null) {
+ timeline = new Timeline(swf, subTags, spriteId);
+ }
+ return timeline;
+ }
+
@Override
public int getCharacterId() {
return spriteId;
@@ -283,7 +295,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
}
RECT rect = getRect(characters, visited);
visited.push(spriteId);
- SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited, image, transformation, colorTransform);
+ SWF.frameToImage(getTimeline(), frame, rect, visited, image, transformation, colorTransform);
visited.pop();
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/DepthState.java b/trunk/src/com/jpexs/decompiler/flash/timeline/DepthState.java
index 101e8e04e..0a58adadb 100644
--- a/trunk/src/com/jpexs/decompiler/flash/timeline/DepthState.java
+++ b/trunk/src/com/jpexs/decompiler/flash/timeline/DepthState.java
@@ -42,6 +42,8 @@ public class DepthState {
public CLIPACTIONS clipActions = null;
public int ratio;
public boolean key = false;
+ public int clipDepth;
+ public int time = 0;
public DepthState() {
@@ -59,5 +61,7 @@ public class DepthState {
backGroundColor = obj.backGroundColor;
clipActions = obj.clipActions;
ratio = obj.ratio;
+ clipDepth = obj.clipDepth;
+ time = obj.time+1;
}
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java b/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java
index 23dcf5ed7..286a8b897 100644
--- a/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java
+++ b/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java
@@ -17,6 +17,8 @@
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.tags.DoActionTag;
+import com.jpexs.decompiler.flash.types.RGB;
+import com.jpexs.decompiler.flash.types.RGBA;
import java.util.HashMap;
import java.util.Map;
@@ -28,6 +30,7 @@ public class Frame {
public Map layers = new HashMap<>();
public DoActionTag action;
+ public RGB backgroundColor = new RGBA(0,0,0,0);
public Frame() {
diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java
index c8655e1fb..03821b4ce 100644
--- a/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java
+++ b/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java
@@ -18,8 +18,10 @@ package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.DoActionTag;
+import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.Tag;
+import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
import com.jpexs.decompiler.flash.types.CLIPACTIONS;
@@ -27,7 +29,9 @@ import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.filters.FILTER;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
*
@@ -36,6 +40,9 @@ import java.util.List;
public class Timeline {
public List frames = new ArrayList<>();
+ public int id;
+ public Map characters = new HashMap<>();
+ public SWF swf;
public Timeline() {
}
@@ -56,9 +63,24 @@ public class Timeline {
return frames.size();
}
- public Timeline(SWF swf) {
+ public Timeline(SWF swf){
+ this(swf,swf.tags,0);
+ }
+
+ public Timeline(SWF swf,List tags,int id) {
+ this.id =id;
+ this.swf = swf;
Frame frame = new Frame();
for (Tag t : swf.tags) {
+ if(t instanceof CharacterTag){
+ CharacterTag c=(CharacterTag)t;
+ characters.put(c.getCharacterId(), c);
+ }
+ }
+ for (Tag t : tags) {
+ if(t instanceof SetBackgroundColorTag){
+ frame.backgroundColor = ((SetBackgroundColorTag)t).backgroundColor;
+ }
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
int depth = po.getDepth();
@@ -103,6 +125,10 @@ public class Timeline {
if (ratio2 > -1) {
fl.ratio = ratio2;
}
+ int clipDepth2 = po.getClipDepth();
+ if(clipDepth2>-1){
+ fl.clipDepth = clipDepth2;
+ }
} else {
fl.matrix = po.getMatrix();
fl.instanceName = po.getInstanceName();
@@ -112,6 +138,7 @@ public class Timeline {
fl.filters = po.getFilters();
fl.ratio = po.getRatio();
fl.clipActions = po.getClipActions();
+ fl.clipDepth = po.getClipDepth();
}
fl.key = true;
}
diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/Timelined.java b/trunk/src/com/jpexs/decompiler/flash/timeline/Timelined.java
new file mode 100644
index 000000000..c37772d4d
--- /dev/null
+++ b/trunk/src/com/jpexs/decompiler/flash/timeline/Timelined.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 JPEXS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.jpexs.decompiler.flash.timeline;
+
+/**
+ *
+ * @author JPEXS
+ */
+public interface Timelined {
+ public Timeline getTimeline();
+}