Distinguish texts and fonts.

This commit is contained in:
Jindra Petřík
2016-11-25 10:59:45 +01:00
parent c5c146906d
commit 6df722eda9
6 changed files with 212 additions and 80 deletions

View File

@@ -19,8 +19,9 @@ public class IggyDataReader implements StructureInterface {
@IggyFieldType(value = DataType.widechar_t, count = 48)
String name;
List<IggyFontData> fontDatas;
List<IggyFontInfo> fontInfos;
Map<Integer, IggyFont> fonts;
Map<Integer, IggyText> texts;
Map<Integer, Integer> text2Font;
private IggyFlashHeader64 header;
private Map<Long, Long> sizesOfOffsets;
@@ -52,50 +53,55 @@ public class IggyDataReader implements StructureInterface {
stream.readUI64(); //pad 1
long[] font_main_offsets = new long[(int) header.font_count];
long[] fontOffsets = new long[(int) header.font_count];
for (int i = 0; i < header.font_count; i++) {
font_main_offsets[i] = stream.position() + stream.readUI64();
fontOffsets[i] = stream.position() + stream.readUI64();
}
long[] font_info_offsets = new long[(int) header.font_count];
for (int i = 0; i < header.font_count; i++) {
long pos = stream.position();
long offset = stream.readUI64();
font_info_offsets[i] = offset == NO_OFFSET ? NO_OFFSET : pos + offset;
List<Long> textOffsets = new ArrayList<>();
while (true) {
long val = stream.readUI64();
if (val == 1) {
break;
}
textOffsets.add(stream.position() + val);
}
long pad_len = 840 - stream.position();
stream.seek(pad_len, SeekMode.CUR);
/*List<ByteArrayDataStream> fontMainStreams = new ArrayList<>();
//long pad_len = 840 - stream.position();
stream.seek(840, SeekMode.SET);
for (int i = 0; i < header.font_count; i++) {
long fontMainOffset = font_main_offsets[i];
//long fontMainSize = sizesOfOffsets.get(font_main_offsets[i]);
//stream.seek(fontMainOffset, SeekMode.SET);
//byte[] fontMainData = stream.readBytes((int) fontMainSize);
//fontMainStreams.add(new ByteArrayDataStream(fontMainData, stream.is64()));
}*/
List<ByteArrayDataStream> fontInfoStreams = new ArrayList<>();
Long lastOffset = null;
texts = new HashMap<>();
text2Font = new HashMap<>();
long textDataSizes[] = new long[(int) header.font_count];
for (int i = 0; i < header.font_count; i++) {
long fontInfoOffset = font_info_offsets[i];
if (fontInfoOffset == NO_OFFSET) {
fontInfoStreams.add(null);
long offsetAfterTexts = header.as3_section_offset;
for (int i = 0; i < textOffsets.size(); i++) {
long textOffset = textOffsets.get(i);
if (lastOffset == null) {
lastOffset = textOffset;
} else {
long fontInfoSize = sizesOfOffsets.get(font_info_offsets[i]);
stream.seek(fontInfoOffset, SeekMode.SET);
byte[] fontInfoData = stream.readBytes((int) fontInfoSize);
fontInfoStreams.add(new ByteArrayDataStream(fontInfoData, stream.is64()));
textDataSizes[i - 1] = textOffset - lastOffset;
}
}
if (lastOffset != null) {
textDataSizes[(int) header.font_count - 1] = offsetAfterTexts - lastOffset;
}
fontDatas = new ArrayList<>();
fontInfos = new ArrayList<>();
for (int i = 0; i < textOffsets.size(); i++) {
long textOffset = textOffsets.get(i);
stream.seek(textOffset, SeekMode.SET);
byte[] textData = stream.readBytes((int) textDataSizes[i]);
IggyText text = new IggyText(new ByteArrayDataStream(textData, stream.is64()));
text2Font.put(text.textId, text.fontId);
texts.put(text.textId, text);
}
fonts = new HashMap<>();
for (int i = 0; i < header.font_count; i++) {
stream.seek(font_main_offsets[i], SeekMode.SET);
IggyFontData part = new IggyFontData(stream);
fontDatas.add(part);
stream.seek(fontOffsets[i], SeekMode.SET);
IggyFont font = new IggyFont(stream);
fonts.put(font.fontId, font);
}
}

View File

@@ -12,6 +12,7 @@ import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -33,16 +34,20 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable {
private List<IggyFlashHeaderInterface> headers = new ArrayList<>();
private List<IggyDataReader> flashDataReaders = new ArrayList<>();
public int getFontCount(int swfIndex) {
return flashDataReaders.get(swfIndex).fontDatas.size();
public Set<Integer> getFontIds(int swfIndex) {
return flashDataReaders.get(swfIndex).fonts.keySet();
}
public IggyFontData getFontData(int swfIndex, int fontIndex) {
return flashDataReaders.get(swfIndex).fontDatas.get(fontIndex);
public IggyFont getFont(int swfIndex, int fontId) {
return flashDataReaders.get(swfIndex).fonts.get(fontId);
}
public IggyFontInfo getFontInfo(int swfIndex, int fontIndex) {
return null; //FIXME!!! //flashDataReaders.get(swfIndex).fontInfos.get(fontIndex);
public IggyText getText(int swfIndex, int textId) {
return flashDataReaders.get(swfIndex).texts.get(textId);
}
public Set<Integer> getTextIds(int swfIndex) {
return flashDataReaders.get(swfIndex).texts.keySet();
}
@Override
@@ -61,8 +66,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable {
subFileEntries.add(new IggySubFileEntry(this));
}
//TODO: use these two for something
List<List<Integer>> indexTables = new ArrayList<>();
List<List<Integer>> indexTables = new ArrayList<>(); //TODO: use this two for something ??
List<List<Long>> offsetTables = new ArrayList<>();
List<AbstractDataStream> flashDataStreams = new ArrayList<>();
@@ -156,6 +160,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable {
};
}
@Override
protected int read() throws IOException {
int val = raf.read();
if (val == -1) {
@@ -217,6 +222,7 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable {
}
public static void main(String[] args) throws IOException {
System.out.println("Iggy file splitter");
if (args.length == 0) {
System.err.println("No file specified");
System.exit(1);

View File

@@ -12,12 +12,12 @@ import org.omg.CORBA.StructMemberHelper;
*
* @author JPEXS
*/
public class IggyFontData implements StructureInterface {
public class IggyFont implements StructureInterface {
@IggyFieldType(DataType.uint16_t)
int type; //stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
int order_in_iggy_file;
int fontId;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte[] zeroone; // stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
@@ -83,7 +83,6 @@ public class IggyFontData implements StructureInterface {
@IggyFieldType(DataType.uint32_t)
long one_padd5;
//FSeek(start_name);
@IggyFieldType(value = DataType.widechar_t, count = 16)
String name;
@@ -95,9 +94,9 @@ public class IggyFontData implements StructureInterface {
byte[] padTo4byteBoundary;
public IggyFontData(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List<IggyCharOffset> charOffsets, List<IggyChar> chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List<IggyCharOffset> charOffsets, List<IggyChar> chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
this.type = type;
this.order_in_iggy_file = order_in_iggy_file;
this.fontId = order_in_iggy_file;
this.zeroone = zeroone;
this.char_count2 = char_count2;
this.what_1 = what_1;
@@ -139,7 +138,7 @@ public class IggyFontData implements StructureInterface {
this.padTo4byteBoundary = padTo4byteBoundary;
}
public IggyFontData(AbstractDataStream stream) throws IOException {
public IggyFont(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
@@ -155,7 +154,7 @@ public class IggyFontData implements StructureInterface {
public void readFromDataStream(AbstractDataStream stream) throws IOException {
ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64());
type = s.readUI16();
order_in_iggy_file = s.readUI16();
fontId = s.readUI16();
zeroone = s.readBytes(28);
char_count2 = s.readUI16();
what_1 = new int[3];

View File

@@ -1,23 +0,0 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyFontInfo implements StructureInterface {
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@@ -0,0 +1,142 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class IggyText implements StructureInterface {
@IggyFieldType(DataType.uint16_t)
int type; // Tag type
@IggyFieldType(DataType.uint16_t)
int textId;
@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;
@IggyFieldType(DataType.uint16_t)
int fontId;
@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
@IggyArrayFieldType(value = DataType.widechar_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.textId = 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.fontId = for_which_font_order_in_iggyfile;
this.zero = zero;
this.one = one;
this.some = some;
this.initialText = name;
}
public IggyText(AbstractDataStream stream) throws IOException {
this.readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream s) throws IOException {
type = s.readUI16();
textId = s.readUI16();
zeroone = s.readBytes(28);
par1 = s.readFloat();
par2 = s.readFloat();
par3 = s.readFloat();
par4 = s.readFloat();
enum_hex = s.readUI16();
fontId = s.readUI16();
zero = s.readUI32();
one = s.readUI64();
some = s.readBytes(32);
StringBuilder textBuilder = new StringBuilder();
do {
char c = (char) s.readUI16();
if (c == '\0') {
break;
}
textBuilder.append(c);
} while (true);
initialText = textBuilder.toString();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getType() {
return type;
}
public int getOrder_in_iggy_file() {
return textId;
}
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 getFor_which_font_order_in_iggyfile() {
return fontId;
}
public long getZero() {
return zero;
}
public long getOne() {
return one;
}
public byte[] getSome() {
return some;
}
public String getIntitalText() {
return initialText;
}
}

View File

@@ -4,8 +4,8 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFCompression;
import com.jpexs.decompiler.flash.iggy.IggyChar;
import com.jpexs.decompiler.flash.iggy.IggyFile;
import com.jpexs.decompiler.flash.iggy.IggyFontData;
import com.jpexs.decompiler.flash.iggy.IggyFontInfo;
import com.jpexs.decompiler.flash.iggy.IggyFont;
import com.jpexs.decompiler.flash.iggy.IggyText;
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
import com.jpexs.decompiler.flash.tags.EndTag;
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
@@ -16,6 +16,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
/**
*
@@ -75,12 +76,13 @@ public class IggyToSwfConvertor {
fat.useNetwork = false;
swf.addTag(fat);
int fontCount = file.getFontCount(swfIndex);
for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) {
IggyFontData iggyFontData = file.getFontData(swfIndex, fontIndex);
IggyFontInfo fontInfo = file.getFontInfo(swfIndex, fontIndex); //TODO!
Set<Integer> fontKeys = file.getFontIds(swfIndex);
for (int fontKey : fontKeys) {
IggyFont iggyFontData = file.getFont(swfIndex, fontKey);
IggyText fontInfo = file.getText(swfIndex, fontKey);
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
fontTag.fontID = fontIndex + 1;
fontTag.fontID = fontKey + 1;
fontTag.codeTable = new ArrayList<>();
fontTag.fontName = iggyFontData.getName();
fontTag.glyphShapeTable = new ArrayList<>();