Merge branch 'master' into dev

# Conflicts:
#	CHANGELOG.md
#	libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java
#	libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java
#	libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggySwfBundle.java
#	src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java
This commit is contained in:
Jindra Petřík
2018-01-13 22:41:04 +01:00
6 changed files with 946 additions and 949 deletions

View File

@@ -1,79 +1,79 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyDeclStrings implements StructureInterface {
@IggyFieldType(DataType.uint64_t)
long one;
//@IggyFieldType(DataType.uint32_t)
//long size;
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
byte xxx[];
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
byte data[];
byte padd[];
@IggyFieldType(DataType.uint64_t)
long one2;
@IggyFieldType(DataType.uint64_t)
long zero;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
one = s.readUI64();
long size = s.readUI32();
xxx = s.readBytes(3);
data = s.readBytes((int) size);
if ((15 + size) % 8 != 0) {
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
} else {
padd = new byte[0];
}
one = s.readUI64();
if (one != 1) {
throw new IOException("Wrong iggy font format (declend)!");
}
zero = s.readUI64();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
s.writeUI64(one);
s.writeUI32(data.length);
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
s.writeBytes(xxx);
s.writeBytes(data);
ib.writeLengthUI32(data.length);
if ((15 + data.length) % 8 != 0) {
byte[] padd = new byte[((int) (((15 + data.length) / 8 + 1) * 8 - 15 - data.length))];
s.writeBytes(padd);
}
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeUI64(one);
s.writeUI64(zero);
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyDeclStrings implements StructureInterface {
@IggyFieldType(DataType.uint64_t)
long one;
//@IggyFieldType(DataType.uint32_t)
//long size;
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
byte xxx[];
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
byte data[];
byte padd[];
@IggyFieldType(DataType.uint64_t)
long one2;
@IggyFieldType(DataType.uint64_t)
long zero;
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
one = s.readUI64();
long size = s.readUI32();
xxx = s.readBytes(3);
data = s.readBytes((int) size);
if ((15 + size) % 8 != 0) {
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
} else {
padd = new byte[0];
}
one = s.readUI64();
if (one != 1) {
throw new IOException("Wrong iggy font format (declend)!");
}
zero = s.readUI64();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
IggyIndexBuilder ib = s.getIndexing();
s.writeUI64(one);
s.writeUI32(data.length);
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
s.writeBytes(xxx);
s.writeBytes(data);
ib.writeLengthUI32(data.length);
if ((15 + data.length) % 8 != 0) {
byte[] padd = new byte[((int) (((15 + data.length) / 8 + 1) * 8 - 15 - data.length))];
s.writeBytes(padd);
}
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
s.writeUI64(one);
s.writeUI64(zero);
}
}

View File

@@ -22,7 +22,6 @@ public class IggySwf implements StructureInterface {
String name;
private List<IggyFont> fonts = new ArrayList<>();
// private List<Long> font_data_addresses = new ArrayList<>();
private List<IggyFont> add_fonts = new ArrayList<>();
// private List<Long> add_font_data_addresses = new ArrayList<>();
@@ -34,7 +33,6 @@ public class IggySwf implements StructureInterface {
}
private List<IggyText> texts = new ArrayList<>();
//private List<Long> text_data_addresses = new ArrayList<>();
private List<IggyText> add_texts = new ArrayList<>();
//private List<Long> add_text_data_addresses = new ArrayList<>();
@@ -42,7 +40,6 @@ public class IggySwf implements StructureInterface {
//private byte font_add_data[];
//private List<Long> font_additional_size = new ArrayList<>();
private IggyFontBinInfo font_bin_info[];
private List<String> sequenceNames = new ArrayList<>();
//private List<Long> sequenceValues = new ArrayList<>();

View File

@@ -1,198 +1,198 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
public static final int STRUCT_SIZE = 104;
public static final int ID = 0xFF06;
@IggyFieldType(DataType.uint16_t)
int type; // Tag type
@IggyFieldType(DataType.uint16_t)
int textIndex;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte zeroone[];
@IggyFieldType(DataType.float_t)
float par1;
@IggyFieldType(DataType.float_t)
float par2;
@IggyFieldType(DataType.float_t)
float par3;
@IggyFieldType(DataType.float_t)
float par4;
@IggyFieldType(DataType.uint16_t)
int enum_hex;
//Guessed
boolean hasText;
boolean wordWrap;
boolean multiline;
boolean password;
boolean readOnly;
boolean hasTextColor;
boolean hasMaxLength;
boolean hasFont;
boolean hasFontClass;
boolean autosize;
boolean hasLayout;
boolean noSelect;
boolean border;
boolean wasStatic;
boolean html;
boolean useOutlines;
@IggyFieldType(DataType.uint16_t)
int fontIndex;
@IggyFieldType(DataType.uint32_t)
long zero;
@IggyFieldType(DataType.uint64_t)
long one;
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
byte[] some; // same for different fonts
long ofs_name;
@IggyArrayFieldType(value = DataType.wchar_t)
String initialText; //till end of info file?
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
this.type = type;
this.textIndex = order_in_iggy_file;
this.zeroone = zeroone;
this.par1 = par1;
this.par2 = par2;
this.par3 = par3;
this.par4 = par4;
this.enum_hex = enum_hex;
this.fontIndex = for_which_font_order_in_iggyfile;
this.zero = zero;
this.one = one;
this.some = some;
this.initialText = name;
}
public IggyText(ReadDataStreamInterface stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
type = s.readUI16();
//characterId - iggy Id
textIndex = s.readUI16();
zeroone = s.readBytes(28);
//bounds?:
par1 = s.readFloat();
par2 = s.readFloat();
par3 = s.readFloat();
par4 = s.readFloat();
enum_hex = s.readUI16();
fontIndex = s.readUI16(); //fontId
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
ofs_name = s.readUI64();
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
initialText = s.readWChar();
s.pad8bytes();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
s.writeUI16(type);
s.writeUI16(textIndex);
s.writeBytes(zeroone);
s.writeFloat(par1);
s.writeFloat(par2);
s.writeFloat(par3);
s.writeFloat(par4);
s.writeUI16(enum_hex);
s.writeUI16(fontIndex);
s.writeUI32(zero);
s.writeUI64(one);
s.writeBytes(some);
s.writeUI64(ofs_name);
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
s.writeWChar(initialText);
s.pad8bytes();
s.getIndexing().write16bitArray(initialText.length() + 1);
s.getIndexing().pad8bytes();
}
public int getType() {
return type;
}
public int getTextIndex() {
return textIndex;
}
public byte[] getZeroone() {
return zeroone;
}
public float getPar1() {
return par1;
}
public float getPar2() {
return par2;
}
public float getPar3() {
return par3;
}
public float getPar4() {
return par4;
}
public int getEnum_hex() {
return enum_hex;
}
public int getFontIndex() {
return fontIndex;
}
public long getZero() {
return zero;
}
public long getOne() {
return one;
}
public byte[] getSome() {
return some;
}
public String getInitialText() {
return initialText;
}
public void setInitialText(String initialText) {
this.initialText = initialText;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
public static final int STRUCT_SIZE = 104;
public static final int ID = 0xFF06;
@IggyFieldType(DataType.uint16_t)
int type; // Tag type
@IggyFieldType(DataType.uint16_t)
int textIndex;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte zeroone[];
@IggyFieldType(DataType.float_t)
float par1;
@IggyFieldType(DataType.float_t)
float par2;
@IggyFieldType(DataType.float_t)
float par3;
@IggyFieldType(DataType.float_t)
float par4;
@IggyFieldType(DataType.uint16_t)
int enum_hex;
//Guessed
boolean hasText;
boolean wordWrap;
boolean multiline;
boolean password;
boolean readOnly;
boolean hasTextColor;
boolean hasMaxLength;
boolean hasFont;
boolean hasFontClass;
boolean autosize;
boolean hasLayout;
boolean noSelect;
boolean border;
boolean wasStatic;
boolean html;
boolean useOutlines;
@IggyFieldType(DataType.uint16_t)
int fontIndex;
@IggyFieldType(DataType.uint32_t)
long zero;
@IggyFieldType(DataType.uint64_t)
long one;
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
byte[] some; // same for different fonts
long ofs_name;
@IggyArrayFieldType(value = DataType.wchar_t)
String initialText; //till end of info file?
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
this.type = type;
this.textIndex = order_in_iggy_file;
this.zeroone = zeroone;
this.par1 = par1;
this.par2 = par2;
this.par3 = par3;
this.par4 = par4;
this.enum_hex = enum_hex;
this.fontIndex = for_which_font_order_in_iggyfile;
this.zero = zero;
this.one = one;
this.some = some;
this.initialText = name;
}
public IggyText(ReadDataStreamInterface stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
type = s.readUI16();
//characterId - iggy Id
textIndex = s.readUI16();
zeroone = s.readBytes(28);
//bounds?:
par1 = s.readFloat();
par2 = s.readFloat();
par3 = s.readFloat();
par4 = s.readFloat();
enum_hex = s.readUI16();
fontIndex = s.readUI16(); //fontId
zero = s.readUI32();
one = s.readUI64(); //01CB FF33 3333
some = s.readBytes(32); // [6] => 40, [24] => 8
ofs_name = s.readUI64();
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
initialText = s.readWChar();
s.pad8bytes();
}
@Override
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
s.writeUI16(type);
s.writeUI16(textIndex);
s.writeBytes(zeroone);
s.writeFloat(par1);
s.writeFloat(par2);
s.writeFloat(par3);
s.writeFloat(par4);
s.writeUI16(enum_hex);
s.writeUI16(fontIndex);
s.writeUI32(zero);
s.writeUI64(one);
s.writeBytes(some);
s.writeUI64(ofs_name);
long name_address = ofs_name + s.position() - 8;
s.seek(name_address, SeekMode.SET);
s.writeWChar(initialText);
s.pad8bytes();
s.getIndexing().write16bitArray(initialText.length() + 1);
s.getIndexing().pad8bytes();
}
public int getType() {
return type;
}
public int getTextIndex() {
return textIndex;
}
public byte[] getZeroone() {
return zeroone;
}
public float getPar1() {
return par1;
}
public float getPar2() {
return par2;
}
public float getPar3() {
return par3;
}
public float getPar4() {
return par4;
}
public int getEnum_hex() {
return enum_hex;
}
public int getFontIndex() {
return fontIndex;
}
public long getZero() {
return zero;
}
public long getOne() {
return one;
}
public byte[] getSome() {
return some;
}
public String getInitialText() {
return initialText;
}
public void setInitialText(String initialText) {
this.initialText = initialText;
}
}

View File

@@ -1,271 +1,271 @@
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFCompression;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyDeclStrings;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import com.jpexs.helpers.ByteArrayRange;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* WIP
*
* @author JPEXS
*/
public class IggyToSwfConvertor {
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
exportSwfToDir(file, outputDir);
}
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
exportSwf(file, fos);
}
}
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
exportSwf(file, fos);
}
}
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
SWF swf = getSwf(file);
swf.saveTo(output);
}
private static int makeLengthsEm(double val) {
return (int) (val * 1024.0);
}
private static int makeLengthsTwip(double val) {
return (int) (val * SWF.unitDivisor);
}
public static SWF getSwf(IggyFile file) {
SWF swf = new SWF();
swf.compression = SWFCompression.NONE;
swf.frameCount = 1; //FIXME!!
swf.frameRate = file.getSwfFrameRate();
swf.gfx = false;
swf.displayRect = new RECT(
makeLengthsTwip(file.getSwfXMin()),
makeLengthsTwip(file.getSwfXMax()),
makeLengthsTwip(file.getSwfYMin()),
makeLengthsTwip(file.getSwfYMax()));
swf.version = 10; //FIXME
FileAttributesTag fat = new FileAttributesTag(swf);
fat.actionScript3 = true;
fat.hasMetadata = false;
fat.useNetwork = false;
swf.addTag(fat);
IggySwf iggySwf = file.getSwf();
int currentCharId = 0;
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
for (int fontIndex = 0; fontIndex < iggySwf.getFonts().size(); fontIndex++) {
IggyFont iggyFont = iggySwf.getFonts().get(fontIndex);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
currentCharId++;
fontIndex2CharId.put(fontIndex, currentCharId);
fontTag.fontID = currentCharId;
/*System.out.println("===================");
System.out.println("xscale: " + iggyFont.getXscale()); //80
System.out.println("yscale: " + iggyFont.getYscale()); //19
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
System.out.println("what_2: " + iggyFont.getWhat_2());
System.out.println("what_3: " + iggyFont.getWhat_3());*/
fontTag.fontKerningTable = new ArrayList<>();
IggyCharKerning ker = iggyFont.getCharKernings();
if (ker != null) {
for (int i = 0; i < ker.getKernCount(); i++) {
int kerningCode1 = ker.getCharsA().get(i);
int kerningCode2 = ker.getCharsA().get(i);
int kerningOffset = ker.getKerningOffsets().get(i);
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
}
}
fontTag.fontFlagsWideCodes = true;
fontTag.fontFlagsWideOffsets = true;
fontTag.fontAscent = iggyFont.getAscent();
fontTag.fontDescent = iggyFont.getDescent();
fontTag.fontLeading = iggyFont.getLeading();
fontTag.codeTable = new ArrayList<>();
fontTag.fontName = iggyFont.getName();
fontTag.glyphShapeTable = new ArrayList<>();
fontTag.fontBoundsTable = new ArrayList<>();
fontTag.fontAdvanceTable = new ArrayList<>();
fontTag.fontFlagsHasLayout = true;
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
int code = iggyFont.getCharIndices().getChars().get(i);
fontTag.codeTable.add(code);
IggyShape glyph = iggyFont.getChars().get(i);
SHAPE shp;
if (glyph != null) {
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
fontTag.fontBoundsTable.add(shp.getBounds());
} else {
shp = new SHAPE();
shp.shapeRecords = new ArrayList<>();
shp.shapeRecords.add(new EndShapeRecord());
fontTag.fontBoundsTable.add(new RECT()); //??
}
fontTag.glyphShapeTable.add(shp);
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
}
fontTag.setModified(true);
swf.addTag(fontTag);
}
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
for (int textIndex = 0; textIndex < iggySwf.getTexts().size(); textIndex++) {
IggyText iggyText = iggySwf.getTexts().get(textIndex);
DefineEditTextTag textTag = new DefineEditTextTag(swf);
currentCharId++;
textIndex2CharId.put(textIndex, currentCharId);
textTag.characterID = currentCharId;
textTag.hasText = true;
textTag.initialText = iggyText.getInitialText();
textTag.html = true;
textTag.noSelect = true;
textTag.wasStatic = true;
textTag.hasFont = false;
textTag.hasFontClass = false;
textTag.hasMaxLength = false;
//textTag.multiline = true;
//textTag.wordWrap = true;
//textTag.hasTextColor = true;
//textTag.textColor = new RGBA(Color.black);
//textTag.fontHeight = 40; //??
textTag.readOnly = true;
textTag.bounds = new RECT(
makeLengthsTwip(iggyText.getPar1()),
makeLengthsTwip(iggyText.getPar3()),
makeLengthsTwip(iggyText.getPar2()),
makeLengthsTwip(iggyText.getPar4())
);
//textTag.hasFont = true;
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
textTag.setModified(true);
swf.addTag(textTag);
}
IggyDeclStrings declStrings = iggySwf.getDeclStrings();
if (declStrings != null) {
byte[] abcData = declStrings.getData();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(new byte[]{1, 0, 0, 0, 0, 0x10, 0, 0x2E});
baos.write(abcData);
} catch (IOException ex) {
//should not happen
}
byte[] fullAbcTagData = baos.toByteArray();
try {
DoABC2Tag nabc = new DoABC2Tag(new SWFInputStream(swf, fullAbcTagData), new ByteArrayRange(fullAbcTagData));
nabc.setModified(true);
swf.addTag(nabc);
} catch (IOException ex) {
//ignore
}
}
swf.addTag(
new EndTag(swf));
swf.setModified(
true);
return swf;
}
public static void main(String[] args) {
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
System.err.println("Invalid arguments");
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
System.exit(1);
}
File file = new File(args[0]);
if (!file.exists()) {
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
System.exit(1);
}
File outDir = new File(args[1]);
if (!outDir.exists()) {
if (!outDir.mkdirs()) {
System.err.println("FAIL: Cannot create output directory");
System.exit(1);
}
}
try {
System.out.print("(1/2) Loading file " + args[0] + "...");
IggyFile iggyFile = new IggyFile(new File(args[0]));
System.out.println("OK");
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
exportAllSwfsToDir(iggyFile, new File(args[1]));
System.out.println("OK");
System.out.println("All finished sucessfully.");
System.exit(0);
} catch (IOException ex) {
System.out.println("FAIL");
System.err.println("Error while converting: " + ex.getMessage());
System.exit(1);
}
}
}
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFCompression;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyDeclStrings;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import com.jpexs.helpers.ByteArrayRange;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* WIP
*
* @author JPEXS
*/
public class IggyToSwfConvertor {
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
exportSwfToDir(file, outputDir);
}
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
exportSwf(file, fos);
}
}
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
exportSwf(file, fos);
}
}
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
SWF swf = getSwf(file);
swf.saveTo(output);
}
private static int makeLengthsEm(double val) {
return (int) (val * 1024.0);
}
private static int makeLengthsTwip(double val) {
return (int) (val * SWF.unitDivisor);
}
public static SWF getSwf(IggyFile file) {
SWF swf = new SWF();
swf.compression = SWFCompression.NONE;
swf.frameCount = 1; //FIXME!!
swf.frameRate = file.getSwfFrameRate();
swf.gfx = false;
swf.displayRect = new RECT(
makeLengthsTwip(file.getSwfXMin()),
makeLengthsTwip(file.getSwfXMax()),
makeLengthsTwip(file.getSwfYMin()),
makeLengthsTwip(file.getSwfYMax()));
swf.version = 10; //FIXME
FileAttributesTag fat = new FileAttributesTag(swf);
fat.actionScript3 = true;
fat.hasMetadata = false;
fat.useNetwork = false;
swf.addTag(fat);
IggySwf iggySwf = file.getSwf();
int currentCharId = 0;
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
for (int fontIndex = 0; fontIndex < iggySwf.getFonts().size(); fontIndex++) {
IggyFont iggyFont = iggySwf.getFonts().get(fontIndex);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
currentCharId++;
fontIndex2CharId.put(fontIndex, currentCharId);
fontTag.fontID = currentCharId;
/*System.out.println("===================");
System.out.println("xscale: " + iggyFont.getXscale()); //80
System.out.println("yscale: " + iggyFont.getYscale()); //19
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
System.out.println("what_2: " + iggyFont.getWhat_2());
System.out.println("what_3: " + iggyFont.getWhat_3());*/
fontTag.fontKerningTable = new ArrayList<>();
IggyCharKerning ker = iggyFont.getCharKernings();
if (ker != null) {
for (int i = 0; i < ker.getKernCount(); i++) {
int kerningCode1 = ker.getCharsA().get(i);
int kerningCode2 = ker.getCharsA().get(i);
int kerningOffset = ker.getKerningOffsets().get(i);
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
}
}
fontTag.fontFlagsWideCodes = true;
fontTag.fontFlagsWideOffsets = true;
fontTag.fontAscent = iggyFont.getAscent();
fontTag.fontDescent = iggyFont.getDescent();
fontTag.fontLeading = iggyFont.getLeading();
fontTag.codeTable = new ArrayList<>();
fontTag.fontName = iggyFont.getName();
fontTag.glyphShapeTable = new ArrayList<>();
fontTag.fontBoundsTable = new ArrayList<>();
fontTag.fontAdvanceTable = new ArrayList<>();
fontTag.fontFlagsHasLayout = true;
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
int code = iggyFont.getCharIndices().getChars().get(i);
fontTag.codeTable.add(code);
IggyShape glyph = iggyFont.getChars().get(i);
SHAPE shp;
if (glyph != null) {
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
fontTag.fontBoundsTable.add(shp.getBounds());
} else {
shp = new SHAPE();
shp.shapeRecords = new ArrayList<>();
shp.shapeRecords.add(new EndShapeRecord());
fontTag.fontBoundsTable.add(new RECT()); //??
}
fontTag.glyphShapeTable.add(shp);
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
}
fontTag.setModified(true);
swf.addTag(fontTag);
}
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
for (int textIndex = 0; textIndex < iggySwf.getTexts().size(); textIndex++) {
IggyText iggyText = iggySwf.getTexts().get(textIndex);
DefineEditTextTag textTag = new DefineEditTextTag(swf);
currentCharId++;
textIndex2CharId.put(textIndex, currentCharId);
textTag.characterID = currentCharId;
textTag.hasText = true;
textTag.initialText = iggyText.getInitialText();
textTag.html = true;
textTag.noSelect = true;
textTag.wasStatic = true;
textTag.hasFont = false;
textTag.hasFontClass = false;
textTag.hasMaxLength = false;
//textTag.multiline = true;
//textTag.wordWrap = true;
//textTag.hasTextColor = true;
//textTag.textColor = new RGBA(Color.black);
//textTag.fontHeight = 40; //??
textTag.readOnly = true;
textTag.bounds = new RECT(
makeLengthsTwip(iggyText.getPar1()),
makeLengthsTwip(iggyText.getPar3()),
makeLengthsTwip(iggyText.getPar2()),
makeLengthsTwip(iggyText.getPar4())
);
//textTag.hasFont = true;
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
textTag.setModified(true);
swf.addTag(textTag);
}
IggyDeclStrings declStrings = iggySwf.getDeclStrings();
if (declStrings != null) {
byte[] abcData = declStrings.getData();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(new byte[]{1, 0, 0, 0, 0, 0x10, 0, 0x2E});
baos.write(abcData);
} catch (IOException ex) {
//should not happen
}
byte[] fullAbcTagData = baos.toByteArray();
try {
DoABC2Tag nabc = new DoABC2Tag(new SWFInputStream(swf, fullAbcTagData), new ByteArrayRange(fullAbcTagData));
nabc.setModified(true);
swf.addTag(nabc);
} catch (IOException ex) {
//ignore
}
}
swf.addTag(
new EndTag(swf));
swf.setModified(
true);
return swf;
}
public static void main(String[] args) {
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
System.err.println("Invalid arguments");
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
System.exit(1);
}
File file = new File(args[0]);
if (!file.exists()) {
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
System.exit(1);
}
File outDir = new File(args[1]);
if (!outDir.exists()) {
if (!outDir.mkdirs()) {
System.err.println("FAIL: Cannot create output directory");
System.exit(1);
}
}
try {
System.out.print("(1/2) Loading file " + args[0] + "...");
IggyFile iggyFile = new IggyFile(new File(args[0]));
System.out.println("OK");
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
exportAllSwfsToDir(iggyFile, new File(args[1]));
System.out.println("OK");
System.out.println("All finished sucessfully.");
System.exit(0);
} catch (IOException ex) {
System.out.println("FAIL");
System.err.println("Error while converting: " + ex.getMessage());
System.exit(1);
}
}
}

View File

@@ -1,210 +1,210 @@
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.SHAPE;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public class SwfToIggyConvertor {
private static float normalizeLengths(int val) {
return (val / 1024f);
}
public static void updateIggy(IggySwf iggySwf, SWF swf) throws IOException {
List<DefineFont2Tag> fontTags = new ArrayList<>();
List<DefineEditTextTag> textTags = new ArrayList<>();
List<DoABC2Tag> abcTags = new ArrayList<>();
for (Tag t : swf.getTags()) {
if (t instanceof DefineFont2Tag) {
fontTags.add((DefineFont2Tag) t);
}
if (t instanceof DefineEditTextTag) {
textTags.add((DefineEditTextTag) t);
}
if (t instanceof DoABC2Tag) {
abcTags.add((DoABC2Tag) t);
}
}
if (abcTags.size() > 1) {
throw new IOException("Cannot save more than one ABC tag");
}
int fontCount = iggySwf.getFonts().size();
if (fontCount != fontTags.size()) {
throw new IOException("Font count is different from original iggy file");
}
for (int i = 0; i < fontCount; i++) {
IggyFont iggyFont = iggySwf.getFonts().get(i);
DefineFont2Tag fontTag = fontTags.get(i);
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
}
int textCount = iggySwf.getTexts().size();
if (textCount != textTags.size()) {
throw new IOException("Text count is different from original iggy file");
}
for (int i = 0; i < textCount; i++) {
IggyText iggyText = iggySwf.getTexts().get(i);
DefineEditTextTag textTag = textTags.get(i);
SwfToIggyConvertor.updateIggyText(iggyText, textTag);
}
if (!abcTags.isEmpty()) {
DoABC2Tag abcTag = abcTags.get(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte abcTagData[] = abcTag.getData();
byte declData[] = Arrays.copyOfRange(abcTagData, 4/*UI32 flags*/ + 1 /*empty string as name*/ + 3 /*versions, leaving one zero intact*/, abcTagData.length);
iggySwf.getDeclStrings().setData(declData);
}
}
public static void updateIggyText(IggyText iggyText, DefineEditTextTag textTag) {
iggyText.setInitialText(textTag.initialText);
}
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
/*byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;*/
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
for (SHAPE s : fontTag.glyphShapeTable) {
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
}
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add(normalizeLengths(adv));
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
//IggyCharOffset
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
}
iggyFont.setCharCount(fontTag.getCharacterCount());
iggyFont.setCharCount2(fontTag.getCharacterCount());
iggyFont.setAscent(fontTag.getAscent());
iggyFont.setDescent(fontTag.getDescent());
iggyFont.setLeading(fontTag.getLeading());
iggyFont.setName(fontTag.getFontName());
iggyFont.setCharOffsets(charOffsets);
iggyFont.setGlyphs(glyphs);
iggyFont.setCodePoints(codePoints);
iggyFont.setCharScales(charScales);
iggyFont.setCharKernings(charKernings);
}
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add((float) adv);
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
charOffsets, glyphs, codePoints, charScales, charKernings);
return iggyFont;
}
}
package com.jpexs.decompiler.flash.iggy.conversion;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggyShape;
import com.jpexs.decompiler.flash.iggy.IggySwf;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.SHAPE;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public class SwfToIggyConvertor {
private static float normalizeLengths(int val) {
return (val / 1024f);
}
public static void updateIggy(IggySwf iggySwf, SWF swf) throws IOException {
List<DefineFont2Tag> fontTags = new ArrayList<>();
List<DefineEditTextTag> textTags = new ArrayList<>();
List<DoABC2Tag> abcTags = new ArrayList<>();
for (Tag t : swf.getTags()) {
if (t instanceof DefineFont2Tag) {
fontTags.add((DefineFont2Tag) t);
}
if (t instanceof DefineEditTextTag) {
textTags.add((DefineEditTextTag) t);
}
if (t instanceof DoABC2Tag) {
abcTags.add((DoABC2Tag) t);
}
}
if (abcTags.size() > 1) {
throw new IOException("Cannot save more than one ABC tag");
}
int fontCount = iggySwf.getFonts().size();
if (fontCount != fontTags.size()) {
throw new IOException("Font count is different from original iggy file");
}
for (int i = 0; i < fontCount; i++) {
IggyFont iggyFont = iggySwf.getFonts().get(i);
DefineFont2Tag fontTag = fontTags.get(i);
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
}
int textCount = iggySwf.getTexts().size();
if (textCount != textTags.size()) {
throw new IOException("Text count is different from original iggy file");
}
for (int i = 0; i < textCount; i++) {
IggyText iggyText = iggySwf.getTexts().get(i);
DefineEditTextTag textTag = textTags.get(i);
SwfToIggyConvertor.updateIggyText(iggyText, textTag);
}
if (!abcTags.isEmpty()) {
DoABC2Tag abcTag = abcTags.get(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte abcTagData[] = abcTag.getData();
byte declData[] = Arrays.copyOfRange(abcTagData, 4/*UI32 flags*/ + 1 /*empty string as name*/ + 3 /*versions, leaving one zero intact*/, abcTagData.length);
iggySwf.getDeclStrings().setData(declData);
}
}
public static void updateIggyText(IggyText iggyText, DefineEditTextTag textTag) {
iggyText.setInitialText(textTag.initialText);
}
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
/*byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;*/
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
for (SHAPE s : fontTag.glyphShapeTable) {
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
}
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add(normalizeLengths(adv));
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
//IggyCharOffset
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
}
iggyFont.setCharCount(fontTag.getCharacterCount());
iggyFont.setCharCount2(fontTag.getCharacterCount());
iggyFont.setAscent(fontTag.getAscent());
iggyFont.setDescent(fontTag.getDescent());
iggyFont.setLeading(fontTag.getLeading());
iggyFont.setName(fontTag.getFontName());
iggyFont.setCharOffsets(charOffsets);
iggyFont.setGlyphs(glyphs);
iggyFont.setCodePoints(codePoints);
iggyFont.setCharScales(charScales);
iggyFont.setCharKernings(charKernings);
}
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
byte zeroone[] = new byte[28];
zeroone[12] = 1;
long flags = 65795;
float unk_float[] = new float[]{
-0.6484375f,
-1.116211f,
1.116211f,
0.6679688f,
0f
};
int xscale = 80;
int yscale = 28;
float ssr1 = 0.9f;
float ssr2 = 0.3f;
long what_2 = 33188160;
long what_3 = 33600216;
byte zeroes48a[] = new byte[48];
byte zeroes48b[] = new byte[48];
float sss1 = 1.1728859f;
float sss2 = 1.1728706f;
float sss3 = 1.1728821f;
float sss4 = 1.1729145f;
List<IggyCharOffset> charOffsets = new ArrayList<>();
List<IggyShape> glyphs = new ArrayList<>();
List<Character> chars = new ArrayList<>();
for (int code : fontTag.codeTable) {
chars.add((char) code);
}
IggyCharIndices codePoints = new IggyCharIndices(chars);
List<Float> scales = new ArrayList<>();
for (int adv : fontTag.fontAdvanceTable) {
scales.add((float) adv);
}
IggyCharAdvances charScales = new IggyCharAdvances(scales);
List<Character> charA = new ArrayList<>();
List<Character> charB = new ArrayList<>();
List<Short> kernOffs = new ArrayList<>();
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
charA.add((char) rec.fontKerningCode1);
charB.add((char) rec.fontKerningCode2);
kernOffs.add((short) rec.fontKerningAdjustment);
}
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
charOffsets, glyphs, codePoints, charScales, charKernings);
return iggyFont;
}
}

View File

@@ -1,188 +1,188 @@
/*
* Copyright (C) 2010-2016 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.treeitems;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFContainerItem;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author JPEXS
*/
public class SWFList implements List<SWF>, SWFContainerItem {
public String name;
public SWFBundle bundle;
public SWFSourceInfo sourceInfo;
public List<SWF> swfs = new ArrayList<>();
public boolean isBundle() {
return bundle != null;
}
@Override
public SWF getSwf() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
if (isBundle()) {
return name;
} else {
return swfs.get(0).getFileTitle();
}
}
@Override
public Iterator<SWF> iterator() {
return swfs.iterator();
}
@Override
public int size() {
return swfs.size();
}
@Override
public boolean isEmpty() {
return swfs.isEmpty();
}
@Override
public boolean contains(Object o) {
return swfs.contains(o);
}
@Override
public Object[] toArray() {
return swfs.toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return swfs.toArray(ts);
}
@Override
public boolean add(SWF e) {
return swfs.add(e);
}
@Override
public boolean remove(Object o) {
return swfs.remove(o);
}
@Override
public boolean containsAll(Collection<?> clctn) {
return swfs.containsAll(clctn);
}
@Override
public boolean addAll(Collection<? extends SWF> clctn) {
return swfs.addAll(clctn);
}
@Override
public boolean removeAll(Collection<?> clctn) {
return swfs.removeAll(clctn);
}
@Override
public boolean retainAll(Collection<?> clctn) {
return swfs.retainAll(clctn);
}
@Override
public void clear() {
swfs.clear();
}
@Override
public boolean addAll(int i, Collection<? extends SWF> clctn) {
return swfs.addAll(i, clctn);
}
@Override
public SWF get(int i) {
if (i < 0 || i >= swfs.size()) {
return null;
}
return swfs.get(i);
}
@Override
public SWF set(int i, SWF e) {
return swfs.set(i, e);
}
@Override
public void add(int i, SWF e) {
swfs.add(i, e);
}
@Override
public SWF remove(int i) {
return swfs.remove(i);
}
@Override
public int indexOf(Object o) {
return swfs.indexOf(0);
}
@Override
public int lastIndexOf(Object o) {
return swfs.lastIndexOf(o);
}
@Override
public ListIterator<SWF> listIterator() {
return swfs.listIterator();
}
@Override
public ListIterator<SWF> listIterator(int i) {
return swfs.listIterator(i);
}
@Override
public List<SWF> subList(int i, int i1) {
return swfs.subList(i, i1);
}
@Override
public boolean isModified() {
for (SWF s : swfs) {
if (s.isModified()) {
return true;
}
}
return false;
}
}
/*
* Copyright (C) 2010-2016 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.treeitems;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.SWFContainerItem;
import com.jpexs.decompiler.flash.SWFSourceInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author JPEXS
*/
public class SWFList implements List<SWF>, SWFContainerItem {
public String name;
public SWFBundle bundle;
public SWFSourceInfo sourceInfo;
public List<SWF> swfs = new ArrayList<>();
public boolean isBundle() {
return bundle != null;
}
@Override
public SWF getSwf() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
if (isBundle()) {
return name;
} else {
return swfs.get(0).getFileTitle();
}
}
@Override
public Iterator<SWF> iterator() {
return swfs.iterator();
}
@Override
public int size() {
return swfs.size();
}
@Override
public boolean isEmpty() {
return swfs.isEmpty();
}
@Override
public boolean contains(Object o) {
return swfs.contains(o);
}
@Override
public Object[] toArray() {
return swfs.toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return swfs.toArray(ts);
}
@Override
public boolean add(SWF e) {
return swfs.add(e);
}
@Override
public boolean remove(Object o) {
return swfs.remove(o);
}
@Override
public boolean containsAll(Collection<?> clctn) {
return swfs.containsAll(clctn);
}
@Override
public boolean addAll(Collection<? extends SWF> clctn) {
return swfs.addAll(clctn);
}
@Override
public boolean removeAll(Collection<?> clctn) {
return swfs.removeAll(clctn);
}
@Override
public boolean retainAll(Collection<?> clctn) {
return swfs.retainAll(clctn);
}
@Override
public void clear() {
swfs.clear();
}
@Override
public boolean addAll(int i, Collection<? extends SWF> clctn) {
return swfs.addAll(i, clctn);
}
@Override
public SWF get(int i) {
if (i < 0 || i >= swfs.size()) {
return null;
}
return swfs.get(i);
}
@Override
public SWF set(int i, SWF e) {
return swfs.set(i, e);
}
@Override
public void add(int i, SWF e) {
swfs.add(i, e);
}
@Override
public SWF remove(int i) {
return swfs.remove(i);
}
@Override
public int indexOf(Object o) {
return swfs.indexOf(0);
}
@Override
public int lastIndexOf(Object o) {
return swfs.lastIndexOf(o);
}
@Override
public ListIterator<SWF> listIterator() {
return swfs.listIterator();
}
@Override
public ListIterator<SWF> listIterator(int i) {
return swfs.listIterator(i);
}
@Override
public List<SWF> subList(int i, int i1) {
return swfs.subList(i, i1);
}
@Override
public boolean isModified() {
for (SWF s : swfs) {
if (s.isModified()) {
return true;
}
}
return false;
}
}