writeToDataStream methods (not in IggyText yet)

This commit is contained in:
Jindra Petřík
2016-11-27 07:56:08 +01:00
parent 2608af6850
commit d05f1e809d
12 changed files with 1366 additions and 1164 deletions

View File

@@ -1,110 +1,116 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.EOFException;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public abstract class AbstractDataStream {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
public abstract Long available();
public abstract long position();
public abstract boolean is64();
protected long readUI64() throws IOException {
try {
return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI64(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
write((int) ((val >> 32) & 0xff));
write((int) ((val >> 40) & 0xff));
write((int) ((val >> 48) & 0xff));
write((int) ((val >> 56) & 0xff));
return true;
}
protected long readUI32() throws IOException {
try {
return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24));
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI32(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
return true;
}
protected int readUI16() throws IOException {
try {
return (readUI8() + (readUI8() << 8)) & 0xffff;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI16(int val) throws IOException {
write(val & 0xff);
write((val >> 8) & 0xff);
return true;
}
protected int readUI8() throws IOException {
try {
return read() & 0xff;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI8(int val) throws IOException {
write(val);
return true;
}
protected float readFloat() throws IOException {
return Float.intBitsToFloat((int) readUI32());
}
protected boolean writeFloat(float val) throws IOException {
return writeUI32(Float.floatToIntBits(val));
}
protected byte[] readBytes(int numBytes) throws IOException {
byte[] ret = new byte[numBytes];
for (int i = 0; i < numBytes; i++) {
ret[i] = (byte) read();
}
return ret;
}
protected abstract int read() throws IOException;
protected abstract void seek(long pos, SeekMode mode) throws IOException;
protected void write(int val) throws IOException {
//nothing
}
}
package com.jpexs.decompiler.flash.iggy;
import java.io.EOFException;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public abstract class AbstractDataStream {
/**
* Available bytes
*
* @return null if unknown, long value otherwise
*/
public abstract Long available();
public abstract long position();
public abstract boolean is64();
protected long readUI64() throws IOException {
try {
return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI64(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
write((int) ((val >> 32) & 0xff));
write((int) ((val >> 40) & 0xff));
write((int) ((val >> 48) & 0xff));
write((int) ((val >> 56) & 0xff));
return true;
}
protected long readUI32() throws IOException {
try {
return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24));
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI32(long val) throws IOException {
write((int) (val & 0xff));
write((int) ((val >> 8) & 0xff));
write((int) ((val >> 16) & 0xff));
write((int) ((val >> 24) & 0xff));
return true;
}
protected int readUI16() throws IOException {
try {
return (readUI8() + (readUI8() << 8)) & 0xffff;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI16(int val) throws IOException {
write(val & 0xff);
write((val >> 8) & 0xff);
return true;
}
protected int readUI8() throws IOException {
try {
return read() & 0xff;
} catch (EOFException ex) {
return -1;
}
}
protected boolean writeUI8(int val) throws IOException {
write(val);
return true;
}
protected float readFloat() throws IOException {
return Float.intBitsToFloat((int) readUI32());
}
protected boolean writeFloat(float val) throws IOException {
return writeUI32(Float.floatToIntBits(val));
}
protected byte[] readBytes(int numBytes) throws IOException {
byte[] ret = new byte[numBytes];
for (int i = 0; i < numBytes; i++) {
ret[i] = (byte) read();
}
return ret;
}
protected void writeBytes(byte[] data) throws IOException {
for (int i = 0; i < data.length; i++) {
write(data[i] & 0xff);
}
}
protected abstract int read() throws IOException;
protected abstract void seek(long pos, SeekMode mode) throws IOException;
protected void write(int val) throws IOException {
//nothing
}
}

View File

@@ -1,37 +1,39 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharAdvances implements StructureInterface {
List<Float> advances;
private long charCount;
public List<Float> getScales() {
return advances;
}
public IggyCharAdvances(AbstractDataStream stream, long charCount) throws IOException {
this.charCount = charCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
advances = new ArrayList<>();
for (int i = 0; i < charCount; i++) {
advances.add(stream.readFloat());
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharAdvances implements StructureInterface {
List<Float> advances;
private long charCount;
public List<Float> getScales() {
return advances;
}
public IggyCharAdvances(AbstractDataStream stream, long charCount) throws IOException {
this.charCount = charCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
advances = new ArrayList<>();
for (int i = 0; i < charCount; i++) {
advances.add(stream.readFloat());
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
for (int i = 0; i < advances.size(); i++) {
stream.writeFloat(advances.get(i));
}
}
}

View File

@@ -1,44 +1,47 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharIndices implements StructureInterface {
@IggyFieldType(value = DataType.widechar_t)
List<Character> chars;
@IggyFieldType(DataType.uint32_t)
long padd;
public List<Character> getChars() {
return chars;
}
private long charCount;
public IggyCharIndices(AbstractDataStream stream, long charCount) throws IOException {
this.charCount = charCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
chars = new ArrayList<>();
for (int i = 0; i < charCount; i++) {
chars.add((char) stream.readUI16());
}
padd = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharIndices implements StructureInterface {
@IggyFieldType(value = DataType.widechar_t)
List<Character> chars;
@IggyFieldType(DataType.uint32_t)
long padd;
public List<Character> getChars() {
return chars;
}
private long charCount;
public IggyCharIndices(AbstractDataStream stream, long charCount) throws IOException {
this.charCount = charCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
chars = new ArrayList<>();
for (int i = 0; i < charCount; i++) {
chars.add((char) stream.readUI16());
}
padd = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
for (int i = 0; i < chars.size(); i++) {
stream.writeUI16(chars.get(i));
}
stream.writeUI32(padd);
}
}

View File

@@ -1,58 +1,63 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharKerning implements StructureInterface {
private long kernCount;
List<Character> charsA;
List<Character> charsB;
List<Short> kerningOffsets;
long pad;
public long getKernCount() {
return kernCount;
}
public List<Character> getCharsA() {
return charsA;
}
public List<Character> getCharsB() {
return charsB;
}
public List<Short> getKerningOffsets() {
return kerningOffsets;
}
public IggyCharKerning(AbstractDataStream stream, long kernCount) throws IOException {
this.kernCount = kernCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
charsA = new ArrayList<>();
charsB = new ArrayList<>();
kerningOffsets = new ArrayList<>();
for (int i = 0; i < kernCount; i++) {
charsA.add((char) stream.readUI16());
charsB.add((char) stream.readUI16());
kerningOffsets.add((short) stream.readUI16());
}
pad = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyCharKerning implements StructureInterface {
private long kernCount;
List<Character> charsA;
List<Character> charsB;
List<Short> kerningOffsets;
long pad;
public long getKernCount() {
return kernCount;
}
public List<Character> getCharsA() {
return charsA;
}
public List<Character> getCharsB() {
return charsB;
}
public List<Short> getKerningOffsets() {
return kerningOffsets;
}
public IggyCharKerning(AbstractDataStream stream, long kernCount) throws IOException {
this.kernCount = kernCount;
readFromDataStream(stream);
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
charsA = new ArrayList<>();
charsB = new ArrayList<>();
kerningOffsets = new ArrayList<>();
for (int i = 0; i < kernCount; i++) {
charsA.add((char) stream.readUI16());
charsB.add((char) stream.readUI16());
kerningOffsets.add((short) stream.readUI16());
}
pad = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
for (int i = 0; i < kernCount; i++) {
stream.writeUI16(charsA.get(i));
stream.writeUI16(charsB.get(i));
stream.writeUI16(kerningOffsets.get(i));
}
stream.writeUI32(pad);
}
}

View File

@@ -1,99 +1,110 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyCharOffset implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyCharOffset.class.getName());
@IggyFieldType(DataType.uint64_t)
long zero;
@IggyFieldType(DataType.uint16_t)
int ischar1;
@IggyFieldType(DataType.uint16_t)
int ischar2;
@IggyFieldType(DataType.uint32_t)
long zero2;
@IggyFieldType(DataType.uint16_t)
int xscale;
@IggyFieldType(DataType.uint16_t)
int yscale;
@IggyFieldType(DataType.uint32_t)
long zero3;
@IggyFieldType(DataType.uint64_t)
long offset;
public IggyCharOffset(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
public IggyCharOffset(long zero, int ischar1, int ischar2, long zero2, int xscale, int yscale, long zero3, long offset) {
this.zero = zero;
this.ischar1 = ischar1;
this.ischar2 = ischar2;
this.zero2 = zero2;
this.xscale = xscale;
this.yscale = yscale;
this.zero3 = zero3;
this.offset = offset;
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
zero = stream.readUI64();
ischar1 = stream.readUI16();
ischar2 = stream.readUI16();
zero2 = stream.readUI32();
xscale = stream.readUI16();
yscale = stream.readUI16();
zero3 = stream.readUI32();
long cur_position = stream.position();
long relative_offset = stream.readUI64();
if (ischar1 > 0) {
offset = cur_position + relative_offset;
} else {
offset = 0;
LOGGER.finer(String.format("Empty char"));
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public long getZero() {
return zero;
}
public boolean isChar1() {
return ischar1 > 0;
}
public boolean isChar2() {
return ischar2 > 0;
}
public long getZero2() {
return zero2;
}
public int getXscale() {
return xscale;
}
public int getYscale() {
return yscale;
}
public long getZero3() {
return zero3;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyCharOffset implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyCharOffset.class.getName());
@IggyFieldType(DataType.uint64_t)
long zero;
@IggyFieldType(DataType.uint16_t)
int ischar1;
@IggyFieldType(DataType.uint16_t)
int ischar2;
@IggyFieldType(DataType.uint32_t)
long zero2;
@IggyFieldType(DataType.uint16_t)
int xscale;
@IggyFieldType(DataType.uint16_t)
int yscale;
@IggyFieldType(DataType.uint32_t)
long zero3;
@IggyFieldType(DataType.uint64_t)
long offset;
public IggyCharOffset(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
public IggyCharOffset(long zero, int ischar1, int ischar2, long zero2, int xscale, int yscale, long zero3, long offset) {
this.zero = zero;
this.ischar1 = ischar1;
this.ischar2 = ischar2;
this.zero2 = zero2;
this.xscale = xscale;
this.yscale = yscale;
this.zero3 = zero3;
this.offset = offset;
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
zero = stream.readUI64();
ischar1 = stream.readUI16();
ischar2 = stream.readUI16();
zero2 = stream.readUI32();
xscale = stream.readUI16();
yscale = stream.readUI16();
zero3 = stream.readUI32();
long cur_position = stream.position();
long relative_offset = stream.readUI64();
if (ischar1 > 0) {
offset = cur_position + relative_offset;
} else {
offset = 0;
LOGGER.finer(String.format("Empty char"));
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
stream.writeUI64(zero);
stream.writeUI16(ischar1);
stream.writeUI16(ischar2);
stream.writeUI32(zero2);
stream.writeUI16(xscale);
stream.writeUI16(yscale);
stream.writeUI32(zero3);
if (ischar1 > 0) {
stream.writeUI64(offset - stream.position());
} else {
stream.writeUI64(1);
}
}
public long getZero() {
return zero;
}
public boolean isChar1() {
return ischar1 > 0;
}
public boolean isChar2() {
return ischar2 > 0;
}
public long getZero2() {
return zero2;
}
public int getXscale() {
return xscale;
}
public int getYscale() {
return yscale;
}
public long getZero3() {
return zero3;
}
}

View File

@@ -1,316 +1,412 @@
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;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyFont implements StructureInterface {
public static final int ID = 0xFF16;
@IggyFieldType(DataType.uint16_t)
int type; //stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
int fontId;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte[] zeroone; // stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
int char_count2;
@IggyFieldType(value = DataType.uint16_t)
int ascent;
@IggyFieldType(value = DataType.uint16_t)
int descent;
@IggyFieldType(value = DataType.uint16_t)
int leading;
@IggyFieldType(DataType.uint64_t)
long flags;
@IggyFieldType(DataType.uint64_t)
long start_of_char_struct;
@IggyFieldType(DataType.uint64_t)
long start_of_char_index;
@IggyFieldType(DataType.uint64_t)
long start_of_scale;
@IggyFieldType(DataType.uint32_t)
long kern_count;
@IggyArrayFieldType(value = DataType.float_t, count = 5)
float[] unk_float;
@IggyFieldType(DataType.uint64_t)
long start_of_kern;
@IggyFieldType(DataType.uint64_t)
long zero_padd;
@IggyFieldType(DataType.uint64_t)
long what_2;
@IggyFieldType(DataType.uint64_t)
long zero_padd_2;
@IggyFieldType(DataType.uint64_t)
long start_of_name;
@IggyFieldType(DataType.uint64_t)
long one_padd;
@IggyFieldType(DataType.uint16_t)
int xscale;
@IggyFieldType(DataType.uint16_t)
int yscale;
@IggyFieldType(DataType.uint64_t)
long zero_padd_3;
@IggyFieldType(DataType.float_t)
float ssr1;
@IggyFieldType(DataType.float_t)
float ssr2;
@IggyFieldType(DataType.uint32_t)
long char_count;
@IggyFieldType(DataType.uint64_t)
long zero_padd_4;
@IggyFieldType(DataType.uint64_t)
long what_3;
@IggyFieldType(value = DataType.uint8_t, count = 272)
byte[] zeroes;
@IggyFieldType(DataType.float_t)
float sss1;
@IggyFieldType(DataType.uint32_t)
long one_padd2;
@IggyFieldType(DataType.float_t)
float sss2;
@IggyFieldType(DataType.uint32_t)
long one_padd3;
@IggyFieldType(DataType.float_t)
float sss3;
@IggyFieldType(DataType.uint32_t)
long one_padd4;
@IggyFieldType(DataType.float_t)
float sss4;
@IggyFieldType(DataType.uint32_t)
long one_padd5;
@IggyFieldType(value = DataType.widechar_t, count = 16)
String name;
List<IggyCharOffset> charOffsets;
List<IggyShape> glyphs;
IggyCharIndices codePoints;
IggyCharAdvances charScales;
IggyCharKerning charKernings;
byte[] padTo4byteBoundary;
public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int ascent, int descent, int leading, 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<IggyShape> chars, IggyCharIndices charIndices, IggyCharAdvances charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
this.type = type;
this.fontId = order_in_iggy_file;
this.zeroone = zeroone;
this.char_count2 = char_count2;
this.ascent = ascent;
this.descent = descent;
this.leading = leading;
this.flags = flags;
this.start_of_char_struct = start_of_char_struct;
this.start_of_char_index = start_of_char_index;
this.start_of_scale = start_of_scale;
this.kern_count = kern_count;
this.unk_float = unk_float;
this.start_of_kern = start_of_kern;
this.zero_padd = zero_padd;
this.what_2 = what_2;
this.zero_padd_2 = zero_padd_2;
this.start_of_name = start_of_name;
this.one_padd = one_padd;
this.xscale = xscale;
this.yscale = yscale;
this.zero_padd_3 = zero_padd_3;
this.ssr1 = ssr1;
this.ssr2 = ssr2;
this.char_count = char_count;
this.zero_padd_4 = zero_padd_4;
this.what_3 = what_3;
this.zeroes = zeroes;
this.sss1 = sss1;
this.one_padd2 = one_padd2;
this.sss2 = sss2;
this.one_padd3 = one_padd3;
this.sss3 = sss3;
this.one_padd4 = one_padd4;
this.sss4 = sss4;
this.one_padd5 = one_padd5;
this.name = name;
this.charOffsets = charOffsets;
this.glyphs = chars;
this.codePoints = charIndices;
this.charScales = charScales;
this.charKernings = charKernings;
this.padTo4byteBoundary = padTo4byteBoundary;
}
public IggyFont(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
private long readAbsoluteOffset(AbstractDataStream stream) throws IOException {
long offset = stream.readUI64();
if (offset == 1) {
return 0;
}
return stream.position() - 8 + offset;
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64());
type = s.readUI16();
fontId = s.readUI16();
zeroone = s.readBytes(28);
char_count2 = s.readUI16();
ascent = s.readUI16();
descent = s.readUI16();
leading = s.readUI16();
flags = s.readUI64();
start_of_char_struct = readAbsoluteOffset(s);
start_of_char_index = readAbsoluteOffset(s);
start_of_scale = readAbsoluteOffset(s);
kern_count = s.readUI32();
unk_float = new float[5];
for (int i = 0; i < unk_float.length; i++) {
unk_float[i] = s.readFloat();
}
start_of_kern = readAbsoluteOffset(s);
zero_padd = s.readUI64();
what_2 = s.readUI64();
zero_padd_2 = s.readUI64();
start_of_name = readAbsoluteOffset(s);
one_padd = s.readUI64();
xscale = s.readUI16();
yscale = s.readUI16();
zero_padd_3 = s.readUI64();
ssr1 = s.readFloat();
ssr2 = s.readFloat();
char_count = s.readUI32();
zero_padd_4 = s.readUI64();
what_3 = s.readUI64();
s.seek(272, SeekMode.CUR);
sss1 = s.readFloat();
one_padd2 = s.readUI32();
sss2 = s.readFloat();
one_padd3 = s.readUI32();
sss3 = s.readFloat();
one_padd4 = s.readUI32();
sss4 = s.readFloat();
one_padd5 = s.readUI32();
if (start_of_name != 0) {
s.seek(start_of_name, SeekMode.SET);
StringBuilder nameBuilder = new StringBuilder();
int nameCharCnt = 0;
do {
char c = (char) s.readUI16();
nameCharCnt++;
if (c == '\0') {
break;
}
nameBuilder.append(c);
} while (true);
s.seek(32 - nameCharCnt * 2, SeekMode.CUR);
name = nameBuilder.toString();
}
s.readUI64(); //pad zero
if (start_of_char_struct != 0) {
s.seek(start_of_char_struct, SeekMode.SET);
charOffsets = new ArrayList<>();
for (int i = 0; i < char_count; i++) {
charOffsets.add(new IggyCharOffset(s));
}
glyphs = new ArrayList<>();
for (int i = 0; i < char_count; i++) {
long offset = charOffsets.get(i).offset;
glyphs.add(new IggyShape(s, offset));
}
}
if (start_of_char_index != 0) {
s.seek(start_of_char_index, SeekMode.SET);
codePoints = new IggyCharIndices(s, char_count);
}
if (start_of_scale != 0) {
s.seek(start_of_scale, SeekMode.SET);
charScales = new IggyCharAdvances(s, char_count);
}
if (start_of_kern != 0) {
s.seek(start_of_kern, SeekMode.SET);
charKernings = new IggyCharKerning(s, kern_count);
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getType() {
return type;
}
public long getFlags() {
return flags;
}
public int getXscale() {
return xscale;
}
public int getYscale() {
return yscale;
}
public long getCharacterCount() {
return char_count;
}
public String getName() {
return name;
}
public List<IggyShape> getChars() {
return glyphs;
}
public IggyCharIndices getCharIndices() {
return codePoints;
}
public IggyCharAdvances getCharAdvances() {
return charScales;
}
public IggyCharKerning getCharKernings() {
return charKernings;
}
public float[] getUnk_float() {
return unk_float;
}
public int getAscent() {
return ascent;
}
public int getDescent() {
return descent;
}
public int getLeading() {
return leading;
}
public long getWhat_2() {
return what_2;
}
public long getWhat_3() {
return what_3;
}
public List<IggyCharOffset> getCharOffsets() {
return charOffsets;
}
}
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;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class IggyFont extends IggyTag {
public static final int ID = 0xFF16;
@IggyFieldType(DataType.uint16_t)
int type; //stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
int fontId;
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
byte[] zeroone; // stejny pro rozdilne fonty
@IggyFieldType(DataType.uint16_t)
int char_count2;
@IggyFieldType(value = DataType.uint16_t)
int ascent;
@IggyFieldType(value = DataType.uint16_t)
int descent;
@IggyFieldType(value = DataType.uint16_t)
int leading;
@IggyFieldType(DataType.uint64_t)
long flags;
@IggyFieldType(DataType.uint64_t)
long start_of_char_struct;
@IggyFieldType(DataType.uint64_t)
long start_of_char_index;
@IggyFieldType(DataType.uint64_t)
long start_of_scale;
@IggyFieldType(DataType.uint32_t)
long kern_count;
@IggyArrayFieldType(value = DataType.float_t, count = 5)
float[] unk_float;
@IggyFieldType(DataType.uint64_t)
long start_of_kern;
@IggyFieldType(DataType.uint64_t)
long zero_padd;
@IggyFieldType(DataType.uint64_t)
long what_2;
@IggyFieldType(DataType.uint64_t)
long zero_padd_2;
@IggyFieldType(DataType.uint64_t)
long start_of_name;
@IggyFieldType(DataType.uint64_t)
long one_padd;
@IggyFieldType(DataType.uint16_t)
int xscale;
@IggyFieldType(DataType.uint16_t)
int yscale;
@IggyFieldType(DataType.uint64_t)
long zero_padd_3;
@IggyFieldType(DataType.float_t)
float ssr1;
@IggyFieldType(DataType.float_t)
float ssr2;
@IggyFieldType(DataType.uint32_t)
long char_count;
@IggyFieldType(DataType.uint64_t)
long zero_padd_4;
@IggyFieldType(DataType.uint64_t)
long what_3;
@IggyFieldType(value = DataType.uint8_t, count = 272)
byte[] zeroes;
@IggyFieldType(DataType.float_t)
float sss1;
@IggyFieldType(DataType.uint32_t)
long one_padd2;
@IggyFieldType(DataType.float_t)
float sss2;
@IggyFieldType(DataType.uint32_t)
long one_padd3;
@IggyFieldType(DataType.float_t)
float sss3;
@IggyFieldType(DataType.uint32_t)
long one_padd4;
@IggyFieldType(DataType.float_t)
float sss4;
@IggyFieldType(DataType.uint32_t)
long one_padd5;
@IggyFieldType(value = DataType.widechar_t, count = 16)
String name;
List<IggyCharOffset> charOffsets;
List<IggyShape> glyphs;
IggyCharIndices codePoints;
IggyCharAdvances charScales;
IggyCharKerning charKernings;
byte[] padTo4byteBoundary;
public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int ascent, int descent, int leading, 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<IggyShape> chars, IggyCharIndices charIndices, IggyCharAdvances charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
this.type = type;
this.fontId = order_in_iggy_file;
this.zeroone = zeroone;
this.char_count2 = char_count2;
this.ascent = ascent;
this.descent = descent;
this.leading = leading;
this.flags = flags;
this.start_of_char_struct = start_of_char_struct;
this.start_of_char_index = start_of_char_index;
this.start_of_scale = start_of_scale;
this.kern_count = kern_count;
this.unk_float = unk_float;
this.start_of_kern = start_of_kern;
this.zero_padd = zero_padd;
this.what_2 = what_2;
this.zero_padd_2 = zero_padd_2;
this.start_of_name = start_of_name;
this.one_padd = one_padd;
this.xscale = xscale;
this.yscale = yscale;
this.zero_padd_3 = zero_padd_3;
this.ssr1 = ssr1;
this.ssr2 = ssr2;
this.char_count = char_count;
this.zero_padd_4 = zero_padd_4;
this.what_3 = what_3;
this.zeroes = zeroes;
this.sss1 = sss1;
this.one_padd2 = one_padd2;
this.sss2 = sss2;
this.one_padd3 = one_padd3;
this.sss3 = sss3;
this.one_padd4 = one_padd4;
this.sss4 = sss4;
this.one_padd5 = one_padd5;
this.name = name;
this.charOffsets = charOffsets;
this.glyphs = chars;
this.codePoints = charIndices;
this.charScales = charScales;
this.charKernings = charKernings;
this.padTo4byteBoundary = padTo4byteBoundary;
}
public IggyFont(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
private long readAbsoluteOffset(AbstractDataStream stream) throws IOException {
long offset = stream.readUI64();
if (offset == 1) {
return 0;
}
return stream.position() - 8 + offset;
}
private void writeAbsoluteOffset(AbstractDataStream stream, long offset) throws IOException {
if (offset == 0) {
stream.writeUI64(1);
} else {
stream.writeUI64(offset - stream.position());
}
}
private void writeRelativeOffset(AbstractDataStream stream, long offset) throws IOException {
if (offset == 0) {
stream.writeUI64(1);
} else {
stream.writeUI64(offset);
}
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64());
type = s.readUI16();
fontId = s.readUI16();
zeroone = s.readBytes(28);
char_count2 = s.readUI16();
ascent = s.readUI16();
descent = s.readUI16();
leading = s.readUI16();
flags = s.readUI64();
start_of_char_struct = readAbsoluteOffset(s);
start_of_char_index = readAbsoluteOffset(s);
start_of_scale = readAbsoluteOffset(s);
kern_count = s.readUI32();
unk_float = new float[5];
for (int i = 0; i < unk_float.length; i++) {
unk_float[i] = s.readFloat();
}
start_of_kern = readAbsoluteOffset(s);
zero_padd = s.readUI64();
what_2 = s.readUI64();
zero_padd_2 = s.readUI64();
start_of_name = readAbsoluteOffset(s);
one_padd = s.readUI64();
xscale = s.readUI16();
yscale = s.readUI16();
zero_padd_3 = s.readUI64();
ssr1 = s.readFloat();
ssr2 = s.readFloat();
char_count = s.readUI32();
zero_padd_4 = s.readUI64();
what_3 = s.readUI64();
s.seek(272, SeekMode.CUR);
sss1 = s.readFloat();
one_padd2 = s.readUI32();
sss2 = s.readFloat();
one_padd3 = s.readUI32();
sss3 = s.readFloat();
one_padd4 = s.readUI32();
sss4 = s.readFloat();
one_padd5 = s.readUI32();
if (start_of_name != 0) {
s.seek(start_of_name, SeekMode.SET);
StringBuilder nameBuilder = new StringBuilder();
int nameCharCnt = 0;
do {
char c = (char) s.readUI16();
nameCharCnt++;
if (c == '\0') {
break;
}
nameBuilder.append(c);
} while (true);
s.seek(32 - nameCharCnt * 2, SeekMode.CUR);
name = nameBuilder.toString();
}
s.readUI64(); //pad zero
if (start_of_char_struct != 0) {
s.seek(start_of_char_struct, SeekMode.SET);
charOffsets = new ArrayList<>();
for (int i = 0; i < char_count; i++) {
charOffsets.add(new IggyCharOffset(s));
}
glyphs = new ArrayList<>();
for (int i = 0; i < char_count; i++) {
long offset = charOffsets.get(i).offset;
glyphs.add(new IggyShape(s, offset));
}
}
if (start_of_char_index != 0) {
s.seek(start_of_char_index, SeekMode.SET);
codePoints = new IggyCharIndices(s, char_count);
}
if (start_of_scale != 0) {
s.seek(start_of_scale, SeekMode.SET);
charScales = new IggyCharAdvances(s, char_count);
}
if (start_of_kern != 0) {
s.seek(start_of_kern, SeekMode.SET);
charKernings = new IggyCharKerning(s, kern_count);
}
}
@Override
public void writeToDataStream(AbstractDataStream s) throws IOException {
s.writeUI16(type);
s.writeUI16(fontId);
s.writeBytes(zeroone);
s.writeUI16(char_count2);
s.writeUI16(ascent);
s.writeUI16(descent);
s.writeUI16(leading);
s.writeUI64(flags);
writeAbsoluteOffset(s, start_of_char_struct);
writeAbsoluteOffset(s, start_of_char_index);
writeAbsoluteOffset(s, start_of_scale);
s.writeUI32(kern_count);
for (int i = 0; i < unk_float.length; i++) {
s.writeFloat(unk_float[i]);
}
writeAbsoluteOffset(s, start_of_kern);
s.writeUI64(zero_padd);
s.writeUI64(what_2);
s.writeUI64(zero_padd_2);
writeAbsoluteOffset(s, start_of_name);
s.writeUI64(one_padd);
s.writeUI16(xscale);
s.writeUI16(yscale);
s.writeUI64(zero_padd_3);
s.writeFloat(ssr1);
s.writeFloat(ssr2);
s.writeUI32(char_count);
s.writeUI64(zero_padd_4);
s.writeUI64(what_3);
//s.seek(272, SeekMode.CUR);
for (int i = 0; i < 272; i++) {
s.write(0);
}
s.writeFloat(sss1);
s.writeUI32(one_padd2);
s.writeFloat(sss2);
s.writeUI32(one_padd3);
s.writeFloat(sss3);
s.writeUI32(one_padd4);
s.writeFloat(sss4);
s.writeUI32(one_padd5);
if (start_of_name != 0) {
for (char c : name.toCharArray()) {
s.writeUI16(c);
}
s.writeUI16(0);
//align to 8 bytes boundary
int len = name.length() * 2 + 2;
int rem = 8 - (len % 8);
for (int i = 0; i < rem; i++) {
s.write(0);
}
}
s.writeUI64(0); //pad zero
if (start_of_char_struct != 0) {
//offsets of shapes
for (IggyCharOffset ofs : charOffsets) {
ofs.writeToDataStream(s);
}
for (IggyShape shp : glyphs) {
shp.writeToDataStream(s);
}
}
if (start_of_char_index != 0) {
for (char c : codePoints.chars) {
s.writeUI16(c);
}
s.writeUI32(0);
}
if (start_of_scale != 0) {
charScales.writeToDataStream(s);
}
if (start_of_kern != 0) {
charKernings.writeToDataStream(s);
}
}
public int getType() {
return type;
}
public long getFlags() {
return flags;
}
public int getXscale() {
return xscale;
}
public int getYscale() {
return yscale;
}
public long getCharacterCount() {
return char_count;
}
public String getName() {
return name;
}
public List<IggyShape> getChars() {
return glyphs;
}
public IggyCharIndices getCharIndices() {
return codePoints;
}
public IggyCharAdvances getCharAdvances() {
return charScales;
}
public IggyCharKerning getCharKernings() {
return charKernings;
}
public float[] getUnk_float() {
return unk_float;
}
public int getAscent() {
return ascent;
}
public int getDescent() {
return descent;
}
public int getLeading() {
return leading;
}
public long getWhat_2() {
return what_2;
}
public long getWhat_3() {
return what_3;
}
public List<IggyCharOffset> getCharOffsets() {
return charOffsets;
}
@Override
public int getTagType() {
return ID;
}
}

View File

@@ -1,153 +1,161 @@
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
*
* little endian all
*
* Based of works of somebody called eternity.
*/
public class IggyHeader implements StructureInterface {
public static long MAGIC = 0xED0A6749;
//Must be 0xED0A6749
@IggyFieldType(DataType.uint32_t)
private long magic = MAGIC;
//Assume 0x900
@IggyFieldType(DataType.uint32_t)
private long version;
//Assuming: 1
@IggyFieldType(value = DataType.uint8_t)
private int platform1;
//32/64
@IggyFieldType(value = DataType.uint8_t)
private int platform2;
//Assuming: 1
@IggyFieldType(value = DataType.uint8_t)
private int platform3;
//Usually: 3
@IggyFieldType(value = DataType.uint8_t)
private int platform4;
//flags for platform 64?
@IggyFieldType(DataType.uint32_t)
private long unk_0C;
@IggyArrayFieldType(value = DataType.uint8_t, count = 12)
private byte[] reserved;
@IggyFieldType(value = DataType.uint32_t)
private long numSubfiles;
public IggyHeader(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
/**
*
* @param version
* @param platform1
* @param platform2 32/64
* @param platform3
* @param platform4
* @param unk_0C
* @param reserved
* @param num_subfiles
*/
public IggyHeader(long version, int platform1, int platform2, int platform3, int platform4, long unk_0C, byte[] reserved, long num_subfiles) {
this.version = version;
this.platform1 = platform1;
this.platform2 = platform2;
this.platform3 = platform3;
this.platform4 = platform4;
this.unk_0C = unk_0C;
this.reserved = reserved;
this.numSubfiles = num_subfiles;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append("version: ").append(version).append(", ");
sb.append("platform: ").append(platform1).append(" ").append(platform2).append(" ").append(platform3).append(" ").append(platform4).append(", ");
sb.append("unk_0C: ").append(String.format("%08X", unk_0C)).append(", ");
sb.append("reserved: 12 bytes").append(", ");
sb.append("num_subfiles: ").append(numSubfiles);
sb.append("]");
return sb.toString();
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
magic = stream.readUI32();
if (magic != IggyHeader.MAGIC) {
throw new IOException("Invalid Iggy file");
}
version = stream.readUI32();
platform1 = stream.readUI8();
platform2 = stream.readUI8(); //32/64
platform3 = stream.readUI8();
platform4 = stream.readUI8();
unk_0C = stream.readUI32();
reserved = stream.readBytes(12);
numSubfiles = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public boolean is64() {
return platform2 == 64;
}
public long getMagic() {
return magic;
}
public long getVersion() {
return version;
}
public int getPlatform1() {
return platform1;
}
public int getPlatform2() {
return platform2;
}
public int getPlatform3() {
return platform3;
}
public int getPlatform4() {
return platform4;
}
public long getUnk_0C() {
return unk_0C;
}
public byte[] getReserved() {
return reserved;
}
public long getNumSubfiles() {
return numSubfiles;
}
}
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
*
* little endian all
*
* Based of works of somebody called eternity.
*/
public class IggyHeader implements StructureInterface {
public static long MAGIC = 0xED0A6749;
//Must be 0xED0A6749
@IggyFieldType(DataType.uint32_t)
private long magic = MAGIC;
//Assume 0x900
@IggyFieldType(DataType.uint32_t)
private long version;
//Assuming: 1
@IggyFieldType(value = DataType.uint8_t)
private int platform1;
//32/64
@IggyFieldType(value = DataType.uint8_t)
private int platform2;
//Assuming: 1
@IggyFieldType(value = DataType.uint8_t)
private int platform3;
//Usually: 3
@IggyFieldType(value = DataType.uint8_t)
private int platform4;
//flags for platform 64?
@IggyFieldType(DataType.uint32_t)
private long unk_0C;
@IggyArrayFieldType(value = DataType.uint8_t, count = 12)
private byte[] reserved;
@IggyFieldType(value = DataType.uint32_t)
private long numSubfiles;
public IggyHeader(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
/**
*
* @param version
* @param platform1
* @param platform2 32/64
* @param platform3
* @param platform4
* @param unk_0C
* @param reserved
* @param num_subfiles
*/
public IggyHeader(long version, int platform1, int platform2, int platform3, int platform4, long unk_0C, byte[] reserved, long num_subfiles) {
this.version = version;
this.platform1 = platform1;
this.platform2 = platform2;
this.platform3 = platform3;
this.platform4 = platform4;
this.unk_0C = unk_0C;
this.reserved = reserved;
this.numSubfiles = num_subfiles;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append("version: ").append(version).append(", ");
sb.append("platform: ").append(platform1).append(" ").append(platform2).append(" ").append(platform3).append(" ").append(platform4).append(", ");
sb.append("unk_0C: ").append(String.format("%08X", unk_0C)).append(", ");
sb.append("reserved: 12 bytes").append(", ");
sb.append("num_subfiles: ").append(numSubfiles);
sb.append("]");
return sb.toString();
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
magic = stream.readUI32();
if (magic != IggyHeader.MAGIC) {
throw new IOException("Invalid Iggy file");
}
version = stream.readUI32();
platform1 = stream.readUI8();
platform2 = stream.readUI8(); //32/64
platform3 = stream.readUI8();
platform4 = stream.readUI8();
unk_0C = stream.readUI32();
reserved = stream.readBytes(12);
numSubfiles = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream s) throws IOException {
s.writeUI32(magic);
s.writeUI32(version);
s.writeUI8(platform1);
s.writeUI8(platform2);
s.writeUI8(platform3);
s.writeUI8(platform4);
s.writeUI32(unk_0C);
s.writeBytes(reserved);
s.writeUI32(numSubfiles);
}
public boolean is64() {
return platform2 == 64;
}
public long getMagic() {
return magic;
}
public long getVersion() {
return version;
}
public int getPlatform1() {
return platform1;
}
public int getPlatform2() {
return platform2;
}
public int getPlatform3() {
return platform3;
}
public int getPlatform4() {
return platform4;
}
public long getUnk_0C() {
return unk_0C;
}
public byte[] getReserved() {
return reserved;
}
public long getNumSubfiles() {
return numSubfiles;
}
}

View File

@@ -1,155 +1,169 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyShape implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyShape.class.getName());
@IggyFieldType(DataType.float_t)
float minx; //bearing X - this is the horizontal distance from the current pen position to the glyph's left bbox edge.
@IggyFieldType(DataType.float_t)
float miny; //bearing Y - this is the vertical distance from the baseline to the top of the glyph's bbox.
@IggyFieldType(DataType.float_t)
float maxx; //advanceX - bearingX
@IggyFieldType(DataType.float_t)
float maxy; //advanceY - bearingY
@IggyFieldType(DataType.uint64_t)
long unk; // stejny vetsinou - napr. 48 - JP: to by mohlo byt advance
@IggyFieldType(DataType.uint64_t)
long count;
@IggyFieldType(DataType.uint64_t)
long one; // 1
@IggyFieldType(DataType.uint64_t)
long one2; // 1
@IggyFieldType(DataType.uint64_t)
long one3; // 1
@IggyFieldType(DataType.uint32_t)
long one4; // 1
@IggyFieldType(DataType.uint32_t)
long two1; // 2
public float getBearingX() {
return minx;
}
public float getBearingY() {
return miny;
}
public float getWidth() {
return maxx - minx;
}
public float getHeight() {
return maxy - miny;
}
List<IggyShapeNode> nodes;
private long offset;
public IggyShape(AbstractDataStream stream, long offset) throws IOException {
this.offset = offset;
readFromDataStream(stream);
}
public IggyShape(float minx, float miny, float maxx, float maxy, long advance, long count, long one, long one2, long one3, long one4, long two1, List<IggyShapeNode> nodes) {
this.minx = minx;
this.miny = miny;
this.maxx = maxx;
this.maxy = maxy;
this.unk = advance;
this.count = count;
this.one = one;
this.one2 = one2;
this.one3 = one3;
this.one4 = one4;
this.two1 = two1;
this.nodes = nodes;
}
@Override
public void readFromDataStream(AbstractDataStream s) throws IOException {
s.seek(offset, SeekMode.SET);
minx = s.readFloat();
miny = s.readFloat();
maxx = s.readFloat();
maxy = s.readFloat();
unk = s.readUI64();
count = s.readUI64();
one = s.readUI64();
one2 = s.readUI64();
one3 = s.readUI64();
one4 = s.readUI32();
two1 = s.readUI32();
if ((one != 1) || (one2 != 1) || (one3 != 1) || (one4 != 1) || (two1 != 2)) {
LOGGER.fine(String.format("Unique header at pos %d, one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", offset, one, one2, one3, one4, two1));
}
nodes = new ArrayList<>();
for (int i = 0; i < count; i++) {
nodes.add(new IggyShapeNode(s, i == 0));
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public float getMinx() {
return minx;
}
public float getMiny() {
return miny;
}
public float getMaxx() {
return maxx;
}
public float getMaxy() {
return maxy;
}
public long getUnk() {
return unk;
}
public long getOne() {
return one;
}
public long getOne2() {
return one2;
}
public long getOne3() {
return one3;
}
public long getOne4() {
return one4;
}
public long getTwo1() {
return two1;
}
public List<IggyShapeNode> getNodes() {
return nodes;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyShape implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyShape.class.getName());
@IggyFieldType(DataType.float_t)
float minx; //bearing X - this is the horizontal distance from the current pen position to the glyph's left bbox edge.
@IggyFieldType(DataType.float_t)
float miny; //bearing Y - this is the vertical distance from the baseline to the top of the glyph's bbox.
@IggyFieldType(DataType.float_t)
float maxx; //advanceX - bearingX
@IggyFieldType(DataType.float_t)
float maxy; //advanceY - bearingY
@IggyFieldType(DataType.uint64_t)
long unk; // stejny vetsinou - napr. 48 - JP: to by mohlo byt advance
@IggyFieldType(DataType.uint64_t)
long count;
@IggyFieldType(DataType.uint64_t)
long one; // 1
@IggyFieldType(DataType.uint64_t)
long one2; // 1
@IggyFieldType(DataType.uint64_t)
long one3; // 1
@IggyFieldType(DataType.uint32_t)
long one4; // 1
@IggyFieldType(DataType.uint32_t)
long two1; // 2
public float getBearingX() {
return minx;
}
public float getBearingY() {
return miny;
}
public float getWidth() {
return maxx - minx;
}
public float getHeight() {
return maxy - miny;
}
List<IggyShapeNode> nodes;
private long offset;
public IggyShape(AbstractDataStream stream, long offset) throws IOException {
this.offset = offset;
readFromDataStream(stream);
}
public IggyShape(float minx, float miny, float maxx, float maxy, long advance, long count, long one, long one2, long one3, long one4, long two1, List<IggyShapeNode> nodes) {
this.minx = minx;
this.miny = miny;
this.maxx = maxx;
this.maxy = maxy;
this.unk = advance;
this.count = count;
this.one = one;
this.one2 = one2;
this.one3 = one3;
this.one4 = one4;
this.two1 = two1;
this.nodes = nodes;
}
@Override
public void readFromDataStream(AbstractDataStream s) throws IOException {
s.seek(offset, SeekMode.SET);
minx = s.readFloat();
miny = s.readFloat();
maxx = s.readFloat();
maxy = s.readFloat();
unk = s.readUI64();
count = s.readUI64();
one = s.readUI64();
one2 = s.readUI64();
one3 = s.readUI64();
one4 = s.readUI32();
two1 = s.readUI32();
if ((one != 1) || (one2 != 1) || (one3 != 1) || (one4 != 1) || (two1 != 2)) {
LOGGER.fine(String.format("Unique header at pos %d, one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", offset, one, one2, one3, one4, two1));
}
nodes = new ArrayList<>();
for (int i = 0; i < count; i++) {
nodes.add(new IggyShapeNode(s, i == 0));
}
}
@Override
public void writeToDataStream(AbstractDataStream s) throws IOException {
s.writeFloat(minx);
s.writeFloat(miny);
s.writeFloat(maxx);
s.writeFloat(maxy);
s.writeUI64(unk);
s.writeUI64(count);
s.writeUI64(one);
s.writeUI64(one2);
s.writeUI64(one3);
s.writeUI32(one4);
s.writeUI32(two1);
for (IggyShapeNode node : nodes) {
node.writeToDataStream(s);
}
}
public float getMinx() {
return minx;
}
public float getMiny() {
return miny;
}
public float getMaxx() {
return maxx;
}
public float getMaxy() {
return maxy;
}
public long getUnk() {
return unk;
}
public long getOne() {
return one;
}
public long getOne2() {
return one2;
}
public long getOne3() {
return one3;
}
public long getOne4() {
return one4;
}
public long getTwo1() {
return two1;
}
public List<IggyShapeNode> getNodes() {
return nodes;
}
}

View File

@@ -1,122 +1,130 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyShapeNode implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyShapeNode.class.getName());
public static int NODE_TYPE_MOVE = 1;
public static int NODE_TYPE_LINE_TO = 2;
public static int NODE_TYPE_CURVE_POINT = 3;
@IggyFieldType(DataType.float_t)
float targetX;
@IggyFieldType(DataType.float_t)
float targetY; // negative
@IggyFieldType(DataType.float_t)
float controlX; // for curves
@IggyFieldType(DataType.float_t)
float controlY; // for curves, negative
@IggyFieldType(DataType.uint8_t) //1-moveto, 2-lineto , 3 - curve to
int node_type;
@IggyFieldType(DataType.uint8_t) // 208 start smooth (for j=1 only), 61 smooth interupt (muze a nemusi byt pro novy oddeleny kus charu - kdyz je subtype predchoziho vetsi nez 0 (kupr 5) bude pro oddeleny usek 61, jinak pokud je subtype predchoziho 0 bude pro oddeleny usek 0)
int node_subtype;
@IggyFieldType(DataType.uint8_t)
int zer1;
@IggyFieldType(DataType.uint8_t)
int zer2;
@IggyFieldType(DataType.uint32_t)
long isstart; // 1 v prubehu nebo 0 pouze pro prvni (i kdyz jsou delene jako dvojtecka!!!)
private boolean first;
public IggyShapeNode(float x1, float y1, float x2, float y2, int node_type, int node_subtype, int zer1, int zer2, long isstart) {
this.targetX = x1;
this.targetY = y1;
this.controlX = x2;
this.controlY = y2;
this.node_type = node_type;
this.node_subtype = node_subtype;
this.zer1 = zer1;
this.zer2 = zer2;
this.isstart = isstart;
}
public IggyShapeNode(AbstractDataStream s, boolean first) throws IOException {
this.first = first;
readFromDataStream(s);
}
@Override
public void readFromDataStream(AbstractDataStream s) throws IOException {
targetX = s.readFloat();
targetY = s.readFloat();
controlX = s.readFloat();
controlY = s.readFloat();
node_type = s.readUI8();
node_subtype = s.readUI8();
zer1 = s.readUI8();
zer2 = s.readUI8();
isstart = s.readUI32();
if ((zer1 != 0) | (zer2 != 0)) {
LOGGER.fine(String.format("Unknown zeroes at pos %08X\n", s.position() - 6));
}
if ((!first) & (isstart != 1)) {
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
}
if ((first) & (isstart != 0)) {
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
}
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public float getX1() {
return targetX;
}
public float getY1() {
return targetY;
}
public float getX2() {
return controlX;
}
public float getY2() {
return controlY;
}
public int getNodeType() {
return node_type;
}
public int getNodeSubType() {
return node_subtype;
}
public int getZer1() {
return zer1;
}
public int getZer2() {
return zer2;
}
public boolean isStart() {
return isstart == 1;
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class IggyShapeNode implements StructureInterface {
private static Logger LOGGER = Logger.getLogger(IggyShapeNode.class.getName());
public static int NODE_TYPE_MOVE = 1;
public static int NODE_TYPE_LINE_TO = 2;
public static int NODE_TYPE_CURVE_POINT = 3;
@IggyFieldType(DataType.float_t)
float targetX;
@IggyFieldType(DataType.float_t)
float targetY; // negative
@IggyFieldType(DataType.float_t)
float controlX; // for curves
@IggyFieldType(DataType.float_t)
float controlY; // for curves, negative
@IggyFieldType(DataType.uint8_t) //1-moveto, 2-lineto , 3 - curve to
int node_type;
@IggyFieldType(DataType.uint8_t) // 208 start smooth (for j=1 only), 61 smooth interupt (muze a nemusi byt pro novy oddeleny kus charu - kdyz je subtype predchoziho vetsi nez 0 (kupr 5) bude pro oddeleny usek 61, jinak pokud je subtype predchoziho 0 bude pro oddeleny usek 0)
int node_subtype;
@IggyFieldType(DataType.uint8_t)
int zer1;
@IggyFieldType(DataType.uint8_t)
int zer2;
@IggyFieldType(DataType.uint32_t)
long isstart; // 1 v prubehu nebo 0 pouze pro prvni (i kdyz jsou delene jako dvojtecka!!!)
private boolean first;
public IggyShapeNode(float x1, float y1, float x2, float y2, int node_type, int node_subtype, int zer1, int zer2, long isstart) {
this.targetX = x1;
this.targetY = y1;
this.controlX = x2;
this.controlY = y2;
this.node_type = node_type;
this.node_subtype = node_subtype;
this.zer1 = zer1;
this.zer2 = zer2;
this.isstart = isstart;
}
public IggyShapeNode(AbstractDataStream s, boolean first) throws IOException {
this.first = first;
readFromDataStream(s);
}
@Override
public void readFromDataStream(AbstractDataStream s) throws IOException {
targetX = s.readFloat();
targetY = s.readFloat();
controlX = s.readFloat();
controlY = s.readFloat();
node_type = s.readUI8();
node_subtype = s.readUI8();
zer1 = s.readUI8();
zer2 = s.readUI8();
isstart = s.readUI32();
if ((zer1 != 0) | (zer2 != 0)) {
LOGGER.fine(String.format("Unknown zeroes at pos %08X\n", s.position() - 6));
}
if ((!first) & (isstart != 1)) {
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
}
if ((first) & (isstart != 0)) {
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
}
}
@Override
public void writeToDataStream(AbstractDataStream s) throws IOException {
s.writeFloat(targetX);
s.writeFloat(targetY);
s.writeFloat(controlX);
s.writeFloat(controlY);
s.writeUI8(node_type);
s.writeUI8(node_subtype);
s.writeUI8(zer1);
s.writeUI8(zer2);
s.writeUI32(isstart);
}
public float getX1() {
return targetX;
}
public float getY1() {
return targetY;
}
public float getX2() {
return controlX;
}
public float getY2() {
return controlY;
}
public int getNodeType() {
return node_type;
}
public int getNodeSubType() {
return node_subtype;
}
public int getZer1() {
return zer1;
}
public int getZer2() {
return zer2;
}
public boolean isStart() {
return isstart == 1;
}
}

View File

@@ -1,70 +1,73 @@
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*/
public class IggySubFileEntry implements StructureInterface {
public static final int TYPE_INDEX = 0;
public static final int TYPE_FLASH = 1;
@SWFType(BasicType.UI32)
long type;
@SWFType(BasicType.UI32)
long size;
//apparently same as size, maybe (un)compressed (?)
@SWFType(BasicType.UI32)
long size2;
//absolute offset
@SWFType(BasicType.UI32)
long offset;
public IggySubFileEntry(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
public IggySubFileEntry(long type, long size, long size2, long offset) {
this.type = type;
this.size = size;
this.size2 = size2;
this.offset = offset;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append("id: ").append(type).append(", ");
sb.append("size: ").append(size).append(", ");
sb.append("size2: ").append(size2).append(", ");
sb.append("offset: ").append(offset);
sb.append("]");
return sb.toString();
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
type = stream.readUI32();
size = stream.readUI32();
size2 = stream.readUI32();
offset = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
package com.jpexs.decompiler.flash.iggy;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*
* Based of works of somebody called eternity.
*/
public class IggySubFileEntry implements StructureInterface {
public static final int TYPE_INDEX = 0;
public static final int TYPE_FLASH = 1;
@SWFType(BasicType.UI32)
long type;
@SWFType(BasicType.UI32)
long size;
//apparently same as size, maybe (un)compressed (?)
@SWFType(BasicType.UI32)
long size2;
//absolute offset
@SWFType(BasicType.UI32)
long offset;
public IggySubFileEntry(AbstractDataStream stream) throws IOException {
readFromDataStream(stream);
}
public IggySubFileEntry(long type, long size, long size2, long offset) {
this.type = type;
this.size = size;
this.size2 = size2;
this.offset = offset;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append("id: ").append(type).append(", ");
sb.append("size: ").append(size).append(", ");
sb.append("size2: ").append(size2).append(", ");
sb.append("offset: ").append(offset);
sb.append("]");
return sb.toString();
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
type = stream.readUI32();
size = stream.readUI32();
size2 = stream.readUI32();
offset = stream.readUI32();
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
stream.writeUI32(type);
stream.writeUI32(size);
stream.writeUI32(size2);
stream.writeUI32(offset);
}
}

View File

@@ -0,0 +1,10 @@
package com.jpexs.decompiler.flash.iggy;
/**
*
* @author JPEXS
*/
public abstract class IggyTag implements StructureInterface {
public abstract int getTagType();
}

View File

@@ -0,0 +1,36 @@
package com.jpexs.decompiler.flash.iggy;
import java.io.IOException;
/**
*
* @author JPEXS
*/
public class RawIggyTag extends IggyTag {
byte[] rawData;
int tagType;
private int length;
public RawIggyTag(int tagType, AbstractDataStream stream, int length) throws IOException {
this.length = length;
this.tagType = tagType;
readFromDataStream(stream);
}
@Override
public int getTagType() {
return tagType;
}
@Override
public void readFromDataStream(AbstractDataStream stream) throws IOException {
rawData = stream.readBytes(length);
}
@Override
public void writeToDataStream(AbstractDataStream stream) throws IOException {
stream.writeBytes(rawData);
}
}