From 189460655133eadeeb5137aa82bff28ef7667540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 4 Dec 2016 18:57:10 +0100 Subject: [PATCH] Saving correct font data offsets --- .../flash/iggy/IggyCharAdvances.java | 5 + .../flash/iggy/IggyCharIndices.java | 6 + .../flash/iggy/IggyCharKerning.java | 10 + .../decompiler/flash/iggy/IggyCharOffset.java | 10 +- .../jpexs/decompiler/flash/iggy/IggyFile.java | 121 +++----- .../flash/iggy/IggyFlashHeader64.java | 77 +++++ .../jpexs/decompiler/flash/iggy/IggyFont.java | 111 ++++++- .../flash/iggy/IggyFontBinInfo.java | 2 +- .../flash/iggy/IggyFontTypeInfo.java | 34 +-- .../decompiler/flash/iggy/IggySequence.java | 71 ----- .../decompiler/flash/iggy/IggyShape.java | 16 +- .../decompiler/flash/iggy/IggyShapeNode.java | 25 +- .../jpexs/decompiler/flash/iggy/IggySwf.java | 272 ++++++++---------- .../conversion/IggyShapeToSwfConvertor.java | 210 +++++++------- .../flash/iggy/conversion/IggySwfBundle.java | 238 ++++++++------- .../iggy/conversion/IggyToSwfConvertor.java | 52 ++-- .../conversion/SwfShapeToIggyConvertor.java | 59 ++++ .../iggy/conversion/SwfToIggyConvertor.java | 157 ++++++++++ .../iggy/streams/AbstractDataStream.java | 11 + .../flash/iggy/streams/IggyIndexBuilder.java | 19 +- .../streams/WriteDataStreamInterface.java | 2 + 21 files changed, 890 insertions(+), 618 deletions(-) delete mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharAdvances.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharAdvances.java index 537e6be3b..61390c3d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharAdvances.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharAdvances.java @@ -20,6 +20,11 @@ public class IggyCharAdvances implements StructureInterface { return advances; } + public IggyCharAdvances(List advances) { + this.advances = advances; + this.charCount = advances.size(); + } + public IggyCharAdvances(ReadDataStreamInterface stream, long charCount) throws IOException { this.charCount = charCount; readFromDataStream(stream); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharIndices.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharIndices.java index 424ce93b0..207dcf724 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharIndices.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharIndices.java @@ -25,6 +25,12 @@ public class IggyCharIndices implements StructureInterface { private long charCount; + public IggyCharIndices(List chars) { + this.chars = chars; + this.charCount = chars.size(); + padd = 0; + } + public IggyCharIndices(ReadDataStreamInterface stream, long charCount) throws IOException { this.charCount = charCount; readFromDataStream(stream); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java index e838c0ad6..1353ced5c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharKerning.java @@ -36,6 +36,16 @@ public class IggyCharKerning implements StructureInterface { return kerningOffsets; } + public IggyCharKerning(List charsA, List charsB, List kerningOffsets) { + if ((charsA.size() != charsB.size()) || (charsB.size() != kerningOffsets.size())) { + throw new RuntimeException("sizes of charsA, charsB and offsets must match"); + } + this.kernCount = charsA.size(); + this.charsA = charsA; + this.charsB = charsB; + this.kerningOffsets = kerningOffsets; + } + public IggyCharKerning(ReadDataStreamInterface stream, long kernCount) throws IOException { this.kernCount = kernCount; readFromDataStream(stream); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java index 2023a9841..d753582db 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharOffset.java @@ -38,15 +38,15 @@ public class IggyCharOffset implements StructureInterface { readFromDataStream(stream); } - public IggyCharOffset(long zero, int ischar1, int ischar2, long zero2, int xscale, int yscale, long zero3, long offset) { - this.zero = zero; + public IggyCharOffset(int ischar1, int ischar2, int xscale, int yscale) { + this.zero = 0; this.ischar1 = ischar1; this.ischar2 = ischar2; - this.zero2 = zero2; + this.zero2 = 0; this.xscale = xscale; this.yscale = yscale; - this.zero3 = zero3; - this.offset = offset; + this.zero3 = 0; + this.offset = 0; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java index 3f6c06395..c49c6a683 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFile.java @@ -35,63 +35,25 @@ public class IggyFile implements StructureInterface { final static Logger LOGGER = Logger.getLogger(IggyFile.class.getName()); + private File originalFile; private IggyHeader header; private List subFileEntries = new ArrayList<>(); private List subFileEntriesData = new ArrayList<>(); - private List iggySwfs = new ArrayList<>(); + private IggySwf iggySwf; public static final int FIRST_TAG_POSITION = 3; - public void replaceFontTag(int targetSwfIndex, int fontIndex, IggyFont newFont) throws IOException { - IggySwf iggySwf = iggySwfs.get(targetSwfIndex); - iggySwf.replaceFontTag(fontIndex, newFont); - - IggyIndexBuilder indexStream = new IggyIndexBuilder(); - DataStreamInterface flashStream = new TemporaryDataStream(); - flashStream.setIndexing(indexStream); - iggySwf.writeToDataStream(flashStream); - byte flashData[] = flashStream.getAllBytes(); - int swfIndex = 0; - int offsetChange = 0; - for (int i = 0; i < subFileEntries.size(); i++) { - IggySubFileEntry entry = subFileEntries.get(i); - entry.offset += offsetChange; - if (entry.type == IggySubFileEntry.TYPE_INDEX) { - if (swfIndex == targetSwfIndex) { - byte indexData[] = indexStream.getIndexBytes(); - long newLen = indexData.length; - long oldLen = entry.size; - entry.size = newLen; - entry.size2 = newLen; - offsetChange += (newLen - oldLen); - subFileEntriesData.set(i, indexData); - } - swfIndex++; - } - if (entry.type == IggySubFileEntry.TYPE_FLASH) { - if (swfIndex == targetSwfIndex) { - long newLen = flashData.length; - long oldLen = entry.size; - entry.size = newLen; - entry.size2 = newLen; - offsetChange += (newLen - oldLen); - subFileEntriesData.set(i, flashData); - } - } - } + public IggySwf getSwf() { + return iggySwf; } - public IggySwf getSwf(int swfIndex) { - return iggySwfs.get(swfIndex); + public int getFontCount() { + return iggySwf.fonts.size(); } - public int getFontCount(int swfIndex) { - return iggySwfs.get(swfIndex).fonts.size(); - } - - public IggyFont getFont(int swfIndex, int fontId) { - return iggySwfs.get(swfIndex).fonts.get(fontId); + public IggyFont getFont(int fontId) { + return iggySwf.fonts.get(fontId); } public IggyFile(String filePath) throws IOException { @@ -99,11 +61,16 @@ public class IggyFile implements StructureInterface { } public IggyFile(File file) throws IOException { + this.originalFile = file; try (ReadDataStreamInterface stream = new RandomAccessFileDataStream(file)) { readFromDataStream(stream); } } + public File getOriginalFile() { + return originalFile; + } + public IggyHeader getHeader() { return header; } @@ -200,8 +167,7 @@ public class IggyFile implements StructureInterface { File outFile = new File(outFileName); IggyFile iggyFile = new IggyFile(inFile); extractIggyFile(inFile, extractDirOrig); - IggySwf iswf = iggyFile.getSwf(0); - iggyFile.replaceSwf(0, iswf); + iggyFile.updateFlashEntry(); outFile.delete(); try (RandomAccessFileDataStream outputStream = new RandomAccessFileDataStream(outFile)) { iggyFile.writeToDataStream(outputStream); @@ -620,32 +586,28 @@ public class IggyFile implements StructureInterface { return null; } - public int getSwfCount() { - return iggySwfs.size(); + public String getSwfName() { + return iggySwf.getName(); } - public String getSwfName(int swfIndex) { - return iggySwfs.get(swfIndex).getName(); + public long getSwfXMin() { + return iggySwf.getHdr().getXMin(); } - public long getSwfXMin(int swfIndex) { - return iggySwfs.get(swfIndex).getHdr().getXMin(); + public long getSwfYMin() { + return iggySwf.getHdr().getYMin(); } - public long getSwfYMin(int swfIndex) { - return iggySwfs.get(swfIndex).getHdr().getYMin(); + public long getSwfXMax() { + return iggySwf.getHdr().getXMax(); } - public long getSwfXMax(int swfIndex) { - return iggySwfs.get(swfIndex).getHdr().getXMax(); + public long getSwfYMax() { + return iggySwf.getHdr().getYMax(); } - public long getSwfYMax(int swfIndex) { - return iggySwfs.get(swfIndex).getHdr().getYMax(); - } - - public float getSwfFrameRate(int swfIndex) { - return iggySwfs.get(swfIndex).getHdr().getFrameRate(); + public float getSwfFrameRate() { + return iggySwf.getHdr().getFrameRate(); } /** @@ -667,11 +629,8 @@ public class IggyFile implements StructureInterface { } } - public boolean replaceSwf(int targetSwfIndex, IggySwf iggySwf) throws IOException { + public boolean updateFlashEntry() throws IOException { - if (targetSwfIndex < 0 || targetSwfIndex >= getSwfCount()) { - throw new ArrayIndexOutOfBoundsException("No such SWF file index"); - } byte replacementData[]; byte replacementIndexData[]; IggyIndexBuilder ib = new IggyIndexBuilder(); @@ -685,21 +644,17 @@ public class IggyFile implements StructureInterface { return false; } - //IggyIndexParser.parseIndex(true, new TemporaryDataStream(replacementIndexData), new ArrayList<>(), new ArrayList<>()); - int swfIndex = 0; long offsetsChange = 0; for (int i = 0; i < subFileEntries.size(); i++) { IggySubFileEntry entry = subFileEntries.get(i); entry.offset += offsetsChange; if (entry.type == IggySubFileEntry.TYPE_FLASH) { - if (swfIndex == targetSwfIndex) { - long oldSize = entry.size; - long newSize = replacementData.length; - entry.size = newSize; - entry.size2 = newSize; - offsetsChange = offsetsChange + (newSize - oldSize); //entries after this one will have modified offsets - subFileEntriesData.set(i, replacementData); - } + long oldSize = entry.size; + long newSize = replacementData.length; + entry.size = newSize; + entry.size2 = newSize; + offsetsChange = offsetsChange + (newSize - oldSize); //entries after this one will have modified offsets + subFileEntriesData.set(i, replacementData); } } @@ -714,7 +669,8 @@ public class IggyFile implements StructureInterface { for (int i = 0; i < subFileEntries.size(); i++) { IggySubFileEntry entry = subFileEntries.get(i); if (entry.type == IggySubFileEntry.TYPE_FLASH) { - iggySwfs.add(new IggySwf(new TemporaryDataStream(getEntryData(i)))); + iggySwf = new IggySwf(new TemporaryDataStream(getEntryData(i))); + break; } /*if (entry.type == IggySubFileEntry.TYPE_INDEX) { IggyIndexParser.parseIndex(true, new TemporaryDataStream(getEntryData(i)), new ArrayList<>(), new ArrayList<>()); @@ -736,6 +692,13 @@ public class IggyFile implements StructureInterface { parseEntries(); } + public void saveChanges() throws IOException { + updateFlashEntry(); + try (RandomAccessFileDataStream raf = new RandomAccessFileDataStream(originalFile)) { + writeToDataStream(raf); + } + } + @Override public void writeToDataStream(WriteDataStreamInterface stream) throws IOException { header.writeToDataStream(stream); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java index fa433e1ab..f5a17c9eb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFlashHeader64.java @@ -99,6 +99,67 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { private long decl_strings_address; private long type_fonts_address; + private long base_ofs_pos; + private long sequence_end_ofs_pos; + private long font_end_ofs_pos; + private long sequence_start1_ofs_pos; + private long sequence_start2_ofs_pos; + private long sequence_start3_ofs_pos; + private long names_ofs_pos; + private long unk78_ofs_pos; + private long last_section_ofs_pos; + private long flash_filename_ofs_pos; + private long decl_strings_ofs_pos; + private long type_fonts_ofs_pos; + + public long getBase_ofs_pos() { + return base_ofs_pos; + } + + public long getSequence_end_ofs_pos() { + return sequence_end_ofs_pos; + } + + public long getFont_end_ofs_pos() { + return font_end_ofs_pos; + } + + public long getSequence_start1_ofs_pos() { + return sequence_start1_ofs_pos; + } + + public long getSequence_start2_ofs_pos() { + return sequence_start2_ofs_pos; + } + + public long getSequence_start3_ofs_pos() { + return sequence_start3_ofs_pos; + } + + public long getNames_ofs_pos() { + return names_ofs_pos; + } + + public long getUnk78_ofs_pos() { + return unk78_ofs_pos; + } + + public long getLast_section_ofs_pos() { + return last_section_ofs_pos; + } + + public long getFlash_filename_ofs_pos() { + return flash_filename_ofs_pos; + } + + public long getDecl_strings_ofs_pos() { + return decl_strings_ofs_pos; + } + + public long getType_fonts_ofs_pos() { + return type_fonts_ofs_pos; + } + /** * Updates all addresses by inserting gap * @@ -146,6 +207,10 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { } public long getSequenceStartAddress2() { + return sequence_start_address2; + } + + public long getSequenceStartAddress3() { return sequence_start_address3; } @@ -175,21 +240,27 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { @Override public void readFromDataStream(ReadDataStreamInterface stream) throws IOException { + base_ofs_pos = stream.position(); off_base = stream.readUI64(); base_address = off_base == 1 ? 0 : off_base + stream.position() - 8; + sequence_end_ofs_pos = stream.position(); off_sequence_end = stream.readUI64(); sequence_end_address = off_sequence_end == 1 ? 0 : off_sequence_end + stream.position() - 8; + font_end_ofs_pos = stream.position(); off_font_end = stream.readUI64(); font_end_address = off_font_end == 1 ? 0 : off_font_end + stream.position() - 8; + sequence_start1_ofs_pos = stream.position(); off_sequence_start1 = stream.readUI64(); sequence_start_address1 = off_sequence_start1 == 1 ? 0 : off_sequence_start1 + stream.position() - 8; + sequence_start2_ofs_pos = stream.position(); off_sequence_start2 = stream.readUI64(); sequence_start_address2 = off_sequence_start2 == 1 ? 0 : off_sequence_start2 + stream.position() - 8; + sequence_start3_ofs_pos = stream.position(); off_sequence_start3 = stream.readUI64(); sequence_start_address3 = off_sequence_start3 == 1 ? 0 : off_sequence_start3 + stream.position() - 8; @@ -209,23 +280,29 @@ public class IggyFlashHeader64 implements IggyFlashHeaderInterface { imported_guid = stream.readUI64(); my_guid = stream.readUI64(); + names_ofs_pos = stream.position(); off_names = stream.readUI64(); names_address = off_names == 1 ? 0 : off_names + stream.position() - 8; + unk78_ofs_pos = stream.position(); off_unk78 = stream.readUI64(); unk78_address = off_unk78 == 1 ? 0 : off_unk78 + stream.position() - 8; unk80 = stream.readUI64(); //Maybe number of imports/names pointed by names_offset + last_section_ofs_pos = stream.position(); off_last_section = stream.readUI64(); last_section_address = off_last_section == 1 ? 0 : off_last_section + stream.position() - 8; + flash_filename_ofs_pos = stream.position(); off_flash_filename = stream.readUI64(); flash_filename_address = off_flash_filename == 1 ? 0 : off_flash_filename + stream.position() - 8; + decl_strings_ofs_pos = stream.position(); off_decl_strings = stream.readUI64(); //relative offset to as3 code (16 bytes header + abc blob) decl_strings_address = off_decl_strings == 1 ? 0 : off_decl_strings + stream.position() - 8; + type_fonts_ofs_pos = stream.position(); off_type_of_fonts = stream.readUI64(); //relative offset to as3 file names table (or classes names or whatever) type_fonts_address = off_type_of_fonts == 1 ? 0 : off_type_of_fonts + stream.position() - 8; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java index 1e93ec19c..9325c7b42 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFont.java @@ -108,9 +108,7 @@ public class IggyFont extends IggyTag { IggyCharAdvances charScales; IggyCharKerning charKernings; - byte[] padTo4byteBoundary; - - public IggyFont(int type, int fontId, byte[] zeroone, int char_count2, int ascent, int descent, int leading, long flags, long kern_count, float[] unk_float, long zero_padd, long what_2, long zero_padd_2, 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[] zeroes48a, byte[] zeroes48b, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List glyphs, IggyCharIndices codePoints, IggyCharAdvances charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) { + public IggyFont(int type, int fontId, byte[] zeroone, int char_count2, int ascent, int descent, int leading, long flags, long kern_count, float[] unk_float, long zero_padd, long what_2, long zero_padd_2, 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[] zeroes48a, byte[] zeroes48b, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List glyphs, IggyCharIndices codePoints, IggyCharAdvances charScales, IggyCharKerning charKernings) { this.type = type; this.fontId = fontId; this.zeroone = zeroone; @@ -149,7 +147,6 @@ public class IggyFont extends IggyTag { this.codePoints = codePoints; this.charScales = charScales; this.charKernings = charKernings; - this.padTo4byteBoundary = padTo4byteBoundary; } public IggyFont(ReadDataStreamInterface stream) throws IOException { @@ -276,8 +273,10 @@ public class IggyFont extends IggyTag { } glyphs = new ArrayList<>(); for (int i = 0; i < char_count; i++) { + //System.err.println("read char " + (i + 1) + "/" + char_count); long addr = charAddresses.get(i); if (addr != 0) { + //System.err.println("read chars at offset " + addr); s.seek(addr, SeekMode.SET); glyphs.add(new IggyShape(s)); } else { @@ -506,4 +505,108 @@ public class IggyFont extends IggyTag { return String.format("IggyFontTag (%04X)", ID); } + public void setType(int type) { + this.type = type; + } + + public void setFontId(int fontId) { + this.fontId = fontId; + } + + public void setCharCount2(int char_count2) { + this.char_count2 = char_count2; + } + + public void setAscent(int ascent) { + this.ascent = ascent; + } + + public void setDescent(int descent) { + this.descent = descent; + } + + public void setLeading(int leading) { + this.leading = leading; + } + + public void setFlags(long flags) { + this.flags = flags; + } + + public void setUnkFloat(float[] unk_float) { + this.unk_float = unk_float; + } + + public void setWhat2(long what_2) { + this.what_2 = what_2; + } + + public void setXScale(int xscale) { + this.xscale = xscale; + } + + public void setYScale(int yscale) { + this.yscale = yscale; + } + + public void setSsr1(float ssr1) { + this.ssr1 = ssr1; + } + + public void setSsr2(float ssr2) { + this.ssr2 = ssr2; + } + + public void setCharCount(long char_count) { + this.char_count = char_count; + } + + public void setWhat3(long what_3) { + this.what_3 = what_3; + } + + public void setSubName(String subName) { + this.subName = subName; + } + + public void setSss1(float sss1) { + this.sss1 = sss1; + } + + public void setSss2(float sss2) { + this.sss2 = sss2; + } + + public void setSss3(float sss3) { + this.sss3 = sss3; + } + + public void setSss4(float sss4) { + this.sss4 = sss4; + } + + public void setName(String name) { + this.name = name; + } + + public void setCharOffsets(List charOffsets) { + this.charOffsets = charOffsets; + } + + public void setGlyphs(List glyphs) { + this.glyphs = glyphs; + } + + public void setCodePoints(IggyCharIndices codePoints) { + this.codePoints = codePoints; + } + + public void setCharScales(IggyCharAdvances charScales) { + this.charScales = charScales; + } + + public void setCharKernings(IggyCharKerning charKernings) { + this.charKernings = charKernings; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java index d11cde5fb..a76f2127b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontBinInfo.java @@ -15,7 +15,7 @@ public class IggyFontBinInfo implements StructureInterface { public static final int STRUCT_SIZE = 96; @IggyFieldType(DataType.uint64_t) - long size_of_this_info = 96; + long size_of_this_info = STRUCT_SIZE; @IggyFieldType(value = DataType.uint16_t, count = 4) int font_specific[]; @IggyFieldType(DataType.float_t) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java index 33ec71665..7760816e2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontTypeInfo.java @@ -21,10 +21,10 @@ public class IggyFontTypeInfo implements StructureInterface { @IggyFieldType(DataType.uint64_t) long font_info_num; - private long local_name_address; + private long local_name_ofs_pos; - public long getLocal_name_address() { - return local_name_address; + public long getLocal_name_ofs_pos() { + return local_name_ofs_pos; } public IggyFontTypeInfo(ReadDataStreamInterface s) throws IOException { @@ -34,39 +34,15 @@ public class IggyFontTypeInfo implements StructureInterface { @Override public void readFromDataStream(ReadDataStreamInterface s) throws IOException { zero = s.readUI64(); + local_name_ofs_pos = s.position(); ofs_local_name = s.readUI64(); - local_name_address = ofs_local_name + s.position() - 8; font_info_num = s.readUI64(); } - public String readFontInfo(ReadDataStreamInterface s) throws IOException { - long pos = s.position(); - s.seek(local_name_address, SeekMode.SET); - StringBuilder inf_font_builder = new StringBuilder(); - while (true) { - char c = (char) s.readUI16(); - if (c == '\0') { - break; - } - inf_font_builder.append(c); - } - s.seek(pos, SeekMode.SET); - return inf_font_builder.toString(); - } - - public void writeFontInfo(String info_name, WriteDataStreamInterface s) throws IOException { - long pos = s.position(); - s.seek(local_name_address, SeekMode.SET); - for (int i = 0; i < info_name.length(); i++) { - s.writeUI16(info_name.charAt(i)); - } - s.writeUI16(0); - s.seek(pos, SeekMode.SET); - } - @Override public void writeToDataStream(WriteDataStreamInterface s) throws IOException { s.writeUI64(zero); + local_name_ofs_pos = s.position(); s.writeUI64(ofs_local_name); s.writeUI64(font_info_num); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java deleted file mode 100644 index 0c635183a..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySequence.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.jpexs.decompiler.flash.iggy; - -import static com.jpexs.decompiler.flash.iggy.IggyFontBinInfo.STRUCT_SIZE; -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 IggySequence implements StructureInterface { - - public static final int STRUCT_SIZE = 16; - - @IggyArrayFieldType(value = DataType.uint64_t, count = 2) - public long onepadd[]; - - @IggyFieldType(DataType.uint64_t) - public long local_seq_offset; - - @IggyFieldType(DataType.uint64_t) - public long zero; - - @IggyFieldType(DataType.wchar_t) - public String sequence_name; - - @IggyFieldType(DataType.uint64_t) - public long zero2; - - // wchar_t sequencname[(sequenceendaddress-sequencestartaddress-localseqoffset)/2]; -// if((sequenceendaddress-sequencestartaddress)%8!=0) byte padd[((sequenceendaddress-sequencestartaddress)/8+1)*8-(sequenceendaddress-sequencestartaddress)]; - public IggySequence(ReadDataStreamInterface stream) throws IOException { - readFromDataStream(stream); - } - - @Override - public void readFromDataStream(ReadDataStreamInterface s) throws IOException { - onepadd = new long[2]; - for (int i = 0; i < onepadd.length; i++) { - onepadd[i] = s.readUI64(); - } - //sequence start - local_seq_offset = s.readUI64(); - zero = s.readUI64(); - sequence_name = s.readWChar(); - s.pad8bytes(); - zero2 = s.readUI64(); //zero2 - } - - @Override - public void writeToDataStream(WriteDataStreamInterface s) throws IOException { - IggyIndexBuilder ib = s.getIndexing(); - ib.writeLengthCustom(16, new int[]{0x00}, new int[]{2}); - for (int i = 0; i < onepadd.length; i++) { - s.writeUI64(onepadd[i]); - } - ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE); - s.writeUI64(local_seq_offset); - s.writeUI64(zero); - ib.write16bitArray(sequence_name.length() + 1); - s.writeWChar(sequence_name); - s.pad8bytes(); - ib.pad8bytes(); - s.writeUI64(zero2); - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java index ec0eb6ed1..b5812944d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShape.java @@ -69,18 +69,18 @@ public class IggyShape implements StructureInterface { 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 nodes) { + public IggyShape(float minx, float miny, float maxx, float maxy, List 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.unk = 0; //?? + this.one = 1; + this.one2 = 1; + this.one3 = 1; + this.one4 = 1; + this.two1 = 2; + this.count = nodes.size(); this.nodes = nodes; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java index 04d9d4132..b99129289 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyShapeNode.java @@ -45,16 +45,17 @@ public class IggyShapeNode implements StructureInterface { 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; + public IggyShapeNode(float targetX, float targetY, float controlX, float controlY, int node_type, int node_subtype, boolean first) { + this.targetX = targetX; + this.targetY = targetY; + this.controlX = controlX; + this.controlY = controlY; this.node_type = node_type; this.node_subtype = node_subtype; - this.zer1 = zer1; - this.zer2 = zer2; - this.isstart = isstart; + this.zer1 = 0; + this.zer2 = 0; + this.first = first; + this.isstart = first ? 0 : 1; } public IggyShapeNode(ReadDataStreamInterface s, boolean first) throws IOException { @@ -98,19 +99,19 @@ public class IggyShapeNode implements StructureInterface { s.writeUI32(isstart); } - public float getX1() { + public float getTargetX() { return targetX; } - public float getY1() { + public float getTargetY() { return targetY; } - public float getX2() { + public float getControlX() { return controlX; } - public float getY2() { + public float getControlY() { return controlY; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java index 6b95d8b1c..f3e3a8ef1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggySwf.java @@ -28,9 +28,9 @@ public class IggySwf implements StructureInterface { String name; List fonts = new ArrayList<>(); - private List font_data_addresses = new ArrayList<>(); + // private List font_data_addresses = new ArrayList<>(); List add_fonts = new ArrayList<>(); - private List add_font_data_addresses = new ArrayList<>(); +// private List add_font_data_addresses = new ArrayList<>(); private IggyFlashHeader64 hdr; @@ -38,14 +38,16 @@ public class IggySwf implements StructureInterface { readFromDataStream(stream); } private List texts = new ArrayList<>(); - private List text_data_addresses = new ArrayList<>(); + //private List text_data_addresses = new ArrayList<>(); private List add_texts = new ArrayList<>(); - private List add_text_data_addresses = new ArrayList<>(); + //private List add_text_data_addresses = new ArrayList<>(); - private byte font_add_data[]; - private List font_additional_size = new ArrayList<>(); + //private byte font_add_data[]; + //private List font_additional_size = new ArrayList<>(); private IggyFontBinInfo font_bin_info[]; - private IggySequence sequence; + private List sequenceNames = new ArrayList<>(); + //private List sequenceValues = new ArrayList<>(); + private IggyFontTypeInfo type_info[]; private String type_info_name[]; private IggyDeclStrings decl_strings; @@ -56,36 +58,6 @@ public class IggySwf implements StructureInterface { return hdr; } - public void replaceFontTag(int fontIndex, IggyFont newFont) throws IOException { - /*long newLen; - byte newData[]; - try (WriteDataStreamInterface stream = new TemporaryDataStream()) { - newFont.writeToDataStream(stream); - newData = stream.getAllBytes(); - newLen = newData.length; - } - - //FIXME - Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_new\\font" + fontIndex + ".bin", newData); - - long oldLen = font_data_sizes[fontIndex]; - long diff = newLen - oldLen; - if (diff != 0) { - font_data_sizes[fontIndex] = newLen; - for (int i = fontIndex; i < hdr.font_count; i++) { - font_data_addresses[i] += diff; - } - for (int i = 0; i < text_addresses.size(); i++) { - text_addresses.set(i, text_addresses.get(i) + diff); - } - for (int i = 0; i < font_add_off.size(); i++) { - font_add_off.set(i, font_add_off.get(i) + diff); - } - } - hdr.insertGapAfter(font_data_addresses[fontIndex], diff); - */ - } - @Override public void readFromDataStream(ReadDataStreamInterface s) throws IOException { this.hdr = new IggyFlashHeader64(s); @@ -97,7 +69,7 @@ public class IggySwf implements StructureInterface { if (pad8 > 8) { s.seek(pad8, SeekMode.CUR); } - //here is offset [2] - 232 + //here is offset [2] - 232 s.seek(hdr.getBaseAddress(), SeekMode.SET); s.readUI64(); //pad 1 @@ -121,12 +93,12 @@ public class IggySwf implements StructureInterface { switch (kind) { case 22 /*FONT*/: IggyFont font = new IggyFont(s); - font_data_addresses.add(addr); + //font_data_addresses.add(addr); fonts.add(font); break; case 6 /*TEXT*/: IggyText text = new IggyText(s); - text_data_addresses.add(addr); + //text_data_addresses.add(addr); texts.add(text); break; default: @@ -151,12 +123,12 @@ public class IggySwf implements StructureInterface { switch (kind) { case 22 /*FONT*/: IggyFont font = new IggyFont(s); - add_font_data_addresses.add(addr); + //add_font_data_addresses.add(addr); add_fonts.add(font); break; case 6 /*TEXT*/: IggyText text = new IggyText(s); - add_text_data_addresses.add(addr); + //add_text_data_addresses.add(addr); add_texts.add(text); break; default: @@ -164,91 +136,6 @@ public class IggySwf implements StructureInterface { } } } - - /* - for (int i = 0; i < hdr.font_count; i++) { - long offset = s.readUI64(); - font_data_addresses[i] = offset + s.position() - 8; - long next_offset = s.readUI64(); - s.seek(-8, SeekMode.CUR); - if (next_offset == 1) { - font_data_sizes[i] = hdr.getFontEndAddress() - font_data_addresses[i]; - } else { - font_data_sizes[i] = next_offset - offset + 8; - } - } - while (true) { - long offset = s.readUI64(); - if (offset == 1) { - break; - } - long text_addr = offset + s.position() - 8; - text_addresses.add(text_addr); - long next_offset = s.readUI64(); - s.seek(-8, SeekMode.CUR); - if (next_offset == 1) { - text_data_sizes.add(hdr.getFontEndAddress() - text_addr); - break; - } else { - text_data_sizes.add(next_offset - offset + 8); - } - } - s.readUI64(); //1 - - if (hdr.getImported_guid() != 0) { - ofs_additional = s.readUI64(); - additional_address = ofs_additional + s.position() - 8; - font_additional_addresses.add(additional_address); - font_additional_size.add(hdr.getFontEndAddress() - font_additional_addresses.get(0)); - - if (s.readUI8(font_additional_addresses.get(0)) != 22) { //additional is not text - // font je hozen mezi infa... - for (int i = 0; i < text_addresses.size(); i++) { //walk all already read texts - if (s.readUI8(text_addresses.get(i)) == 22) { //check if it's text - long pomoff; - long pomsize; - pomoff = text_addresses.get(i); - pomsize = text_data_sizes.get(i); - text_addresses.set(i, font_additional_addresses.get(0)); - text_data_sizes.set(i, font_additional_size.get(0)); - font_additional_addresses.set(0, pomoff); - font_additional_size.set(0, pomsize); - } - } - } - }*/ - - /* if (s.readUI8(s.position()) == 22) { //22 = Text - byte[] textHdr = s.readBytes(IggyText.STRUCT_SIZE); - String textStr = s.readWChar(); - s.pad8bytes(); - }*/ - //here is offset [3] - 744 - /* fonts = new ArrayList<>(); - for (int i = 0; i < hdr.font_count; i++) { - s.seek(font_data_addresses[i], SeekMode.SET); - byte font_data[] = s.readBytes((int) font_data_sizes[i]); - //FIXME - //Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\font" + i + ".bin", font_data); - s.seek(-font_data_sizes[i], SeekMode.CUR); - IggyFont font = new IggyFont(s); - fonts.add(font); - } - - for (int i = 0; - i < text_addresses.size(); - i++) { - s.seek(text_addresses.get(i), SeekMode.SET); - texts.add(new IggyText(s)); - //byte text_data[] = s.readBytes((int) (long) text_data_sizes.get(i)); - //text_data_bytes.add(text_data); - } - - if (hdr.getImported_guid() - != 0) { - s.seek(font_additional_addresses.get(0), SeekMode.SET); - font_add_data = s.readBytes((int) (long) font_additional_size.get(0)); - }*/ s.seek(hdr.getFontEndAddress(), SeekMode.SET); //here is offset [4] - 856 ? font_bin_info = new IggyFontBinInfo[(int) hdr.font_count]; @@ -256,9 +143,33 @@ public class IggySwf implements StructureInterface { font_bin_info[i] = new IggyFontBinInfo(s); } - s.seek(hdr.getSequenceStartAddress1(), SeekMode.SET); - sequence = new IggySequence(s); + sequenceNames = new ArrayList<>(); + long seq_addresses[] = new long[]{hdr.getSequenceStartAddress1(), hdr.getSequenceStartAddress2(), hdr.getSequenceStartAddress3()}; + long seq_name_addresses[] = new long[3]; + for (int i = 0; i < 3; i++) { + if (seq_addresses[i] == 0) { + seq_name_addresses[i] = 0; + //0 + } else { + s.seek(seq_addresses[i], SeekMode.SET); + long ofs_seq_name = s.readUI64(); + seq_name_addresses[i] = ofs_seq_name == 1 ? 0 : ofs_seq_name + s.position() - 8; + s.readUI64(); //is this crucial? + } + } + + for (int i = 0; i < 3; i++) { + if (seq_name_addresses[i] > 0) { + s.seek(seq_name_addresses[i], SeekMode.SET); + sequenceNames.add(s.readWChar()); + } else { + sequenceNames.add(null); + } + } + s.pad8bytes(); + + //sequence = new IggySequence(s); s.seek(hdr.getTypeFontsAddress(), SeekMode.SET); type_info = new IggyFontTypeInfo[(int) hdr.font_count]; type_info_name = new String[(int) hdr.font_count]; @@ -266,7 +177,8 @@ public class IggySwf implements StructureInterface { type_info[i] = new IggyFontTypeInfo(s); } for (int i = 0; i < hdr.font_count; i++) { - type_info_name[i] = type_info[i].readFontInfo(s); + s.seek(type_info[i].getLocal_name_ofs_pos() + type_info[i].ofs_local_name, SeekMode.SET); + type_info_name[i] = s.readWChar(); } s.seek(hdr.getDeclStringsAddress(), SeekMode.SET); @@ -290,64 +202,114 @@ public class IggySwf implements StructureInterface { ib.write16bitArray(name.length() + 1); ib.writeTwoPaddingBytes(); ib.write64bitPointerArray(64); - for (int i = 0; i < font_data_addresses.size(); i++) { - long offset = font_data_addresses.get(i) - s.position(); - s.writeUI64(offset); + long posBeforeOffsets = s.position(); + + final int FILL_LATER = 1; + + List fontPosFillLater = new ArrayList<>(); + + for (int i = 0; i < fonts.size(); i++) { + fontPosFillLater.add(s.position()); + s.writeUI64(FILL_LATER); } - for (int i = 0; i < text_data_addresses.size(); i++) { - long offset = text_data_addresses.get(i) - s.position(); - s.writeUI64(offset); + List textPosFillLater = new ArrayList<>(); + for (int i = 0; i < texts.size(); i++) { + textPosFillLater.add(s.position()); + s.writeUI64(FILL_LATER); } s.writeUI64(1); - if (additional_address != 0) { - long ofs_additional = additional_address - s.position(); - s.writeUI64(ofs_additional); + + long addPosFillLater = s.position(); + s.writeUI64(FILL_LATER); + long posAfter = posBeforeOffsets + 64 * 8; + long curPos = s.position(); + long numLeft = posAfter - curPos; + long ofsLeft = numLeft / 8; + for (int i = 0; i < ofsLeft - 1; i++) { + s.writeUI64(FILL_LATER); } - while (s.position() < font_data_addresses.get(0)) { - s.writeUI64(1); - } for (int i = 0; i < fonts.size(); i++) { - s.seek(font_data_addresses.get(i), SeekMode.SET); + s.setOlderOffsetToThisPos(fontPosFillLater.get(i)); fonts.get(i).writeToDataStream(s); } for (int i = 0; i < texts.size(); i++) { - s.seek(text_data_addresses.get(i), SeekMode.SET); + s.setOlderOffsetToThisPos(textPosFillLater.get(i)); texts.get(i).writeToDataStream(s); } - if (hdr.getImported_guid() != 0) { + if (!add_fonts.isEmpty() || !add_texts.isEmpty()) { + s.setOlderOffsetToThisPos(addPosFillLater); + + List addFontPosFillLater = new ArrayList<>(); + for (int i = 0; i < add_fonts.size(); i++) { - s.seek(add_font_data_addresses.get(i), SeekMode.SET); - fonts.get(i).writeToDataStream(s); + addFontPosFillLater.add(s.position()); + s.writeUI64(FILL_LATER); + } + List addTextPosFillLater = new ArrayList<>(); + for (int i = 0; i < add_texts.size(); i++) { + addTextPosFillLater.add(s.position()); + s.writeUI64(FILL_LATER); + } + s.writeUI64(FILL_LATER); + for (int i = 0; i < add_fonts.size(); i++) { + s.setOlderOffsetToThisPos(addFontPosFillLater.get(i)); + add_fonts.get(i).writeToDataStream(s); } for (int i = 0; i < add_texts.size(); i++) { - s.seek(add_text_data_addresses.get(i), SeekMode.SET); - texts.get(i).writeToDataStream(s); + s.setOlderOffsetToThisPos(addTextPosFillLater.get(i)); + add_texts.get(i).writeToDataStream(s); } } - s.seek(hdr.getFontEndAddress(), SeekMode.SET); + s.setOlderOffsetToThisPos(hdr.getFont_end_ofs_pos()); ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count); for (int i = 0; i < hdr.font_count; i++) { font_bin_info[i].writeToDataStream(s); } - s.seek(hdr.getSequenceStartAddress1(), SeekMode.SET); - sequence.writeToDataStream(s); + long seq_ofs_pos[] = new long[]{hdr.getSequence_start1_ofs_pos(), hdr.getSequence_start2_ofs_pos(), hdr.getSequence_start3_ofs_pos()}; + long off_seq_expected[] = new long[]{hdr.off_sequence_start1, hdr.off_sequence_start2, hdr.off_sequence_start3}; + + long seq_name_fill_later[] = new long[3]; + + s.setOlderOffsetToThisPos(seq_ofs_pos[0]); + s.writeUI64(1); + s.writeUI64(1); + ib.writeLengthCustom(16, new int[]{0}, new int[]{2}); + + seq_name_fill_later[2] = s.position(); + s.setOlderOffsetToThisPos(seq_ofs_pos[2]); + s.writeUI64(FILL_LATER); + s.writeUI64(0); + ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE); + for (int i = 0; i < 3; i++) { + if (sequenceNames.get(i) != null) { + s.setOlderOffsetToThisPos(seq_name_fill_later[i]); + ib.write16bitArray(sequenceNames.get(i).length() + 1); + s.writeWChar(sequenceNames.get(i)); + } + } + s.pad8bytes(); + ib.pad8bytes(); ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count); - s.seek(hdr.getTypeFontsAddress(), SeekMode.SET); + s.setOlderOffsetToThisPos(hdr.getType_fonts_ofs_pos()); + //s.seek(hdr.getTypeFontsAddress(), SeekMode.SET); for (int i = 0; i < hdr.font_count; i++) { type_info[i].writeToDataStream(s); } for (int i = 0; i < hdr.font_count; i++) { ib.write16bitArray(type_info_name[i].length() + 1); - type_info[i].writeFontInfo(type_info_name[i], s); + s.setOlderOffsetToThisPos(type_info[i].getLocal_name_ofs_pos()); + s.writeWChar(type_info_name[i]); } s.pad8bytes(); ib.pad8bytes(); - s.seek(hdr.getDeclStringsAddress(), SeekMode.SET); + + s.setOlderOffsetToThisPos(hdr.getDecl_strings_ofs_pos()); + //s.seek(hdr.getDeclStringsAddress(), SeekMode.SET); decl_strings.writeToDataStream(s); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyShapeToSwfConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyShapeToSwfConvertor.java index 8644c6882..00ab98dce 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyShapeToSwfConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyShapeToSwfConvertor.java @@ -1,105 +1,105 @@ -package com.jpexs.decompiler.flash.iggy.conversion; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.iggy.IggyShape; -import com.jpexs.decompiler.flash.iggy.IggyShapeNode; -import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; -import com.jpexs.decompiler.flash.types.LINESTYLE; -import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; -import com.jpexs.decompiler.flash.types.RGB; -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 java.awt.Color; -import java.util.ArrayList; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class IggyShapeToSwfConvertor { - - private static int makeLengthsEmX(double val) { - return (int) (val * 1024.0); - } - - private static int makeLengthsEmY(double val) { - return (int) (val * 1024.0); - } - - public static SHAPE convertCharToShape(IggyShape igchar) { - SHAPE shape = new SHAPE(); - List retList = new ArrayList<>(); - List ignodes = igchar.getNodes(); - - int prevX = 0; - int prevY = 0; - - for (IggyShapeNode ign : ignodes) { - if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_MOVE) { - StyleChangeRecord scr = new StyleChangeRecord(); - scr.stateMoveTo = true; - prevX = scr.moveDeltaX = makeLengthsEmX(ign.getX1()); - prevY = scr.moveDeltaY = makeLengthsEmY(ign.getY1()); - scr.fillStyles = new FILLSTYLEARRAY(); - scr.lineStyles = new LINESTYLEARRAY(); - scr.calculateBits(); - retList.add(scr); - } else { - - int curX1 = makeLengthsEmX(ign.getX1()); - int curY1 = makeLengthsEmY(ign.getY1()); - - int curX2 = makeLengthsEmX(ign.getX2()); - int curY2 = makeLengthsEmY(ign.getY2()); - - if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_LINE_TO) { - StraightEdgeRecord ser = new StraightEdgeRecord(); - ser.deltaX = curX1 - prevX; - ser.deltaY = curY1 - prevY; - ser.generalLineFlag = true; - ser.simplify(); - ser.calculateBits(); - prevX = curX1; - prevY = curY1; - retList.add(ser); - } else if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_CURVE_POINT) { - CurvedEdgeRecord cer = new CurvedEdgeRecord(); - cer.controlDeltaX = curX2 - prevX; - cer.controlDeltaY = curY2 - prevY; - cer.anchorDeltaX = curX1 - curX2; - cer.anchorDeltaY = curY1 - curY2; - prevX = curX1; - prevY = curY1; - cer.calculateBits(); - retList.add(cer); - } - } - } - if (!retList.isEmpty()) { - StyleChangeRecord init; - if (retList.get(0) instanceof StyleChangeRecord) { - init = (StyleChangeRecord) retList.get(0); - } else { - init = new StyleChangeRecord(); - retList.add(0, init); - } - init.stateFillStyle0 = true; - init.fillStyle0 = 1; - shape.numFillBits = 1; - - } else { - shape.numFillBits = 0; - - } - retList.add(new EndShapeRecord()); - shape.shapeRecords = retList; - shape.numLineBits = 0; - - return shape; - } -} +package com.jpexs.decompiler.flash.iggy.conversion; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.iggy.IggyShape; +import com.jpexs.decompiler.flash.iggy.IggyShapeNode; +import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.LINESTYLE; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.RGB; +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 java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class IggyShapeToSwfConvertor { + + private static int makeLengthsEmX(double val) { + return (int) (val * 1024.0); + } + + private static int makeLengthsEmY(double val) { + return (int) (val * 1024.0); + } + + public static SHAPE convertCharToShape(IggyShape igchar) { + SHAPE shape = new SHAPE(); + List retList = new ArrayList<>(); + List ignodes = igchar.getNodes(); + + int prevX = 0; + int prevY = 0; + + for (IggyShapeNode ign : ignodes) { + if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_MOVE) { + StyleChangeRecord scr = new StyleChangeRecord(); + scr.stateMoveTo = true; + prevX = scr.moveDeltaX = makeLengthsEmX(ign.getTargetX()); + prevY = scr.moveDeltaY = makeLengthsEmY(ign.getTargetY()); + scr.fillStyles = new FILLSTYLEARRAY(); + scr.lineStyles = new LINESTYLEARRAY(); + scr.calculateBits(); + retList.add(scr); + } else { + + int curX1 = makeLengthsEmX(ign.getTargetX()); + int curY1 = makeLengthsEmY(ign.getTargetY()); + + int curX2 = makeLengthsEmX(ign.getControlX()); + int curY2 = makeLengthsEmY(ign.getControlY()); + + if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_LINE_TO) { + StraightEdgeRecord ser = new StraightEdgeRecord(); + ser.deltaX = curX1 - prevX; + ser.deltaY = curY1 - prevY; + ser.generalLineFlag = true; + ser.simplify(); + ser.calculateBits(); + prevX = curX1; + prevY = curY1; + retList.add(ser); + } else if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_CURVE_POINT) { + CurvedEdgeRecord cer = new CurvedEdgeRecord(); + cer.controlDeltaX = curX2 - prevX; + cer.controlDeltaY = curY2 - prevY; + cer.anchorDeltaX = curX1 - curX2; + cer.anchorDeltaY = curY1 - curY2; + prevX = curX1; + prevY = curY1; + cer.calculateBits(); + retList.add(cer); + } + } + } + if (!retList.isEmpty()) { + StyleChangeRecord init; + if (retList.get(0) instanceof StyleChangeRecord) { + init = (StyleChangeRecord) retList.get(0); + } else { + init = new StyleChangeRecord(); + retList.add(0, init); + } + init.stateFillStyle0 = true; + init.fillStyle0 = 1; + shape.numFillBits = 1; + + } else { + shape.numFillBits = 0; + + } + retList.add(new EndShapeRecord()); + shape.shapeRecords = retList; + shape.numLineBits = 0; + + return shape; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggySwfBundle.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggySwfBundle.java index 330342129..058f010e1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggySwfBundle.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggySwfBundle.java @@ -1,104 +1,134 @@ -package com.jpexs.decompiler.flash.iggy.conversion; - -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFBundle; -import com.jpexs.decompiler.flash.iggy.IggyFile; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.MemoryInputStream; -import com.jpexs.helpers.ReReadableInputStream; -import com.jpexs.helpers.streams.SeekableInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -/** - * - * @author JPEXS - */ -public class IggySwfBundle implements SWFBundle { - - private IggyFile iggyFile; - - public IggySwfBundle(InputStream is) throws IOException { - this(is, null); - } - - public IggySwfBundle(File filename) throws IOException { - this(null, filename); - } - - protected IggySwfBundle(InputStream is, File filename) throws IOException { - initBundle(is, filename); - } - - protected void initBundle(InputStream is, File filename) throws IOException { - if (filename == null) { - filename = File.createTempFile("bundle", ".iggy"); - Helper.saveStream(is, filename); - } - iggyFile = new IggyFile(filename); - } - - @Override - public int length() { - return iggyFile.getSwfCount(); - } - - @Override - public Set getKeys() { - Set ret = new TreeSet<>(); - for (int i = 0; i < length(); i++) { - ret.add(iggyFile.getSwfName(i)); - } - return ret; - } - - private int keyToSwfIndex(String key) { - for (int i = 0; i < length(); i++) { - if (key.equals(iggyFile.getSwfName(i))) { - return i; - } - } - throw new IllegalArgumentException("Key " + key + " does not exist!"); - } - - @Override - public SeekableInputStream getSWF(String key) throws IOException { - SWF swf = IggyToSwfConvertor.getSwf(iggyFile, keyToSwfIndex(key)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - swf.saveTo(baos); - MemoryInputStream mis = new MemoryInputStream(baos.toByteArray()); - return mis; - } - - @Override - public Map getAll() throws IOException { - Map ret = new HashMap<>(); - for (String key : getKeys()) { - ret.put(key, getSWF(key)); - } - return ret; - } - - @Override - public String getExtension() { - return "iggy"; - } - - @Override - public boolean isReadOnly() { - return true; //TODO: make writable - } - - @Override - public boolean putSWF(String key, InputStream is) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - -} +package com.jpexs.decompiler.flash.iggy.conversion; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.SWFBundle; +import com.jpexs.decompiler.flash.iggy.IggyFile; +import com.jpexs.decompiler.flash.iggy.IggyFont; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.MemoryInputStream; +import com.jpexs.helpers.ReReadableInputStream; +import com.jpexs.helpers.streams.SeekableInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class IggySwfBundle implements SWFBundle { + + private IggyFile iggyFile; + + public IggySwfBundle(InputStream is) throws IOException { + this(is, null); + } + + public IggySwfBundle(File filename) throws IOException { + this(null, filename); + } + + protected IggySwfBundle(InputStream is, File filename) throws IOException { + initBundle(is, filename); + } + + protected void initBundle(InputStream is, File filename) throws IOException { + if (filename == null) { + filename = File.createTempFile("bundle", ".iggy"); + Helper.saveStream(is, filename); + } + iggyFile = new IggyFile(filename); + } + + @Override + public int length() { + return 1; + } + + @Override + public Set getKeys() { + Set ret = new TreeSet<>(); + for (int i = 0; i < length(); i++) { + ret.add(iggyFile.getSwfName()); + } + return ret; + } + + private int keyToSwfIndex(String key) { + for (int i = 0; i < length(); i++) { + if (key.equals(iggyFile.getSwfName())) { + return i; + } + } + throw new IllegalArgumentException("Key " + key + " does not exist!"); + } + + @Override + public SeekableInputStream getSWF(String key) throws IOException { + SWF swf = IggyToSwfConvertor.getSwf(iggyFile); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + swf.saveTo(baos); + MemoryInputStream mis = new MemoryInputStream(baos.toByteArray()); + return mis; + } + + @Override + public Map getAll() throws IOException { + Map ret = new HashMap<>(); + for (String key : getKeys()) { + ret.put(key, getSWF(key)); + } + return ret; + } + + @Override + public String getExtension() { + return "iggy"; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public boolean putSWF(String key, InputStream is) throws IOException { + try { + int swfIndex = 0; + SWF swf = new SWF(is, false, false); + List fontTags = new ArrayList<>(); + for (CharacterTag ct : swf.getCharacters().values()) { + if (ct instanceof DefineFont2Tag) { + fontTags.add((DefineFont2Tag) ct); + } + } + int fontCount = iggyFile.getFontCount(); + if (fontCount != fontTags.size()) { + throw new IOException("Font count is different from original iggy file"); + } + for (int i = 0; i < fontCount; i++) { + IggyFont iggyFont = iggyFile.getFont(i); + DefineFont2Tag fontTag = fontTags.get(i); + SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag); + } + iggyFile.saveChanges(); + return true; + } catch (InterruptedException ex) { + return false; + } + + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java index 18947a11d..3fcaafad2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyToSwfConvertor.java @@ -9,6 +9,7 @@ import com.jpexs.decompiler.flash.iggy.IggyCharOffset; import com.jpexs.decompiler.flash.iggy.IggyCharAdvances; 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; @@ -44,56 +45,42 @@ import java.util.Set; */ public class IggyToSwfConvertor { - public static SWF[] getAllSwfs(IggyFile file) { - SWF[] ret = new SWF[file.getSwfCount()]; - for (int i = 0; i < ret.length; i++) { - ret[i] = getSwf(file, i); - } - return ret; - } - public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException { - for (int swfIndex = 0; swfIndex < file.getSwfCount(); swfIndex++) { - exportSwfToDir(file, swfIndex, outputDir); + 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 exportSwfToDir(IggyFile file, int swfIndex, File outputDir) throws IOException { - try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName(swfIndex)))) { - exportSwf(file, swfIndex, fos); - } - } - - public static void exportSwfToFile(IggyFile file, int swfIndex, File outputFile) throws IOException { + public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException { try (FileOutputStream fos = new FileOutputStream(outputFile)) { - exportSwf(file, swfIndex, fos); + exportSwf(file, fos); } } - public static void exportSwf(IggyFile file, int swfIndex, OutputStream output) throws IOException { - SWF swf = getSwf(file, swfIndex); + public static void exportSwf(IggyFile file, OutputStream output) throws IOException { + SWF swf = getSwf(file); swf.saveTo(output); } - private static int makeLengthsTwip(double val) { - return (int) (val * SWF.unitDivisor); - } - private static int makeLengthsEm(double val) { return (int) (val * 1024.0); } - public static SWF getSwf(IggyFile file, int swfIndex) { + public static SWF getSwf(IggyFile file) { SWF swf = new SWF(); swf.compression = SWFCompression.NONE; swf.frameCount = 1; //FIXME!! - swf.frameRate = file.getSwfFrameRate(swfIndex); + swf.frameRate = file.getSwfFrameRate(); swf.gfx = false; swf.displayRect = new RECT( - (int) (file.getSwfXMin(swfIndex) * SWF.unitDivisor), - (int) (file.getSwfXMax(swfIndex) * SWF.unitDivisor), - (int) (file.getSwfYMin(swfIndex) * SWF.unitDivisor), - (int) (file.getSwfYMax(swfIndex) * SWF.unitDivisor)); + (int) (file.getSwfXMin() * SWF.unitDivisor), + (int) (file.getSwfXMax() * SWF.unitDivisor), + (int) (file.getSwfYMin() * SWF.unitDivisor), + (int) (file.getSwfYMax() * SWF.unitDivisor)); swf.version = 10; //FIXME FileAttributesTag fat = new FileAttributesTag(swf); @@ -101,15 +88,14 @@ public class IggyToSwfConvertor { fat.hasMetadata = false; fat.useNetwork = false; swf.addTag(fat); - //Set fontIndices = file.getFontIds(swfIndex); - int fontCount = file.getFontCount(swfIndex); + int fontCount = file.getFontCount(); int currentCharId = 0; Map fontIndex2CharId = new HashMap<>(); for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) { - IggyFont iggyFont = file.getFont(swfIndex, fontIndex); + IggyFont iggyFont = file.getFont(fontIndex); DefineFont2Tag fontTag = new DefineFont2Tag(swf); currentCharId++; fontIndex2CharId.put(fontIndex, currentCharId); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java new file mode 100644 index 000000000..c23c6a009 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfShapeToIggyConvertor.java @@ -0,0 +1,59 @@ +package com.jpexs.decompiler.flash.iggy.conversion; + +import com.jpexs.decompiler.flash.iggy.IggyShape; +import com.jpexs.decompiler.flash.iggy.IggyShapeNode; +import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.SHAPE; +import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord; +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 java.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class SwfShapeToIggyConvertor { + + private static float normalizeLengths(int val) { + return (val / 1024f); + } + + public static IggyShape convertShape(SHAPE swfShape) { + /*if (swfShape.shapeRecords.size() == 1) { //no glyphs, maybe space + return null; + }*/ + List nodes = new ArrayList<>(); + RECT bounds = swfShape.getBounds(); + boolean first = true; + float curX = 0f; + float curY = 0f; + for (SHAPERECORD rec : swfShape.shapeRecords) { + if (rec instanceof StraightEdgeRecord) { + StraightEdgeRecord ser = (StraightEdgeRecord) rec; + curX += normalizeLengths(ser.deltaX); + curY += normalizeLengths(ser.deltaY); + nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_LINE_TO, 0, first)); + } else if (rec instanceof CurvedEdgeRecord) { + CurvedEdgeRecord cer = (CurvedEdgeRecord) rec; + float controlX = curX + normalizeLengths(cer.controlDeltaX); + float controlY = curY + normalizeLengths(cer.controlDeltaY); + curX = curX + normalizeLengths(cer.controlDeltaX + cer.anchorDeltaX); + curY = curY + normalizeLengths(cer.controlDeltaY + cer.anchorDeltaY); + nodes.add(new IggyShapeNode(curX, curY, controlX, controlY, IggyShapeNode.NODE_TYPE_CURVE_POINT, 0, first)); + } else if (rec instanceof StyleChangeRecord) { + StyleChangeRecord scr = (StyleChangeRecord) rec; + if (scr.stateMoveTo) { + curX = normalizeLengths(scr.moveDeltaX); + curY = normalizeLengths(scr.moveDeltaY); + nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_MOVE, 0, first)); + } + } + first = false; + } + IggyShape ret = new IggyShape(normalizeLengths(bounds.Xmin), normalizeLengths(bounds.Ymin), normalizeLengths(bounds.Xmax), normalizeLengths(bounds.Ymax), nodes); + return ret; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java new file mode 100644 index 000000000..649135c3b --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/SwfToIggyConvertor.java @@ -0,0 +1,157 @@ +package com.jpexs.decompiler.flash.iggy.conversion; + +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.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.types.KERNINGRECORD; +import com.jpexs.decompiler.flash.types.SHAPE; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class SwfToIggyConvertor { + + private static float normalizeLengths(int val) { + return (val / 1024f); + } + + 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 charOffsets = new ArrayList<>(); + + List glyphs = new ArrayList<>(); + + for (SHAPE s : fontTag.glyphShapeTable) { + glyphs.add(SwfShapeToIggyConvertor.convertShape(s)); + } + + List chars = new ArrayList<>(); + for (int code : fontTag.codeTable) { + chars.add((char) code); + } + IggyCharIndices codePoints = new IggyCharIndices(chars); + List scales = new ArrayList<>(); + for (int adv : fontTag.fontAdvanceTable) { + scales.add(normalizeLengths(adv)); + } + IggyCharAdvances charScales = new IggyCharAdvances(scales); + List charA = new ArrayList<>(); + List charB = new ArrayList<>(); + List 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); + /* + 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); + */ + } + + 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 charOffsets = new ArrayList<>(); + List glyphs = new ArrayList<>(); + List chars = new ArrayList<>(); + for (int code : fontTag.codeTable) { + chars.add((char) code); + } + IggyCharIndices codePoints = new IggyCharIndices(chars); + List scales = new ArrayList<>(); + for (int adv : fontTag.fontAdvanceTable) { + scales.add((float) adv); + } + IggyCharAdvances charScales = new IggyCharAdvances(scales); + List charA = new ArrayList<>(); + List charB = new ArrayList<>(); + List 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; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java index 73876d1a8..2cda5f443 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/AbstractDataStream.java @@ -227,4 +227,15 @@ public abstract class AbstractDataStream implements DataStreamInterface { writeUI64(actual); seek(curPos, SeekMode.SET); } + + public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException { + if (expected == 1) { + return; + } + long curPos = position(); + long actual = curPos - savedPos; + if (actual != expected) { + throw new RuntimeException("Expected " + expected + " but found actual " + actual + ". Diff:" + ((actual - expected) > 0 ? "+" : "") + (actual - expected)); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java index 7b4322c4a..9d1356e63 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/IggyIndexBuilder.java @@ -4,20 +4,14 @@ import com.jpexs.decompiler.flash.iggy.IggyCharKerning; import com.jpexs.decompiler.flash.iggy.IggyCharOffset; import com.jpexs.decompiler.flash.iggy.IggyFontBinInfo; import com.jpexs.decompiler.flash.iggy.IggyFontTypeInfo; -import com.jpexs.decompiler.flash.iggy.IggySequence; import com.jpexs.decompiler.flash.iggy.IggyShape; import com.jpexs.decompiler.flash.iggy.IggyShapeNode; import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; import java.util.logging.Logger; /** @@ -73,7 +67,7 @@ public class IggyIndexBuilder { private static final int CONST_VAL_GENERAL_FONT_INFO_SIZE = 112; private static final int CONST_VAL_GENERAL_FONT_INFO2_SIZE = 240; private static final int CONST_VAL_TEXT_DATA_SIZE = 104; - private static final int CONST_VAL_SEQUENCE_SIZE = IggySequence.STRUCT_SIZE; + private static final int CONST_VAL_SEQUENCE_SIZE = 16; public static final int CONST_SHAPE_NODE_SIZE = 0; public static final int CONST_KERNING_RECORD_SIZE = 1; @@ -175,8 +169,12 @@ public class IggyIndexBuilder { long ret = 0; long rem = cnt; while (true) { + if (rem == 0) { + break; + } if (rem == 1) { - return writeIndex(constIndex, false, 0); + ret += writeIndex(constIndex, false, 0); + break; } if (rem <= 64) { ret += writeIndex(0x80 + (int) rem - 1, false, constIndex); @@ -307,10 +305,7 @@ public class IggyIndexBuilder { int index; indexStream.writeUI8((int) val); - if ((index = (int) val) < 0) { - LOGGER.severe(String.format("< 0xC0: Cannot read index.")); - return 0; - } + index = (int) val; if (index >= constTable.size()) { LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, constTable.size())); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java index 40f696376..079d53136 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/streams/WriteDataStreamInterface.java @@ -21,6 +21,8 @@ public interface WriteDataStreamInterface extends AutoCloseable { public void setOlderOffsetToThisPos(long savedPos) throws IOException; + public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException; + public boolean writeUI64(long val) throws IOException; public boolean writeSI64(long val) throws IOException;