Issue #282: FLA export to CS5, CS5.5 and CC format.

This commit is contained in:
Jindra Petk
2014-02-11 23:24:28 +01:00
parent cd756d6006
commit 590b1ca9f3
16 changed files with 300 additions and 94 deletions

View File

@@ -105,6 +105,7 @@ import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
import com.jpexs.decompiler.flash.types.filters.FILTER;
import com.jpexs.decompiler.flash.types.sound.AdpcmDecoder;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import com.jpexs.decompiler.flash.xfl.XFLConverter;
import com.jpexs.decompiler.graph.ExportMode;
import com.jpexs.decompiler.graph.Graph;
@@ -2064,12 +2065,12 @@ public final class SWF implements TreeItem {
return ret;
}
public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel) throws IOException {
XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel);
public void exportFla(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException {
XFLConverter.convertSWF(handler, this, swfName, outfile, true, generator, generatorVerName, generatorVersion, parallel, version);
}
public void exportXfl(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel) throws IOException {
XFLConverter.convertSWF(handler, this, swfName, outfile, false, generator, generatorVerName, generatorVersion, parallel);
public void exportXfl(AbortRetryIgnoreHandler handler, String outfile, String swfName, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion version) throws IOException {
XFLConverter.convertSWF(handler, this, swfName, outfile, false, generator, generatorVerName, generatorVersion, parallel, version);
}
public static AffineTransform matrixToTransform(MATRIX mat) {

View File

@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.RenameType;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
import com.jpexs.decompiler.flash.gui.Main;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import com.jpexs.decompiler.graph.ExportMode;
import com.jpexs.helpers.Helper;
import com.sun.jna.Platform;
@@ -130,6 +131,7 @@ public class CommandLineArgumentParser {
Level traceLevel = Level.WARNING;
Queue<String> args = new LinkedList<>(Arrays.asList(arguments));
AbortRetryIgnoreHandler handler = null;
String format = null;
String nextParam;
OUTER:
@@ -186,8 +188,10 @@ public class CommandLineArgumentParser {
System.exit(0);
} else if (nextParam.equals("-proxy")) {
parseProxy(args);
} else if (nextParam.equals("-format")) {
format = parseFormat(args);
} else if (nextParam.equals("-export")) {
parseExport(args, handler, traceLevel);
parseExport(args, handler, traceLevel, format);
} else if (nextParam.equals("-compress")) {
parseCompress(args);
} else if (nextParam.equals("-decompress")) {
@@ -434,7 +438,7 @@ public class CommandLineArgumentParser {
Main.startProxy(port);
}
private static void parseExport(Queue<String> args, AbortRetryIgnoreHandler handler, Level traceLevel) {
private static void parseExport(Queue<String> args, AbortRetryIgnoreHandler handler, Level traceLevel, String format) {
if (args.size() < 3) {
badArguments();
}
@@ -554,11 +558,27 @@ public class CommandLineArgumentParser {
exportOK = true;
break;
case "fla":
exfile.exportFla(handler, outDir.getAbsolutePath(), inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get());
FLAVersion flaVersion = FLAVersion.fromString(format);
if(flaVersion == null){
flaVersion = FLAVersion.CS6; //Defaults to CS6
if(format!=null){
System.err.println("Invalid export FLA format: "+format);
badArguments();
}
}
exfile.exportFla(handler, outDir.getAbsolutePath(), inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get(),flaVersion);
exportOK = true;
break;
case "xfl":
exfile.exportXfl(handler, outDir.getAbsolutePath(), inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get());
case "xfl":
FLAVersion xflVersion = FLAVersion.fromString(format);
if(xflVersion == null){
xflVersion = FLAVersion.CS6; //Defaults to CS6
if(format!=null){
System.err.println("Invalid export XFL format: "+format);
badArguments();
}
}
exfile.exportXfl(handler, outDir.getAbsolutePath(), inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get(),xflVersion);
exportOK = true;
break;
default:
@@ -670,6 +690,13 @@ public class CommandLineArgumentParser {
System.exit(0);
}
private static String parseFormat(Queue<String> args) {
if (args.size() < 1) {
badArguments();
}
return args.remove().toLowerCase();
}
private static void parseDumpSwf(Queue<String> args) {
if (args.isEmpty()) {
badArguments();

View File

@@ -105,6 +105,7 @@ import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.TEXTRECORD;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import com.jpexs.decompiler.graph.ExportMode;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
@@ -1700,30 +1701,53 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
String fileName = (new File(swf.file).getName());
fileName = fileName.substring(0, fileName.length() - 4) + ".fla";
fc.setSelectedFile(new File(selDir + fileName));
FileFilter fla = new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.getName().toLowerCase().endsWith(".fla"));
}
List<FileFilter> flaFilters = new ArrayList<>();
List<FileFilter> xflFilters = new ArrayList<>();
List<FLAVersion> versions = new ArrayList<>();
FileFilter defaultFilter = null;
for (int i = FLAVersion.values().length - 1; i >= 0; i--) {
final FLAVersion v = FLAVersion.values()[i];
if (!swf.isAS3 && v.minASVersion() > 2) {
//This version does not support AS1/2
} else {
versions.add(v);
FileFilter f = new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.getName().toLowerCase().endsWith(".fla"));
}
@Override
public String getDescription() {
return translate("filter.fla");
}
};
FileFilter xfl = new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.getName().toLowerCase().endsWith(".xfl"));
}
@Override
public String getDescription() {
return translate("filter.fla").replace("%version%", v.applicationName());
}
};
if (v == FLAVersion.CS6) {
defaultFilter = f;
fc.setFileFilter(f);
} else {
fc.addChoosableFileFilter(f);
}
flaFilters.add(f);
f = new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || (f.getName().toLowerCase().endsWith(".xfl"));
}
@Override
public String getDescription() {
return translate("filter.xfl");
@Override
public String getDescription() {
return translate("filter.xfl").replace("%version%", v.applicationName());
}
};
fc.addChoosableFileFilter(f);
xflFilters.add(f);
}
};
fc.setFileFilter(fla);
fc.addChoosableFileFilter(xfl);
}
if (defaultFilter == null) {
defaultFilter = flaFilters.get(0);
}
fc.setAcceptAllFileFilterUsed(false);
JFrame f = new JFrame();
View.setWindowIcon(f);
@@ -1733,12 +1757,13 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
File sf = Helper.fixDialogFile(fc.getSelectedFile());
Main.startWork(translate("work.exporting.fla") + "...");
final boolean compressed = fc.getFileFilter() == fla;
final boolean compressed = flaFilters.contains(fc.getFileFilter());
if (!compressed) {
if (sf.getName().endsWith(".fla")) {
sf = new File(sf.getAbsolutePath().substring(0, sf.getAbsolutePath().length() - 4) + ".xfl");
}
}
final FLAVersion selectedVersion = versions.get(compressed ? flaFilters.indexOf(fc.getFileFilter()) : xflFilters.indexOf(fc.getFileFilter()));
final File selfile = sf;
new CancellableWorker() {
@Override
@@ -1746,9 +1771,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
Helper.freeMem();
try {
if (compressed) {
swf.exportFla(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get());
swf.exportFla(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get(), selectedVersion);
} else {
swf.exportXfl(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get());
swf.exportXfl(errorHandler, selfile.getAbsolutePath(), new File(swf.file).getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get(), selectedVersion);
}
} catch (IOException ex) {
View.showMessageDialog(null, translate("error.export") + ": " + ex.getClass().getName() + " " + ex.getLocalizedMessage(), translate("error"), JOptionPane.ERROR_MESSAGE);

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Not found
message.rename.renamed = Identifiers renamed: %count%
filter.images = Images (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 Document (*.fla)
filter.xfl = Flash CS 6 Uncompressed Document (*.xfl)
filter.fla = %version% Document (*.fla)
filter.xfl = %version% Uncompressed Document (*.xfl)
filter.swf = SWF files (*.swf)
error = Error

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Nenalezeno
message.rename.renamed = Po\u010det p\u0159ejmenovan\u00fdch identifik\u00e1tor\u016f: %count%
filter.images = Obr\u00e1zky (*.jpg,*.gif,*.png)
filter.fla = Dokument Flash CS 6 (*.fla)
filter.xfl = Nekomprimovan\u00fd Dokument Flash CS 6 (*.xfl)
filter.fla = Dokument %version% (*.fla)
filter.xfl = Nekomprimovan\u00fd Dokument %version% (*.xfl)
filter.swf = SWF soubory (*.swf)
error = Chyba

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = No encontrado
message.rename.renamed = Identificadores renombrados: %count%
filter.images = Im\u00e1genes (*.jpg,*.gif,*.png)
filter.fla = Documento Flash CS 6 (*.fla)
filter.xfl = Documento no comprimido Flash CS 6 (*.xfl)
filter.fla = Documento %version% (*.fla)
filter.xfl = Documento no comprimido %version% (*.xfl)
filter.swf = Archivos SWF (*.swf)
error = Error

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Pas trouv\u00e9
message.rename.renamed = Nombre d'identificateurs renomm\u00e9s : %count%
filter.images = Images (*.jpg,*.gif,*.png)
filter.fla = Document Flash CS 6 (*.fla)
filter.xfl = Document d\u00e9compress\u00e9 Flash CS 6 (*.xfl)
filter.fla = Document %version% (*.fla)
filter.xfl = Document d\u00e9compress\u00e9 %version% (*.xfl)
filter.swf = Fichiers SWF (*.swf)
error = Erreur

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Nem tal\u00e1lhat\u00f3
message.rename.renamed = %count% azonos\u00edt\u00f3 \u00e1tnevezve
filter.images = K\u00e9pek (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 Dokumentum (*.fla)
filter.xfl = Flash CS 6 T\u00f6m\u00f6r\u00edtetlen dokumentum (*.xfl)
filter.fla = %version% Dokumentum (*.fla)
filter.xfl = %version% T\u00f6m\u00f6r\u00edtetlen dokumentum (*.xfl)
filter.swf = SWF f\u00e1ljok (*.swf)
error = Hiba

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Niet gevonden
message.rename.renamed = Identifiers werden hernoemd: %count%
filter.images = Images (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 Document (*.fla)
filter.xfl = Flash CS 6 Ongecomprimeerde Document (*.xfl)
filter.fla = %version% Document (*.fla)
filter.xfl = %version% Ongecomprimeerde Document (*.xfl)
filter.swf = SWF-bestanden (*.swf)
error = Fout

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = N\u00e3o Encontrado
message.rename.renamed = Identificadores Renomeados: %count%
filter.images = Imagens (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 Documento (*.fla)
filter.xfl = Flash CS 6 Documento n\u00e3o comprimido (*.xfl)
filter.fla = %version% Documento (*.fla)
filter.xfl = %version% Documento n\u00e3o comprimido (*.xfl)
filter.swf = Ficheiros SWF (*.swf)
error = Erro

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = \u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043
message.rename.renamed = \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043e: %count%
filter.images = \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f (*.jpg,*.gif,*.png)
filter.fla = \u041f\u0440\u043e\u0435\u043a\u0442 Flash CS 6 (*.fla)
filter.xfl = \u041d\u0435\u0441\u0436\u0430\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 Flash CS 6 (*.xfl)
filter.fla = \u041f\u0440\u043e\u0435\u043a\u0442 %version% (*.fla)
filter.xfl = \u041d\u0435\u0441\u0436\u0430\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 %version% (*.xfl)
filter.swf = SWF \u0444\u0430\u0439\u043b\u044b (*.swf)
error = \u041e\u0448\u0438\u0431\u043a\u0430

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = Hittades inte
message.rename.renamed = Identifierare som har \u00e4ndrat namn: %count%
filter.images = Bilder (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 Dokument (*.fla)
filter.xfl = Flash CS 6 Okomprimerat Dokument (*.xfl)
filter.fla = %version% Dokument (*.fla)
filter.xfl = %version% Okomprimerat Dokument (*.xfl)
filter.swf = SWF filer (*.swf)
error = Fel

View File

@@ -127,8 +127,8 @@ message.rename.notfound.title = \u041d\u0435 \u0437\u043d\u0430\u0439\u0434\u043
message.rename.renamed = \u0406\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u043e\u0440\u0456\u0432 \u043f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043e: %count%
filter.images = \u0417\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f (*.jpg,*.gif,*.png)
filter.fla = \u041f\u0440\u043e\u0435\u043a\u0442 Flash CS 6 (*.fla)
filter.xfl = \u041d\u0435\u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 Flash CS 6 (*.xfl)
filter.fla = \u041f\u0440\u043e\u0435\u043a\u0442 %version% (*.fla)
filter.xfl = \u041d\u0435\u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 %version% (*.xfl)
filter.swf = SWF \u0444\u0430\u0439\u043b\u0438 (*.swf)
error = \u041f\u043e\u043c\u0438\u043b\u043a\u0430

View File

@@ -129,8 +129,8 @@ message.rename.notfound.title = \u6ca1\u6709\u627e\u5230
message.rename.renamed = \u6807\u8bc6\u7b26\u91cd\u547d\u540d\u6570\uff1a %count%
filter.images = \u56fe\u7247 (*.jpg,*.gif,*.png)
filter.fla = Flash CS 6 \u6587\u4ef6 (*.fla)
filter.xfl = Flash CS 6 \u672a\u538b\u7f29\u6587\u4ef6 (*.xfl)
filter.fla = %version% \u6587\u4ef6 (*.fla)
filter.xfl = %version% \u672a\u538b\u7f29\u6587\u4ef6 (*.xfl)
filter.swf = SWF \u6587\u4ef6 (*.swf)
error = \u9519\u8bef

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.xfl;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author JPEXS
*/
public enum FLAVersion {
CS5("CS5","Flash CS 5","2.0",10),
CS5_5("CS5.5","Flash CS 5.5","2.1",11),
CS6("CS6","Flash CS 6","2.2",17),
CC("CC","Flash CC","2.4",Integer.MAX_VALUE){
@Override
public int minASVersion() {
return 3; //AS 1/2 not supported anymore
}
};
private final String xflVersion;
private final String shortName;
private final String applicationName;
private final int maxSwfVersion;
private static final Map<Integer,String> versionToPlayerMap=new HashMap<>();
static{
versionToPlayerMap.put(10,"FlashPlayer10.0"); //10 & 10.1
versionToPlayerMap.put(11,"FlashPlayer10.2");
versionToPlayerMap.put(12,"FlashPlayer10.3");
versionToPlayerMap.put(13,"FlashPlayer11.0");
versionToPlayerMap.put(14,"FlashPlayer11.1");
versionToPlayerMap.put(15,"FlashPlayer11.2");
versionToPlayerMap.put(16,"FlashPlayer11.3");
versionToPlayerMap.put(17,"FlashPlayer11.4");
versionToPlayerMap.put(18,"FlashPlayer11.5");
versionToPlayerMap.put(19,"FlashPlayer11.6");
versionToPlayerMap.put(20,"FlashPlayer11.7");
versionToPlayerMap.put(21,"FlashPlayer11.8");
versionToPlayerMap.put(22,"FlashPlayer11.9");
versionToPlayerMap.put(23,"FlashPlayer12.0");
}
private FLAVersion(String shortName,String applicationName,String xflVersion,int maxSwfVersion){
this.xflVersion = xflVersion;
this.shortName = shortName;
this.applicationName = applicationName;
this.maxSwfVersion = maxSwfVersion;
}
public String xflVersion() {
return xflVersion;
}
public int maxSwfVersion(){
return maxSwfVersion;
}
public int minASVersion(){
return 1;
}
public String applicationName(){
return applicationName;
}
public String shortName(){
return shortName;
}
@Override
public String toString() {
return shortName;
}
public static String swfVersionToPlayer(int version){
if(versionToPlayerMap.containsKey(version)){
return versionToPlayerMap.get(version);
}
return "";
}
public static FLAVersion fromString(String s){
if(s == null){
return null;
}
for(FLAVersion v:FLAVersion.values()){
if(v.shortName.toLowerCase().equals(s.toLowerCase())){
return v;
}
if(v.xflVersion.equals(s)){
return v;
}
}
return null;
}
}

View File

@@ -143,7 +143,7 @@ public class XFLConverter {
public static final int KEY_MODE_SHAPE_TWEEN = 17922;
public static final int KEY_MODE_MOTION_TWEEN = 8195;
public static final int KEY_MODE_SHAPE_LAYERS = 8192;
private XFLConverter() {
}
@@ -971,7 +971,7 @@ public class XFLConverter {
return ret;
}
public static String convertSymbolInstance(String name, MATRIX matrix, CXFORM colorTransform, CXFORMWITHALPHA colorTransformAlpha, boolean cacheAsBitmap, int blendMode, List<FILTER> filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap<Integer, CharacterTag> characters, List<Tag> tags) {
public static String convertSymbolInstance(String name, MATRIX matrix, CXFORM colorTransform, CXFORMWITHALPHA colorTransformAlpha, boolean cacheAsBitmap, int blendMode, List<FILTER> filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap<Integer, CharacterTag> characters, List<Tag> tags, FLAVersion flaVersion) {
String ret = "";
if (matrix == null) {
matrix = new MATRIX();
@@ -1013,7 +1013,7 @@ public class XFLConverter {
if (cacheAsBitmap) {
ret += " cacheAsBitmap=\"true\"";
}
if (!isVisible) {
if (!isVisible && flaVersion.ordinal()>=FLAVersion.CS5_5.ordinal()) {
ret += " isVisible=\"false\"";
}
ret += ">";
@@ -1107,7 +1107,7 @@ public class XFLConverter {
return new Date().getTime() / 1000;
}
public static String convertLibrary(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles) {
public static String convertLibrary(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles,FLAVersion flaVersion) {
//TODO: Imported assets
//linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf"
@@ -1211,7 +1211,7 @@ public class XFLConverter {
} else if (character instanceof DefineVideoStreamTag) {
recCharStr = convertVideoInstance(null, matrix, (DefineVideoStreamTag) character, null);
} else {
recCharStr = convertSymbolInstance(null, matrix, null, colorTransformAlpha, false, blendMode, filters, true, null, null, characters.get(rec.characterId), characters, tags);
recCharStr = convertSymbolInstance(null, matrix, null, colorTransformAlpha, false, blendMode, filters, true, null, null, characters.get(rec.characterId), characters, tags,flaVersion);
}
int duration = frame - lastFrame;
lastFrame = frame;
@@ -1248,7 +1248,7 @@ public class XFLConverter {
if (sprite.subTags.isEmpty()) { //probably AS2 class
continue;
}
symbolStr += convertTimeline(sprite.spriteId, oneInstanceShapes, backgroundColor, tags, sprite.getSubTags(), characters, "Symbol " + symbol.getCharacterId());
symbolStr += convertTimeline(sprite.spriteId, oneInstanceShapes, backgroundColor, tags, sprite.getSubTags(), characters, "Symbol " + symbol.getCharacterId(),flaVersion);
} else if (symbol instanceof ShapeTag) {
itemIcon = "1";
ShapeTag shape = (ShapeTag) symbol;
@@ -1268,7 +1268,12 @@ public class XFLConverter {
if (itemIcon != null) {
symbLinkStr += " itemIcon=\"" + itemIcon + "\"";
}
symbLinkStr += " loadImmediate=\"false\" lastModified=\"" + getTimestamp() + "\"/>"; //TODO: itemID=\"518de416-00000341\"
symbLinkStr += " loadImmediate=\"false\"";
if(flaVersion.ordinal()>=FLAVersion.CS5_5.ordinal()) {
symbLinkStr += " lastModified=\"" + getTimestamp() + "\"";
//TODO: itemID=\"518de416-00000341\"
}
symbLinkStr += "/>";
symbols.add(symbLinkStr);
} else if (symbol instanceof ImageTag) {
ImageTag imageTag = (ImageTag) symbol;
@@ -1584,7 +1589,7 @@ public class XFLConverter {
ret += " keyMode=\"" + KEY_MODE_NORMAL + "\"";
}
String soundEnvelopeStr = "";
if (soundStreamHead != null) {
if (soundStreamHead != null && startSound == null) {
ret += " soundName=\"sound" + soundStreamHead.getCharacterId() + "." + soundStreamHead.getExportFormat() + "\"";
ret += " soundSync=\"stream\"";
soundEnvelopeStr += "<SoundEnvelope>";
@@ -1684,7 +1689,7 @@ public class XFLConverter {
return ret;
}
private static String convertFrames(String prevStr, String afterStr, List<Integer> oneInstanceShapes, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, int depth) {
private static String convertFrames(String prevStr, String afterStr, List<Integer> oneInstanceShapes, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, int depth, FLAVersion flaVersion) {
String ret = "";
prevStr += "<frames>";
int frame = -1;
@@ -1815,7 +1820,7 @@ public class XFLConverter {
} else if (character instanceof DefineVideoStreamTag) {
elements += convertVideoInstance(instanceName, matrix, (DefineVideoStreamTag) character, clipActions);
} else {
elements += convertSymbolInstance(instanceName, matrix, colorTransForm, colorTransFormAlpha, cacheAsBitmap, blendMode, filters, isVisible, backGroundColor, clipActions, character, characters, tags);
elements += convertSymbolInstance(instanceName, matrix, colorTransForm, colorTransFormAlpha, cacheAsBitmap, blendMode, filters, isVisible, backGroundColor, clipActions, character, characters, tags,flaVersion);
}
}
}
@@ -2018,7 +2023,7 @@ public class XFLConverter {
return outlineColor.toHexRGB();
}
public static String convertTimeline(int spriteId, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, String name) {
public static String convertTimeline(int spriteId, List<Integer> oneInstanceShapes, String backgroundColor, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, String name, FLAVersion flaVersion) {
String ret = "";
ret += "<DOMTimeline name=\"" + name + "\">";
ret += "<layers>";
@@ -2041,7 +2046,7 @@ public class XFLConverter {
ret += "<DOMLayer name=\"Layer " + (index + 1) + "\" color=\"" + randomOutlineColor() + "\" ";
ret += " layerType=\"mask\" locked=\"true\"";
ret += ">";
ret += convertFrames("", "", oneInstanceShapes, tags, timelineTags, characters, po.getDepth());
ret += convertFrames("", "", oneInstanceShapes, tags, timelineTags, characters, po.getDepth(),flaVersion);
ret += "</DOMLayer>";
index++;
break;
@@ -2082,7 +2087,7 @@ public class XFLConverter {
}
layerPrev += ">";
String layerAfter = "</DOMLayer>";
String cf = convertFrames(layerPrev, layerAfter, oneInstanceShapes, tags, timelineTags, characters, d);
String cf = convertFrames(layerPrev, layerAfter, oneInstanceShapes, tags, timelineTags, characters, d,flaVersion);
if (cf.isEmpty()) {
index--;
}
@@ -2486,7 +2491,25 @@ public class XFLConverter {
return ret;
}
public static void convertSWF(AbortRetryIgnoreHandler handler, SWF swf, String swfFileName, String outfile, boolean compressed, String generator, String generatorVerName, String generatorVersion, boolean parallel) throws IOException {
public static void convertSWF(AbortRetryIgnoreHandler handler, SWF swf, String swfFileName, String outfile, boolean compressed, String generator, String generatorVerName, String generatorVersion, boolean parallel, FLAVersion flaVersion) throws IOException {
FileAttributesTag fa = null;
for (Tag t : swf.tags) {
if (t instanceof FileAttributesTag) {
fa = (FileAttributesTag) t;
}
}
boolean useAS3 = false;
boolean useNetwork = false;
if (fa != null) {
useAS3 = fa.actionScript3;
useNetwork = fa.useNetwork;
}
if(!useAS3 && flaVersion.minASVersion()>2){
throw new IllegalArgumentException("FLA version "+flaVersion+" does not support AS1/2");
}
File file = new File(outfile);
File outDir = file.getParentFile();
if (!outDir.exists()) {
@@ -2510,19 +2533,7 @@ public class XFLConverter {
Map<Integer, String> characterClasses = getCharacterClasses(swf.tags);
Map<Integer, String> characterVariables = getCharacterVariables(swf.tags);
FileAttributesTag fa = null;
for (Tag t : swf.tags) {
if (t instanceof FileAttributesTag) {
fa = (FileAttributesTag) t;
}
}
boolean useAS3 = false;
boolean useNetwork = false;
if (fa != null) {
useAS3 = fa.actionScript3;
useNetwork = fa.useNetwork;
}
String backgroundColor = "#ffffff";
for (Tag t : swf.tags) {
if (t instanceof SetBackgroundColorTag) {
@@ -2530,7 +2541,7 @@ public class XFLConverter {
backgroundColor = sbc.backgroundColor.toHexRGB();
}
}
domDocument += "<DOMDocument xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://ns.adobe.com/xfl/2008/\" currentTimeline=\"1\" xflVersion=\"2.2\" creatorInfo=\"" + generator + "\" platform=\"Windows\" versionInfo=\"Saved by " + generatorVerName + "\" majorVersion=\"" + generatorVersion + "\" buildNumber=\"\" nextSceneIdentifier=\"2\" playOptionsPlayLoop=\"false\" playOptionsPlayPages=\"false\" playOptionsPlayFrameActions=\"false\" autoSaveHasPrompted=\"true\"";
domDocument += "<DOMDocument xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://ns.adobe.com/xfl/2008/\" currentTimeline=\"1\" xflVersion=\""+flaVersion.xflVersion()+"\" creatorInfo=\"" + generator + "\" platform=\"Windows\" versionInfo=\"Saved by " + generatorVerName + "\" majorVersion=\"" + generatorVersion + "\" buildNumber=\"\" nextSceneIdentifier=\"2\" playOptionsPlayLoop=\"false\" playOptionsPlayPages=\"false\" playOptionsPlayFrameActions=\"false\" autoSaveHasPrompted=\"true\"";
domDocument += " backgroundColor=\"" + backgroundColor + "\"";
domDocument += " frameRate=\"" + swf.frameRate + "\"";
@@ -2544,9 +2555,9 @@ public class XFLConverter {
}
domDocument += ">";
domDocument += convertLibrary(swf, characterVariables, characterClasses, oneInstaceShapes, backgroundColor, swf.tags, characters, files, datfiles);
domDocument += convertLibrary(swf, characterVariables, characterClasses, oneInstaceShapes, backgroundColor, swf.tags, characters, files, datfiles,flaVersion);
domDocument += "<timelines>";
domDocument += convertTimeline(0, oneInstaceShapes, backgroundColor, swf.tags, swf.tags, characters, "Scene 1");
domDocument += convertTimeline(0, oneInstaceShapes, backgroundColor, swf.tags, swf.tags, characters, "Scene 1",flaVersion);
domDocument += "</timelines>";
domDocument += "</DOMDocument>";
domDocument = prettyFormatXML(domDocument);
@@ -2586,6 +2597,7 @@ public class XFLConverter {
}
}
int flaSwfVersion = swf.version>flaVersion.maxSwfVersion()?flaVersion.maxSwfVersion():swf.version;
String publishSettings = "<flash_profiles>\n"
+ "<flash_profile version=\"1.0\" name=\"Default\" current=\"true\">\n"
+ " <PublishFormatProperties enabled=\"true\">\n"
@@ -2597,7 +2609,7 @@ public class XFLConverter {
+ " <gif>0</gif>\n"
+ " <jpeg>0</jpeg>\n"
+ " <png>0</png>\n"
+ " <qt>0</qt>\n"
+ (flaVersion.ordinal()>=FLAVersion.CC.ordinal()?" <svg>0</svg>\n":" <qt>0</qt>\n")
+ " <rnwk>0</rnwk>\n"
+ " <swc>0</swc>\n"
+ " <flashDefaultName>1</flashDefaultName>\n"
@@ -2607,7 +2619,7 @@ public class XFLConverter {
+ " <gifDefaultName>1</gifDefaultName>\n"
+ " <jpegDefaultName>1</jpegDefaultName>\n"
+ " <pngDefaultName>1</pngDefaultName>\n"
+ " <qtDefaultName>1</qtDefaultName>\n"
+ (flaVersion.ordinal()>=FLAVersion.CC.ordinal()?" <svgDefaultName>1</svgDefaultName>\n":" <qtDefaultName>1</qtDefaultName>\n")
+ " <rnwkDefaultName>1</rnwkDefaultName>\n"
+ " <swcDefaultName>1</swcDefaultName>\n"
+ " <flashFileName>" + baseName + ".swf</flashFileName>\n"
@@ -2617,7 +2629,7 @@ public class XFLConverter {
+ " <gifFileName>" + baseName + ".gif</gifFileName>\n"
+ " <jpegFileName>" + baseName + ".jpg</jpegFileName>\n"
+ " <pngFileName>" + baseName + ".png</pngFileName>\n"
+ " <qtFileName>" + baseName + ".mov</qtFileName>\n"
+ (flaVersion.ordinal()>=FLAVersion.CC.ordinal()?" <svgFileName>1</svgFileName>\n":" <qtFileName>1</qtFileName>\n")
+ " <rnwkFileName>" + baseName + ".smil</rnwkFileName>\n"
+ " <swcFileName>" + baseName + ".swc</swcFileName>\n"
+ " </PublishFormatProperties>\n"
@@ -2660,8 +2672,8 @@ public class XFLConverter {
+ " <EventFormat>0</EventFormat>\n"
+ " <EventCompress>7</EventCompress>\n"
+ " <OverrideSounds>0</OverrideSounds>\n"
+ " <Version>15</Version>\n"
+ " <ExternalPlayer>FlashPlayer11.2</ExternalPlayer>\n"
+ " <Version>"+flaSwfVersion+"</Version>\n"
+ " <ExternalPlayer>"+FLAVersion.swfVersionToPlayer(flaSwfVersion)+"</ExternalPlayer>\n"
+ " <ActionScriptVersion>" + (useAS3 ? "3" : "2") + "</ActionScriptVersion>\n"
+ " <PackageExportFrame>1</PackageExportFrame>\n"
+ " <PackagePaths></PackagePaths>\n"
@@ -2691,7 +2703,27 @@ public class XFLConverter {
+ " <DefaultLibraryLinkage>rsl</DefaultLibraryLinkage>\n"
+ " <RSLPreloaderMethod>wrap</RSLPreloaderMethod>\n"
+ " <RSLPreloaderSWF>$(AppConfig)/ActionScript 3.0/rsls/loader_animation.swf</RSLPreloaderSWF>\n"
+ " <LibraryPath>\n"
+ ((flaVersion.ordinal()>=FLAVersion.CC.ordinal())?(
" <LibraryPath>\n"
+ " <library-path-entry>\n"
+ " <swc-path>$(AppConfig)/ActionScript 3.0/libs</swc-path>\n"
+ " <linkage>merge</linkage>\n"
+ " </library-path-entry>\n"
+ " <library-path-entry>\n"
+ " <swc-path>$(FlexSDK)/frameworks/libs/flex.swc</swc-path>\n"
+ " <linkage>merge</linkage>\n"
+ " <rsl-url>textLayout_2.0.0.232.swz</rsl-url>\n"
+ " </library-path-entry>\n"
+ " <library-path-entry>\n"
+ " <swc-path>$(FlexSDK)/frameworks/libs/core.swc</swc-path>\n"
+ " <linkage>merge</linkage>\n"
+ " <rsl-url>textLayout_2.0.0.232.swz</rsl-url>\n"
+ " </library-path-entry>\n"
+ " </LibraryPath>\n"
+ " <LibraryVersions>\n"
+ " </LibraryVersions> "):
" <LibraryPath>\n"
+ " <library-path-entry>\n"
+ " <swc-path>$(AppConfig)/ActionScript 3.0/libs</swc-path>\n"
+ " <linkage>merge</linkage>\n"
@@ -2712,7 +2744,9 @@ public class XFLConverter {
+ " <policy-file-url>http://fpdownload.adobe.com/pub/swz/crossdomain.xml</policy-file-url>\n"
+ " <rsl-url>textLayout_2.0.0.232.swz</rsl-url>\n"
+ " </library-version>\n"
+ " </LibraryVersions>\n"
+ " </LibraryVersions>\n")
+ " </PublishFlashProperties>\n"
+ " <PublishJpegProperties enabled=\"true\">\n"
+ " <Width>" + width + "</Width>\n"
@@ -2776,7 +2810,9 @@ public class XFLConverter {
+ " <MaxColors>255</MaxColors>\n"
+ " <PaletteName></PaletteName>\n"
+ " </PublishPNGProperties>\n"
+ " <PublishQTProperties enabled=\"true\">\n"
+ ((flaVersion.ordinal()>=FLAVersion.CC.ordinal())?"":
(" <PublishQTProperties enabled=\"true\">\n"
+ " <Width>" + width + "</Width>\n"
+ " <Height>" + height + "</Height>\n"
+ " <MatchMovieDim>1</MatchMovieDim>\n"
@@ -2789,7 +2825,7 @@ public class XFLConverter {
+ " <PausedAtStart>0</PausedAtStart>\n"
+ " <PlayEveryFrame>0</PlayEveryFrame>\n"
+ " <Flatten>1</Flatten>\n"
+ " </PublishQTProperties>\n"
+ " </PublishQTProperties>\n"))
+ "</flash_profile>\n"
+ "</flash_profiles>";