From 7d4a8dc8cc5df35c24bb27be3ac38b02485955f2 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sun, 1 Feb 2015 13:02:45 +0100 Subject: [PATCH] outlines fixed --- .../src/com/jpexs/decompiler/flash/SWF.java | 58 ++++++--- .../flash/exporters/ShapeExporter.java | 3 +- .../exporters/shape/ShapeExporterBase.java | 64 +++++----- .../flash/tags/DefineButtonTag.java | 10 +- .../flash/tags/DefineEditTextTag.java | 4 +- .../flash/tags/DefineMorphShape2Tag.java | 6 +- .../flash/tags/DefineMorphShapeTag.java | 6 +- .../flash/tags/DefineSpriteTag.java | 10 +- .../decompiler/flash/tags/DefineText2Tag.java | 4 +- .../decompiler/flash/tags/DefineTextTag.java | 4 +- .../decompiler/flash/tags/base/ButtonTag.java | 9 +- .../flash/tags/base/DrawableTag.java | 16 +-- .../decompiler/flash/tags/base/FontTag.java | 5 +- .../decompiler/flash/tags/base/ImageTag.java | 5 +- .../flash/tags/base/RenderContext.java | 35 ++++++ .../decompiler/flash/tags/base/ShapeTag.java | 5 +- .../decompiler/flash/tags/base/TextTag.java | 3 +- .../decompiler/flash/timeline/Timeline.java | 115 +++++++++--------- .../com/jpexs/helpers/SerializableImage.java | 12 +- .../flash/gui/FolderPreviewPanel.java | 3 +- .../decompiler/flash/gui/ImagePanel.java | 21 ++-- 21 files changed, 236 insertions(+), 162 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/RenderContext.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 67873b9ef..19518d5cf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -102,6 +102,7 @@ import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.RemoveTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.timeline.Clip; @@ -2784,12 +2785,17 @@ public final class SWF implements SWFContainerItem, Timelined { Matrix m = transformation.clone(); m.translate(-rect.Xmin, -rect.Ymin); m.scale(zoom); - frameToImage(timeline, frame, time, stateUnderCursor, mouseButton, image, m, colorTransform); - putToCache(key, image); + RenderContext renderContext = new RenderContext(); + renderContext.stateUnderCursor = stateUnderCursor; + renderContext.mouseButton = mouseButton; + frameToImage(timeline, frame, time, renderContext, image, m, colorTransform); + if (useCache) { + putToCache(key, image); + } return image; } - public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, DepthState stateUnderCursor, int mouseButton, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform, double zoom) { + public static void framesToImage(Timeline timeline, List ret, int startFrame, int stopFrame, RenderContext renderContext, RECT displayRect, int totalFrameCount, Stack visited, Matrix transformation, ColorTransform colorTransform, double zoom) { RECT rect = displayRect; for (int f = 0; f < timeline.getFrames().size(); f++) { SerializableImage image = new SerializableImage((int) (rect.getWidth() / SWF.unitDivisor) + 1, @@ -2797,12 +2803,12 @@ public final class SWF implements SWFContainerItem, Timelined { image.fillTransparent(); Matrix m = new Matrix(); m.translate(-rect.Xmin, -rect.Ymin); - frameToImage(timeline, f, 0, stateUnderCursor, mouseButton, image, m, colorTransform); + frameToImage(timeline, f, 0, renderContext, image, m, colorTransform); ret.add(image); } } - public static void frameToImage(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public static void frameToImage(Timeline timeline, int frame, int time, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { double unzoom = SWF.unitDivisor; if (timeline.getFrames().size() <= frame) { return; @@ -2850,7 +2856,6 @@ public final class SWF implements SWFContainerItem, Timelined { boolean showPlaceholder = false; if (character instanceof DrawableTag) { DrawableTag drawable = (DrawableTag) character; - SerializableImage img; Matrix drawMatrix = new Matrix(); int drawableFrameCount = drawable.getNumFrames(); if (drawableFrameCount == 0) { @@ -2858,10 +2863,9 @@ public final class SWF implements SWFContainerItem, Timelined { } int dframe = (time + layer.time) % drawableFrameCount; if (character instanceof ButtonTag) { - ButtonTag bt = (ButtonTag) character; dframe = ButtonTag.FRAME_UP; - if (stateUnderCursor == layer) { - if (mouseButton > 0) { + if (renderContext.stateUnderCursor == layer) { + if (renderContext.mouseButton > 0) { dframe = ButtonTag.FRAME_DOWN; } else { dframe = ButtonTag.FRAME_OVER; @@ -2905,22 +2909,40 @@ public final class SWF implements SWFContainerItem, Timelined { continue; } - img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB); - img.fillTransparent(); - m.translate(-rect.xMin, -rect.yMin); drawMatrix.translate(rect.xMin, rect.yMin); - drawable.toImage(dframe, layer.time + time, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans); - //if(stateUnderCursor == layer){ - /* if(true){ - Graphics2D gg = (Graphics2D)img.getGraphics(); + SerializableImage img = null; + String cacheKey = null; + if (drawable instanceof ShapeTag) { + cacheKey = m.toString() + clrTrans.toString(); + img = renderContext.shapeCache.get(cacheKey); + } + + if (img == null) { + img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB); + img.fillTransparent(); + + drawable.toImage(dframe, layer.time + time, layer.ratio, renderContext, img, m, clrTrans); + + if (cacheKey != null) { + renderContext.shapeCache.put(cacheKey, img); + } + } + + /*//if (renderContext.stateUnderCursor == layer) { + if (true) { + BufferedImage bi = img.getBufferedImage(); + ColorModel cm = bi.getColorModel(); + boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); + WritableRaster raster = bi.copyData(null); + img = new SerializableImage(new BufferedImage(cm, raster, isAlphaPremultiplied, null)); + Graphics2D gg = (Graphics2D) img.getGraphics(); gg.setStroke(new BasicStroke(3)); gg.setPaint(Color.red); gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); - gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m))); + gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(dframe, layer.time + time, layer.ratio, renderContext, m))); }*/ - if (layer.filters != null) { for (FILTER filter : layer.filters) { img = filter.apply(img); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java index cae9e54e5..287f9abf0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ShapeExporter.java @@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.helpers.BMPFile; import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; import com.jpexs.decompiler.flash.types.RECT; @@ -111,7 +112,7 @@ public class ShapeExporter { Matrix m = new Matrix(); m.translate(-rect.Xmin, -rect.Ymin); m.scale(settings.zoom); - st.toImage(0, 0, 0, null, 0, img, m, new CXFORMWITHALPHA()); + st.toImage(0, 0, 0, new RenderContext(), img, m, new CXFORMWITHALPHA()); if (settings.mode == ShapeExportMode.PNG) { ImageHelper.write(img.getBufferedImage(), "PNG", new FileOutputStream(file)); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java index bf2e32476..c9a1da868 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/ShapeExporterBase.java @@ -52,15 +52,15 @@ public abstract class ShapeExporterBase implements IShapeExporter { private final List _lineStyles; - private final List>> _fillEdgeMaps; + private final List> _fillPaths; - private final List>> _lineEdgeMaps; + private final List> _linePaths; private final ColorTransform colorTransform; - private static final Cache>>> fillEdgeMapCache = Cache.getInstance(true, true, "fillEdgeMap"); + private static final Cache>> fillEdgeMapCache = Cache.getInstance(true, true, "fillEdgeMap"); - private static final Cache>>> lineEdgeMapCache = Cache.getInstance(true, true, "lineEdgeMap"); + private static final Cache>> lineEdgeMapCache = Cache.getInstance(true, true, "lineEdgeMap"); public ShapeExporterBase(SHAPE shape, ColorTransform colorTransform) { this.shape = shape; @@ -73,30 +73,38 @@ public abstract class ShapeExporterBase implements IShapeExporter { _lineStyles.addAll(Arrays.asList(shapeWithStyle.lineStyles.lineStyles)); } - List>> fillEdgeMaps = fillEdgeMapCache.get(shape); - List>> lineEdgeMaps = lineEdgeMapCache.get(shape); - if (fillEdgeMaps == null || lineEdgeMaps == null) { + List> fillPaths = fillEdgeMapCache.get(shape); + List> linePaths = lineEdgeMapCache.get(shape); + if (fillPaths == null || linePaths == null) { // Create edge maps - fillEdgeMaps = new ArrayList<>(); - lineEdgeMaps = new ArrayList<>(); + List>> fillEdgeMaps = new ArrayList<>(); + List>> lineEdgeMaps = new ArrayList<>(); createEdgeMaps(shape, _fillStyles, _lineStyles, fillEdgeMaps, lineEdgeMaps); - fillEdgeMapCache.put(shape, fillEdgeMaps); - lineEdgeMapCache.put(shape, lineEdgeMaps); + int count = lineEdgeMaps.size(); + fillPaths = new ArrayList<>(count); + linePaths = new ArrayList<>(count); + for (int i = 0; i < count; i++) { + fillPaths.add(createPathFromEdgeMap(fillEdgeMaps.get(i))); + linePaths.add(createPathFromEdgeMap(lineEdgeMaps.get(i))); + } + + fillEdgeMapCache.put(shape, fillPaths); + lineEdgeMapCache.put(shape, linePaths); } - _fillEdgeMaps = fillEdgeMaps; - _lineEdgeMaps = lineEdgeMaps; + _fillPaths = fillPaths; + _linePaths = linePaths; } public void export() { // Let the doc handler know that a shape export starts beginShape(); // Export fills and strokes for each group separately - for (int i = 0; i < _lineEdgeMaps.size(); i++) { + for (int i = 0; i < _linePaths.size(); i++) { // Export fills first - exportFillPath(i); + exportFillPath(_fillPaths.get(i)); // Export strokes last - exportLinePath(i); + exportLinePath(_linePaths.get(i)); } // Let the doc handler know that we're done exporting a shape endShape(); @@ -203,7 +211,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected void processSubPath(List subPath, int lineStyleIdx, int fillStyleIdx0, int fillStyleIdx1, + private void processSubPath(List subPath, int lineStyleIdx, int fillStyleIdx0, int fillStyleIdx1, Map> currentFillEdgeMap, Map> currentLineEdgeMap) { List path; if (fillStyleIdx0 != 0) { @@ -234,8 +242,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected void exportFillPath(int groupIndex) { - List path = createPathFromEdgeMap(_fillEdgeMaps.get(groupIndex)); + private void exportFillPath(List path) { PointInt pos = PointInt.MAX; int fillStyleIdx = Integer.MAX_VALUE; if (path.size() > 0) { @@ -309,8 +316,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected void exportLinePath(int groupIndex) { - List path = createPathFromEdgeMap(_lineEdgeMaps.get(groupIndex)); + private void exportLinePath(List path) { PointInt pos = PointInt.MAX; int lineStyleIdx = Integer.MAX_VALUE; if (path.size() > 0) { @@ -399,7 +405,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected List createPathFromEdgeMap(Map> edgeMap) { + private List createPathFromEdgeMap(Map> edgeMap) { List newPath = new ArrayList<>(); List styleIdxArray = new ArrayList<>(); for (Integer styleIdx : edgeMap.keySet()) { @@ -412,7 +418,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { return newPath; } - protected void cleanEdgeMap(Map> edgeMap) { + private void cleanEdgeMap(Map> edgeMap) { for (Integer styleIdx : edgeMap.keySet()) { List subPath = edgeMap.get(styleIdx); if (subPath != null && subPath.size() > 0) { @@ -444,7 +450,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected Map> createCoordMap(List path) { + private Map> createCoordMap(List path) { Map> coordMap = new HashMap<>(); for (int i = 0; i < path.size(); i++) { PointInt from = path.get(i).getFrom(); @@ -461,7 +467,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { return coordMap; } - protected void removeEdgeFromCoordMap(Map> coordMap, IEdge edge) { + private void removeEdgeFromCoordMap(Map> coordMap, IEdge edge) { String key = edge.getFrom().getX() + "_" + edge.getFrom().getY(); List coordMapArray = coordMap.get(key); if (coordMapArray != null) { @@ -476,7 +482,7 @@ public abstract class ShapeExporterBase implements IShapeExporter { } } - protected IEdge findNextEdgeInCoordMap(Map> coordMap, IEdge edge) { + private IEdge findNextEdgeInCoordMap(Map> coordMap, IEdge edge) { String key = edge.getTo().getX() + "_" + edge.getTo().getY(); List coordMapArray = coordMap.get(key); if (coordMapArray != null && coordMapArray.size() > 0) { @@ -485,15 +491,15 @@ public abstract class ShapeExporterBase implements IShapeExporter { return null; } - protected void appendFillStyles(List v1, FILLSTYLE[] v2) { + private void appendFillStyles(List v1, FILLSTYLE[] v2) { v1.addAll(Arrays.asList(v2)); } - protected void appendLineStyles(List v1, LINESTYLE[] v2) { + private void appendLineStyles(List v1, LINESTYLE[] v2) { v1.addAll(Arrays.asList(v2)); } - protected void appendEdges(List v1, List v2) { + private void appendEdges(List v1, List v2) { for (int i = 0; i < v2.size(); i++) { v1.add(v2.get(i)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index b106eb54a..f297d2ce3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -386,19 +386,21 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { } } - timeline.getFrames().add(frameUp); + + List frames = timeline.getFrames(); + frames.add(frameUp); if (frameOver.layers.isEmpty()) { frameOver = frameUp; } - timeline.getFrames().add(frameOver); + frames.add(frameOver); if (frameDown.layers.isEmpty()) { frameDown = frameOver; } - timeline.getFrames().add(frameDown); + frames.add(frameDown); if (frameHit.layers.isEmpty()) { frameHit = frameUp; } - timeline.getFrames().add(frameHit); + frames.add(frameHit); return timeline; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index 9105f8ebb..12208bb81 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.dynamictext.CharacterWithStyle; import com.jpexs.decompiler.flash.tags.dynamictext.DynamicTextModel; @@ -35,7 +36,6 @@ import com.jpexs.decompiler.flash.tags.dynamictext.Word; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; @@ -810,7 +810,7 @@ public class DefineEditTextTag extends TextTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { render(false, image, transformation, colorTransform); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java index 2084369f6..95bbc6265 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java @@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter; import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; -import com.jpexs.decompiler.flash.timeline.DepthState; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; @@ -361,7 +361,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { SHAPEWITHSTYLE shape = getShapeAtRatio(ratio); // shapeNum: 4 // todo: Currently the generated image is not cached, because the cache @@ -396,7 +396,7 @@ public class DefineMorphShape2Tag extends MorphShapeTag { } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java index 200abe861..cabbdd63b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java @@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter; import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; -import com.jpexs.decompiler.flash.timeline.DepthState; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; @@ -337,7 +337,7 @@ public class DefineMorphShapeTag extends MorphShapeTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { SHAPEWITHSTYLE shape = getShapeAtRatio(ratio); // shapeNum: 3 // todo: Currently the generated image is not cached, because the cache @@ -372,7 +372,7 @@ public class DefineMorphShapeTag extends MorphShapeTag { } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { return transformation.toTransform().createTransformedShape(getShapeAtRatio(ratio).getOutline()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index 99122af31..9d59e3eb7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; -import com.jpexs.decompiler.flash.timeline.DepthState; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.Timeline; import com.jpexs.decompiler.flash.timeline.Timelined; @@ -289,8 +289,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { - SWF.frameToImage(getTimeline(), frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform); + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform); } @Override @@ -337,8 +337,8 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { - return getTimeline().getOutline(frame, time, ratio, stateUnderCursor, mouseButton, transformation); + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { + return getTimeline().getOutline(frame, time, ratio, renderContext, transformation); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java index 6b38b2fa9..2ce71b04b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java @@ -26,11 +26,11 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; @@ -549,7 +549,7 @@ public class DefineText2Tag extends TextTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { staticTextToImage(swf, textRecords, 2, image, getTextMatrix(), transformation, colorTransform); /*try { DefineText2Tag originalTag = (DefineText2Tag) getOriginalTag(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java index 72ae78b90..1ae34e528 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java @@ -27,11 +27,11 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; @@ -568,7 +568,7 @@ public class DefineTextTag extends TextTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { staticTextToImage(swf, textRecords, 1, image, getTextMatrix(), transformation, colorTransform); /*try { DefineTextTag originalTag = (DefineTextTag) getOriginalTag(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java index 85a579a24..fc1374617 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ButtonTag.java @@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Timelined; import com.jpexs.decompiler.flash.types.BUTTONRECORD; import com.jpexs.decompiler.flash.types.ColorTransform; @@ -62,13 +61,13 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { - return getTimeline().getOutline(frame, time, ratio, stateUnderCursor, mouseButton, transformation); + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { + return getTimeline().getOutline(frame, time, ratio, renderContext, transformation); } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { - SWF.frameToImage(getTimeline(), frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform); + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + SWF.frameToImage(getTimeline(), frame, time, renderContext, image, transformation, colorTransform); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java index 475a49405..ae57f6b3e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java @@ -1,23 +1,23 @@ /* * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.helpers.SerializableImage; import java.awt.Shape; @@ -29,7 +29,9 @@ import java.io.IOException; */ public interface DrawableTag extends BoundedTag { - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform); + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation); + + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform); public void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level, double zoom) throws IOException; @@ -38,6 +40,4 @@ public interface DrawableTag extends BoundedTag { public int getNumFrames(); public boolean isSingleFrame(); - - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index 76103e7c0..2a26398f2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.tags.DefineFontNameTag; import com.jpexs.decompiler.flash.tags.DefineText2Tag; import com.jpexs.decompiler.flash.tags.DefineTextTag; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.RECT; @@ -290,7 +289,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform); } @@ -313,7 +312,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { RECT r = getRect(); return new Area(new Rectangle(r.Xmin, r.Ymin, r.getWidth(), r.getHeight())); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index bef4e0429..4849aa56d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; 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.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.FILLSTYLE; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; @@ -184,7 +183,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { BitmapExporter.export(swf, getShape(), null, image, transformation, colorTransform); } @@ -212,7 +211,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { return transformation.toTransform().createTransformedShape(getShape().getOutline()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/RenderContext.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/RenderContext.java new file mode 100644 index 000000000..3ebfc946b --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/RenderContext.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.tags.base; + +import com.jpexs.decompiler.flash.timeline.DepthState; +import com.jpexs.helpers.SerializableImage; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author JPEXS + */ +public class RenderContext { + + public DepthState stateUnderCursor; + + public int mouseButton; + + public Map shapeCache = new HashMap<>(); +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java index 2c93e4a67..b9a340003 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ShapeTag.java @@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; import com.jpexs.decompiler.flash.exporters.shape.PathExporter; import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; import com.jpexs.decompiler.flash.helpers.LazyObject; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; @@ -68,12 +67,12 @@ public abstract class ShapeTag extends CharacterTag implements DrawableTag, Lazy } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { return transformation.toTransform().createTransformedShape(getShapes().getOutline()); } @Override - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + 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 paths = PathExporter.export(getShapes()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java index b1658ab93..7a69d077d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java @@ -29,7 +29,6 @@ import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; import com.jpexs.decompiler.flash.importers.TextImportResizeTextBoundsMode; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.text.TextParseException; -import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.FILLSTYLE; import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; @@ -579,7 +578,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { } @Override - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { RECT r = getBounds(); Shape shp = new Rectangle.Double(r.Xmin, r.Ymin, r.getWidth(), r.getHeight()); return transformation.toTransform().createTransformedShape(shp); //TODO: match character shapes (?) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index c1658f149..208e6c8f1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.RemoveTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.types.CLIPACTIONS; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.MATRIX; @@ -67,6 +68,8 @@ public class Timeline { public Tag parentTag; + public int maxDepth; + public List tags; private final List frames = new ArrayList<>(); @@ -120,18 +123,19 @@ public class Timeline { public final int getMaxDepth() { ensureInitialized(); - return getMaxDepthInternal(); + return maxDepth; } - public final int getMaxDepthInternal() { + private int getMaxDepthInternal() { int max_depth = 0; for (Frame f : frames) { for (int depth : f.layers.keySet()) { if (depth > max_depth) { max_depth = depth; } - if (f.layers.get(depth).clipDepth > max_depth) { - max_depth = f.layers.get(depth).clipDepth; + int clipDepth = f.layers.get(depth).clipDepth; + if (clipDepth > max_depth) { + max_depth = clipDepth; } } } @@ -285,9 +289,10 @@ public class Timeline { frames.add(frame); } + maxDepth = getMaxDepthInternal(); + // todo: enable again after TweenDetector.detectRanges implemented //detectTweens(); - int maxDepth = getMaxDepthInternal(); for (int d = 1; d <= maxDepth; d++) { for (int f = frames.size() - 1; f >= 0; f--) { if (frames.get(f).layers.get(d) != null) { @@ -307,7 +312,6 @@ public class Timeline { } private void detectTweens() { - int maxDepth = getMaxDepthInternal(); for (int d = 1; d <= maxDepth; d++) { int characterId = -1; int len = 0; @@ -405,8 +409,8 @@ public class Timeline { return modified; } - public void toImage(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { - SWF.frameToImage(this, frame, time, stateUnderCursor, mouseButton, image, transformation, colorTransform); + public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, Matrix transformation, ColorTransform colorTransform) { + SWF.frameToImage(this, frame, time, renderContext, image, transformation, colorTransform); } public String toHtmlCanvas(double unitDivisor, List frames) { @@ -417,7 +421,6 @@ public class Timeline { Frame fr = getFrames().get(frame); sounds.addAll(fr.sounds); soundClasses.addAll(fr.soundClasses); - int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { DepthState ds = fr.layers.get(d); if (ds != null) { @@ -448,7 +451,6 @@ public class Timeline { public void getObjectsOutlines(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List objs, List outlines) { Frame fr = getFrames().get(frame); Stack clips = new Stack<>(); - int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { Clip currentClip = null; for (int i = clips.size() - 1; i >= 0; i--) { @@ -460,27 +462,27 @@ public class Timeline { if (!clips.isEmpty()) { currentClip = clips.peek(); } - DepthState ds = fr.layers.get(d); - if (ds == null) { + DepthState layer = fr.layers.get(d); + if (layer == null) { continue; } - if (!ds.isVisible) { + if (!layer.isVisible) { continue; } - CharacterTag c = swf.getCharacter(ds.characterId); - if (c instanceof DrawableTag) { - Matrix m = new Matrix(ds.matrix); + CharacterTag character = swf.getCharacter(layer.characterId); + if (character instanceof DrawableTag) { + DrawableTag drawable = (DrawableTag) character; + Matrix m = new Matrix(layer.matrix); m = m.preConcatenate(transformation); - int dframe = 0; - if (c instanceof Timelined) { - int frameCount = ((Timelined) c).getTimeline().frames.size(); - if (frameCount == 0) { - return; - } - dframe = ds.time % frameCount; - if (c instanceof ButtonTag) { - ButtonTag bt = (ButtonTag) c; + int drawableFrameCount = drawable.getNumFrames(); + if (drawableFrameCount == 0) { + drawableFrameCount = 1; + } + int dframe = (time + layer.time) % drawableFrameCount; + if (character instanceof Timelined) { + if (character instanceof ButtonTag) { + ButtonTag bt = (ButtonTag) character; dframe = ButtonTag.FRAME_HITTEST; /*dframe = ButtonTag.FRAME_UP; if (stateUnderCursor == ds) { @@ -492,7 +494,11 @@ public class Timeline { }*/ } } - Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.time + time, ds.ratio, stateUnderCursor, mouseButton, m); + + RenderContext renderContext = new RenderContext(); + renderContext.stateUnderCursor = stateUnderCursor; + renderContext.mouseButton = mouseButton; + Shape cshape = ((DrawableTag) character).getOutline(dframe, layer.time + time, layer.ratio, renderContext, m); Area addArea = new Area(cshape); if (currentClip != null) { @@ -500,25 +506,24 @@ public class Timeline { a.subtract(new Area(currentClip.shape)); addArea.subtract(a); } - if (ds.clipDepth > -1) { - Clip clip = new Clip(addArea, ds.clipDepth); + if (layer.clipDepth > -1) { + Clip clip = new Clip(addArea, layer.clipDepth); clips.push(clip); } else { - objs.add(ds); + objs.add(layer); outlines.add(addArea); } - if (c instanceof Timelined) { - ((Timelined) c).getTimeline().getObjectsOutlines(dframe, time + ds.time, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines); + if (character instanceof Timelined) { + ((Timelined) character).getTimeline().getObjectsOutlines(dframe, time + layer.time, layer.ratio, stateUnderCursor, mouseButton, m, objs, outlines); } } } } - public Shape getOutline(int frame, int time, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation) { + public Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation) { Frame fr = getFrames().get(frame); Area area = new Area(); Stack clips = new Stack<>(); - int maxDepth = getMaxDepthInternal(); for (int d = maxDepth; d >= 0; d--) { Clip currentClip = null; for (int i = clips.size() - 1; i >= 0; i--) { @@ -530,30 +535,30 @@ public class Timeline { if (!clips.isEmpty()) { currentClip = clips.peek(); } - DepthState ds = fr.layers.get(d); - if (ds == null) { + DepthState layer = fr.layers.get(d); + if (layer == null) { continue; } - if (!ds.isVisible) { + if (!layer.isVisible) { continue; } - CharacterTag c = swf.getCharacter(ds.characterId); - if (c instanceof DrawableTag) { - Matrix m = new Matrix(ds.matrix); + CharacterTag character = swf.getCharacter(layer.characterId); + if (character instanceof DrawableTag) { + DrawableTag drawable = (DrawableTag) character; + Matrix m = new Matrix(layer.matrix); m = m.preConcatenate(transformation); - int dframe = 0; - if (c instanceof Timelined) { - int frameCount = ((Timelined) c).getTimeline().frames.size(); - if (frameCount < 1) { - frameCount = 1; - } - dframe = (time + ds.time) % frameCount; - if (c instanceof ButtonTag) { - ButtonTag bt = (ButtonTag) c; + int drawableFrameCount = drawable.getNumFrames(); + if (drawableFrameCount == 0) { + drawableFrameCount = 1; + } + int dframe = (time + layer.time) % drawableFrameCount; + if (character instanceof Timelined) { + if (character instanceof ButtonTag) { + ButtonTag bt = (ButtonTag) character; dframe = ButtonTag.FRAME_UP; - if (stateUnderCursor == ds) { - if (mouseButton > 0) { + if (renderContext.stateUnderCursor == layer) { + if (renderContext.mouseButton > 0) { dframe = ButtonTag.FRAME_DOWN; } else { dframe = ButtonTag.FRAME_OVER; @@ -561,7 +566,8 @@ public class Timeline { } } } - Shape cshape = ((DrawableTag) c).getOutline(dframe, time + ds.time, ds.ratio, stateUnderCursor, mouseButton, m); + + Shape cshape = ((DrawableTag) character).getOutline(dframe, time + layer.time, layer.ratio, renderContext, m); Area addArea = new Area(cshape); if (currentClip != null) { @@ -569,8 +575,8 @@ public class Timeline { a.subtract(new Area(currentClip.shape)); addArea.subtract(a); } - if (ds.clipDepth > -1) { - Clip clip = new Clip(addArea, ds.clipDepth); + if (layer.clipDepth > -1) { + Clip clip = new Clip(addArea, layer.clipDepth); clips.push(clip); } else { area.add(addArea); @@ -590,8 +596,7 @@ public class Timeline { } public boolean isSingleFrame(int frame) { - Frame frameObj = frames.get(frame); - int maxDepth = getMaxDepthInternal(); + Frame frameObj = getFrames().get(frame); for (int i = 1; i <= maxDepth; i++) { if (!frameObj.layers.containsKey(i)) { continue; diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/SerializableImage.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/SerializableImage.java index f0b2566cf..820ccc045 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/helpers/SerializableImage.java +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/SerializableImage.java @@ -57,16 +57,16 @@ public class SerializableImage implements Serializable { this.image = image; } - public SerializableImage(int i, int i1, int i2) { - image = new BufferedImage(i, i1, i2); + public SerializableImage(int width, int height, int imageType) { + image = new BufferedImage(width, height, imageType); } - public SerializableImage(ColorModel cm, WritableRaster wr, boolean bln, Hashtable hshtbl) { - image = new BufferedImage(cm, wr, bln, hshtbl); + public SerializableImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties) { + image = new BufferedImage(cm, raster, isRasterPremultiplied, properties); } - public SerializableImage(int i, int i1, int i2, IndexColorModel icm) { - image = new BufferedImage(i, i1, i2, icm); + public SerializableImage(int width, int height, int imageType, IndexColorModel cm) { + image = new BufferedImage(width, height, imageType, cm); } public BufferedImage getBufferedImage() { diff --git a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java index 73e606404..84d8fc931 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.ImageTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.flash.types.ColorTransform; @@ -327,7 +328,7 @@ public class FolderPreviewPanel extends JPanel { image.fillTransparent(); if (imgSrc == null) { DrawableTag drawable = (DrawableTag) treeItem; - drawable.toImage(0, 0, 0, null, 0, image, m, new ColorTransform()); + drawable.toImage(0, 0, 0, new RenderContext(), image, m, new ColorTransform()); } else { Graphics2D g = (Graphics2D) image.getGraphics(); g.setTransform(m.toTransform()); diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index f07ceee6a..f88eb9c55 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -25,6 +25,7 @@ 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.tags.base.DrawableTag; +import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.timeline.DepthState; @@ -585,10 +586,10 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis Matrix m = new Matrix(); m.translate(-rect.Xmin * zoomDouble, -rect.Ymin * zoomDouble); m.scale(zoomDouble); - textTag.toImage(0, 0, 0, null, 0, image, m, new ConstantColorColorTransform(0xFFC0C0C0)); + textTag.toImage(0, 0, 0, new RenderContext(), image, m, new ConstantColorColorTransform(0xFFC0C0C0)); if (newTextTag != null) { - newTextTag.toImage(0, 0, 0, null, 0, image, m, new ConstantColorColorTransform(0xFF000000)); + newTextTag.toImage(0, 0, 0, new RenderContext(), image, m, new ConstantColorColorTransform(0xFF000000)); } iconPanel.setImg(image); @@ -679,7 +680,10 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis Matrix m = new Matrix(); m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom); m.scale(zoom); - drawable.getTimeline().toImage(frame, time, frame, stateUnderCursor, mouseButton, image, m, new ColorTransform()); + RenderContext renderContext = new RenderContext(); + renderContext.stateUnderCursor = stateUnderCursor; + renderContext.mouseButton = mouseButton; + drawable.getTimeline().toImage(frame, time, frame, renderContext, image, m, new ColorTransform()); Graphics2D gg = (Graphics2D) image.getGraphics(); gg.setStroke(new BasicStroke(3)); @@ -693,7 +697,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis if (cht != null) { if (cht instanceof DrawableTag) { DrawableTag dt = (DrawableTag) cht; - Shape outline = dt.getOutline(0, ds.time, ds.ratio, stateUnderCursor, mouseButton, new Matrix(ds.matrix)); + Shape outline = dt.getOutline(0, ds.time, ds.ratio, renderContext, new Matrix(ds.matrix)); Rectangle bounds = outline.getBounds(); bounds.x *= zoom; bounds.y *= zoom; @@ -740,8 +744,6 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis lastMouseEvent = this.lastMouseEvent; } - updatePos(timelined, lastMouseEvent, counter); - synchronized (ImagePanel.class) { frame = this.frame; time = this.time; @@ -762,10 +764,13 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value; getOutlines(timelined, frame, time, zoomDouble, stateUnderCursor, mouseButton, counter); + updatePos(timelined, lastMouseEvent, counter); + Matrix mat = new Matrix(); mat.translateX = swf.displayRect.Xmin; mat.translateY = swf.displayRect.Ymin; SerializableImage img = getFrame(swf, frame, time, timelined, stateUnderCursor, mouseButton, selectedDepth, zoomDouble); + List sounds = new ArrayList<>(); List soundClasses = new ArrayList<>(); timeline.getSounds(frame, time, stateUnderCursor, mouseButton, sounds, soundClasses); @@ -822,7 +827,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } } - private void getOutlines(Timelined timelined, int frame, int time, double zoom, DepthState stateUnderCursor, int mouseButton, int counter) { + private List getOutlines(Timelined timelined, int frame, int time, double zoom, DepthState stateUnderCursor, int mouseButton, int counter) { List objs = new ArrayList<>(); List outlines = new ArrayList<>(); Matrix m = new Matrix(); @@ -841,6 +846,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis iconPanel.setOutlines(objs, outlines); } } + + return outlines; } public synchronized void stop() {