Added #2119 Option to export assets with names like their assigned classes via SymbolClass, without character id

This commit is contained in:
Jindra Petřík
2023-11-17 19:05:38 +01:00
parent e2b8f54981
commit 7fd930489e
15 changed files with 533 additions and 292 deletions

View File

@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- AS3 Debugging - export/import ByteArray variable data
- [#2123] FLA export - show some progress info
- Label that flex compiler is used (when it's enabled in settings)
- [#2119] Option to export assets with names like their assigned classes via SymbolClass, without character id
### Fixed
- [#2021], [#2000] Caret position in editors when using tabs and / or unicode
@@ -3281,6 +3282,7 @@ Major version of SWF to XML export changed to 2.
[alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7
[#2100]: https://www.free-decompiler.com/flash/issues/2100
[#2123]: https://www.free-decompiler.com/flash/issues/2123
[#2119]: https://www.free-decompiler.com/flash/issues/2119
[#2021]: https://www.free-decompiler.com/flash/issues/2021
[#2000]: https://www.free-decompiler.com/flash/issues/2000
[#2116]: https://www.free-decompiler.com/flash/issues/2116

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
@@ -98,12 +99,18 @@ public class InstanceInfo {
String className = getName(abc.constants).getNameWithNamespace(abc.constants, false).toRawString();
CharacterTag ct = abc.getSwf().getCharacterByClass(className);
if (ct != null) {
String fileName = ct.getCharacterExportFileName();
if (Configuration.as3ExportNamesUseClassNamesOnly.get()) {
fileName = getName(abc.constants).getNameWithNamespace(abc.constants, false).toRawString();
}
fileName = Helper.makeFileName(fileName);
if (ct instanceof DefineBinaryDataTag) {
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".bin\", mimeType=\"application/octet-stream\")]").newLine();
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + fileName + ".bin\", mimeType=\"application/octet-stream\")]").newLine();
}
if (ct instanceof ImageTag) {
ImageTag it = (ImageTag) ct;
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ((ImageTag) ct).getImageFormat().getExtension() + "\")]").newLine();
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + fileName + ((ImageTag) ct).getImageFormat().getExtension() + "\")]").newLine();
}
if (ct instanceof DefineSpriteTag) {
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + "assets.swf\", symbol=\"" + Helper.escapeActionScriptString(className) + "\")]").newLine();
@@ -111,7 +118,7 @@ public class InstanceInfo {
if (ct instanceof DefineSoundTag) {
//should be mp3, otherwise it won't work. Should we convert this?
DefineSoundTag st = (DefineSoundTag) ct;
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + "." + (st.getSoundFormat().formatId == SoundFormat.FORMAT_MP3 ? "mp3" : "wav") + "\")]").newLine();
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + fileName + "." + (st.getSoundFormat().formatId == SoundFormat.FORMAT_MP3 ? "mp3" : "wav") + "\")]").newLine();
}
if (ct instanceof FontTag) {
FontTag ft = (FontTag) ct;
@@ -125,7 +132,7 @@ public class InstanceInfo {
}
}
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".ttf\",").newLine();
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + fileName + ".ttf\",").newLine();
writer.appendNoHilight("fontName=\"" + Helper.escapeActionScriptString(ft.getFontNameIntag()) + "\",").newLine();
writer.appendNoHilight("fontFamily=\"" + Helper.escapeActionScriptString(ft.getFontName()) + "\",").newLine();
writer.appendNoHilight("mimeType=\"application/x-font\",").newLine();
@@ -174,7 +181,7 @@ public class InstanceInfo {
if (ct instanceof DefineFont4Tag) {
DefineFont4Tag ft4 = (DefineFont4Tag) ct;
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + Helper.makeFileName(ct.getCharacterExportFileName()) + ".cff\",").newLine();
writer.appendNoHilight("[Embed(source=\"" + ASSETS_DIR + fileName + ".cff\",").newLine();
writer.appendNoHilight("fontName=\"" + Helper.escapeActionScriptString(ft4.fontName) + "\",").newLine();
writer.appendNoHilight("mimeType=\"application/x-font\",").newLine();
writer.appendNoHilight("fontWeight=\"" + (ft4.fontFlagsBold ? "bold" : "normal") + "\",").newLine();

View File

@@ -982,6 +982,10 @@ public final class Configuration {
@ConfigurationDefaultInt(1000)
@ConfigurationCategory("limit")
public static ConfigurationItem<Integer> boxBlurPixelsLimit = null;
@ConfigurationDefaultBoolean(false)
@ConfigurationCategory("export")
public static ConfigurationItem<Boolean> as3ExportNamesUseClassNamesOnly = null;
private enum OSId {
WINDOWS, OSX, UNIX

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -30,8 +31,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
*
@@ -78,8 +82,20 @@ public class BinaryDataExporter {
fos.write(bdt.binaryData.getRangeData());
}
}, handler).run();
ret.add(file);
Set<String> classNames = bdt.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.Font4ExportMode;
import com.jpexs.decompiler.flash.exporters.settings.Font4ExportSettings;
import com.jpexs.decompiler.flash.tags.DefineFont4Tag;
@@ -32,8 +33,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -84,7 +88,19 @@ public class Font4Exporter {
exportFont(st, settings.mode, file);
}, handler).run();
ret.add(file);
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;

View File

@@ -46,6 +46,8 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
@@ -100,9 +102,21 @@ public class FontExporter {
new RetryTask(() -> {
exportFont(st, settings.mode, file);
}, handler).run();
ret.add(file);
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;
}

View File

@@ -166,6 +166,75 @@ public class FrameExporter {
FrameExportSettings fes = new FrameExportSettings(fem, settings.zoom);
return exportFrames(handler, outdir, swf, containerId, frames, fes, evl);
}
private class MyFrameIterator implements Iterator<BufferedImage> {
private int pos = 0;
private final Timeline tim;
private final List<Integer> fframes;
private final EventListener evl;
private final boolean usesTransparency;
private final Color backgroundColor;
private final FrameExportSettings settings;
public MyFrameIterator(
Timeline tim,
List<Integer> fframes,
final EventListener evl,
boolean usesTransparency,
Color backgroundColor,
FrameExportSettings settings
) {
this.tim = tim;
this.fframes = fframes;
this.evl = evl;
this.usesTransparency = usesTransparency;
this.backgroundColor = backgroundColor;
this.settings = settings;
}
public void reset() {
pos = 0;
}
@Override
public boolean hasNext() {
if (Thread.currentThread().isInterrupted()) {
return false;
}
return fframes.size() > pos;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public BufferedImage next() {
if (!hasNext()) {
return null;
}
Tag parentTag = tim.getParentTag();
String tagName = parentTag == null ? "" : parentTag.getName();
if (evl != null) {
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tagName);
}
int fframe = fframes.get(pos++);
BufferedImage result = SWF.frameToImageGet(tim, fframe, 0, null, 0, tim.displayRect, new Matrix(), null, usesTransparency ? null : backgroundColor, settings.zoom, true).getBufferedImage();
if (Thread.currentThread().isInterrupted()) {
return null;
}
if (evl != null) {
evl.handleExportedEvent("frame", pos, fframes.size(), tagName);
}
return result;
}
}
public List<File> exportFrames(AbortRetryIgnoreHandler handler, String outdir, final SWF swf, int containerId, List<Integer> frames, final FrameExportSettings settings, final EventListener evl) throws IOException, InterruptedException {
final List<File> ret = new ArrayList<>();
@@ -177,12 +246,21 @@ public class FrameExporter {
return ret;
}
Timeline tim0;
String path = "";
List<String> paths = new ArrayList<>();
if (containerId == 0) {
tim0 = swf.getTimeline();
paths.add("");
} else {
tim0 = ((Timelined) swf.getCharacter(containerId)).getTimeline();
path = File.separator + Helper.makeFileName(swf.getCharacter(containerId).getExportFileName());
Set<String> classNames = swf.getCharacter(containerId).getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
paths.add(File.separator + Helper.makeFileName(className));
}
} else {
paths.add(File.separator + Helper.makeFileName(swf.getCharacter(containerId).getExportFileName()));
}
}
final Timeline tim = tim0;
@@ -195,8 +273,14 @@ public class FrameExporter {
}
}
final File foutdir = new File(outdir + path);
Path.createDirectorySafe(foutdir);
final List<File> foutdirs = new ArrayList<>();
for (String path : paths) {
File foutdir = new File(outdir + path);
foutdirs.add(foutdir);
Path.createDirectorySafe(foutdir);
}
final List<Integer> fframes = frames;
@@ -215,25 +299,27 @@ public class FrameExporter {
final int fi = i;
final Color fbackgroundColor = null;
new RetryTask(() -> {
int frame = fframes.get(fi);
File f = new File(foutdir + File.separator + (frame + 1) + ".svg");
try (OutputStream fos = new BufferedOutputStream(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, settings.zoom, "frame");
if (fbackgroundColor != null) {
exporter.setBackGroundColor(fbackgroundColor);
}
for (File foutdir : foutdirs) {
new RetryTask(() -> {
int frame = fframes.get(fi);
File f = new File(foutdir + File.separator + (frame + 1) + ".svg");
try (OutputStream fos = new BufferedOutputStream(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, settings.zoom, "frame");
if (fbackgroundColor != null) {
exporter.setBackGroundColor(fbackgroundColor);
}
tim.toSVG(frame, 0, null, 0, exporter, null, 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
ret.add(f);
}, handler).run();
tim.toSVG(frame, 0, null, 0, exporter, null, 0);
fos.write(Utf8Helper.getBytes(exporter.getSVG()));
}
ret.add(f);
}, handler).run();
}
if (Thread.currentThread().isInterrupted()) {
break;
@@ -257,104 +343,106 @@ public class FrameExporter {
final Timeline ftim = tim;
final Color fbackgroundColor = null;
final SWF fswf = swf;
new RetryTask(() -> {
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);
for (File foutdir : foutdirs) {
new RetryTask(() -> {
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 (final OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
fos.write(Utf8Helper.getBytes("\r\n"));
fos.write(Utf8Helper.getBytes("var scalingGrids = {};\r\nvar boundRects = {};\r\n"));
Set<Integer> library = new HashSet<>();
ftim.getNeededCharacters(fframes, library);
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 (final OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
fos.write(Utf8Helper.getBytes("\r\n"));
fos.write(Utf8Helper.getBytes("var scalingGrids = {};\r\nvar boundRects = {};\r\n"));
Set<Integer> library = new HashSet<>();
ftim.getNeededCharacters(fframes, library);
SWF.libraryToHtmlCanvas(fswf, library, fos);
SWF.libraryToHtmlCanvas(fswf, library, fos);
String currentName = ftim.id == 0 ? "main" : SWF.getTypePrefix(fswf.getCharacter(ftim.id)) + ftim.id;
String currentName = ftim.id == 0 ? "main" : SWF.getTypePrefix(fswf.getCharacter(ftim.id)) + ftim.id;
StringBuilder sb = new StringBuilder();
sb.append("function ").append(currentName).append("(ctx,ctrans,frame,ratio,time){\r\n");
sb.append("\tctx.save();\r\n");
sb.append("\tctx.transform(1,0,0,1,").append(-ftim.displayRect.Xmin * settings.zoom / SWF.unitDivisor).append(",").append(-ftim.displayRect.Ymin * settings.zoom / SWF.unitDivisor).append(");\r\n");
framesToHtmlCanvas(sb, SWF.unitDivisor / settings.zoom, ftim, fframes, 0, null, 0, ftim.displayRect, null, fbackgroundColor);
sb.append("\tctx.restore();\r\n");
sb.append("}\r\n\r\n");
StringBuilder sb = new StringBuilder();
sb.append("function ").append(currentName).append("(ctx,ctrans,frame,ratio,time){\r\n");
sb.append("\tctx.save();\r\n");
sb.append("\tctx.transform(1,0,0,1,").append(-ftim.displayRect.Xmin * settings.zoom / SWF.unitDivisor).append(",").append(-ftim.displayRect.Ymin * settings.zoom / SWF.unitDivisor).append(");\r\n");
framesToHtmlCanvas(sb, SWF.unitDivisor / settings.zoom, ftim, fframes, 0, null, 0, ftim.displayRect, null, fbackgroundColor);
sb.append("\tctx.restore();\r\n");
sb.append("}\r\n\r\n");
sb.append("var frame = -1;\r\n");
sb.append("var time = 0;\r\n");
sb.append("var frames = [];\r\n");
for (int i : fframes) {
sb.append("frames.push(").append(i).append(");\r\n");
}
sb.append("\r\n");
RGB backgroundColor1 = new RGB(255, 255, 255);
if (setBgColorTag != null) {
backgroundColor1 = setBgColorTag.backgroundColor;
sb.append("var frame = -1;\r\n");
sb.append("var time = 0;\r\n");
sb.append("var frames = [];\r\n");
for (int i : fframes) {
sb.append("frames.push(").append(i).append(");\r\n");
}
sb.append("\r\n");
RGB backgroundColor1 = new RGB(255, 255, 255);
if (setBgColorTag != null) {
backgroundColor1 = setBgColorTag.backgroundColor;
}
sb.append("var backgroundColor = \"").append(backgroundColor1.toHexRGB()).append("\";\r\n");
sb.append("var originalWidth = ").append(width).append(";\r\n");
sb.append("var originalHeight= ").append(height).append(";\r\n");
sb.append("function nextFrame(ctx,ctrans){\r\n");
sb.append("\tvar oldframe = frame;\r\n");
sb.append("\tframe = (frame+1)%frames.length;\r\n");
sb.append("\tif(frame==oldframe){time++;}else{time=0;};\r\n");
sb.append("\tdrawFrame();\r\n");
sb.append("}\r\n\r\n");
sb.append("function drawFrame(){\r\n");
sb.append("\tctx.fillStyle = backgroundColor;\r\n");
sb.append("\tctx.fillRect(0,0,canvas.width,canvas.height);\r\n");
sb.append("\tctx.save();\r\n");
sb.append("\tctx.transform(canvas.width/originalWidth,0,0,canvas.height/originalHeight,0,0);\r\n");
sb.append("\t").append(currentName).append("(ctx,ctrans,frames[frame],0,time);\r\n");
sb.append("\tctx.restore();\r\n");
sb.append("}\r\n\r\n");
if (ftim.swf.frameRate > 0) {
sb.append("window.setInterval(function(){nextFrame(ctx,ctrans);},").append((int) (1000.0 / ftim.swf.frameRate)).append(");\r\n");
}
sb.append("nextFrame(ctx,ctrans);\r\n");
fos.write(Utf8Helper.getBytes(sb.toString()));
}
sb.append("var backgroundColor = \"").append(backgroundColor1.toHexRGB()).append("\";\r\n");
sb.append("var originalWidth = ").append(width).append(";\r\n");
sb.append("var originalHeight= ").append(height).append(";\r\n");
sb.append("function nextFrame(ctx,ctrans){\r\n");
sb.append("\tvar oldframe = frame;\r\n");
sb.append("\tframe = (frame+1)%frames.length;\r\n");
sb.append("\tif(frame==oldframe){time++;}else{time=0;};\r\n");
sb.append("\tdrawFrame();\r\n");
sb.append("}\r\n\r\n");
sb.append("function drawFrame(){\r\n");
sb.append("\tctx.fillStyle = backgroundColor;\r\n");
sb.append("\tctx.fillRect(0,0,canvas.width,canvas.height);\r\n");
sb.append("\tctx.save();\r\n");
sb.append("\tctx.transform(canvas.width/originalWidth,0,0,canvas.height/originalHeight,0,0);\r\n");
sb.append("\t").append(currentName).append("(ctx,ctrans,frames[frame],0,time);\r\n");
sb.append("\tctx.restore();\r\n");
sb.append("}\r\n\r\n");
if (ftim.swf.frameRate > 0) {
sb.append("window.setInterval(function(){nextFrame(ctx,ctrans);},").append((int) (1000.0 / ftim.swf.frameRate)).append(");\r\n");
}
sb.append("nextFrame(ctx,ctrans);\r\n");
fos.write(Utf8Helper.getBytes(sb.toString()));
}
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");
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);
}
} else {
f.renameTo(fmin);
}
File fh = new File(foutdir + File.separator + "frames.html");
try (OutputStream fos = new BufferedOutputStream(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);
File fh = new File(foutdir + File.separator + "frames.html");
try (OutputStream fos = new BufferedOutputStream(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()));
}
if (packed) {
fos.write(Utf8Helper.getBytes(";"));
}
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getJsSuffix()));
fos.write(Utf8Helper.getBytes(CanvasShapeExporter.getHtmlSuffix()));
}
fmin.delete();
fmin.delete();
ret.add(f);
}, handler).run();
ret.add(f);
}, handler).run();
}
if (evl != null) {
Tag parentTag = tim.getParentTag();
@@ -366,28 +454,13 @@ public class FrameExporter {
if (settings.mode == FrameExportMode.SWF) {
Color fBackgroundColor = backgroundColor;
if (exportAll) {
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.swf");
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
try {
new PreviewExporter().exportSwf(fos, swf.getCharacter(containerId), fBackgroundColor, 0, false);
} catch (ActionParseException ex) {
Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
}
ret.add(f);
}, handler).run();
} else {
for (Integer frame : fframes) {
for (File foutdir : foutdirs) {
new RetryTask(() -> {
File f = new File(foutdir + File.separator + (frame + 1) + ".swf");
Frame fn = (Frame) tim.getFrame(frame);
File f = new File(foutdir + File.separator + "frames.swf");
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
try {
new PreviewExporter().exportSwf(fos, fn, fBackgroundColor, 0, false);
new PreviewExporter().exportSwf(fos, swf.getCharacter(containerId), fBackgroundColor, 0, false);
} catch (ActionParseException ex) {
Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -396,184 +469,175 @@ public class FrameExporter {
ret.add(f);
}, handler).run();
}
} else {
for (Integer frame : fframes) {
for (File foutdir : foutdirs) {
new RetryTask(() -> {
File f = new File(foutdir + File.separator + (frame + 1) + ".swf");
Frame fn = (Frame) tim.getFrame(frame);
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
try {
new PreviewExporter().exportSwf(fos, fn, fBackgroundColor, 0, false);
} catch (ActionParseException ex) {
Logger.getLogger(MorphShapeExporter.class.getName()).log(Level.SEVERE, null, ex);
}
}
ret.add(f);
}, handler).run();
}
}
}
}
final Color fbackgroundColor = backgroundColor;
final boolean fusesTransparency = settings.mode == FrameExportMode.PNG || settings.mode == FrameExportMode.GIF;
final Iterator<BufferedImage> frameImages = new Iterator<BufferedImage>() {
private int pos = 0;
@Override
public boolean hasNext() {
if (Thread.currentThread().isInterrupted()) {
return false;
}
return fframes.size() > pos;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public BufferedImage next() {
if (!hasNext()) {
return null;
}
Tag parentTag = tim.getParentTag();
String tagName = parentTag == null ? "" : parentTag.getName();
if (evl != null) {
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tagName);
}
int fframe = fframes.get(pos++);
BufferedImage result = SWF.frameToImageGet(tim, fframe, 0, null, 0, tim.displayRect, new Matrix(), null, fusesTransparency ? null : fbackgroundColor, settings.zoom, true).getBufferedImage();
if (Thread.currentThread().isInterrupted()) {
return null;
}
if (evl != null) {
evl.handleExportedEvent("frame", pos, fframes.size(), tagName);
}
return result;
}
};
final boolean usesTransparency = settings.mode == FrameExportMode.PNG || settings.mode == FrameExportMode.GIF;
final MyFrameIterator frameImages = new MyFrameIterator(tim, fframes, evl, usesTransparency, backgroundColor, settings);
switch (settings.mode) {
case GIF:
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.gif");
makeGIF(frameImages, swf.frameRate, f, evl);
ret.add(f);
}, handler).run();
break;
case BMP:
for (int i = 0; frameImages.hasNext(); i++) {
final int fi = i;
for (File foutdir : foutdirs) {
frameImages.reset();
new RetryTask(() -> {
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".bmp");
BufferedImage img = frameImages.next();
if (img != null) {
BMPFile.saveBitmap(img, f);
}
File f = new File(foutdir + File.separator + "frames.gif");
makeGIF(frameImages, swf.frameRate, f, evl);
ret.add(f);
}, handler).run();
}
break;
case BMP:
for (File foutdir : foutdirs) {
frameImages.reset();
for (int i = 0; frameImages.hasNext(); i++) {
final int fi = i;
new RetryTask(() -> {
File f = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".bmp");
BufferedImage img = frameImages.next();
if (img != null) {
BMPFile.saveBitmap(img, f);
}
ret.add(f);
}, handler).run();
}
}
break;
case PNG:
for (int i = 0; frameImages.hasNext(); i++) {
final int fi = i;
new RetryTask(() -> {
File file = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".png");
BufferedImage img = frameImages.next();
if (img != null) {
ImageHelper.write(img, ImageFormat.PNG, file);
ret.add(file);
}
}, handler).run();
for (File foutdir : foutdirs) {
frameImages.reset();
for (int i = 0; frameImages.hasNext(); i++) {
final int fi = i;
new RetryTask(() -> {
File file = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".png");
BufferedImage img = frameImages.next();
if (img != null) {
ImageHelper.write(img, ImageFormat.PNG, file);
ret.add(file);
}
}, handler).run();
}
}
//ShapeExporterBase.clearCache();
break;
case PDF:
if (frameImages.hasNext()) {
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.pdf");
PDFJob job = new PDFJob(new BufferedOutputStream(new FileOutputStream(f)));
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
Paper p = new Paper();
/*BufferedImage img = frameImages.next();
p.setSize(img.getWidth() + 10, img.getHeight() + 10);*/
for (File foutdir : foutdirs) {
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.pdf");
PDFJob job = new PDFJob(new BufferedOutputStream(new FileOutputStream(f)));
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
Paper p = new Paper();
/*BufferedImage img = frameImages.next();
p.setSize(img.getWidth() + 10, img.getHeight() + 10);*/
int pos = 0;
RECT rect = tim.displayRect;
int pos = 0;
RECT rect = tim.displayRect;
double w = (rect.getWidth() * settings.zoom / SWF.unitDivisor);
double h = (rect.getHeight() * settings.zoom / SWF.unitDivisor);
p.setSize(w, h);
pf.setPaper(p);
double zoom = settings.zoom;
Matrix m = new Matrix();
m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom);
m.scale(zoom);
Matrix transformation = m;
Map<Integer, Font> existingFonts = new HashMap<>();
double w = (rect.getWidth() * settings.zoom / SWF.unitDivisor);
double h = (rect.getHeight() * settings.zoom / SWF.unitDivisor);
p.setSize(w, h);
pf.setPaper(p);
double zoom = settings.zoom;
Matrix m = new Matrix();
m.translate(-rect.Xmin * zoom, -rect.Ymin * zoom);
m.scale(zoom);
Matrix transformation = m;
Map<Integer, Font> existingFonts = new HashMap<>();
while (pos < fframes.size()) {
while (pos < fframes.size()) {
if (evl != null) {
Tag parentTag = tim.getParentTag();
String tagName = parentTag == null ? "" : parentTag.getName();
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tagName);
}
int fframe = fframes.get(pos);
final Graphics2D g = (Graphics2D) job.getGraphics(pf);
//g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
if (evl != null) {
Tag parentTag = tim.getParentTag();
String tagName = parentTag == null ? "" : parentTag.getName();
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tagName);
}
int fframe = fframes.get(pos);
final Graphics2D g = (Graphics2D) job.getGraphics(pf);
//g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null);
SerializableImage image = new SerializableImage((int) w + 1, (int) h + 1, SerializableImage.TYPE_INT_ARGB_PRE) {
SerializableImage image = new SerializableImage((int) w + 1, (int) h + 1, SerializableImage.TYPE_INT_ARGB_PRE) {
private Graphics2D compositeGraphics;
private Graphics2D compositeGraphics;
@Override
public Graphics getGraphics() {
if (compositeGraphics != null) {
@Override
public Graphics getGraphics() {
if (compositeGraphics != null) {
return compositeGraphics;
}
final Graphics2D parentGraphics = (Graphics2D) super.getGraphics();
compositeGraphics = new DualPdfGraphics2D(parentGraphics, (PDFGraphics) g, existingFonts);
return compositeGraphics;
}
final Graphics2D parentGraphics = (Graphics2D) super.getGraphics();
compositeGraphics = new DualPdfGraphics2D(parentGraphics, (PDFGraphics) g, existingFonts);
return compositeGraphics;
@Override
public void fillTransparent() {
}
};
//if (backGroundColor == null) {
// image.fillTransparent();
int imgWidth = (int) (rect.getWidth() * zoom / SWF.unitDivisor) + 1;
int imgHeight = (int) (rect.getHeight() * zoom / SWF.unitDivisor) + 1;
if (!usesTransparency && fbackgroundColor != null) {
g.setComposite(AlphaComposite.Src);
g.setColor(fbackgroundColor);
g.fill(new Rectangle(imgWidth, imgHeight));
}
@Override
public void fillTransparent() {
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = new Point(-1, -1);
renderContext.mouseButton = 0;
renderContext.stateUnderCursor = new ArrayList<>();
try {
tim.toImage(fframe, fframe, renderContext, image, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL, 0, true);
} catch (Exception ex) {
ex.printStackTrace();
}
g.dispose();
};
//if (backGroundColor == null) {
// image.fillTransparent();
int imgWidth = (int) (rect.getWidth() * zoom / SWF.unitDivisor) + 1;
int imgHeight = (int) (rect.getHeight() * zoom / SWF.unitDivisor) + 1;
if (!fusesTransparency && fbackgroundColor != null) {
g.setComposite(AlphaComposite.Src);
g.setColor(fbackgroundColor);
g.fill(new Rectangle(imgWidth, imgHeight));
if (Thread.currentThread().isInterrupted()) {
return;
}
pos++;
}
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = new Point(-1, -1);
renderContext.mouseButton = 0;
renderContext.stateUnderCursor = new ArrayList<>();
try {
tim.toImage(fframe, fframe, renderContext, image, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL, 0, true);
} catch (Exception ex) {
ex.printStackTrace();
}
g.dispose();
if (Thread.currentThread().isInterrupted()) {
return;
}
pos++;
}
job.end();
ret.add(f);
}, handler).run();
job.end();
ret.add(f);
}, handler).run();
}
}
break;
case AVI:
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.avi");
makeAVI(frameImages, swf.frameRate, f, evl);
ret.add(f);
}, handler).run();
for (File foutdir : foutdirs) {
frameImages.reset();
new RetryTask(() -> {
File f = new File(foutdir + File.separator + "frames.avi");
makeAVI(frameImages, swf.frameRate, f, evl);
ret.add(f);
}, handler).run();
}
break;
}

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.settings.ImageExportSettings;
import com.jpexs.decompiler.flash.helpers.BMPFile;
@@ -38,8 +39,12 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.imageio.ImageIO;
/**
@@ -118,7 +123,6 @@ public class ImageExporter {
}
}, handler).run();
final File alphaBinFile = new File(outdir + File.separator + Helper.makeFileName(imageTag.getCharacterExportFileName() + ".alpha.bin"));
final File alphaPngFile = new File(outdir + File.separator + Helper.makeFileName(imageTag.getCharacterExportFileName() + ".alpha.png"));
if ((imageTag instanceof HasSeparateAlphaChannel)
@@ -145,7 +149,26 @@ public class ImageExporter {
}, handler).run();
}
}
ret.add(file);
Set<String> classNames = imageTag.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + "." + ImageHelper.getImageFormatString(fileFormat)));
File classAlphaPngFile = new File(outdir + File.separator + Helper.makeFileName(className + ".alpha.png"));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
if (alphaPngFile.exists()) {
Files.copy(alphaPngFile.toPath(), classAlphaPngFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
ret.add(classFile);
}
file.delete();
if (alphaPngFile.exists()) {
alphaPngFile.delete();
}
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;

View File

@@ -22,11 +22,11 @@ import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
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.MorphShapeExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
import com.jpexs.decompiler.flash.exporters.morphshape.CanvasMorphShapeExporter;
import com.jpexs.decompiler.flash.exporters.settings.MorphShapeExportSettings;
import com.jpexs.decompiler.flash.helpers.BMPFile;
@@ -53,6 +53,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -106,8 +108,9 @@ public class MorphShapeExporter {
final File file = new File(outdir + File.separator + characterID + settings.getFileExtension());
final File fileStart = new File(outdir + File.separator + characterID + ".start" + settings.getFileExtension());
final File fileEnd = new File(outdir + File.separator + characterID + ".end" + settings.getFileExtension());
MorphShapeTag mst = (MorphShapeTag) t;
new RetryTask(() -> {
MorphShapeTag mst = (MorphShapeTag) t;
switch (settings.mode) {
case SVG_START_END:
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fileStart))) {
@@ -218,8 +221,42 @@ public class MorphShapeExporter {
break;
}
}, handler).run();
ret.add(file);
Set<String> classNames = mst.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + settings.getFileExtension()));
File classFileStart = new File(outdir + File.separator + Helper.makeFileName(className + ".start" + settings.getFileExtension()));
File classFileEnd = new File(outdir + File.separator + Helper.makeFileName(className + ".end" + settings.getFileExtension()));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
if (fileStart.exists()) {
new RetryTask(() -> {
Files.copy(fileStart.toPath(), classFileStart.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
}
if (fileEnd.exists()) {
new RetryTask(() -> {
Files.copy(fileEnd.toPath(), classFileEnd.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
}
}
file.delete();
if (fileStart.exists()) {
fileStart.delete();
}
if (fileEnd.exists()) {
fileEnd.delete();
}
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;
}

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
import com.jpexs.decompiler.flash.exporters.settings.MovieExportSettings;
import com.jpexs.decompiler.flash.flv.FLVOutputStream;
@@ -40,11 +41,14 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
@@ -90,6 +94,20 @@ public class MovieExporter {
}
}, handler).run();
Set<String> classNames = videoStream.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ".flv"));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;
}

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
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;
@@ -50,6 +51,8 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -161,7 +164,20 @@ public class ShapeExporter {
break;
}
}, handler).run();
ret.add(file);
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + settings.getFileExtension()));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings;
import com.jpexs.decompiler.flash.flv.AUDIODATA;
@@ -28,6 +29,7 @@ import com.jpexs.decompiler.flash.flv.FLVTAG;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalSound;
@@ -43,9 +45,13 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
@@ -86,32 +92,44 @@ public class SoundExporter {
final SoundTag st = (SoundTag) t;
String ext = "wav";
String ext = ".wav";
SoundFormat fmt = st.getSoundFormat();
switch (fmt.getNativeExportFormat()) {
case MP3:
if (settings.mode.hasMP3()) {
ext = "mp3";
ext = ".mp3";
}
break;
case FLV:
if (settings.mode.hasFlv()) {
ext = "flv";
ext = ".flv";
}
break;
}
if (settings.mode == SoundExportMode.FLV) {
ext = "flv";
ext = ".flv";
}
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + "." + ext);
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + ext);
new RetryTask(() -> {
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
exportSound(os, st, settings.mode);
}
}, handler).run();
ret.add(file);
Set<String> classNames = (st instanceof CharacterTag) ? ((CharacterTag)st).getClassNames() : new HashSet<>();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
},handler).run();
ret.add(classFile);
}
file.delete();
} else {
ret.add(file);
}
if (Thread.currentThread().isInterrupted()) {
break;

View File

@@ -48,7 +48,7 @@ public class ShapeExportSettings {
case SWF:
return ".swf";
default:
throw new Error("Unsupported morphshape export mode: " + mode);
throw new Error("Unsupported shape export mode: " + mode);
}
}
}

View File

@@ -751,3 +751,6 @@ config.description.formatting.tab.size = Number of spaces per tab
config.name.boxBlurPixelsLimit = Box blur filter pixels limit
config.description.boxBlurPixelsLimit = Maximum number of pixels to calculate boxblur filter. The actual limit is this number multiplied by 10000. If the number of pixels is greater, then blurX and blurY is decreased.
config.name.as3ExportNamesUseClassNamesOnly = Exported assets have names bases on classes only (AS3)
config.description.as3ExportNamesUseClassNamesOnly = Exported asset files (images, sound, ...) take names only from SymbolClass tag - their assigned classes. No character id is added. Also when multiple classes is assigned to same asset, it is exported multiple times. (For ActionScript 3 SWFs)

View File

@@ -741,3 +741,6 @@ config.description.formatting.tab.size = Po\u010det mezer v tabel\u00e1toru
config.name.boxBlurPixelsLimit = Limit pixel\u016f box blur filtru
config.description.boxBlurPixelsLimit = Maxim\u00e1ln\u00ed po\u010det pixel\u016f pro v\u00fdpo\u010det boxblur filtru. Aktu\u00e1ln\u00ed limit je toto \u010d\u00edslo kr\u00e1t 10000. Pokud je po\u010det pixel\u016f v\u011bt\u0161\u00ed, je zmen\u0161en blurX, blurY.
config.name.as3ExportNamesUseClassNamesOnly = Exportovan\u00e9 zdroje maj\u00ed n\u00e1zvy zalo\u017een\u00e9 pouze na n\u00e1zvech t\u0159\u00edd (AS3)
config.description.as3ExportNamesUseClassNamesOnly = Exportovan\u00e9 soubory zdroj\u016f (obr\u00e1zky, zvuky, ...) p\u0159eberou n\u00e1zvy z SymbolClass tagu - jejich p\u0159i\u0159azen\u00e9 t\u0159\u00eddy. Id charakteru nebude p\u0159id\u00e1no. Tak\u00e9 pokud bude v\u00edce t\u0159\u00edd p\u0159i\u0159azeno jednomu assetu, bude exportov\u00e1n v\u00edcekr\u00e1t. (Pro ActionScript 3 SWF soubory)