From 2ef5d26b0e1c2bf4a5be0270785e4a3cb3bd30c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 24 Mar 2026 21:45:48 +0100 Subject: [PATCH] feat: export all four states of a button (#2671) Closes #2671 --- .../flash/exporters/FrameExporter.java | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) 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 5818a6535..07b11af65 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 @@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ButtonTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.RenderContext; @@ -65,12 +66,10 @@ import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; import com.jpexs.helpers.SerializableImage; import com.jpexs.helpers.utf8.Utf8Helper; -import com.jpexs.images.apng.AnimatedPngDecoder; import com.jpexs.images.apng.AnimatedPngEncoder; import com.jpexs.images.apng.data.AnimatedPngData; import com.jpexs.images.apng.data.AnimationFrameData; import dev.matrixlab.webp4j.WebPCodec; -import dev.matrixlab.webp4j.animation.AnimatedWebPEncoder; import dev.matrixlab.webp4j.gif.GifToWebPConfig; import gnu.jpdf.PDFGraphics; import gnu.jpdf.PDFJob; @@ -142,11 +141,14 @@ public class FrameExporter { if (frames == null) { frames = new ArrayList<>(); - frames.add(0); // todo: export all frames + frames.add(ButtonTag.FRAME_UP); + frames.add(ButtonTag.FRAME_OVER); + frames.add(ButtonTag.FRAME_DOWN); + frames.add(ButtonTag.FRAME_HITTEST); } FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom, true, settings.aaScale); - return exportFrames(handler, outdir, swf, containerId, frames, 1, fes, evl); + return exportFrames(handler, outdir, swf, containerId, frames, 1, fes, evl, true); } public List exportSpriteFrames(AbortRetryIgnoreHandler handler, String outdir, SWF swf, int containerId, List frames, int subframesLength, SpriteExportSettings settings, EventListener evl) throws IOException, InterruptedException { @@ -274,6 +276,31 @@ public class FrameExporter { } public List exportFrames(AbortRetryIgnoreHandler handler, String outdir, final SWF swf, int containerId, List frames, int subFramesLength, final FrameExportSettings settings, final EventListener evl) throws IOException, InterruptedException { + return exportFrames(handler, outdir, swf, containerId, frames, subFramesLength, settings, evl, false); + } + + private String getFrameFileName(int frame, boolean button) { + String buttonSuffix = ""; + if (button) { + switch (frame) { + case ButtonTag.FRAME_UP + 1: + buttonSuffix = "_up"; + break; + case ButtonTag.FRAME_OVER + 1: + buttonSuffix = "_over"; + break; + case ButtonTag.FRAME_DOWN + 1: + buttonSuffix = "_down"; + break; + case ButtonTag.FRAME_HITTEST + 1: + buttonSuffix = "_hittest"; + break; + } + } + return "" + frame + buttonSuffix; + } + + public List exportFrames(AbortRetryIgnoreHandler handler, String outdir, final SWF swf, int containerId, List frames, int subFramesLength, final FrameExportSettings settings, final EventListener evl, boolean button) throws IOException, InterruptedException { final List ret = new ArrayList<>(); if (CancellableWorker.isInterrupted()) { return ret; @@ -355,8 +382,8 @@ public class FrameExporter { final Color fbackgroundColor = backgroundColor; for (File foutdir : foutdirs) { new RetryTask(() -> { - int frame = subFramesLength > 1 ? fframes.get(0) : fframes.get(fi); - File f = new File(foutdir + File.separator + ((subFramesLength > 1 ? fi : fframes.get(fi)) + 1) + ".svg"); + int frame = subFramesLength > 1 ? fframes.get(0) : fframes.get(fi); + File f = new File(foutdir + File.separator + getFrameFileName(((subFramesLength > 1 ? fi : fframes.get(fi)) + 1), button) + ".svg"); try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) { ExportRectangle rect = new ExportRectangle(tim.displayRect); rect.xMax *= settings.zoom; @@ -588,7 +615,7 @@ public class FrameExporter { new RetryTask(() -> { int fileNum = subFramesLength > 1 ? fi + 1 : (fframes.get(fi) + 1); - File f = new File(foutdir + File.separator + fileNum + ".bmp"); + File f = new File(foutdir + File.separator + getFrameFileName(fileNum, button) + ".bmp"); BufferedImage img = frameImages.next(); if (img != null) { BMPFile.saveBitmap(img, f); @@ -606,7 +633,7 @@ public class FrameExporter { new RetryTask(() -> { int fileNum = subFramesLength > 1 ? fi + 1 : (fframes.get(fi) + 1); - File f = new File(foutdir + File.separator + fileNum + ".webp"); + File f = new File(foutdir + File.separator + getFrameFileName(fileNum, button) + ".webp"); BufferedImage img = frameImages.next(); if (img != null) { try (FileOutputStream fos = new FileOutputStream(f)) { @@ -625,7 +652,7 @@ public class FrameExporter { final int fi = i; new RetryTask(() -> { int fileNum = subFramesLength > 1 ? fi + 1 : (fframes.get(fi) + 1); - File file = new File(foutdir + File.separator + fileNum + ".png"); + File file = new File(foutdir + File.separator + getFrameFileName(fileNum, button) + ".png"); BufferedImage img = frameImages.next(); if (img != null) { ImageHelper.write(img, ImageFormat.PNG, file);