diff --git a/CHANGELOG.md b/CHANGELOG.md index a724c5606..cc18f601d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. - [#1015], [#1466], [#1513] Better error messages during saving, display message on out of memory - [#1657] Option to disable adding second quote/bracket/parenthesis - Option to automatically show error dialog on every error +- [#1676] View video tags in external flash projector ### Fixed - PDF export - NullPointer when font of text is missing diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java index 46ff2185f..246ff2b46 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FrameExporter.java @@ -389,7 +389,7 @@ public class FrameExporter { try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) { try { - new PreviewExporter().exportSwf(fos, swf.getCharacter(containerId), fBackgroundColor, 0); + new PreviewExporter().exportSwf(fos, swf.getCharacter(containerId), fBackgroundColor, 0, false); } catch (ActionParseException ex) { Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex); } @@ -405,7 +405,7 @@ public class FrameExporter { try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) { try { - new PreviewExporter().exportSwf(fos, fn, fBackgroundColor, 0); + new PreviewExporter().exportSwf(fos, fn, fBackgroundColor, 0, false); } catch (ActionParseException ex) { Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java index 793c43989..31c01bbb0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/MorphShapeExporter.java @@ -121,7 +121,7 @@ public class MorphShapeExporter { case SWF: try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) { try { - new PreviewExporter().exportSwf(fos, mst, null, 0); + new PreviewExporter().exportSwf(fos, mst, null, 0, false); } catch (ActionParseException ex) { Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java index aeeeb0d31..73eb8604c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java @@ -12,7 +12,8 @@ * 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.exporters; import com.jpexs.decompiler.flash.SWF; @@ -21,10 +22,14 @@ import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; +import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.tags.DefineBitsTag; +import com.jpexs.decompiler.flash.tags.DefineButton2Tag; +import com.jpexs.decompiler.flash.tags.DefineButtonTag; import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag; import com.jpexs.decompiler.flash.tags.DefineMorphShapeTag; +import com.jpexs.decompiler.flash.tags.DefineShapeTag; import com.jpexs.decompiler.flash.tags.DefineSoundTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DefineTextTag; @@ -46,6 +51,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterIdTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.FontTag; +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.SoundStreamHeadTypeTag; @@ -54,13 +60,23 @@ import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Frame; import com.jpexs.decompiler.flash.timeline.Timelined; import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.flash.types.BUTTONCONDACTION; +import com.jpexs.decompiler.flash.types.BUTTONRECORD; +import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA; +import com.jpexs.decompiler.flash.types.FILLSTYLE; +import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.SHAPE; +import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; +import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; +import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; +import com.jpexs.decompiler.graph.CompilationException; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -73,6 +89,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -85,7 +103,147 @@ public class PreviewExporter { public static final int MORPH_SHAPE_ANIMATION_FRAME_RATE = 30; - public SWFHeader exportSwf(OutputStream os, TreeItem treeItem, Color backgroundColor, int fontPageNum) throws IOException, ActionParseException { + private void updateProgressBar(int xmin, int ymin, SWF swf, SWFOutputStream sos2, int width, int height, int progressBarHeight, int currentFrame, int totalFrames) throws IOException { + Matrix m = new Matrix(); + m.translate(xmin, ymin + height - progressBarHeight * 20); + m.scale(width * currentFrame / totalFrames, progressBarHeight * 20); + new PlaceObject2Tag(swf, true, 2, -1, m.toMATRIX(), null, -1, null, -1, null).writeTag(sos2); + } + + private void addControls(int xmin, int ymin, int progressBarHeight, SWF swf, SWFOutputStream sos2, int width, int numFrames, int height) throws IOException { + int progressBarShapeId = swf.getNextCharacterId(); + int overVideoButtonId = progressBarShapeId + 1; + int progressBarButtonId = overVideoButtonId + 1; + + Color progressBarColor = Color.red; + DefineShapeTag dsh = new DefineShapeTag(swf); + dsh.shapeBounds = new RECT(0, 20, 0, 20 * progressBarHeight); + dsh.shapeId = progressBarShapeId; + dsh.shapes.fillStyles.fillStyles = new FILLSTYLE[1]; + dsh.shapes.fillStyles.fillStyles[0] = new FILLSTYLE(); + dsh.shapes.fillStyles.fillStyles[0].fillStyleType = FILLSTYLE.SOLID; + dsh.shapes.fillStyles.fillStyles[0].color = new RGB(progressBarColor); + dsh.shapes.shapeRecords.clear(); + StyleChangeRecord scr = new StyleChangeRecord(); + scr.stateFillStyle0 = true; + scr.fillStyle0 = 1; + scr.stateMoveTo = true; + scr.moveDeltaX = 0; + scr.moveDeltaY = 0; + dsh.shapes.shapeRecords.add(scr); + StraightEdgeRecord ser; + ser = new StraightEdgeRecord(); + ser.vertLineFlag = true; + ser.deltaY = 1; + dsh.shapes.shapeRecords.add(ser); + ser = new StraightEdgeRecord(); + ser.deltaX = 1; + dsh.shapes.shapeRecords.add(ser); + ser = new StraightEdgeRecord(); + ser.vertLineFlag = true; + ser.deltaY = -1; + dsh.shapes.shapeRecords.add(ser); + ser = new StraightEdgeRecord(); + ser.deltaX = -1; + dsh.shapes.shapeRecords.add(ser); + dsh.shapes.shapeRecords.add(new EndShapeRecord()); + + dsh.writeTag(sos2); + + DefineButton2Tag overVideoButton = new DefineButton2Tag(swf); + overVideoButton.buttonId = overVideoButtonId; + + BUTTONRECORD br; + br = new BUTTONRECORD(); + br.buttonStateUp = false; + br.buttonStateDown = false; + br.buttonStateOver = false; + br.buttonStateHitTest = true; + br.characterId = progressBarShapeId; + br.placeDepth = 1; + br.colorTransform = new CXFORMWITHALPHA(); + br.placeMatrix = new MATRIX(); + overVideoButton.characters.add(br); + + BUTTONCONDACTION bca; + ActionScript2Parser ap; + + bca = new BUTTONCONDACTION(swf, overVideoButton); + bca.isLast = true; + ap = new ActionScript2Parser(swf, bca); + try { + bca.setActions(ap.actionsFromString("on(press){" + + "stopped = !stopped; if(stopped) {stop();}else{play();}" + + "}")); + } catch (CompilationException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (ActionParseException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } + overVideoButton.actions.add(bca); + + overVideoButton.writeTag(sos2); + + DefineButton2Tag progressBarButton = new DefineButton2Tag(swf); + progressBarButton.buttonId = progressBarButtonId; + progressBarButton.characters.add(br); + + bca = new BUTTONCONDACTION(swf, overVideoButton); + bca.isLast = true; + + ap = new ActionScript2Parser(swf, bca); + try { + bca.setActions(ap.actionsFromString("on(press){" + + "var f = Math.round(_root._xmouse*" + numFrames + "/" + (width / SWF.unitDivisor) + ");" + + "if(stopped){" + + "gotoAndStop(f);" + + "}else{" + + "gotoAndPlay(f);" + + "}" + + "}")); + } catch (CompilationException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (ActionParseException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } + progressBarButton.actions.add(bca); + + progressBarButton.writeTag(sos2); + + Matrix m; + + m = new Matrix(); + m.translate(xmin, ymin + height - progressBarHeight * 20); + m.scale(1, progressBarHeight * 20); + + new PlaceObject2Tag(swf, false, 2, progressBarShapeId, m.toMATRIX(), null, -1, null, -1, null).writeTag(sos2); + + m = new Matrix(); + m.scale(width, height - progressBarHeight * 20); + + new PlaceObject2Tag(swf, false, 3, overVideoButtonId, m.toMATRIX(), null, -1, null, -1, null).writeTag(sos2); + + m = new Matrix(); + m.translate(xmin, ymin + height - progressBarHeight * 20); + m.scale(width, progressBarHeight * 20); + + new PlaceObject2Tag(swf, false, 4, progressBarButtonId, m.toMATRIX(), null, -1, null, -1, null).writeTag(sos2); + + DoActionTag doAction; + doAction = new DoActionTag(swf); + ap = new ActionScript2Parser(swf, doAction); + try { + doAction.setActions(ap.actionsFromString("var stopped = false;")); + } catch (CompilationException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (ActionParseException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } + + doAction.writeTag(sos2); + } + + public SWFHeader exportSwf(OutputStream os, TreeItem treeItem, Color backgroundColor, int fontPageNum, boolean showControls) throws IOException, ActionParseException { SWF swf = treeItem.getSwf(); int frameCount = 1; @@ -133,16 +291,29 @@ public class PreviewExporter { treeItemBounds = ((Frame) treeItem).timeline.timelined.getRect(); } - if (treeItemBounds != null) { - if (outrect.getWidth() < treeItemBounds.getWidth()) { - outrect.Xmax += treeItemBounds.getWidth() - outrect.getWidth(); - } + if (showControls) { + outrect = new RECT(treeItemBounds); + } else { + if (treeItemBounds != null) { + if (outrect.getWidth() < treeItemBounds.getWidth()) { + outrect.Xmax += treeItemBounds.getWidth() - outrect.getWidth(); + } - if (outrect.getHeight() < treeItemBounds.getHeight()) { - outrect.Ymax += treeItemBounds.getHeight() - outrect.getHeight(); + if (outrect.getHeight() < treeItemBounds.getHeight()) { + outrect.Ymax += treeItemBounds.getHeight() - outrect.getHeight(); + } } } + if (!(treeItem instanceof DefineVideoStreamTag) && !(treeItem instanceof MorphShapeTag)) { + showControls = false; + } + + int progressBarHeight = 20; + if (showControls) { + outrect.Ymax += progressBarHeight * 20; + } + int width = outrect.getWidth(); int height = outrect.getHeight(); @@ -252,12 +423,16 @@ public class PreviewExporter { mat.hasScale = false; mat.translateX = 0; mat.translateY = 0; + int rxmin = 0; + int rymin = 0; if (treeItem instanceof BoundedTag) { RECT r = ((BoundedTag) treeItem).getRect(); - mat.translateX = -r.Xmin; - mat.translateY = -r.Ymin; + rxmin = r.Xmin; + rymin = r.Ymin; + /*mat.translateX = -r.Xmin; + mat.translateY = -r.Ymin;*/ mat.translateX = mat.translateX + width / 2 - r.getWidth() / 2; - mat.translateY = mat.translateY + height / 2 - r.getHeight() / 2; + mat.translateY = mat.translateY + (showControls ? height - progressBarHeight * 20 : height) / 2 - r.getHeight() / 2; } else { mat.translateX = width / 4; mat.translateY = height / 4; @@ -352,10 +527,16 @@ public class PreviewExporter { } new ShowFrameTag(swf).writeTag(sos2); } else if ((treeItem instanceof DefineMorphShapeTag) || (treeItem instanceof DefineMorphShape2Tag)) { + if (showControls) { + addControls(rxmin, rymin, progressBarHeight, swf, sos2, width, 65536, height); + } new PlaceObject2Tag(swf, false, 1, chtId, mat, null, 0, null, -1, null).writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); for (int ratio = 0; ratio < 65536; ratio += 65536 / frameCount) { new PlaceObject2Tag(swf, true, 1, chtId, mat, null, ratio, null, -1, null).writeTag(sos2); + if (showControls) { + updateProgressBar(rxmin, rymin, swf, sos2, width, height, progressBarHeight, ratio, 65536); + } new ShowFrameTag(swf).writeTag(sos2); } } else if (treeItem instanceof SoundStreamHeadTypeTag) { @@ -472,8 +653,6 @@ public class PreviewExporter { new ShowFrameTag(swf).writeTag(sos2); } else if (treeItem instanceof DefineVideoStreamTag) { - - new PlaceObject2Tag(swf, false, 1, chtId, mat, null, -1, null, -1, null).writeTag(sos2); List frs = new ArrayList<>(videoFrames.values()); Collections.sort(frs, new Comparator() { @Override @@ -481,12 +660,19 @@ public class PreviewExporter { return o1.frameNum - o2.frameNum; } }); + if (showControls) { + addControls(rxmin, rymin, progressBarHeight, swf, sos2, width, videoFrames.size(), height); + } + new PlaceObject2Tag(swf, false, 1, chtId, mat, null, -1, null, -1, null).writeTag(sos2); boolean first = true; int ratio = 0; for (VideoFrameTag f : frs) { if (!first) { ratio++; new PlaceObject2Tag(swf, true, 1, -1, null, null, ratio, null, -1, null).writeTag(sos2); + if (showControls) { + updateProgressBar(rxmin, rymin, swf, sos2, width, height, progressBarHeight, ratio, videoFrames.size()); + } } f.writeTag(sos2); new ShowFrameTag(swf).writeTag(sos2); 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 8e8ed58e0..7cb952d08 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 @@ -148,7 +148,7 @@ public class ShapeExporter { case SWF: try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) { try { - new PreviewExporter().exportSwf(fos, st, null, 0); + new PreviewExporter().exportSwf(fos, st, null, 0, false); } catch (ActionParseException ex) { Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/libsrc/ffdec_lib/testdata/graphics/Cute Cat - 3092.flv b/libsrc/ffdec_lib/testdata/graphics/Cute Cat - 3092.flv new file mode 100644 index 000000000..49fec3b6e Binary files /dev/null and b/libsrc/ffdec_lib/testdata/graphics/Cute Cat - 3092.flv differ diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics.swf b/libsrc/ffdec_lib/testdata/graphics/graphics.swf index ba6bb5ed2..f878a0d97 100644 Binary files a/libsrc/ffdec_lib/testdata/graphics/graphics.swf and b/libsrc/ffdec_lib/testdata/graphics/graphics.swf differ diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/DOMDocument.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/DOMDocument.xml index 249b4c132..42a4a6514 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/DOMDocument.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/DOMDocument.xml @@ -1,11 +1,12 @@ - + - + + @@ -35,9 +36,10 @@ + - + @@ -51,7 +53,7 @@ - + @@ -167,7 +169,7 @@ - + @@ -779,10 +781,10 @@ !3980 1990|2980 1990!2980 1990|2980 990!2980 990|3980 990!3980 990|3980 1990"/> - + @@ -1381,18 +1383,18 @@ - + - - + + @@ -2147,6 +2149,9 @@ + + + @@ -2774,7 +2779,7 @@ - + @@ -3507,6 +3512,31 @@ + + + + + + + + + 062 Video + + + + + + + + + + + + + + + + @@ -3514,6 +3544,8 @@ + + @@ -3532,7 +3564,5 @@ - - \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/ScaledRect.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/ScaledRect.xml index 8f4c44f65..b79e532f5 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/ScaledRect.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/ScaledRect.xml @@ -28,100 +28,125 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -274,7 +299,7 @@ - + diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/Sprite1.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/Sprite1.xml index e775eccfa..21fc928b6 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/Sprite1.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/Sprite1.xml @@ -25,9 +25,9 @@ - - + + diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/VideoSprite.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/VideoSprite.xml new file mode 100644 index 000000000..4172ec870 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/VideoSprite.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/grid.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/grid.xml index 9808d212a..97303d54f 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/grid.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/LIBRARY/grid.xml @@ -28,114 +28,71 @@ - - - - - - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml index 7e3b12786..e22df05fa 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml @@ -5,8 +5,8 @@ xmlns:xmp="http://ns.adobe.com/xap/1.0/"> Adobe Flash Professional CS6 - build 481 2021-03-14T08:29:20+01:00 - 2021-03-31T08:35:56+02:00 - 2021-03-31T08:35:56+02:00 + 2021-04-02T15:02:59+02:00 + 2021-04-02T15:02:59+02:00 @@ -15,7 +15,7 @@ - xmp.iid:9AAB0C59EB91EB11BA29D0B5CA3B8804 + xmp.iid:E3E40BC0B393EB11B4038A481A0499E8 xmp.did:D6D3FE199784EB1187FEAE6972EC5115 xmp.did:D6D3FE199784EB1187FEAE6972EC5115 @@ -110,6 +110,12 @@ 2021-03-14T08:29:20+01:00 Adobe Flash Professional CS6 - build 481 + + created + xmp.iid:E3E40BC0B393EB11B4038A481A0499E8 + 2021-03-14T08:29:20+01:00 + Adobe Flash Professional CS6 - build 481 + diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/bin/M 6 1617368920.dat b/libsrc/ffdec_lib/testdata/graphics/graphics/bin/M 6 1617368920.dat new file mode 100644 index 000000000..d591a022f Binary files /dev/null and b/libsrc/ffdec_lib/testdata/graphics/graphics/bin/M 6 1617368920.dat differ diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache b/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache index 286476ad3..3c3ff0412 100644 Binary files a/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache and b/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache differ diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 7d4439c52..c0d2100b5 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -467,6 +467,28 @@ public class Main { } } + public static void runAsync(File swfFile) { + String playerLocation = Configuration.playerLocation.get(); + if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) { + ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + advancedSettings("paths"); + return; + } + try { + final Process process = Runtime.getRuntime().exec(new String[]{playerLocation, swfFile.getAbsolutePath()}); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + if (process.isAlive()) { + process.destroyForcibly(); + } + } + }); + } catch (IOException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + public static void run(SWF swf) { String flashVars = "";//key=val&key2=val2 String playerLocation = Configuration.playerLocation.get(); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 1664cee7f..e2672229e 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -3559,10 +3559,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se previewPanel.showImagePanel(swf, swf, -1); } else { previewPanel.setParametersPanelVisible(false); - if (flashPanel != null) { //same for flashPanel2 - previewPanel.showFlashViewerPanel(); - previewPanel.showSwf(swf); - } + //if (flashPanel != null) { //same for flashPanel2 + previewPanel.showFlashViewerPanel(); + previewPanel.showSwf(swf); + + //} } } else if ((treeItem instanceof PlaceObjectTypeTag) && (previewPanel != dumpPreviewPanel)) { TreePath path = tagTree.getModel().getTreePath(treeItem); diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index f1dccbf0b..f5f20e9af 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -48,8 +48,12 @@ import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -190,6 +194,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel private final int PLACE_EDIT_RAW = 2; private int placeEditMode = 0; + //used only for flash player + private TreeItem currentItem; + public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; setDividerSize(this.readOnly ? 0 : dividerSize); @@ -355,8 +362,8 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel flashPlayPanel2.add(new PlayerControls(mainPanel, flashPanel), BorderLayout.SOUTH); leftComponent = flashPlayPanel2; } else { - JPanel swtPanel = new JPanel(new BorderLayout()); - String labelStr = ""; + JPanel swtPanel = new JPanel(new GridBagLayout()); + /*String labelStr = ""; if (!Platform.isWindows()) { labelStr = mainPanel.translate("notavailonthisplatform"); } else { @@ -368,7 +375,17 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel } String htmlLabelStr = "
" + labelStr.replace("\n", "
") + "
"; swtPanel.add(new JLabel(htmlLabelStr, JLabel.CENTER), BorderLayout.CENTER); - swtPanel.setBackground(View.getDefaultBackgroundColor()); + swtPanel.setBackground(View.getDefaultBackgroundColor());*/ + + JPanel buttonsPanel = new JPanel(new FlowLayout()); + JButton flashProjectorButton = new JButton(mainPanel.translate("button.showin.flashprojector")); + flashProjectorButton.addActionListener(this::flashProjectorActionPerformed); + buttonsPanel.add(flashProjectorButton); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.CENTER; + gbc.fill = GridBagConstraints.HORIZONTAL; + swtPanel.add(buttonsPanel, gbc); + leftComponent = swtPanel; } @@ -376,6 +393,10 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel return pan; } + private void flashProjectorActionPerformed(ActionEvent e) { + createAndRunTempSwf(currentItem); + } + private JPanel createImagesCard() { JPanel shapesCard = new JPanel(new BorderLayout()); JPanel previewPanel = new JPanel(new BorderLayout()); @@ -716,6 +737,46 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel nextFontsButton.setVisible(false); } + private void createAndRunTempSwf(TreeItem treeItem) { + try { + File extTempFile = File.createTempFile("ffdec_viewext_", ".swf"); + extTempFile.deleteOnExit(); + + if (treeItem instanceof SWF) { + SWF swf = (SWF) treeItem; + try (FileOutputStream fos = new FileOutputStream(extTempFile)) { + swf.saveTo(fos); + } + } else { + Color backgroundColor = View.getSwfBackgroundColor(); + + if (treeItem instanceof Tag) { + Tag tag = (Tag) treeItem; + if (tag instanceof FontTag) { //Fonts are always black on white + backgroundColor = View.getDefaultBackgroundColor(); + } + } else if (treeItem instanceof Frame) { + Frame fn = (Frame) treeItem; + SWF sourceSwf = fn.getSwf(); + if (fn.timeline.timelined == sourceSwf) { + SetBackgroundColorTag setBgColorTag = sourceSwf.getBackgroundColor(); + if (setBgColorTag != null) { + backgroundColor = setBgColorTag.backgroundColor.toColor(); + } + } + } + + SWFHeader header; + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(extTempFile))) { + header = new PreviewExporter().exportSwf(fos, treeItem, backgroundColor, fontPageNum, true); + } + } + Main.runAsync(extTempFile); + } catch (IOException | ActionParseException ex) { + Logger.getLogger(PreviewPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + public void createAndShowTempSwf(TreeItem treeItem) { try { if (tempFile != null) { @@ -745,13 +806,15 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel SWFHeader header; try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { - header = new PreviewExporter().exportSwf(fos, treeItem, backgroundColor, fontPageNum); + header = new PreviewExporter().exportSwf(fos, treeItem, backgroundColor, fontPageNum, false); } if (flashPanel != null) { flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, header.frameRate); } + this.currentItem = treeItem; + showFlashViewerPanel(); } catch (IOException | ActionParseException ex) { Logger.getLogger(PreviewPanel.class.getName()).log(Level.SEVERE, null, ex); @@ -759,6 +822,10 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel } public void showSwf(SWF swf) { + currentItem = swf; + if (flashPanel == null) { + return; + } Color backgroundColor = View.getDefaultBackgroundColor(); SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor(); if (setBgColorTag != null) { diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 58f0ba21b..0c26a39d4 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -826,3 +826,5 @@ notavailable.activex = Preview of this object is not available since Flash Activ notavailable.activex.disable = You can enable using internal viewer by unchecking\n \ Advanced Settings / Other / (Deprecated) Use Adobe Flash player for preview of objects\n \ But unfortunately, this won't work for movie tags. + +button.showin.flashprojector = Show in flash projector \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index 6260360c3..bcea586ea 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -801,4 +801,6 @@ notavailable.activex = N\u00e1hled tohoto objektu nen\u00ed dostupn\u00fd proto\ notavailable.activex.disable = M\u016f\u017eete povolit pou\u017eit\u00ed intern\u00edho prohl\u00ed\u017ee\u010de od\u0161krtnut\u00edm\n \ Pokro\u010dil\u00e1 nastaven\u00ed / Ostatn\u00ed / (P\u0159ekon\u00e1no) Pou\u017e\u00edvat Adobe Flash player pro n\u00e1hledy objekt\u016f\n \ - Ale bohu\u017eel, tohle nebude fungovat pro tagy s videi. \ No newline at end of file + Ale bohu\u017eel, tohle nebude fungovat pro tagy s videi. + +button.showin.flashprojector = Zobrazit ve flash projektoru \ No newline at end of file