From 27c29368d85cd756da0b189e47db07a9e8c29dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 24 Nov 2016 15:20:22 +0100 Subject: [PATCH] first try to convert --- .../jpexs/decompiler/flash/iggy/IggyChar.java | 51 +++++++++++- .../flash/iggy/IggyCharIndices.java | 4 + .../decompiler/flash/iggy/IggyCharNode.java | 41 ++++++++++ .../decompiler/flash/iggy/IggyDataReader.java | 8 +- .../jpexs/decompiler/flash/iggy/IggyFile.java | 12 +++ .../{IggyFontPart.java => IggyFontData.java} | 46 ++++++++++- .../conversion/IggyCharToShapeConvertor.java | 82 +++++++++++++++++++ .../iggy/conversion/IggyToSwfConvertor.java | 50 ++++++++++- 8 files changed, 280 insertions(+), 14 deletions(-) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/{IggyFontPart.java => IggyFontData.java} (88%) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyCharToShapeConvertor.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyChar.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyChar.java index c14b7fd69..d6aaf6cca 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyChar.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyChar.java @@ -14,7 +14,6 @@ public class IggyChar implements StructureInterface { private static Logger LOGGER = Logger.getLogger(IggyChar.class.getName()); - //if offset = 1, zadnychar, 1 byte[1] @IggyFieldType(DataType.float_t) float minx; @IggyFieldType(DataType.float_t) @@ -24,7 +23,7 @@ public class IggyChar implements StructureInterface { @IggyFieldType(DataType.float_t) float maxy; @IggyFieldType(DataType.uint64_t) - long unk; // stejny vetsinou - napr. 48 + long unk; // stejny vetsinou - napr. 48 - JP: to by mohlo byt advance @IggyFieldType(DataType.uint64_t) long count; @IggyFieldType(DataType.uint64_t) @@ -77,8 +76,8 @@ public class IggyChar implements StructureInterface { 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\n", offset)); + 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<>(); @@ -93,4 +92,48 @@ public class IggyChar implements StructureInterface { 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 getNodes() { + return nodes; + } + } 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 ff2e44047..59bebd63b 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 @@ -16,6 +16,10 @@ public class IggyCharIndices implements StructureInterface { @IggyFieldType(DataType.uint32_t) long padd; + public List getChars() { + return chars; + } + private long charCount; public IggyCharIndices(AbstractDataStream stream, long charCount) throws IOException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharNode.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharNode.java index 9ca4bd9d9..5ebd55880 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharNode.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyCharNode.java @@ -13,6 +13,10 @@ public class IggyCharNode implements StructureInterface { private static Logger LOGGER = Logger.getLogger(IggyCharNode.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 x1; @IggyFieldType(DataType.float_t) @@ -78,4 +82,41 @@ public class IggyCharNode implements StructureInterface { public void writeToDataStream(AbstractDataStream stream) throws IOException { throw new UnsupportedOperationException("Not supported yet."); } + + public float getX1() { + return x1; + } + + public float getY1() { + return y1; + } + + public float getX2() { + return x2; + } + + public float getY2() { + return y2; + } + + 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; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java index 423080ab8..725b64fbd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyDataReader.java @@ -19,7 +19,7 @@ public class IggyDataReader implements StructureInterface { @IggyFieldType(value = DataType.widechar_t, count = 48) String name; - List fontParts; + List fontDatas; List fontInfos; private IggyFlashHeader64 header; @@ -90,12 +90,12 @@ public class IggyDataReader implements StructureInterface { } } - fontParts = new ArrayList<>(); + fontDatas = new ArrayList<>(); fontInfos = new ArrayList<>(); for (int i = 0; i < header.font_count; i++) { stream.seek(font_main_offsets[i], SeekMode.SET); - IggyFontPart part = new IggyFontPart(stream); - fontParts.add(part); + IggyFontData part = new IggyFontData(stream); + fontDatas.add(part); } } 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 80e6e7321..7eebdf523 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 @@ -33,6 +33,18 @@ public class IggyFile extends AbstractDataStream implements AutoCloseable { private List headers = new ArrayList<>(); private List flashDataReaders = new ArrayList<>(); + public int getFontCount(int swfIndex) { + return flashDataReaders.get(swfIndex).fontDatas.size(); + } + + public IggyFontData getFontData(int swfIndex, int fontIndex) { + return flashDataReaders.get(swfIndex).fontDatas.get(fontIndex); + } + + public IggyFontInfo getFontInfo(int swfIndex, int fontIndex) { + return null; //FIXME!!! //flashDataReaders.get(swfIndex).fontInfos.get(fontIndex); + } + @Override public long position() { try { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontPart.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java similarity index 88% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontPart.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java index 2dfc6e5f6..36b91ab78 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontPart.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/IggyFontData.java @@ -12,7 +12,7 @@ import org.omg.CORBA.StructMemberHelper; * * @author JPEXS */ -public class IggyFontPart implements StructureInterface { +public class IggyFontData implements StructureInterface { @IggyFieldType(DataType.uint16_t) int type; //stejny pro rozdilne fonty @@ -95,7 +95,7 @@ public class IggyFontPart implements StructureInterface { byte[] padTo4byteBoundary; - public IggyFontPart(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) { + public IggyFontData(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int[] what_1, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List charOffsets, List chars, IggyCharIndices charIndices, IggyCharScales charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) { this.type = type; this.order_in_iggy_file = order_in_iggy_file; this.zeroone = zeroone; @@ -139,7 +139,7 @@ public class IggyFontPart implements StructureInterface { this.padTo4byteBoundary = padTo4byteBoundary; } - public IggyFontPart(AbstractDataStream stream) throws IOException { + public IggyFontData(AbstractDataStream stream) throws IOException { readFromDataStream(stream); } @@ -246,4 +246,44 @@ public class IggyFontPart implements StructureInterface { 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 getChars() { + return chars; + } + + public IggyCharIndices getCharIndices() { + return charIndices; + } + + public IggyCharScales getCharScales() { + return charScales; + } + + public IggyCharKerning getCharKernings() { + return charKernings; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyCharToShapeConvertor.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyCharToShapeConvertor.java new file mode 100644 index 000000000..50c06398f --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/iggy/conversion/IggyCharToShapeConvertor.java @@ -0,0 +1,82 @@ +package com.jpexs.decompiler.flash.iggy.conversion; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.iggy.IggyChar; +import com.jpexs.decompiler.flash.iggy.IggyCharNode; +import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY; +import com.jpexs.decompiler.flash.types.LINESTYLEARRAY; +import com.jpexs.decompiler.flash.types.SHAPE; +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.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class IggyCharToShapeConvertor { + + private static int convertDistance(double val) { + return (int) (val * SWF.unitDivisor); + } + + public static SHAPE convertCharToShape(IggyChar igchar) { + SHAPE shape = new SHAPE(); + List retList = new ArrayList<>(); + List ignodes = igchar.getNodes(); + for (IggyCharNode ign : ignodes) { + if (ign.getNodeType() == IggyCharNode.NODE_TYPE_MOVE) { + StyleChangeRecord scr = new StyleChangeRecord(); + scr.fillStyle0 = 1; + scr.stateFillStyle0 = true; + scr.stateMoveTo = true; + scr.moveDeltaX = convertDistance(ign.getX1()); + scr.moveDeltaY = convertDistance(ign.getY1()); + scr.lineStyles = new LINESTYLEARRAY(); + scr.fillStyles = new FILLSTYLEARRAY(); + scr.calculateBits(); + retList.add(scr); + } + if (ign.getNodeType() == IggyCharNode.NODE_TYPE_LINE_TO) { + StraightEdgeRecord ser = new StraightEdgeRecord(); + ser.deltaX = convertDistance(ign.getX2() - ign.getX1()); + ser.deltaY = convertDistance(ign.getY2() - ign.getY1()); + ser.generalLineFlag = true; + ser.vertLineFlag = false; + ser.calculateBits(); + retList.add(ser); + } + + if (ign.getNodeType() == IggyCharNode.NODE_TYPE_CURVE_POINT) { + //TODO: Make curve record + StraightEdgeRecord ser = new StraightEdgeRecord(); + ser.deltaX = convertDistance(ign.getX2() - ign.getX1()); + ser.deltaY = convertDistance(ign.getY2() - ign.getY1()); + ser.generalLineFlag = true; + ser.vertLineFlag = false; + ser.calculateBits(); + retList.add(ser); + } + } + + StyleChangeRecord init; + if (!retList.isEmpty() && retList.get(0) instanceof StyleChangeRecord) { + init = (StyleChangeRecord) retList.get(0); + } else { + init = new StyleChangeRecord(); + retList.add(0, init); + } + + retList.add(new EndShapeRecord()); + init.stateFillStyle0 = true; + init.fillStyle0 = 1; + shape.shapeRecords = retList; + shape.numFillBits = 1; + shape.numLineBits = 0; + + return shape; + } +} 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 08600b772..bee681cab 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 @@ -2,12 +2,20 @@ package com.jpexs.decompiler.flash.iggy.conversion; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFCompression; +import com.jpexs.decompiler.flash.iggy.IggyChar; import com.jpexs.decompiler.flash.iggy.IggyFile; +import com.jpexs.decompiler.flash.iggy.IggyFontData; +import com.jpexs.decompiler.flash.iggy.IggyFontInfo; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; +import com.jpexs.decompiler.flash.tags.EndTag; +import com.jpexs.decompiler.flash.tags.FileAttributesTag; import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.decompiler.flash.types.SHAPE; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; /** * @@ -59,9 +67,45 @@ public class IggyToSwfConvertor { (int) (file.getSwfXMax(swfIndex) * SWF.unitDivisor), (int) (file.getSwfYMin(swfIndex) * SWF.unitDivisor), (int) (file.getSwfYMax(swfIndex) * SWF.unitDivisor)); - swf.version = 9; //FIXME + swf.version = 10; //FIXME + + FileAttributesTag fat = new FileAttributesTag(swf); + fat.actionScript3 = false; + fat.hasMetadata = false; + fat.useNetwork = false; + swf.addTag(fat); + + int fontCount = file.getFontCount(swfIndex); + for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) { + IggyFontData iggyFontData = file.getFontData(swfIndex, fontIndex); + IggyFontInfo fontInfo = file.getFontInfo(swfIndex, fontIndex); //TODO! + DefineFont2Tag fontTag = new DefineFont2Tag(swf); + fontTag.fontID = fontIndex + 1; + fontTag.codeTable = new ArrayList<>(); + fontTag.fontName = iggyFontData.getName(); + fontTag.glyphShapeTable = new ArrayList<>(); + fontTag.fontAdvanceTable = new ArrayList<>(); + + for (int i = 0; i < iggyFontData.getCharacterCount(); i++) { + int code = iggyFontData.getCharIndices().getChars().get(i); + IggyChar chr = iggyFontData.getChars().get(i); + if (chr != null) { + fontTag.codeTable.add(code); + fontTag.glyphShapeTable.add(IggyCharToShapeConvertor.convertCharToShape(chr)); + fontTag.fontAdvanceTable.add((int) chr.getUnk()); + } + //TODO: handle spaces, etc. + } + fontTag.setModified(true); + swf.addTag(fontTag); + } + swf.addTag(new EndTag(swf)); + swf.setModified(true); + + return swf; + } + + public static void main(String[] args) throws IOException { - //TODO!!! - throw new UnsupportedOperationException("Not implemented yet"); } }