mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-30 08:41:25 +00:00
#798 ffdec doesn't show what it's exporting
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
@@ -21,5 +22,9 @@ package com.jpexs.decompiler.flash;
|
||||
*/
|
||||
public interface EventListener {
|
||||
|
||||
public void handleExportingEvent(String type, int index, int count, Object data);
|
||||
|
||||
public void handleExportedEvent(String type, int index, int count, Object data);
|
||||
|
||||
public void handleEvent(String event, Object data);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash;
|
||||
|
||||
import SevenZip.Compression.LZMA.Decoder;
|
||||
import SevenZip.Compression.LZMA.Encoder;
|
||||
import com.jpacker.JPacker;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.CachedDecompilation;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
@@ -61,12 +60,8 @@ import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.FramesExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
|
||||
import com.jpexs.decompiler.flash.helpers.BMPFile;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
@@ -83,7 +78,6 @@ import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
@@ -118,18 +112,9 @@ import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
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.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.filters.BEVELFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
|
||||
import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GLOWFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER;
|
||||
import com.jpexs.decompiler.flash.xfl.FLAVersion;
|
||||
import com.jpexs.decompiler.flash.xfl.XFLConverter;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
@@ -146,23 +131,17 @@ import com.jpexs.helpers.NulStream;
|
||||
import com.jpexs.helpers.ProgressListener;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import gnu.jpdf.PDFJob;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.print.PageFormat;
|
||||
import java.awt.print.Paper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -1064,7 +1043,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean exportAS3Class(String className, String outdir, ScriptExportMode exportMode, boolean parallel) throws Exception {
|
||||
public boolean exportAS3Class(String className, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws Exception {
|
||||
boolean exported = false;
|
||||
|
||||
List<ABCContainerTag> abcList = getAbcList();
|
||||
@@ -1077,11 +1056,10 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (scrs.size() > 1) {
|
||||
cnt = "script " + (j + 1) + "/" + scrs.size() + " ";
|
||||
}
|
||||
String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcList.size() + " " + cnt + scr.getPath() + " ...";
|
||||
informListeners("exporting", exStr);
|
||||
String eventData = cnt + scr.getPath() + " ...";
|
||||
evl.handleExportingEvent("tag", i + 1, abcList.size(), eventData);
|
||||
scr.export(outdir, exportMode, parallel);
|
||||
exStr = "Exported " + "tag " + (i + 1) + "/" + abcList.size() + " " + cnt + scr.getPath() + " ...";
|
||||
informListeners("exported", exStr);
|
||||
evl.handleExportedEvent("tag", i + 1, abcList.size(), eventData);
|
||||
exported = true;
|
||||
}
|
||||
}
|
||||
@@ -1142,7 +1120,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
long stopTime;
|
||||
|
||||
public ExportPackTask(AbortRetryIgnoreHandler handler, AtomicInteger index, int count, ClassPath path, ScriptPack pack, String directory, ScriptExportMode exportMode, boolean parallel) {
|
||||
EventListener eventListener;
|
||||
|
||||
public ExportPackTask(AbortRetryIgnoreHandler handler, AtomicInteger index, int count, ClassPath path, ScriptPack pack, String directory, ScriptExportMode exportMode, boolean parallel, EventListener evl) {
|
||||
this.pack = pack;
|
||||
this.directory = directory;
|
||||
this.exportMode = exportMode;
|
||||
@@ -1151,6 +1131,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
this.count = count;
|
||||
this.parallel = parallel;
|
||||
this.handler = handler;
|
||||
this.eventListener = evl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1165,12 +1146,12 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
};
|
||||
int currentIndex = index.getAndIncrement();
|
||||
synchronized (ABC.class) {
|
||||
informListeners("exporting", "Exporting script " + currentIndex + "/" + count + " " + path);
|
||||
eventListener.handleExportingEvent("script", currentIndex, count, path);
|
||||
}
|
||||
new RetryTask(rio, handler).run();
|
||||
synchronized (ABC.class) {
|
||||
long time = stopTime - startTime;
|
||||
informListeners("exported", "Exported script " + currentIndex + "/" + count + " " + path + ", " + Helper.formatTimeSec(time));
|
||||
eventListener.handleExportedEvent("script", currentIndex, count, path + ", " + Helper.formatTimeSec(time));
|
||||
}
|
||||
return rio.result;
|
||||
}
|
||||
@@ -1188,7 +1169,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<File> exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel) {
|
||||
private List<File> exportActionScript3(final AbortRetryIgnoreHandler handler, final String outdir, final ScriptExportMode exportMode, final boolean parallel, final EventListener evl) {
|
||||
final AtomicInteger cnt = new AtomicInteger(1);
|
||||
|
||||
final List<File> ret = new ArrayList<>();
|
||||
@@ -1200,7 +1181,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
for (MyEntry<ClassPath, ScriptPack> item : packs) {
|
||||
ExportPackTask task = new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, exportMode, parallel);
|
||||
ExportPackTask task = new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, exportMode, parallel, evl);
|
||||
ret.add(task.call());
|
||||
}
|
||||
return null;
|
||||
@@ -1215,7 +1196,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(Configuration.getParallelThreadCount());
|
||||
List<Future<File>> futureResults = new ArrayList<>();
|
||||
for (MyEntry<ClassPath, ScriptPack> item : packs) {
|
||||
Future<File> future = executor.submit(new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, exportMode, parallel));
|
||||
Future<File> future = executor.submit(new ExportPackTask(handler, cnt, packs.size(), item.getKey(), item.getValue(), outdir, exportMode, parallel, evl));
|
||||
futureResults.add(future);
|
||||
}
|
||||
|
||||
@@ -1247,22 +1228,33 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
public EventListener getExportEventListener() {
|
||||
EventListener evl = new EventListener() {
|
||||
@Override
|
||||
public void handleEvent(String event, Object data) {
|
||||
if (event.equals("exporting") || event.equals("exported")) {
|
||||
informListeners(event, data);
|
||||
public void handleExportingEvent(String type, int index, int count, Object data) {
|
||||
for (EventListener listener : listeners) {
|
||||
listener.handleExportingEvent(type, index, count, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleExportedEvent(String type, int index, int count, Object data) {
|
||||
for (EventListener listener : listeners) {
|
||||
listener.handleExportedEvent(type, index, count, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(String event, Object data) {
|
||||
informListeners(event, data);
|
||||
}
|
||||
};
|
||||
|
||||
return evl;
|
||||
}
|
||||
|
||||
public List<File> exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel) throws IOException {
|
||||
public List<File> exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
final EventListener evl = getExportEventListener();
|
||||
|
||||
if (isAS3()) {
|
||||
ret.addAll(exportActionScript3(handler, outdir, exportMode, parallel));
|
||||
ret.addAll(exportActionScript3(handler, outdir, exportMode, parallel, evl));
|
||||
} else {
|
||||
ret.addAll(exportActionScript2(handler, outdir, exportMode, parallel, evl));
|
||||
}
|
||||
@@ -1486,7 +1478,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
fos.write(chunkBytes);
|
||||
}
|
||||
|
||||
private static void makeAVI(Iterator<BufferedImage> images, int frameRate, File file) throws IOException {
|
||||
public static void makeAVI(Iterator<BufferedImage> images, int frameRate, File file) throws IOException {
|
||||
if (!images.hasNext()) {
|
||||
return;
|
||||
}
|
||||
@@ -1504,7 +1496,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
}
|
||||
|
||||
private static void makeGIF(Iterator<BufferedImage> images, int frameRate, File file) throws IOException {
|
||||
public static void makeGIF(Iterator<BufferedImage> images, int frameRate, File file) throws IOException {
|
||||
if (!images.hasNext()) {
|
||||
return;
|
||||
}
|
||||
@@ -1521,7 +1513,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTypePrefix(CharacterTag c) {
|
||||
public static String getTypePrefix(CharacterTag c) {
|
||||
if (c instanceof ShapeTag) {
|
||||
return "shape";
|
||||
}
|
||||
@@ -1579,290 +1571,6 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
public List<File> exportFrames(AbortRetryIgnoreHandler handler, String outdir, int containerId, List<Integer> frames, final FramesExportSettings settings) throws IOException {
|
||||
final List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
Timeline tim = null;
|
||||
String path = "";
|
||||
if (containerId == 0) {
|
||||
tim = getTimeline();
|
||||
} else {
|
||||
tim = ((Timelined) getCharacter(containerId)).getTimeline();
|
||||
path = File.separator + Helper.makeFileName(getCharacter(containerId).getExportFileName());
|
||||
}
|
||||
if (frames == null) {
|
||||
int frameCnt = tim.getFrameCount();
|
||||
frames = new ArrayList<>();
|
||||
for (int i = 0; i < frameCnt; i++) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
final File foutdir = new File(outdir + path);
|
||||
if (!foutdir.exists()) {
|
||||
if (!foutdir.mkdirs()) {
|
||||
if (!foutdir.exists()) {
|
||||
throw new IOException("Cannot create directory " + outdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<Integer> fframes = frames;
|
||||
|
||||
Color backgroundColor = null;
|
||||
if (settings.mode == FramesExportMode.AVI) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sb = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sb.backgroundColor.toColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.mode == FramesExportMode.SVG) {
|
||||
for (int i = 0; i < frames.size(); i++) {
|
||||
final int fi = i;
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
int frame = fframes.get(fi);
|
||||
File f = new File(foutdir + File.separator + frame + ".svg");
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
ExportRectangle rect = new ExportRectangle(ftim.displayRect);
|
||||
rect.xMax *= settings.zoom;
|
||||
rect.yMax *= settings.zoom;
|
||||
rect.xMin *= settings.zoom;
|
||||
rect.yMin *= settings.zoom;
|
||||
SVGExporter exporter = new SVGExporter(rect);
|
||||
if (fbackgroundColor != null) {
|
||||
exporter.setBackGroundColor(fbackgroundColor);
|
||||
}
|
||||
frameToSvg(ftim, frame, 0, null, 0, exporter, new ColorTransform(), 0, settings.zoom);
|
||||
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (settings.mode == FramesExportMode.CANVAS) {
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final SWF fswf = this;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File fcanvas = new File(foutdir + File.separator + "canvas.js");
|
||||
Helper.saveStream(SWF.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/canvas.js"), fcanvas);
|
||||
ret.add(fcanvas);
|
||||
|
||||
File f = new File(foutdir + File.separator + "frames.js");
|
||||
File fmin = new File(foutdir + File.separator + "frames.min.js");
|
||||
int width = (int) (ftim.displayRect.getWidth() * settings.zoom / SWF.unitDivisor);
|
||||
int height = (int) (ftim.displayRect.getHeight() * settings.zoom / SWF.unitDivisor);
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
fos.write(Utf8Helper.getBytes("\r\n"));
|
||||
Set<Integer> library = new HashSet<>();
|
||||
ftim.getNeededCharacters(fframes, library);
|
||||
|
||||
writeLibrary(fswf, library, fos);
|
||||
|
||||
String currentName = ftim.id == 0 ? "main" : getTypePrefix(fswf.getCharacter(ftim.id)) + ftim.id;
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function " + currentName + "(ctx,ctrans,frame,ratio,time){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.save();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.transform(1,0,0,1," + (-ftim.displayRect.Xmin * settings.zoom / unitDivisor) + "," + (-ftim.displayRect.Ymin * settings.zoom / unitDivisor) + ");\r\n"));
|
||||
fos.write(Utf8Helper.getBytes(framesToHtmlCanvas(unitDivisor / settings.zoom, ftim, fframes, 0, null, 0, ftim.displayRect, new ColorTransform(), fbackgroundColor)));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.restore();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
fos.write(Utf8Helper.getBytes("var frame = -1;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var time = 0;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var frames = [];\r\n"));
|
||||
for (int i : fframes) {
|
||||
fos.write(Utf8Helper.getBytes("frames.push(" + i + ");\r\n"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes("\r\n"));
|
||||
RGB backgroundColor = new RGB(255, 255, 255);
|
||||
for (Tag t : fswf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sb = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sb.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
fos.write(Utf8Helper.getBytes("var backgroundColor = \"" + backgroundColor.toHexRGB() + "\";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var originalWidth = " + width + ";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var originalHeight= " + height + ";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("function nextFrame(ctx,ctrans){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tvar oldframe = frame;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tframe = (frame+1)%frames.length;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tif(frame==oldframe){time++;}else{time=0;};\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tdrawFrame();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function drawFrame(){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.fillStyle = backgroundColor;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.fillRect(0,0,canvas.width,canvas.height);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.save();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.transform(canvas.width/originalWidth,0,0,canvas.height/originalHeight,0,0);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\t" + currentName + "(ctx,ctrans,frames[frame],0,time);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.restore();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
if (ftim.swf.frameRate > 0) {
|
||||
fos.write(Utf8Helper.getBytes("window.setInterval(function(){nextFrame(ctx,ctrans);}," + (int) (1000.0 / ftim.swf.frameRate) + ");\r\n"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes("nextFrame(ctx,ctrans);\r\n"));
|
||||
}
|
||||
|
||||
boolean packed = false;
|
||||
if (Configuration.packJavaScripts.get()) {
|
||||
try {
|
||||
JPacker.main(new String[]{"-q", "-b", "62", "-o", fmin.getAbsolutePath(), f.getAbsolutePath()});
|
||||
f.delete();
|
||||
packed = true;
|
||||
} catch (Exception | Error e) { // Something wrong in the packer
|
||||
logger.log(Level.WARNING, "JPacker: Cannot minimize script");
|
||||
f.renameTo(fmin);
|
||||
}
|
||||
} else {
|
||||
f.renameTo(fmin);
|
||||
}
|
||||
|
||||
File fh = new File(foutdir + File.separator + "frames.html");
|
||||
try (FileOutputStream fos = new FileOutputStream(fh); FileInputStream fis = new FileInputStream(fmin)) {
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlPrefix(width, height)));
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getJsPrefix()));
|
||||
byte buf[] = new byte[1000];
|
||||
int cnt;
|
||||
while ((cnt = fis.read(buf)) > 0) {
|
||||
fos.write(buf, 0, cnt);
|
||||
}
|
||||
if (packed) {
|
||||
fos.write(Utf8Helper.getBytes(";"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getJsSuffix()));
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlSuffix()));
|
||||
}
|
||||
fmin.delete();
|
||||
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final Iterator<BufferedImage> frameImages = new Iterator<BufferedImage>() {
|
||||
|
||||
private int pos = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return fframes.size() > pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage next() {
|
||||
if (!hasNext()) {
|
||||
return null;
|
||||
}
|
||||
return frameToImageGet(ftim, fframes.get(pos++), 0, null, 0, ftim.displayRect, new Matrix(), new ColorTransform(), fbackgroundColor, false, settings.zoom).getBufferedImage();
|
||||
}
|
||||
};
|
||||
|
||||
switch (settings.mode) {
|
||||
case GIF:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.gif");
|
||||
makeGIF(frameImages, frameRate, f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
case BMP:
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
final int fi = i;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".bmp");
|
||||
BMPFile.saveBitmap(frameImages.next(), f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
}
|
||||
break;
|
||||
case PNG:
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
final int fi = i;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".png");
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
ImageHelper.write(frameImages.next(), "PNG", fos);
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
}
|
||||
break;
|
||||
case PDF:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.pdf");
|
||||
PDFJob job = new PDFJob(new FileOutputStream(f));
|
||||
PageFormat pf = new PageFormat();
|
||||
pf.setOrientation(PageFormat.PORTRAIT);
|
||||
Paper p = new Paper();
|
||||
BufferedImage img0 = frameImages.next();
|
||||
p.setSize(img0.getWidth() + 10, img0.getHeight() + 10);
|
||||
pf.setPaper(p);
|
||||
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
BufferedImage img = frameImages.next();
|
||||
Graphics g = job.getGraphics(pf);
|
||||
g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
job.end();
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
case AVI:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.avi");
|
||||
makeAVI(frameImages, frameRate, f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void getVariables(ConstantPool constantPool, BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, ActionGraphSource code, int ip, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, List<Integer> visited, HashMap<DirectValueActionItem, String> usageTypes, String path) throws InterruptedException {
|
||||
boolean debugMode = false;
|
||||
while ((ip > -1) && ip < code.size()) {
|
||||
@@ -2509,239 +2217,6 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String jsArrColor(RGB rgb) {
|
||||
return "[" + rgb.red + "," + rgb.green + "," + rgb.blue + "," + ((rgb instanceof RGBA) ? ((RGBA) rgb).getAlphaFloat() : 1) + "]";
|
||||
}
|
||||
|
||||
public static String framesToHtmlCanvas(double unitDivisor, Timeline timeline, List<Integer> frames, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, ColorTransform colorTransform, Color backGroundColor) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (frames == null) {
|
||||
frames = new ArrayList<>();
|
||||
for (int i = 0; i < timeline.getFrameCount(); i++) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
sb.append("\tvar clips = [];\r\n");
|
||||
sb.append("\tvar frame_cnt = ").append(timeline.getFrameCount()).append(";\r\n");
|
||||
sb.append("\tframe = frame % frame_cnt;\r\n");
|
||||
sb.append("\tswitch(frame){\r\n");
|
||||
int maxDepth = timeline.getMaxDepth();
|
||||
Stack<Integer> clipDepths = new Stack<>();
|
||||
for (int frame : frames) {
|
||||
sb.append("\t\tcase ").append(frame).append(":\r\n");
|
||||
Frame frameObj = timeline.getFrame(frame);
|
||||
for (int i = 1; i <= maxDepth + 1; i++) {
|
||||
while (!clipDepths.isEmpty() && clipDepths.peek() <= i) {
|
||||
clipDepths.pop();
|
||||
sb.append("\t\t\tvar o = clips.pop();\r\n");
|
||||
sb.append("\t\t\tctx.globalCompositeOperation = \"destination-in\";\r\n");
|
||||
sb.append("\t\t\tctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.drawImage(o.clipCanvas,0,0);\r\n");
|
||||
sb.append("\t\t\tvar ms=o.ctx._matrix;\r\n");
|
||||
sb.append("\t\t\to.ctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\to.ctx.globalCompositeOperation = \"source-over\";\r\n");
|
||||
sb.append("\t\t\to.ctx.drawImage(canvas,0,0);\r\n");
|
||||
sb.append("\t\t\to.ctx.applyTransforms(ms);\r\n");
|
||||
sb.append("\t\t\tctx = o.ctx;\r\n");
|
||||
sb.append("\t\t\tcanvas = o.canvas;\r\n");
|
||||
}
|
||||
if (!frameObj.layers.containsKey(i)) {
|
||||
continue;
|
||||
}
|
||||
DepthState layer = frameObj.layers.get(i);
|
||||
if (!timeline.swf.getCharacters().containsKey(layer.characterId)) {
|
||||
continue;
|
||||
}
|
||||
if (!layer.isVisible) {
|
||||
continue;
|
||||
}
|
||||
CharacterTag character = timeline.swf.getCharacter(layer.characterId);
|
||||
|
||||
if (colorTransform == null) {
|
||||
colorTransform = new ColorTransform();
|
||||
}
|
||||
Matrix placeMatrix = new Matrix(layer.matrix);
|
||||
placeMatrix.scaleX /= unitDivisor;
|
||||
placeMatrix.scaleY /= unitDivisor;
|
||||
placeMatrix.rotateSkew0 /= unitDivisor;
|
||||
placeMatrix.rotateSkew1 /= unitDivisor;
|
||||
placeMatrix.translateX /= unitDivisor;
|
||||
placeMatrix.translateY /= unitDivisor;
|
||||
|
||||
int f = 0;
|
||||
String fstr = "0";
|
||||
if (character instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sp = (DefineSpriteTag) character;
|
||||
Timeline tim = sp.getTimeline();
|
||||
if (tim.getFrameCount() > 0) {
|
||||
f = layer.time % tim.getFrameCount();
|
||||
fstr = "(" + f + "+time)%" + tim.getFrameCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.clipDepth != -1) {
|
||||
clipDepths.push(layer.clipDepth);
|
||||
sb.append("\t\t\tclips.push({ctx:ctx,canvas:canvas});\r\n");
|
||||
sb.append("\t\t\tvar ccanvas = createCanvas(canvas.width,canvas.height);\r\n");
|
||||
sb.append("\t\t\tvar cctx = ccanvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(cctx);\r\n");
|
||||
sb.append("\t\t\tcctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tcanvas = ccanvas;\r\n");
|
||||
sb.append("\t\t\tctx = cctx;\r\n");
|
||||
}
|
||||
|
||||
if (layer.filters != null && layer.filters.size() > 0) {
|
||||
sb.append("\t\t\tvar oldctx = ctx;\r\n");
|
||||
sb.append("\t\t\tvar fcanvas = createCanvas(canvas.width,canvas.height);");
|
||||
sb.append("\t\t\tvar fctx = fcanvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(fctx);\r\n");
|
||||
sb.append("\t\t\tfctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tctx = fctx;\r\n");
|
||||
}
|
||||
|
||||
ColorTransform ctrans = layer.colorTransForm;
|
||||
String ctrans_str = "ctrans";
|
||||
if (ctrans == null) {
|
||||
ctrans = new ColorTransform();
|
||||
} else {
|
||||
ctrans_str = "ctrans.merge(new cxform("
|
||||
+ ctrans.getRedAdd() + "," + ctrans.getGreenAdd() + "," + ctrans.getBlueAdd() + "," + ctrans.getAlphaAdd() + ","
|
||||
+ ctrans.getRedMulti() + "," + ctrans.getGreenMulti() + "," + ctrans.getBlueMulti() + "," + ctrans.getAlphaMulti()
|
||||
+ "))";
|
||||
}
|
||||
sb.append("\t\t\tplace(\"").append(getTypePrefix(character)).append(layer.characterId).append("\",canvas,ctx,[").append(placeMatrix.scaleX).append(",")
|
||||
.append(placeMatrix.rotateSkew0).append(",")
|
||||
.append(placeMatrix.rotateSkew1).append(",")
|
||||
.append(placeMatrix.scaleY).append(",")
|
||||
.append(placeMatrix.translateX).append(",")
|
||||
.append(placeMatrix.translateY).append("],").append(ctrans_str).append(",").append("").append(layer.blendMode < 1 ? 1 : layer.blendMode).append(",").append(fstr).append(",").append(layer.ratio < 0 ? 0 : layer.ratio).append(",time").append(");\r\n");
|
||||
|
||||
if (layer.filters != null && layer.filters.size() > 0) {
|
||||
for (FILTER filter : layer.filters) {
|
||||
if (filter instanceof COLORMATRIXFILTER) {
|
||||
COLORMATRIXFILTER cmf = (COLORMATRIXFILTER) filter;
|
||||
String mat = "[";
|
||||
for (int k = 0; k < cmf.matrix.length; k++) {
|
||||
if (k > 0) {
|
||||
mat += ",";
|
||||
}
|
||||
mat += cmf.matrix[k];
|
||||
}
|
||||
mat += "]";
|
||||
sb.append("\t\t\tfcanvas = Filters.colorMatrix(fcanvas,fcanvas.getContext(\"2d\"),").append(mat).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof CONVOLUTIONFILTER) {
|
||||
CONVOLUTIONFILTER cf = (CONVOLUTIONFILTER) filter;
|
||||
int height = cf.matrix.length;
|
||||
int width = cf.matrix[0].length;
|
||||
float[] matrix2 = new float[width * height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
matrix2[y * width + x] = cf.matrix[x][y] * cf.divisor + cf.bias;
|
||||
}
|
||||
}
|
||||
String mat = "[";
|
||||
for (int k = 0; k < matrix2.length; k++) {
|
||||
if (k > 0) {
|
||||
mat += ",";
|
||||
}
|
||||
mat += matrix2[k];
|
||||
}
|
||||
mat += "]";
|
||||
sb.append("\t\t\tfcanvas = Filters.convolution(fcanvas,fcanvas.getContext(\"2d\"),").append(mat).append(",false);\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GLOWFILTER) {
|
||||
GLOWFILTER gf = (GLOWFILTER) filter;
|
||||
sb.append("\t\t\tfcanvas = Filters.glow(fcanvas,fcanvas.getContext(\"2d\"),").append(gf.blurX).append(",").append(gf.blurY).append(",").append(gf.strength).append(",").append(jsArrColor(gf.glowColor)).append(",").append(gf.innerGlow ? "true" : "false").append(",").append(gf.knockout ? "true" : "false").append(",").append(gf.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof DROPSHADOWFILTER) {
|
||||
DROPSHADOWFILTER ds = (DROPSHADOWFILTER) filter;
|
||||
sb.append("\t\t\tfcanvas = Filters.dropShadow(fcanvas,fcanvas.getContext(\"2d\"),").append(ds.blurX).append(",").append(ds.blurY).append(",").append((int) (ds.angle * 180 / Math.PI)).append(",").append(ds.distance).append(",").append(jsArrColor(ds.dropShadowColor)).append(",").append(ds.innerShadow ? "true" : "false").append(",").append(ds.passes).append(",").append(ds.strength).append(",").append(ds.knockout ? "true" : "false").append(");\r\n");
|
||||
}
|
||||
if (filter instanceof BEVELFILTER) {
|
||||
BEVELFILTER bv = (BEVELFILTER) filter;
|
||||
String type = "Filters.INNER";
|
||||
if (bv.onTop && !bv.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!bv.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
sb.append("\t\t\tfcanvas = Filters.bevel(fcanvas,fcanvas.getContext(\"2d\"),").append(bv.blurX).append(",").append(bv.blurY).append(",").append(bv.strength).append(",").append(type).append(",").append(jsArrColor(bv.highlightColor)).append(",").append(jsArrColor(bv.shadowColor)).append(",").append((int) (bv.angle * 180 / Math.PI)).append(",").append(bv.distance).append(",").append(bv.knockout ? "true" : "false").append(",").append(bv.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GRADIENTBEVELFILTER) {
|
||||
GRADIENTBEVELFILTER gbf = (GRADIENTBEVELFILTER) filter;
|
||||
String colArr = "[";
|
||||
String ratArr = "[";
|
||||
for (int k = 0; k < gbf.gradientColors.length; k++) {
|
||||
if (k > 0) {
|
||||
colArr += ",";
|
||||
ratArr += ",";
|
||||
}
|
||||
colArr += jsArrColor(gbf.gradientColors[k]);
|
||||
ratArr += gbf.gradientRatio[k] / 255f;
|
||||
}
|
||||
colArr += "]";
|
||||
ratArr += "]";
|
||||
String type = "Filters.INNER";
|
||||
if (gbf.onTop && !gbf.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!gbf.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
|
||||
sb.append("\t\t\tfcanvas = Filters.gradientBevel(fcanvas,fcanvas.getContext(\"2d\"),").append(colArr).append(",").append(ratArr).append(",").append(gbf.blurX).append(",").append(gbf.blurY).append(",").append(gbf.strength).append(",").append(type).append(",").append((int) (gbf.angle * 180 / Math.PI)).append(",").append(gbf.distance).append(",").append(gbf.knockout ? "true" : "false").append(",").append(gbf.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GRADIENTGLOWFILTER) {
|
||||
GRADIENTGLOWFILTER ggf = (GRADIENTGLOWFILTER) filter;
|
||||
String colArr = "[";
|
||||
String ratArr = "[";
|
||||
for (int k = 0; k < ggf.gradientColors.length; k++) {
|
||||
if (k > 0) {
|
||||
colArr += ",";
|
||||
ratArr += ",";
|
||||
}
|
||||
colArr += jsArrColor(ggf.gradientColors[k]);
|
||||
ratArr += ggf.gradientRatio[k] / 255f;
|
||||
}
|
||||
colArr += "]";
|
||||
ratArr += "]";
|
||||
String type = "Filters.INNER";
|
||||
if (ggf.onTop && !ggf.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!ggf.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
|
||||
sb.append("\t\t\tfcanvas = Filters.gradientGlow(fcanvas,fcanvas.getContext(\"2d\"),").append(ggf.blurX).append(",").append(ggf.blurY).append(",").append((int) (ggf.angle * 180 / Math.PI)).append(",").append(ggf.distance).append(",").append(colArr).append(",").append(ratArr).append(",").append(type).append(",").append(ggf.passes).append(",").append(ggf.strength).append(",").append(ggf.knockout ? "true" : "false").append(");\r\n");
|
||||
}
|
||||
}
|
||||
sb.append("\t\t\tctx = oldctx;\r\n");
|
||||
sb.append("\t\t\tvar ms=ctx._matrix;\r\n");
|
||||
sb.append("\t\t\tctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.drawImage(fcanvas,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.applyTransforms(ms);\r\n");
|
||||
}
|
||||
|
||||
if (layer.clipDepth != -1) {
|
||||
sb.append("\t\t\tclips[clips.length-1].clipCanvas = canvas;\r\n");
|
||||
sb.append("\t\t\tcanvas = createCanvas(canvas.width,canvas.height);\r\n");
|
||||
sb.append("\t\t\tvar nctx = canvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(nctx);\r\n");
|
||||
sb.append("\t\t\tnctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tctx = nctx;\r\n");
|
||||
}
|
||||
}
|
||||
sb.append("\t\t\tbreak;\r\n");
|
||||
}
|
||||
sb.append("\t}\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void frameToSvg(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, SVGExporter exporter, ColorTransform colorTransform, int level, double zoom) throws IOException {
|
||||
if (timeline.getFrameCount() <= frame) {
|
||||
return;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
|
||||
@@ -34,7 +35,7 @@ import java.util.List;
|
||||
*/
|
||||
public class BinaryDataExporter {
|
||||
|
||||
public List<File> exportBinaryData(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, BinaryDataExportSettings settings) throws IOException {
|
||||
public List<File> exportBinaryData(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, BinaryDataExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -48,9 +49,22 @@ public class BinaryDataExporter {
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DefineBinaryDataTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (final Tag t : tags) {
|
||||
if (t instanceof DefineBinaryDataTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("binarydata", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
int characterID = ((DefineBinaryDataTag) t).getCharacterId();
|
||||
|
||||
final File file = new File(outdir + File.separator + characterID + ".bin");
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
@@ -61,8 +75,15 @@ public class BinaryDataExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("binarydata", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.google.typography.font.sfntly.data.WritableFontData;
|
||||
import com.google.typography.font.tools.conversion.woff.WoffWriter;
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.ApplicationInfo;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
|
||||
@@ -51,7 +52,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class FontExporter {
|
||||
|
||||
public List<File> exportFonts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final FontExportSettings settings) throws IOException {
|
||||
public List<File> exportFonts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final FontExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -64,16 +65,27 @@ public class FontExporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
File newfile = null;
|
||||
if (t instanceof FontTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("font", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final FontTag st = (FontTag) t;
|
||||
String ext = ".ttf";
|
||||
if (settings.mode == FontExportMode.WOFF) {
|
||||
ext = ".woff";
|
||||
}
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName() + ext));
|
||||
newfile = file;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
@@ -81,11 +93,16 @@ public class FontExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
ret.add(newfile);
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("font", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -120,7 +137,12 @@ public class FontExporter {
|
||||
ttfFile = File.createTempFile("ffdec_export", ".ttf");
|
||||
}
|
||||
|
||||
Fontastic f = new Fontastic(t.getFontNameIntag(), ttfFile);
|
||||
String fontName = t.getFontNameIntag();
|
||||
if (fontName.length() == 0) {
|
||||
fontName = "noname";
|
||||
}
|
||||
|
||||
Fontastic f = new Fontastic(fontName, ttfFile);
|
||||
String cop = t.getCopyright();
|
||||
|
||||
f.getEngine().setCopyrightYear(cop == null ? "" : cop);
|
||||
|
||||
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* 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.exporters;
|
||||
|
||||
import com.jpacker.JPacker;
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.FramesExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
|
||||
import com.jpexs.decompiler.flash.helpers.BMPFile;
|
||||
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.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.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.filters.BEVELFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.COLORMATRIXFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.CONVOLUTIONFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.DROPSHADOWFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GLOWFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER;
|
||||
import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import gnu.jpdf.PDFJob;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.print.PageFormat;
|
||||
import java.awt.print.Paper;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FrameExporter {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FrameExporter.class.getName());
|
||||
|
||||
public List<File> exportFrames(AbortRetryIgnoreHandler handler, String outdir, final SWF swf, int containerId, List<Integer> frames, final FramesExportSettings settings, final EventListener evl) throws IOException {
|
||||
final List<File> ret = new ArrayList<>();
|
||||
if (swf.tags.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
Timeline tim0;
|
||||
String path = "";
|
||||
if (containerId == 0) {
|
||||
tim0 = swf.getTimeline();
|
||||
} else {
|
||||
tim0 = ((Timelined) swf.getCharacter(containerId)).getTimeline();
|
||||
path = File.separator + Helper.makeFileName(swf.getCharacter(containerId).getExportFileName());
|
||||
}
|
||||
|
||||
final Timeline tim = tim0;
|
||||
|
||||
if (frames == null) {
|
||||
int frameCnt = tim.getFrameCount();
|
||||
frames = new ArrayList<>();
|
||||
for (int i = 0; i < frameCnt; i++) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
final File foutdir = new File(outdir + path);
|
||||
if (!foutdir.exists()) {
|
||||
if (!foutdir.mkdirs()) {
|
||||
if (!foutdir.exists()) {
|
||||
throw new IOException("Cannot create directory " + outdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<Integer> fframes = frames;
|
||||
|
||||
Color backgroundColor = null;
|
||||
if (settings.mode == FramesExportMode.AVI) {
|
||||
for (Tag t : swf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sb = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sb.backgroundColor.toColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.mode == FramesExportMode.SVG) {
|
||||
for (int i = 0; i < frames.size(); i++) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("frame", i, frames.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
|
||||
final int fi = i;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
int frame = fframes.get(fi);
|
||||
File f = new File(foutdir + File.separator + frame + ".svg");
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
ExportRectangle rect = new ExportRectangle(tim.displayRect);
|
||||
rect.xMax *= settings.zoom;
|
||||
rect.yMax *= settings.zoom;
|
||||
rect.xMin *= settings.zoom;
|
||||
rect.yMin *= settings.zoom;
|
||||
SVGExporter exporter = new SVGExporter(rect);
|
||||
if (fbackgroundColor != null) {
|
||||
exporter.setBackGroundColor(fbackgroundColor);
|
||||
}
|
||||
SWF.frameToSvg(tim, frame, 0, null, 0, exporter, new ColorTransform(), 0, settings.zoom);
|
||||
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("frame", i, frames.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (settings.mode == FramesExportMode.CANVAS) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("canvas", 1, 1, tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final SWF fswf = swf;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File fcanvas = new File(foutdir + File.separator + "canvas.js");
|
||||
Helper.saveStream(SWF.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/canvas.js"), fcanvas);
|
||||
ret.add(fcanvas);
|
||||
|
||||
File f = new File(foutdir + File.separator + "frames.js");
|
||||
File fmin = new File(foutdir + File.separator + "frames.min.js");
|
||||
int width = (int) (ftim.displayRect.getWidth() * settings.zoom / SWF.unitDivisor);
|
||||
int height = (int) (ftim.displayRect.getHeight() * settings.zoom / SWF.unitDivisor);
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
fos.write(Utf8Helper.getBytes("\r\n"));
|
||||
Set<Integer> library = new HashSet<>();
|
||||
ftim.getNeededCharacters(fframes, library);
|
||||
|
||||
SWF.writeLibrary(fswf, library, fos);
|
||||
|
||||
String currentName = ftim.id == 0 ? "main" : SWF.getTypePrefix(fswf.getCharacter(ftim.id)) + ftim.id;
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function " + currentName + "(ctx,ctrans,frame,ratio,time){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.save();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.transform(1,0,0,1," + (-ftim.displayRect.Xmin * settings.zoom / SWF.unitDivisor) + "," + (-ftim.displayRect.Ymin * settings.zoom / SWF.unitDivisor) + ");\r\n"));
|
||||
fos.write(Utf8Helper.getBytes(framesToHtmlCanvas(SWF.unitDivisor / settings.zoom, ftim, fframes, 0, null, 0, ftim.displayRect, new ColorTransform(), fbackgroundColor)));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.restore();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
fos.write(Utf8Helper.getBytes("var frame = -1;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var time = 0;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var frames = [];\r\n"));
|
||||
for (int i : fframes) {
|
||||
fos.write(Utf8Helper.getBytes("frames.push(" + i + ");\r\n"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes("\r\n"));
|
||||
RGB backgroundColor = new RGB(255, 255, 255);
|
||||
for (Tag t : fswf.tags) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
SetBackgroundColorTag sb = (SetBackgroundColorTag) t;
|
||||
backgroundColor = sb.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
fos.write(Utf8Helper.getBytes("var backgroundColor = \"" + backgroundColor.toHexRGB() + "\";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var originalWidth = " + width + ";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("var originalHeight= " + height + ";\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("function nextFrame(ctx,ctrans){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tvar oldframe = frame;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tframe = (frame+1)%frames.length;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tif(frame==oldframe){time++;}else{time=0;};\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tdrawFrame();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
|
||||
fos.write(Utf8Helper.getBytes("function drawFrame(){\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.fillStyle = backgroundColor;\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.fillRect(0,0,canvas.width,canvas.height);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.save();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.transform(canvas.width/originalWidth,0,0,canvas.height/originalHeight,0,0);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\t" + currentName + "(ctx,ctrans,frames[frame],0,time);\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("\tctx.restore();\r\n"));
|
||||
fos.write(Utf8Helper.getBytes("}\r\n\r\n"));
|
||||
if (ftim.swf.frameRate > 0) {
|
||||
fos.write(Utf8Helper.getBytes("window.setInterval(function(){nextFrame(ctx,ctrans);}," + (int) (1000.0 / ftim.swf.frameRate) + ");\r\n"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes("nextFrame(ctx,ctrans);\r\n"));
|
||||
}
|
||||
|
||||
boolean packed = false;
|
||||
if (Configuration.packJavaScripts.get()) {
|
||||
try {
|
||||
JPacker.main(new String[]{"-q", "-b", "62", "-o", fmin.getAbsolutePath(), f.getAbsolutePath()});
|
||||
f.delete();
|
||||
packed = true;
|
||||
} catch (Exception | Error e) { // Something wrong in the packer
|
||||
logger.log(Level.WARNING, "JPacker: Cannot minimize script");
|
||||
f.renameTo(fmin);
|
||||
}
|
||||
} else {
|
||||
f.renameTo(fmin);
|
||||
}
|
||||
|
||||
File fh = new File(foutdir + File.separator + "frames.html");
|
||||
try (FileOutputStream fos = new FileOutputStream(fh); FileInputStream fis = new FileInputStream(fmin)) {
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlPrefix(width, height)));
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getJsPrefix()));
|
||||
byte buf[] = new byte[1000];
|
||||
int cnt;
|
||||
while ((cnt = fis.read(buf)) > 0) {
|
||||
fos.write(buf, 0, cnt);
|
||||
}
|
||||
if (packed) {
|
||||
fos.write(Utf8Helper.getBytes(";"));
|
||||
}
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getJsSuffix()));
|
||||
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlSuffix()));
|
||||
}
|
||||
fmin.delete();
|
||||
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("canvas", 1, 1, tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
final Timeline ftim = tim;
|
||||
final Color fbackgroundColor = backgroundColor;
|
||||
final Iterator<BufferedImage> frameImages = new Iterator<BufferedImage>() {
|
||||
|
||||
private int pos = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return fframes.size() > pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage next() {
|
||||
if (!hasNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
return SWF.frameToImageGet(ftim, fframes.get(pos++), 0, null, 0, ftim.displayRect, new Matrix(), new ColorTransform(), fbackgroundColor, false, settings.zoom).getBufferedImage();
|
||||
}
|
||||
};
|
||||
|
||||
switch (settings.mode) {
|
||||
case GIF:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.gif");
|
||||
SWF.makeGIF(frameImages, swf.frameRate, f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
case BMP:
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
final int fi = i;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".bmp");
|
||||
BMPFile.saveBitmap(frameImages.next(), f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
}
|
||||
break;
|
||||
case PNG:
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
final int fi = i;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".png");
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
ImageHelper.write(frameImages.next(), "PNG", fos);
|
||||
}
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
}
|
||||
break;
|
||||
case PDF:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.pdf");
|
||||
PDFJob job = new PDFJob(new FileOutputStream(f));
|
||||
PageFormat pf = new PageFormat();
|
||||
pf.setOrientation(PageFormat.PORTRAIT);
|
||||
Paper p = new Paper();
|
||||
BufferedImage img0 = frameImages.next();
|
||||
p.setSize(img0.getWidth() + 10, img0.getHeight() + 10);
|
||||
pf.setPaper(p);
|
||||
|
||||
for (int i = 0; frameImages.hasNext(); i++) {
|
||||
BufferedImage img = frameImages.next();
|
||||
Graphics g = job.getGraphics(pf);
|
||||
g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
job.end();
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
case AVI:
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
File f = new File(foutdir + File.separator + "frames.avi");
|
||||
SWF.makeAVI(frameImages, swf.frameRate, f);
|
||||
ret.add(f);
|
||||
}
|
||||
}, handler).run();
|
||||
break;
|
||||
}
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("frame", fframes.size(), fframes.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String jsArrColor(RGB rgb) {
|
||||
return "[" + rgb.red + "," + rgb.green + "," + rgb.blue + "," + ((rgb instanceof RGBA) ? ((RGBA) rgb).getAlphaFloat() : 1) + "]";
|
||||
}
|
||||
|
||||
public static String framesToHtmlCanvas(double unitDivisor, Timeline timeline, List<Integer> frames, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, ColorTransform colorTransform, Color backGroundColor) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (frames == null) {
|
||||
frames = new ArrayList<>();
|
||||
for (int i = 0; i < timeline.getFrameCount(); i++) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
sb.append("\tvar clips = [];\r\n");
|
||||
sb.append("\tvar frame_cnt = ").append(timeline.getFrameCount()).append(";\r\n");
|
||||
sb.append("\tframe = frame % frame_cnt;\r\n");
|
||||
sb.append("\tswitch(frame){\r\n");
|
||||
int maxDepth = timeline.getMaxDepth();
|
||||
Stack<Integer> clipDepths = new Stack<>();
|
||||
for (int frame : frames) {
|
||||
sb.append("\t\tcase ").append(frame).append(":\r\n");
|
||||
Frame frameObj = timeline.getFrame(frame);
|
||||
for (int i = 1; i <= maxDepth + 1; i++) {
|
||||
while (!clipDepths.isEmpty() && clipDepths.peek() <= i) {
|
||||
clipDepths.pop();
|
||||
sb.append("\t\t\tvar o = clips.pop();\r\n");
|
||||
sb.append("\t\t\tctx.globalCompositeOperation = \"destination-in\";\r\n");
|
||||
sb.append("\t\t\tctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.drawImage(o.clipCanvas,0,0);\r\n");
|
||||
sb.append("\t\t\tvar ms=o.ctx._matrix;\r\n");
|
||||
sb.append("\t\t\to.ctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\to.ctx.globalCompositeOperation = \"source-over\";\r\n");
|
||||
sb.append("\t\t\to.ctx.drawImage(canvas,0,0);\r\n");
|
||||
sb.append("\t\t\to.ctx.applyTransforms(ms);\r\n");
|
||||
sb.append("\t\t\tctx = o.ctx;\r\n");
|
||||
sb.append("\t\t\tcanvas = o.canvas;\r\n");
|
||||
}
|
||||
if (!frameObj.layers.containsKey(i)) {
|
||||
continue;
|
||||
}
|
||||
DepthState layer = frameObj.layers.get(i);
|
||||
if (!timeline.swf.getCharacters().containsKey(layer.characterId)) {
|
||||
continue;
|
||||
}
|
||||
if (!layer.isVisible) {
|
||||
continue;
|
||||
}
|
||||
CharacterTag character = timeline.swf.getCharacter(layer.characterId);
|
||||
|
||||
if (colorTransform == null) {
|
||||
colorTransform = new ColorTransform();
|
||||
}
|
||||
Matrix placeMatrix = new Matrix(layer.matrix);
|
||||
placeMatrix.scaleX /= unitDivisor;
|
||||
placeMatrix.scaleY /= unitDivisor;
|
||||
placeMatrix.rotateSkew0 /= unitDivisor;
|
||||
placeMatrix.rotateSkew1 /= unitDivisor;
|
||||
placeMatrix.translateX /= unitDivisor;
|
||||
placeMatrix.translateY /= unitDivisor;
|
||||
|
||||
int f = 0;
|
||||
String fstr = "0";
|
||||
if (character instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sp = (DefineSpriteTag) character;
|
||||
Timeline tim = sp.getTimeline();
|
||||
if (tim.getFrameCount() > 0) {
|
||||
f = layer.time % tim.getFrameCount();
|
||||
fstr = "(" + f + "+time)%" + tim.getFrameCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.clipDepth != -1) {
|
||||
clipDepths.push(layer.clipDepth);
|
||||
sb.append("\t\t\tclips.push({ctx:ctx,canvas:canvas});\r\n");
|
||||
sb.append("\t\t\tvar ccanvas = createCanvas(canvas.width,canvas.height);\r\n");
|
||||
sb.append("\t\t\tvar cctx = ccanvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(cctx);\r\n");
|
||||
sb.append("\t\t\tcctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tcanvas = ccanvas;\r\n");
|
||||
sb.append("\t\t\tctx = cctx;\r\n");
|
||||
}
|
||||
|
||||
if (layer.filters != null && layer.filters.size() > 0) {
|
||||
sb.append("\t\t\tvar oldctx = ctx;\r\n");
|
||||
sb.append("\t\t\tvar fcanvas = createCanvas(canvas.width,canvas.height);");
|
||||
sb.append("\t\t\tvar fctx = fcanvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(fctx);\r\n");
|
||||
sb.append("\t\t\tfctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tctx = fctx;\r\n");
|
||||
}
|
||||
|
||||
ColorTransform ctrans = layer.colorTransForm;
|
||||
String ctrans_str = "ctrans";
|
||||
if (ctrans == null) {
|
||||
ctrans = new ColorTransform();
|
||||
} else {
|
||||
ctrans_str = "ctrans.merge(new cxform("
|
||||
+ ctrans.getRedAdd() + "," + ctrans.getGreenAdd() + "," + ctrans.getBlueAdd() + "," + ctrans.getAlphaAdd() + ","
|
||||
+ ctrans.getRedMulti() + "," + ctrans.getGreenMulti() + "," + ctrans.getBlueMulti() + "," + ctrans.getAlphaMulti()
|
||||
+ "))";
|
||||
}
|
||||
sb.append("\t\t\tplace(\"").append(SWF.getTypePrefix(character)).append(layer.characterId).append("\",canvas,ctx,[").append(placeMatrix.scaleX).append(",")
|
||||
.append(placeMatrix.rotateSkew0).append(",")
|
||||
.append(placeMatrix.rotateSkew1).append(",")
|
||||
.append(placeMatrix.scaleY).append(",")
|
||||
.append(placeMatrix.translateX).append(",")
|
||||
.append(placeMatrix.translateY).append("],").append(ctrans_str).append(",").append("").append(layer.blendMode < 1 ? 1 : layer.blendMode).append(",").append(fstr).append(",").append(layer.ratio < 0 ? 0 : layer.ratio).append(",time").append(");\r\n");
|
||||
|
||||
if (layer.filters != null && layer.filters.size() > 0) {
|
||||
for (FILTER filter : layer.filters) {
|
||||
if (filter instanceof COLORMATRIXFILTER) {
|
||||
COLORMATRIXFILTER cmf = (COLORMATRIXFILTER) filter;
|
||||
String mat = "[";
|
||||
for (int k = 0; k < cmf.matrix.length; k++) {
|
||||
if (k > 0) {
|
||||
mat += ",";
|
||||
}
|
||||
mat += cmf.matrix[k];
|
||||
}
|
||||
mat += "]";
|
||||
sb.append("\t\t\tfcanvas = Filters.colorMatrix(fcanvas,fcanvas.getContext(\"2d\"),").append(mat).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof CONVOLUTIONFILTER) {
|
||||
CONVOLUTIONFILTER cf = (CONVOLUTIONFILTER) filter;
|
||||
int height = cf.matrix.length;
|
||||
int width = cf.matrix[0].length;
|
||||
float[] matrix2 = new float[width * height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
matrix2[y * width + x] = cf.matrix[x][y] * cf.divisor + cf.bias;
|
||||
}
|
||||
}
|
||||
String mat = "[";
|
||||
for (int k = 0; k < matrix2.length; k++) {
|
||||
if (k > 0) {
|
||||
mat += ",";
|
||||
}
|
||||
mat += matrix2[k];
|
||||
}
|
||||
mat += "]";
|
||||
sb.append("\t\t\tfcanvas = Filters.convolution(fcanvas,fcanvas.getContext(\"2d\"),").append(mat).append(",false);\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GLOWFILTER) {
|
||||
GLOWFILTER gf = (GLOWFILTER) filter;
|
||||
sb.append("\t\t\tfcanvas = Filters.glow(fcanvas,fcanvas.getContext(\"2d\"),").append(gf.blurX).append(",").append(gf.blurY).append(",").append(gf.strength).append(",").append(jsArrColor(gf.glowColor)).append(",").append(gf.innerGlow ? "true" : "false").append(",").append(gf.knockout ? "true" : "false").append(",").append(gf.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof DROPSHADOWFILTER) {
|
||||
DROPSHADOWFILTER ds = (DROPSHADOWFILTER) filter;
|
||||
sb.append("\t\t\tfcanvas = Filters.dropShadow(fcanvas,fcanvas.getContext(\"2d\"),").append(ds.blurX).append(",").append(ds.blurY).append(",").append((int) (ds.angle * 180 / Math.PI)).append(",").append(ds.distance).append(",").append(jsArrColor(ds.dropShadowColor)).append(",").append(ds.innerShadow ? "true" : "false").append(",").append(ds.passes).append(",").append(ds.strength).append(",").append(ds.knockout ? "true" : "false").append(");\r\n");
|
||||
}
|
||||
if (filter instanceof BEVELFILTER) {
|
||||
BEVELFILTER bv = (BEVELFILTER) filter;
|
||||
String type = "Filters.INNER";
|
||||
if (bv.onTop && !bv.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!bv.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
sb.append("\t\t\tfcanvas = Filters.bevel(fcanvas,fcanvas.getContext(\"2d\"),").append(bv.blurX).append(",").append(bv.blurY).append(",").append(bv.strength).append(",").append(type).append(",").append(jsArrColor(bv.highlightColor)).append(",").append(jsArrColor(bv.shadowColor)).append(",").append((int) (bv.angle * 180 / Math.PI)).append(",").append(bv.distance).append(",").append(bv.knockout ? "true" : "false").append(",").append(bv.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GRADIENTBEVELFILTER) {
|
||||
GRADIENTBEVELFILTER gbf = (GRADIENTBEVELFILTER) filter;
|
||||
String colArr = "[";
|
||||
String ratArr = "[";
|
||||
for (int k = 0; k < gbf.gradientColors.length; k++) {
|
||||
if (k > 0) {
|
||||
colArr += ",";
|
||||
ratArr += ",";
|
||||
}
|
||||
colArr += jsArrColor(gbf.gradientColors[k]);
|
||||
ratArr += gbf.gradientRatio[k] / 255f;
|
||||
}
|
||||
colArr += "]";
|
||||
ratArr += "]";
|
||||
String type = "Filters.INNER";
|
||||
if (gbf.onTop && !gbf.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!gbf.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
|
||||
sb.append("\t\t\tfcanvas = Filters.gradientBevel(fcanvas,fcanvas.getContext(\"2d\"),").append(colArr).append(",").append(ratArr).append(",").append(gbf.blurX).append(",").append(gbf.blurY).append(",").append(gbf.strength).append(",").append(type).append(",").append((int) (gbf.angle * 180 / Math.PI)).append(",").append(gbf.distance).append(",").append(gbf.knockout ? "true" : "false").append(",").append(gbf.passes).append(");\r\n");
|
||||
}
|
||||
|
||||
if (filter instanceof GRADIENTGLOWFILTER) {
|
||||
GRADIENTGLOWFILTER ggf = (GRADIENTGLOWFILTER) filter;
|
||||
String colArr = "[";
|
||||
String ratArr = "[";
|
||||
for (int k = 0; k < ggf.gradientColors.length; k++) {
|
||||
if (k > 0) {
|
||||
colArr += ",";
|
||||
ratArr += ",";
|
||||
}
|
||||
colArr += jsArrColor(ggf.gradientColors[k]);
|
||||
ratArr += ggf.gradientRatio[k] / 255f;
|
||||
}
|
||||
colArr += "]";
|
||||
ratArr += "]";
|
||||
String type = "Filters.INNER";
|
||||
if (ggf.onTop && !ggf.innerShadow) {
|
||||
type = "Filters.FULL";
|
||||
} else if (!ggf.innerShadow) {
|
||||
type = "Filters.OUTER";
|
||||
}
|
||||
|
||||
sb.append("\t\t\tfcanvas = Filters.gradientGlow(fcanvas,fcanvas.getContext(\"2d\"),").append(ggf.blurX).append(",").append(ggf.blurY).append(",").append((int) (ggf.angle * 180 / Math.PI)).append(",").append(ggf.distance).append(",").append(colArr).append(",").append(ratArr).append(",").append(type).append(",").append(ggf.passes).append(",").append(ggf.strength).append(",").append(ggf.knockout ? "true" : "false").append(");\r\n");
|
||||
}
|
||||
}
|
||||
sb.append("\t\t\tctx = oldctx;\r\n");
|
||||
sb.append("\t\t\tvar ms=ctx._matrix;\r\n");
|
||||
sb.append("\t\t\tctx.setTransform(1,0,0,1,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.drawImage(fcanvas,0,0);\r\n");
|
||||
sb.append("\t\t\tctx.applyTransforms(ms);\r\n");
|
||||
}
|
||||
|
||||
if (layer.clipDepth != -1) {
|
||||
sb.append("\t\t\tclips[clips.length-1].clipCanvas = canvas;\r\n");
|
||||
sb.append("\t\t\tcanvas = createCanvas(canvas.width,canvas.height);\r\n");
|
||||
sb.append("\t\t\tvar nctx = canvas.getContext(\"2d\");\r\n");
|
||||
sb.append("\t\t\tenhanceContext(nctx);\r\n");
|
||||
sb.append("\t\t\tnctx.applyTransforms(ctx._matrix);\r\n");
|
||||
sb.append("\t\t\tctx = nctx;\r\n");
|
||||
}
|
||||
}
|
||||
sb.append("\t\t\tbreak;\r\n");
|
||||
}
|
||||
sb.append("\t}\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
|
||||
@@ -39,7 +40,7 @@ import java.util.Locale;
|
||||
*/
|
||||
public class ImageExporter {
|
||||
|
||||
public List<File> exportImages(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final ImageExportSettings settings) throws IOException {
|
||||
public List<File> exportImages(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, ImageExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -52,10 +53,24 @@ public class ImageExporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final Tag t : tags) {
|
||||
if (t instanceof ImageTag) {
|
||||
|
||||
String fileFormat = ((ImageTag) t).getImageFormat().toUpperCase(Locale.ENGLISH);
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof ImageTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof ImageTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("image", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final ImageTag imageTag = (ImageTag) t;
|
||||
|
||||
String fileFormat = imageTag.getImageFormat().toUpperCase(Locale.ENGLISH);
|
||||
if (settings.mode == ImageExportMode.PNG) {
|
||||
fileFormat = "png";
|
||||
}
|
||||
@@ -66,9 +81,8 @@ public class ImageExporter {
|
||||
if (settings.mode == ImageExportMode.BMP) {
|
||||
fileFormat = "bmp";
|
||||
}
|
||||
{
|
||||
|
||||
final ImageTag imageTag = (ImageTag) t;
|
||||
{
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(imageTag.getCharacterExportFileName() + "." + fileFormat));
|
||||
final String ffileFormat = fileFormat;
|
||||
|
||||
@@ -87,8 +101,14 @@ public class ImageExporter {
|
||||
ret.add(file);
|
||||
}
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("image", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -48,7 +49,7 @@ import java.util.Set;
|
||||
public class MorphShapeExporter {
|
||||
|
||||
//TODO: implement morphshape export. How to handle 65536 frames?
|
||||
public List<File> exportMorphShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final MorphShapeExportSettings settings) throws IOException {
|
||||
public List<File> exportMorphShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final MorphShapeExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -62,8 +63,20 @@ public class MorphShapeExporter {
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof MorphShapeTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (final Tag t : tags) {
|
||||
if (t instanceof MorphShapeTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("morphshape", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
int characterID = 0;
|
||||
if (t instanceof CharacterTag) {
|
||||
characterID = ((CharacterTag) t).getCharacterId();
|
||||
@@ -71,7 +84,6 @@ public class MorphShapeExporter {
|
||||
String ext = settings.mode == MorphShapeExportMode.CANVAS ? "html" : "svg";
|
||||
|
||||
final File file = new File(outdir + File.separator + characterID + "." + ext);
|
||||
final int fcharacterID = characterID;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
@@ -109,6 +121,12 @@ public class MorphShapeExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("morphshape", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +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.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -45,7 +47,7 @@ import java.util.List;
|
||||
*/
|
||||
public class MovieExporter {
|
||||
|
||||
|
||||
public List<File> exportMovies(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final MovieExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -58,8 +60,21 @@ public class MovieExporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DefineVideoStreamTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DefineVideoStreamTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("movie", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final DefineVideoStreamTag videoStream = (DefineVideoStreamTag) t;
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(videoStream.getCharacterExportFileName() + ".flv"));
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@@ -71,6 +86,11 @@ public class MovieExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("movie", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -53,7 +54,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class ShapeExporter {
|
||||
|
||||
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final ShapeExportSettings settings) throws IOException {
|
||||
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final ShapeExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -67,8 +68,20 @@ public class ShapeExporter {
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof ShapeTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (final Tag t : tags) {
|
||||
if (t instanceof ShapeTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("shape", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
int characterID = 0;
|
||||
if (t instanceof CharacterTag) {
|
||||
characterID = ((CharacterTag) t).getCharacterId();
|
||||
@@ -141,6 +154,12 @@ public class ShapeExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("shape", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
if (settings.mode == ShapeExportMode.CANVAS) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -48,7 +49,7 @@ import java.util.List;
|
||||
*/
|
||||
public class SoundExporter {
|
||||
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final SoundExportSettings settings) throws IOException {
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final SoundExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -61,14 +62,21 @@ public class SoundExporter {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Tag t : tags) {
|
||||
File newfile = null;
|
||||
int id = 0;
|
||||
if (t instanceof DefineSoundTag) {
|
||||
id = ((DefineSoundTag) t).soundId;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final SoundTag st = (SoundTag) t;
|
||||
|
||||
String ext = "wav";
|
||||
@@ -90,7 +98,6 @@ public class SoundExporter {
|
||||
}
|
||||
|
||||
final File file = new File(outdir + File.separator + st.getCharacterExportFileName() + "." + ext);
|
||||
newfile = file;
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
@@ -100,10 +107,14 @@ public class SoundExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
ret.add(newfile);
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
@@ -48,7 +49,7 @@ public class TextExporter {
|
||||
|
||||
public static final String TEXT_EXPORT_FILENAME_PLAIN = "textsplain.txt";
|
||||
|
||||
public List<File> exportTexts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final TextExportSettings settings) throws IOException {
|
||||
public List<File> exportTexts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final TextExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -62,9 +63,21 @@ public class TextExporter {
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof TextTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
if (settings.mode == TextExportMode.SVG) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof TextTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("text", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final TextTag textTag = (TextTag) t;
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(textTag.getCharacterExportFileName() + ".svg"));
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@@ -79,6 +92,12 @@ public class TextExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("text", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -119,6 +138,10 @@ public class TextExporter {
|
||||
} else {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof TextTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("text", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final TextTag textTag = (TextTag) t;
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(textTag.getCharacterExportFileName() + ".txt"));
|
||||
new RetryTask(new RunnableIOEx() {
|
||||
@@ -137,6 +160,12 @@ public class TextExporter {
|
||||
}
|
||||
}, handler).run();
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("text", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,13 +47,13 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class AS2ScriptExporter {
|
||||
|
||||
public List<File> exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Map<String, ASMSource> asms, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
|
||||
public List<File> exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Map<String, ASMSource> asms, final ScriptExportMode exportMode, final EventListener evl) throws IOException {
|
||||
try {
|
||||
List<File> result = CancellableWorker.call(new Callable<List<File>>() {
|
||||
|
||||
@Override
|
||||
public List<File> call() throws Exception {
|
||||
return exportAS2Scripts(handler, outdir, asms, exportMode, ev);
|
||||
return exportAS2Scripts(handler, outdir, asms, exportMode, evl);
|
||||
}
|
||||
}, Configuration.exportTimeout.get(), TimeUnit.SECONDS);
|
||||
return result;
|
||||
@@ -62,7 +62,7 @@ public class AS2ScriptExporter {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private List<File> exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Map<String, ASMSource> asms, ScriptExportMode exportMode, EventListener ev) throws IOException {
|
||||
private List<File> exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Map<String, ASMSource> asms, ScriptExportMode exportMode, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (!outdir.endsWith(File.separator)) {
|
||||
outdir += File.separator;
|
||||
@@ -90,7 +90,7 @@ public class AS2ScriptExporter {
|
||||
}
|
||||
existingNames.add(name);
|
||||
|
||||
File f = exportAS2Script(handler, currentOutDir, asm, exportMode, ev, cnt, asms.size(), name);
|
||||
File f = exportAS2Script(handler, currentOutDir, asm, exportMode, evl, cnt, asms.size(), name);
|
||||
if (f != null) {
|
||||
ret.add(f);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class AS2ScriptExporter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private File exportAS2Script(AbortRetryIgnoreHandler handler, String outdir, ASMSource asm, ScriptExportMode exportMode, EventListener ev, AtomicInteger index, int count, String name) throws IOException {
|
||||
private File exportAS2Script(AbortRetryIgnoreHandler handler, String outdir, ASMSource asm, ScriptExportMode exportMode, EventListener evl, AtomicInteger index, int count, String name) throws IOException {
|
||||
boolean retry;
|
||||
do {
|
||||
retry = false;
|
||||
@@ -116,8 +116,8 @@ public class AS2ScriptExporter {
|
||||
}
|
||||
|
||||
String f = outdir + name + ".as";
|
||||
if (ev != null) {
|
||||
ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f);
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("script", currentIndex, count, f);
|
||||
}
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
@@ -141,9 +141,9 @@ public class AS2ScriptExporter {
|
||||
|
||||
long stopTime = System.currentTimeMillis();
|
||||
|
||||
if (ev != null) {
|
||||
if (evl != null) {
|
||||
long time = stopTime - startTime;
|
||||
ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time));
|
||||
evl.handleExportedEvent("script", currentIndex, count, f + ", " + Helper.formatTimeSec(time));
|
||||
}
|
||||
|
||||
return file;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.FrameExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
@@ -426,7 +427,7 @@ public class Timeline {
|
||||
}
|
||||
|
||||
public String toHtmlCanvas(double unitDivisor, List<Integer> frames) {
|
||||
return SWF.framesToHtmlCanvas(unitDivisor, this, frames, 0, null, 0, displayRect, new ColorTransform(), null);
|
||||
return FrameExporter.framesToHtmlCanvas(unitDivisor, this, frames, 0, null, 0, displayRect, new ColorTransform(), null);
|
||||
}
|
||||
|
||||
public void getSounds(int frame, int time, DepthState stateUnderCursor, int mouseButton, List<Integer> sounds, List<String> soundClasses) {
|
||||
|
||||
@@ -3064,7 +3064,7 @@ public class XFLConverter {
|
||||
}
|
||||
if (useAS3) {
|
||||
try {
|
||||
swf.exportActionScript(handler, outDir.getAbsolutePath(), ScriptExportMode.AS, parallel);
|
||||
swf.exportActionScript(handler, outDir.getAbsolutePath(), ScriptExportMode.AS, parallel, null);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, "Error during ActionScript3 export", ex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user