GFX testdata

This commit is contained in:
Jindra Petřík
2023-11-05 21:11:10 +01:00
parent 21aa0486f7
commit 6336f078d1
17 changed files with 456 additions and 97 deletions
@@ -139,6 +139,7 @@ import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalImage2;
import com.jpexs.decompiler.flash.tags.gfx.ExporterInfo;
import com.jpexs.decompiler.flash.timeline.AS2Package;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.FrameScript;
@@ -412,9 +413,13 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
@Internal
private AbcIndexing abcIndex;
@Internal
private int numAbcIndexDependencies = 0;
private volatile Map<String, Map<String, com.jpexs.decompiler.flash.action.as2.Trait>> uninitializedAs2ClassTraits = null;
@Internal
private ExporterInfo exporterInfo = null;
private static AbcIndexing playerGlobalAbcIndex;
@@ -442,6 +447,24 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
public static final int LIBRARY_AIR = 0;
public static final int LIBRARY_FLASH = 1;
public void setExporterInfo(ExporterInfo exporterInfo) {
this.exporterInfo = exporterInfo;
}
public ExporterInfo getExporterInfo() {
return exporterInfo;
}
public boolean hasStrippedShapesFromFonts() {
if (exporterInfo == null) {
return false;
}
if (exporterInfo.hasFlagShapesStrippedFromDefineFont()) {
return true;
}
return false;
}
public static AbcIndexing getPlayerGlobalAbcIndex() {
return playerGlobalAbcIndex;
}
@@ -1215,9 +1215,15 @@ public class SWFInputStream implements AutoCloseable {
boolean doParse = true;
if (parseTags && !parallel1 && doParse && (tag instanceof TagStub)) {
if (((parseTags && !parallel1 && doParse) || (tag.getId() == ExporterInfo.ID)) && (tag instanceof TagStub)) {
tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags, lazy, true);
}
if (tag instanceof ExporterInfo) {
ExporterInfo ei = (ExporterInfo) tag;
if (swf != null) {
swf.setExporterInfo(ei);
}
}
DumpInfo di = dumpInfo;
if (di != null && tag != null) {
di.name = tag.getName();
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.types.LANGCODE;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
@@ -72,6 +73,7 @@ public class DefineFont2Tag extends FontTag {
public String fontName;
@Conditional("!strippedShapes")
public List<SHAPE> glyphShapeTable;
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
@@ -100,6 +102,12 @@ public class DefineFont2Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
@Internal
public long unknownGfx;
@Internal
public boolean strippedShapes = false;
/**
* Constructor
*
@@ -140,28 +148,41 @@ public class DefineFont2Tag extends FontTag {
languageCode = sis.readLANGCODE("languageCode");
fontName = sis.readNetString("fontName");
int numGlyphs = sis.readUI16("numGlyphs");
long[] offsetTable = new long[numGlyphs];
long pos = sis.getPos();
for (int i = 0; i < numGlyphs; i++) { //offsetTable
if (fontFlagsWideOffsets) {
offsetTable[i] = sis.readUI32("offset");
} else {
offsetTable[i] = sis.readUI16("offset");
strippedShapes = swf.hasStrippedShapesFromFonts();
if (!strippedShapes) {
long[] offsetTable = new long[numGlyphs];
long pos = sis.getPos();
for (int i = 0; i < numGlyphs; i++) { //offsetTable
if (fontFlagsWideOffsets) {
offsetTable[i] = sis.readUI32("offset");
} else {
offsetTable[i] = sis.readUI16("offset");
}
}
}
if (numGlyphs > 0 || fontFlagsHasLayout) {
if (fontFlagsWideOffsets) {
sis.readUI32("codeTableOffset");
} else {
sis.readUI16("codeTableOffset");
if (numGlyphs > 0 || fontFlagsHasLayout) {
if (fontFlagsWideOffsets) {
sis.readUI32("codeTableOffset");
} else {
sis.readUI16("codeTableOffset");
}
}
}
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
} else {
if (numGlyphs > 0 || fontFlagsHasLayout) {
unknownGfx = sis.readUI32("unknownGfx");
}
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
glyphShapeTable.add(new SHAPE());
}
}
codeTable = new ArrayList<>(); //[numGlyphs];
@@ -260,33 +281,37 @@ public class DefineFont2Tag extends FontTag {
int numGlyphs = glyphShapeTable.size();
sos.writeUI16(numGlyphs);
List<Long> offsetTable = new ArrayList<>();
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
if (!swf.hasStrippedShapesFromFonts()) {
List<Long> offsetTable = new ArrayList<>();
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
SWFOutputStream sos3 = new SWFOutputStream(baosGlyphShapes, getVersion(), getCharset());
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add((glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
for (Long offset : offsetTable) {
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) (long) offset);
SWFOutputStream sos3 = new SWFOutputStream(baosGlyphShapes, getVersion(), getCharset());
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add((glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
}
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
for (Long offset : offsetTable) {
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) (long) offset);
}
}
if (numGlyphs > 0 || fontFlagsHasLayout) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
if (numGlyphs > 0 || fontFlagsHasLayout) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
}
}
}
if (numGlyphs > 0) {
sos.write(baGlyphShapes);
if (!swf.hasStrippedShapesFromFonts() && numGlyphs > 0) {
sos.write(baGlyphShapes);
}
} else {
sos.writeUI32(unknownGfx);
}
for (int i = 0; i < numGlyphs; i++) {
if (fontFlagsWideCodes) {
@@ -21,12 +21,14 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.helpers.FontHelper;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.gfx.ExporterInfo;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
import com.jpexs.decompiler.flash.types.LANGCODE;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
@@ -72,6 +74,7 @@ public class DefineFont3Tag extends FontTag {
public String fontName;
@Conditional("!strippedShapes")
public List<SHAPE> glyphShapeTable;
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
@@ -99,6 +102,12 @@ public class DefineFont3Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
@Internal
public long unknownGfx;
@Internal
public boolean strippedShapes = false;
/**
* Constructor
@@ -133,26 +142,38 @@ public class DefineFont3Tag extends FontTag {
languageCode = sis.readLANGCODE("languageCode");
fontName = sis.readNetString("fontName");
int numGlyphs = sis.readUI16("numGlyphs");
long[] offsetTable = new long[numGlyphs];
long pos = sis.getPos();
for (int i = 0; i < numGlyphs; i++) { //offsetTable
if (fontFlagsWideOffsets) {
offsetTable[i] = sis.readUI32("offset");
} else {
offsetTable[i] = sis.readUI16("offset");
strippedShapes = swf.hasStrippedShapesFromFonts();
if (!strippedShapes) {
long[] offsetTable = new long[numGlyphs];
long pos = sis.getPos();
for (int i = 0; i < numGlyphs; i++) { //offsetTable
if (fontFlagsWideOffsets) {
offsetTable[i] = sis.readUI32("offset");
} else {
offsetTable[i] = sis.readUI16("offset");
}
}
}
if (numGlyphs > 0 || fontFlagsHasLayout) {
if (fontFlagsWideOffsets) {
sis.readUI32("codeTableOffset");
} else {
sis.readUI16("codeTableOffset");
if (numGlyphs > 0 || fontFlagsHasLayout) {
if (fontFlagsWideOffsets) {
sis.readUI32("codeTableOffset");
} else {
sis.readUI16("codeTableOffset");
}
}
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
} else {
if (numGlyphs > 0 || fontFlagsHasLayout) {
unknownGfx = sis.readUI32("unknownGfx");
}
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
glyphShapeTable.add(new SHAPE());
}
}
glyphShapeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
codeTable = new ArrayList<>();
for (int i = 0; i < numGlyphs; i++) {
@@ -237,11 +258,14 @@ public class DefineFont3Tag extends FontTag {
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
SWFOutputStream sos3 = new SWFOutputStream(baosGlyphShapes, getVersion(), getCharset());
int numGlyphs = glyphShapeTable.size();
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add(sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
byte[] baGlyphShapes = null;
if (!swf.hasStrippedShapesFromFonts()) {
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add(sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
}
baGlyphShapes = baosGlyphShapes.toByteArray();
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
sos.writeUI16(fontID);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
@@ -256,24 +280,28 @@ public class DefineFont3Tag extends FontTag {
sos.writeNetString(fontName);
sos.writeUI16(numGlyphs);
for (long offset : offsetTable) {
long offset2 = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + offset;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset2);
} else {
sos.writeUI16((int) offset2);
if (!swf.hasStrippedShapesFromFonts()) {
for (long offset : offsetTable) {
long offset2 = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + offset;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset2);
} else {
sos.writeUI16((int) offset2);
}
}
}
if (numGlyphs > 0 || fontFlagsHasLayout) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
if (numGlyphs > 0 || fontFlagsHasLayout) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
}
}
}
if (numGlyphs > 0) {
sos.write(baGlyphShapes);
if (numGlyphs > 0) {
sos.write(baGlyphShapes);
}
} else {
sos.writeUI32(unknownGfx);
}
for (int i = 0; i < numGlyphs; i++) {
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.tags.base.FontInfoTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
@@ -50,10 +51,17 @@ public class DefineFontTag extends FontTag {
@SWFType(BasicType.UI16)
public int fontId;
@Conditional("!strippedShapes")
public List<SHAPE> glyphShapeTable;
@Internal
private FontInfoTag fontInfoTag = null;
@Internal
public long unknownGfx;
@Internal
public boolean strippedShapes = false;
/**
* Constructor
@@ -83,7 +91,9 @@ public class DefineFontTag extends FontTag {
fontId = sis.readUI16("fontId");
glyphShapeTable = new ArrayList<>();
if (sis.available() > 0) {
strippedShapes = swf.hasStrippedShapesFromFonts();
if (!strippedShapes && sis.available() > 0) {
long pos = sis.getPos();
int firstOffset = sis.readUI16("firstOffset");
int nGlyphs = firstOffset / 2;
@@ -98,6 +108,9 @@ public class DefineFontTag extends FontTag {
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
}
if (strippedShapes) {
unknownGfx = sis.readUI32("unknownGfx");
}
}
/**
@@ -109,17 +122,21 @@ public class DefineFontTag extends FontTag {
@Override
public synchronized void getData(SWFOutputStream sos) throws IOException {
sos.writeUI16(fontId);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
List<Integer> offsetTable = new ArrayList<>();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion(), getCharset());
for (SHAPE shape : glyphShapeTable) {
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
sos2.writeSHAPE(shape, 1);
}
for (int offset : offsetTable) {
sos.writeUI16(offset);
}
sos.write(baos2.toByteArray());
if (!swf.hasStrippedShapesFromFonts()) {
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
List<Integer> offsetTable = new ArrayList<>();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion(), getCharset());
for (SHAPE shape : glyphShapeTable) {
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
sos2.writeSHAPE(shape, 1);
}
for (int offset : offsetTable) {
sos.writeUI16(offset);
}
sos.write(baos2.toByteArray());
} else {
sos.writeUI32(unknownGfx);
}
}
@Override
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.helpers.ByteArrayRange;
import java.io.IOException;
@@ -90,4 +91,25 @@ public class DefineExternalGradient extends Tag {
public String toString() {
return tagName + " (g" + gradientId + ")";
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "fileName", fileName);
String bitmapFormatStr = "0x" + Integer.toHexString(bitmapsFormat);
switch (bitmapsFormat) {
case BITMAP_FORMAT_DEFAULT:
bitmapFormatStr = "default (0)";
break;
case BITMAP_FORMAT_TGA:
bitmapFormatStr = "TGA (1)";
break;
case BITMAP_FORMAT_DDS:
bitmapFormatStr = "DDS (2)";
break;
}
tagInfo.addInfo("general", "bitmapsFormat", bitmapFormatStr);
tagInfo.addInfo("general", "gradientSize", gradientSize);
}
}
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.gfx.TgaSupport;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
@@ -219,4 +220,25 @@ public class DefineExternalImage extends ImageTag {
public boolean importSupported() {
return false;
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "exportName", exportName);
tagInfo.addInfo("general", "fileName", fileName);
String bitmapFormatStr = "0x" + Integer.toHexString(bitmapFormat);
switch (bitmapFormat) {
case BITMAP_FORMAT_DEFAULT:
bitmapFormatStr = "default (0)";
break;
case BITMAP_FORMAT_TGA:
bitmapFormatStr = "TGA (1)";
break;
case BITMAP_FORMAT_DDS:
bitmapFormatStr = "DDS (2)";
break;
}
tagInfo.addInfo("general", "bitmapFormat", bitmapFormatStr);
}
}
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.gfx.TgaSupport;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
@@ -268,4 +269,38 @@ public class DefineExternalImage2 extends ImageTag {
public void setCharacterId(int characterId) {
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "exportName", exportName);
tagInfo.addInfo("general", "fileName", fileName);
String bitmapFormatStr = "0x" + Integer.toHexString(bitmapFormat);
switch (bitmapFormat) {
case BITMAP_FORMAT_DEFAULT:
bitmapFormatStr = "default (0)";
break;
case BITMAP_FORMAT_TGA:
bitmapFormatStr = "TGA (1)";
break;
case BITMAP_FORMAT_DDS:
bitmapFormatStr = "DDS (2)";
break;
case BITMAP_FORMAT2_JPEG:
bitmapFormatStr = "JPEG (10)";
break;
case BITMAP_FORMAT2_TGA:
bitmapFormatStr = "TGA (13)";
break;
case BITMAP_FORMAT2_DDS:
bitmapFormatStr = "DDS (14)";
break;
}
tagInfo.addInfo("general", "bitmapFormat", bitmapFormatStr);
if (unknownID != 0) {
tagInfo.addInfo("general", "imageId", imageID);
}
}
}
@@ -235,6 +235,8 @@ public class DefineExternalSound extends CharacterTag implements SoundTag {
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
SoundFormat soundFormat = getSoundFormat();
tagInfo.addInfo("general", "exportName", exportName);
tagInfo.addInfo("general", "fileName", fileName);
tagInfo.addInfo("general", "codecName", soundFormat.getFormatName());
tagInfo.addInfo("general", "exportFormat", soundFormat.getNativeExportFormat());
tagInfo.addInfo("general", "samplingRate", soundFormat.samplingRate);
@@ -248,6 +248,7 @@ public class DefineExternalStreamSound extends Tag implements CharacterIdTag, So
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
SoundFormat soundFormat = getSoundFormat();
tagInfo.addInfo("general", "fileName", fileName);
tagInfo.addInfo("general", "codecName", soundFormat.getFormatName());
tagInfo.addInfo("general", "exportFormat", soundFormat.getNativeExportFormat());
tagInfo.addInfo("general", "samplingRate", soundFormat.samplingRate);
@@ -20,8 +20,11 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.helpers.ByteArrayRange;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
@@ -74,4 +77,16 @@ public class DefineGradientMap extends Tag {
indices[i] = sis.readUI16("index");
}
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
List<String> indicesStr = new ArrayList<>();
for (int index : indices) {
indicesStr.add("" + index);
}
tagInfo.addInfo("general", "indices", String.join(", ", indicesStr));
}
}
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.gfx;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
@@ -219,4 +220,15 @@ public class DefineSubImage extends ImageTag {
}
}
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "imageId", imageId);
tagInfo.addInfo("general", "x1", x1);
tagInfo.addInfo("general", "y1", y1);
tagInfo.addInfo("general", "x2", x2);
tagInfo.addInfo("general", "y2", y2);
}
}
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.helpers.ByteArrayRange;
import java.io.IOException;
import java.util.ArrayList;
@@ -49,15 +50,28 @@ public class ExporterInfo extends Tag {
public List<Long> codeOffsets;
public static final int BITMAP_FORMAT_DEFAULT = 0;
public static final int BITMAP_FORMAT_TGA = 1;
public static final int BITMAP_FORMAT_DDS = 2;
//It looks like gfxexport produces BITMAP_FORMAT2_* values for format,
//but BITMAP_FORMAT_* works the same way
public static final int BITMAP_FORMAT2_JPEG = 10;
public static final int BITMAP_FORMAT2_TGA = 13;
public static final int BITMAP_FORMAT2_DDS = 14;
public static final int FLAG_CONTAINS_GLYPH_TEXTURES = 1;
public static final int FLAG_GLYPHS_STRIPPED_FROM_DEFINEFONT = 2;
public static final int FLAG_GRADIENT_IMAGES_EXPORTED = 4;
public static final int FLAG_SHAPES_STRIPPED_FROM_DEFINEFONT = 16;
/**
* Gets data bytes
@@ -117,4 +131,49 @@ public class ExporterInfo extends Tag {
}
}
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "version", version);
tagInfo.addInfo("general", "flags", "0x" + Long.toHexString(flags));
String bitmapFormatStr = "0x" + Integer.toHexString(bitmapFormat);
switch (bitmapFormat) {
case BITMAP_FORMAT_DEFAULT:
bitmapFormatStr = "default (0)";
break;
case BITMAP_FORMAT_TGA:
bitmapFormatStr = "TGA (1)";
break;
case BITMAP_FORMAT_DDS:
bitmapFormatStr = "DDS (2)";
break;
case BITMAP_FORMAT2_JPEG:
bitmapFormatStr = "JPEG (10)";
break;
case BITMAP_FORMAT2_TGA:
bitmapFormatStr = "TGA (13)";
break;
case BITMAP_FORMAT2_DDS:
bitmapFormatStr = "DDS (14)";
break;
}
tagInfo.addInfo("general", "bitmapFormat", bitmapFormatStr);
tagInfo.addInfo("general", "prefix", prefix);
tagInfo.addInfo("general", "swfName", swfName);
if (codeOffsets != null) {
List<String> codeOffsetsStr = new ArrayList<>();
for (long codeOffset : codeOffsets) {
codeOffsetsStr.add("" + codeOffset);
}
tagInfo.addInfo("general", "codeOffsets", String.join(", ", codeOffsetsStr));
}
}
public boolean hasFlagShapesStrippedFromDefineFont() {
return (flags & FLAG_SHAPES_STRIPPED_FROM_DEFINEFONT) == FLAG_SHAPES_STRIPPED_FROM_DEFINEFONT;
}
}
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.TagInfo;
import com.jpexs.decompiler.flash.types.gfx.FONTINFO;
import com.jpexs.decompiler.flash.types.gfx.GFxInputStream;
import com.jpexs.decompiler.flash.types.gfx.GFxOutputStream;
@@ -38,7 +39,9 @@ public class FontTextureInfo extends Tag {
public static final String NAME = "FontTextureInfo";
public long textureID;
public int textureID;
public int unknownID;
public int textureFormat;
@@ -61,7 +64,18 @@ public class FontTextureInfo extends Tag {
public static final int TEXTURE_FORMAT_TGA = 1;
public static final int TEXTURE_FORMAT_DDS = 2;
//It looks like gfxexport produces TEXTURE_FORMAT2_* values for format,
//but BITMAP_FORMAT_* works the same way
public static final int TEXTURE_FORMAT2_JPEG = 10;
public static final int TEXTURE_FORMAT2_TGA = 13;
public static final int TEXTURE_FORMAT2_DDS = 14;
public static final int UNKNOWN_IS_SINGLE = 0;
public static final int UNKNOWN_IS_MULTIPLE = 6;
/**
* Gets data bytes
*
@@ -70,7 +84,8 @@ public class FontTextureInfo extends Tag {
*/
@Override
public void getData(SWFOutputStream sos) throws IOException {
sos.writeUI32(textureID);
sos.writeUI16(textureID);
sos.writeUI16(unknownID);
sos.writeUI16(textureFormat);
sos.writeNetString(fileName);
sos.writeUI16(textureWidth);
@@ -106,7 +121,8 @@ public class FontTextureInfo extends Tag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
textureID = sis.readUI32("textureID");
textureID = sis.readUI16("textureID");
unknownID = sis.readUI16("unknownID");
textureFormat = sis.readUI16("textureFormat");
fileName = sis.readNetString("fileName");
textureWidth = sis.readUI16("textureWidth");
@@ -116,20 +132,64 @@ public class FontTextureInfo extends Tag {
int numTexGlyphs = sis.readUI16("numTexGlyphs");
texGlyphs = new TEXGLYPH[numTexGlyphs];
MemoryInputStream mis = sis.getBaseStream();
long misStartPos;
misStartPos = mis.getPos();
for (int i = 0; i < numTexGlyphs; i++) {
GFxInputStream gis = new GFxInputStream(mis);
gis.dumpInfo = sis.dumpInfo;
texGlyphs[i] = new TEXGLYPH(gis);
}
sis.skipBytes(mis.getPos());
sis.skipBytes(mis.getPos() - misStartPos);
int numFonts = sis.readUI16("numFonts");
fonts = new FONTINFO[numFonts];
mis = sis.getBaseStream();
misStartPos = mis.getPos();
for (int i = 0; i < numFonts; i++) {
GFxInputStream gis = new GFxInputStream(mis);
gis.dumpInfo = sis.dumpInfo;
fonts[i] = new FONTINFO(gis);
}
sis.skipBytes(mis.getPos());
sis.skipBytes(mis.getPos() - misStartPos);
}
@Override
public String toString() {
return tagName + " (ft" + textureID + ")";
}
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
tagInfo.addInfo("general", "textureId", textureID);
String textureFormatStr = "0x" + Integer.toHexString(textureFormat);
switch (textureFormat) {
case TEXTURE_FORMAT_DEFAULT:
textureFormatStr = "default (0)";
break;
case TEXTURE_FORMAT_TGA:
textureFormatStr = "TGA (1)";
break;
case TEXTURE_FORMAT_DDS:
textureFormatStr = "DDS (2)";
break;
case TEXTURE_FORMAT2_JPEG:
textureFormatStr = "JPEG (10)";
break;
case TEXTURE_FORMAT2_TGA:
textureFormatStr = "TGA (13)";
break;
case TEXTURE_FORMAT2_DDS:
textureFormatStr = "DDS (14)";
break;
}
tagInfo.addInfo("general", "textureFormat", textureFormatStr);
tagInfo.addInfo("general", "fileName", fileName);
tagInfo.addInfo("general", "width", textureWidth);
tagInfo.addInfo("general", "height", textureHeight);
tagInfo.addInfo("general", "padPixels", padPixels);
tagInfo.addInfo("general", "nominalGlyphSz", nominalGlyphSz);
tagInfo.addInfo("general", "glyphCount", texGlyphs.length);
tagInfo.addInfo("general", "fontCount", fonts.length);
}
}
@@ -50,6 +50,11 @@ public class SHAPE implements NeedsCharacters, Serializable {
private Shape cachedOutline;
private Shape fastCachedOutline;
public SHAPE() {
shapeRecords = new ArrayList<>();
shapeRecords.add(new EndShapeRecord());
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
for (SHAPERECORD r : shapeRecords) {