mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-07 01:34:49 +00:00
Added: Generator Templates (.swt) files support and related tags (Flash 3-5)
(CharacterSet, GenCommand, NameCharacter, DefineTextFormat, FontRef) DefineVideo tag support (Flash 4) SerialNumber tag support (before Flash 7)
This commit is contained in:
@@ -207,8 +207,9 @@ public class OpenableSourceInfo {
|
||||
|| !(
|
||||
extension.equals(".swf")
|
||||
|| extension.equals(".spl")
|
||||
|| extension.equals(".swt")
|
||||
|| extension.equals(".gfx")
|
||||
|| extension.equals(".abc")
|
||||
|| extension.equals(".abc")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSpecial;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSpecialType;
|
||||
import com.jpexs.decompiler.flash.tags.CSMSettingsTag;
|
||||
import com.jpexs.decompiler.flash.tags.CharacterSetTag;
|
||||
import com.jpexs.decompiler.flash.tags.DebugIDTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
|
||||
@@ -160,8 +161,10 @@ import com.jpexs.decompiler.flash.tags.DefineShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineText2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineTextFormatTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineTextTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineVideoTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DoABCTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoActionTag;
|
||||
@@ -172,9 +175,11 @@ import com.jpexs.decompiler.flash.tags.EnableTelemetryTag;
|
||||
import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.tags.FontRefTag;
|
||||
import com.jpexs.decompiler.flash.tags.FrameLabelTag;
|
||||
import com.jpexs.decompiler.flash.tags.FreeAllTag;
|
||||
import com.jpexs.decompiler.flash.tags.FreeCharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.GenCommandTag;
|
||||
import com.jpexs.decompiler.flash.tags.ImportAssets2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.ImportAssetsTag;
|
||||
import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
|
||||
@@ -191,6 +196,7 @@ import com.jpexs.decompiler.flash.tags.ProtectTag;
|
||||
import com.jpexs.decompiler.flash.tags.RemoveObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.RemoveObjectTag;
|
||||
import com.jpexs.decompiler.flash.tags.ScriptLimitsTag;
|
||||
import com.jpexs.decompiler.flash.tags.SerialNumberTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetTabIndexTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
@@ -275,6 +281,10 @@ 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 com.jpexs.decompiler.flash.types.text.format.ControlTextFormatRecord;
|
||||
import com.jpexs.decompiler.flash.types.text.format.EndTextFormatRecord;
|
||||
import com.jpexs.decompiler.flash.types.text.format.TextFormatRecord;
|
||||
import com.jpexs.decompiler.flash.types.text.format.TextTextFormatRecord;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.FakeMemoryInputStream;
|
||||
@@ -1633,7 +1643,9 @@ public class SWFInputStream implements AutoCloseable {
|
||||
case 37:
|
||||
ret = new DefineEditTextTag(sis, data);
|
||||
break;
|
||||
//case 38: DefineVideo / DefineMouseTarget
|
||||
case 38: // or DefineMouseTarget
|
||||
ret = new DefineVideoTag(sis, data);
|
||||
break;
|
||||
case 39:
|
||||
ret = new DefineSpriteTag(sis, level, data, parallel, skipUnusualTags);
|
||||
break;
|
||||
@@ -1641,9 +1653,15 @@ public class SWFInputStream implements AutoCloseable {
|
||||
ret = new NameCharacterTag(sis, data);
|
||||
break;
|
||||
case 41: //or NameObject
|
||||
ret = new ProductInfoTag(sis, data);
|
||||
if (swf == null || swf.version >= 7) {
|
||||
ret = new ProductInfoTag(sis, data);
|
||||
} else {
|
||||
ret = new SerialNumberTag(sis, data);
|
||||
}
|
||||
break;
|
||||
case 42:
|
||||
ret = new DefineTextFormatTag(sis, data);
|
||||
break;
|
||||
//case 42: DefineTextFormat
|
||||
case 43:
|
||||
ret = new FrameLabelTag(sis, data);
|
||||
break;
|
||||
@@ -1658,10 +1676,16 @@ public class SWFInputStream implements AutoCloseable {
|
||||
case 48:
|
||||
ret = new DefineFont2Tag(sis, data);
|
||||
break;
|
||||
//case 49: GenCommand
|
||||
case 49:
|
||||
ret = new GenCommandTag(sis, data);
|
||||
break;
|
||||
//case 50: DefineCommandObj
|
||||
//case 51: CharacterSet
|
||||
//case 52: FontRef
|
||||
case 51:
|
||||
ret = new CharacterSetTag(sis, data);
|
||||
break;
|
||||
case 52:
|
||||
ret = new FontRefTag(sis, data);
|
||||
break;
|
||||
//case 53: DefineFunction
|
||||
//case 54: PlaceFunction
|
||||
//case 55: GenTagObject
|
||||
@@ -3796,6 +3820,108 @@ public class SWFInputStream implements AutoCloseable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one TextFormatRecord value from the stream
|
||||
* @param name Name
|
||||
* @return TextFormatRecord value
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public TextFormatRecord readTextFormatRecord(String name) throws IOException {
|
||||
newDumpLevel(name, "TextFormatRecord");
|
||||
int controlFlag = (int) readUB(1, "controlFlag");
|
||||
|
||||
if (controlFlag == 0) {
|
||||
int length = (int) readUB(7, "length");
|
||||
if (length > 0) {
|
||||
TextTextFormatRecord textRecord = new TextTextFormatRecord();
|
||||
byte[] bytes = readBytes(length * 2, "text");
|
||||
byte[] halfBytes = new byte[length];
|
||||
for (int i = 0; i < halfBytes.length; i++) {
|
||||
halfBytes[i] = bytes[i * 2];
|
||||
}
|
||||
textRecord.text = new String(halfBytes, swf.getCharset());
|
||||
DumpInfo di = dumpInfo;
|
||||
if (di != null) {
|
||||
di.name = "TextTextFormatRecord";
|
||||
}
|
||||
endDumpLevel();
|
||||
return textRecord;
|
||||
}
|
||||
|
||||
DumpInfo di = dumpInfo;
|
||||
if (di != null) {
|
||||
di.name = "EndTextFormatRecord";
|
||||
}
|
||||
endDumpLevel();
|
||||
return new EndTextFormatRecord();
|
||||
}
|
||||
int controlType = (int) readUB(7, "controlType");
|
||||
|
||||
ControlTextFormatRecord controlRecord = new ControlTextFormatRecord();
|
||||
controlRecord.type = controlType;
|
||||
switch (controlType) {
|
||||
case ControlTextFormatRecord.TYPE_STYLE:
|
||||
controlRecord.style = readUI8("style");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_FONT_ID:
|
||||
controlRecord.fontId = readUI16("fontId");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_FONT_HEIGHT:
|
||||
controlRecord.fontHeight = readUI16("fontHeight");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_COLOR:
|
||||
controlRecord.color = readRGBA("color");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_SCRIPT:
|
||||
controlRecord.script = readUI8("script");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_KERNING:
|
||||
controlRecord.kerning = readSI16("kerning");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_ALIGN:
|
||||
controlRecord.align = readUI8("align");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_INDENT:
|
||||
controlRecord.indent = readSI16("indent");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_LEFT_MARGIN:
|
||||
controlRecord.leftMargin = readSI16("leftMargin");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_RIGHT_MARGIN:
|
||||
controlRecord.rightMargin = readSI16("rightMargin");
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_LINE_SPACE:
|
||||
controlRecord.lineSpace = readSI16("lineSpace");
|
||||
break;
|
||||
}
|
||||
DumpInfo di = dumpInfo;
|
||||
if (di != null) {
|
||||
di.name = "ControlTextFormatRecord";
|
||||
}
|
||||
endDumpLevel();
|
||||
return controlRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads List of TextFormatRecord values from the stream
|
||||
* @param name Name
|
||||
* @return List of TextFormatRecord values
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public List<TextFormatRecord> readTextFormatRecords(String name) throws IOException {
|
||||
newDumpLevel(name, "TextFormatRecords");
|
||||
List<TextFormatRecord> records = new ArrayList<>();
|
||||
while (true) {
|
||||
TextFormatRecord record = readTextFormatRecord("record");
|
||||
if (record instanceof EndTextFormatRecord) {
|
||||
break;
|
||||
}
|
||||
records.add(record);
|
||||
}
|
||||
endDumpLevel();
|
||||
return records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of available bytes in the stream.
|
||||
*
|
||||
|
||||
@@ -79,6 +79,9 @@ 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 com.jpexs.decompiler.flash.types.text.format.ControlTextFormatRecord;
|
||||
import com.jpexs.decompiler.flash.types.text.format.TextFormatRecord;
|
||||
import com.jpexs.decompiler.flash.types.text.format.TextTextFormatRecord;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -2151,4 +2154,73 @@ public class SWFOutputStream extends OutputStream {
|
||||
public void writeAmf3Object(Amf3Value value) throws IOException, NoSerializerExistsException {
|
||||
writeAmf3Object(value, new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes List of TextFormatRecord values to the stream. Terminates with zero.
|
||||
* @param records List of records
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public void writeTextFormatRecords(List<TextFormatRecord> records) throws IOException {
|
||||
for (TextFormatRecord record : records) {
|
||||
writeTextFormatRecord(record);
|
||||
}
|
||||
writeUI8(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes TextFormatRecord value to the stream.
|
||||
*
|
||||
* @param value TextFormatRecord value
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public void writeTextFormatRecord(TextFormatRecord value) throws IOException {
|
||||
if (value instanceof TextTextFormatRecord) {
|
||||
TextTextFormatRecord textRecord = (TextTextFormatRecord) value;
|
||||
byte[] halfBytes = textRecord.text.getBytes(charset);
|
||||
writeUI8(halfBytes.length);
|
||||
for (int i = 0; i < halfBytes.length; i++) {
|
||||
writeUI8(halfBytes[i]);
|
||||
writeUI8(0);
|
||||
}
|
||||
}
|
||||
if (value instanceof ControlTextFormatRecord) {
|
||||
ControlTextFormatRecord controlRecord = (ControlTextFormatRecord) value;
|
||||
writeUI8(0x80 | controlRecord.type);
|
||||
switch (controlRecord.type) {
|
||||
case ControlTextFormatRecord.TYPE_STYLE:
|
||||
writeUI8(controlRecord.style);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_FONT_ID:
|
||||
writeUI16(controlRecord.fontId);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_FONT_HEIGHT:
|
||||
writeUI16(controlRecord.fontHeight);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_COLOR:
|
||||
writeRGBA(controlRecord.color);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_SCRIPT:
|
||||
writeUI8(controlRecord.script);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_KERNING:
|
||||
writeSI16(controlRecord.kerning);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_ALIGN:
|
||||
writeUI8(controlRecord.align);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_INDENT:
|
||||
writeSI16(controlRecord.indent);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_LEFT_MARGIN:
|
||||
writeSI16(controlRecord.leftMargin);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_RIGHT_MARGIN:
|
||||
writeSI16(controlRecord.rightMargin);
|
||||
break;
|
||||
case ControlTextFormatRecord.TYPE_LINE_SPACE:
|
||||
writeSI16(controlRecord.lineSpace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,13 +157,15 @@ public class SwfXmlImporter {
|
||||
|
||||
static {
|
||||
Map<String, Class> tags = new HashMap<>();
|
||||
Map<Integer, TagTypeInfo> knownTags = Tag.getKnownClasses();
|
||||
Map<Integer, List<TagTypeInfo>> knownTags = Tag.getKnownClasses();
|
||||
for (Integer key : knownTags.keySet()) {
|
||||
Class cls = knownTags.get(key).getCls();
|
||||
if (!ReflectionTools.canInstantiate(cls)) {
|
||||
System.err.println("Can't instantiate: " + cls.getName());
|
||||
for (TagTypeInfo tagTypeInfo : knownTags.get(key)) {
|
||||
Class cls = tagTypeInfo.getCls();
|
||||
if (!ReflectionTools.canInstantiate(cls)) {
|
||||
System.err.println("Can't instantiate: " + cls.getName());
|
||||
}
|
||||
tags.put(cls.getSimpleName(), cls);
|
||||
}
|
||||
tags.put(cls.getSimpleName(), cls);
|
||||
}
|
||||
|
||||
swfTags = tags;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
public class CharacterSetTag extends Tag {
|
||||
public static final int ID = 51;
|
||||
|
||||
public static final String NAME = "CharacterSet";
|
||||
|
||||
|
||||
public long unknown;
|
||||
|
||||
public CharacterSetTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public CharacterSetTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
unknown = sis.readUI32("unknown");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI32(unknown);
|
||||
}
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
|
||||
if (r.buttonStateHitTest) {
|
||||
frameHit.layers.put(r.placeDepth, new DepthState(layer, frameHit, frameHit, false));
|
||||
if (!r.buttonStateDown) {
|
||||
frameDown.layers.get(r.placeDepth).key = true;
|
||||
frameHit.layers.get(r.placeDepth).key = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.flash.types.text.format.TextFormatRecord;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DefineTextFormat tag - define text format. Used by Flash Generator Templates.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
public class DefineTextFormatTag extends Tag implements CharacterIdTag {
|
||||
|
||||
public static final int ID = 42;
|
||||
|
||||
public static final String NAME = "DefineTextFormat";
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int textId;
|
||||
|
||||
public RECT bounds;
|
||||
|
||||
public List<TextFormatRecord> records = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf SWF
|
||||
*/
|
||||
public DefineTextFormatTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public DefineTextFormatTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
textId = sis.readUI16("textId");
|
||||
bounds = sis.readRECT("textBounds");
|
||||
records = sis.readTextFormatRecords("textFormatRecords");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @param sos SWF output stream
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(textId);
|
||||
sos.writeRECT(bounds);
|
||||
sos.writeTextFormatRecords(records);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return textId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterId(int characterId) {
|
||||
this.textId = characterId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DefineVideo tag - references QuickTime video by URL.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
public class DefineVideoTag extends Tag {
|
||||
|
||||
public static final int ID = 38;
|
||||
|
||||
public static final String NAME = "DefineVideo";
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int videoId;
|
||||
|
||||
/**
|
||||
* QuickTime video path (.mov)
|
||||
*/
|
||||
public String videoFileName;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf SWF
|
||||
*/
|
||||
public DefineVideoTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public DefineVideoTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
videoId = sis.readUI16("videoId");
|
||||
videoFileName = sis.readString("videoFileName");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @param sos SWF output stream
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(videoId);
|
||||
sos.writeString(videoFileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* FontRef tag - external font reference. Used by Flash Generator Templates.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
public class FontRefTag extends Tag {
|
||||
|
||||
public static final int ID = 52;
|
||||
|
||||
public static final String NAME = "FontRef";
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
/**
|
||||
* File name with "fft" extension - it's a SWF file containing DefineFont2 + Protect
|
||||
*/
|
||||
public String fontFileName;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf SWF
|
||||
*/
|
||||
public FontRefTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public FontRefTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
fontId = sis.readUI16("fontId");
|
||||
fontFileName = sis.readString("fontFileName");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @param sos SWF output stream
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(fontId);
|
||||
sos.writeString(fontFileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Table;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GenCommand tag - Command to Generator in Flash Templates.
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
public class GenCommandTag extends Tag {
|
||||
public static final int ID = 49;
|
||||
|
||||
public static final String NAME = "GenCommand";
|
||||
|
||||
public static final int TYPE_MOVIE = 0x01;
|
||||
public static final int TYPE_BUTTON = 0x02;
|
||||
public static final int TYPE_GRAPHICS = 0x04;
|
||||
public static final int TYPE_GLOBAL = 0x08;
|
||||
|
||||
public static final int FLAG_LOOP = 0x0010;
|
||||
public static final int FLAG_PLAY_ONCE = 0x0020;
|
||||
public static final int FLAG_SINGLE_FRAME = 0x0040;
|
||||
|
||||
|
||||
|
||||
public boolean typeMovie = false;
|
||||
|
||||
public boolean typeButton = false;
|
||||
|
||||
public boolean typeGraphics = false;
|
||||
|
||||
public boolean typeGlobal = false;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int depth = 0;
|
||||
|
||||
@Conditional("typeGraphics")
|
||||
public boolean flagLoop = false;
|
||||
|
||||
@Conditional("typeGraphics")
|
||||
public boolean flagPlayOnce = false;
|
||||
|
||||
@Conditional("typeGraphics")
|
||||
public boolean flagSingleFrame = false;
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
@Conditional("typeGraphics")
|
||||
public int frameNum = 0;
|
||||
|
||||
public String command = "NoCommand";
|
||||
|
||||
|
||||
@SWFArray(value = "name", countField = "paramCount")
|
||||
@Table(value = "parameters", itemName = "parameter")
|
||||
public List<String> parameterNames = new ArrayList<>();
|
||||
|
||||
@SWFArray(value = "value", countField = "paramCount")
|
||||
@Table(value = "parameters", itemName = "parameter")
|
||||
public List<String> commandValues = new ArrayList<>();
|
||||
|
||||
|
||||
public GenCommandTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public GenCommandTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
int type = sis.readUI16("type");
|
||||
typeMovie = (type & TYPE_MOVIE) > 0;
|
||||
typeButton = (type & TYPE_BUTTON) > 0;
|
||||
typeGraphics = (type & TYPE_GRAPHICS) > 0;
|
||||
typeGlobal = (type & TYPE_GLOBAL) > 0;
|
||||
depth = sis.readUI16("depth");
|
||||
if (typeGraphics) {
|
||||
int flags = sis.readUI16("flags");
|
||||
flagLoop = (flags & FLAG_LOOP) > 0;
|
||||
flagPlayOnce = (flags & FLAG_PLAY_ONCE) > 0;
|
||||
flagSingleFrame = (flags & FLAG_SINGLE_FRAME) > 0;
|
||||
|
||||
frameNum = sis.readUI16("frameNum");
|
||||
}
|
||||
String fullCommandStr = sis.readString("command");
|
||||
if (!fullCommandStr.contains(" ")) {
|
||||
this.command = fullCommandStr;
|
||||
return;
|
||||
}
|
||||
this.command = fullCommandStr.substring(0, fullCommandStr.indexOf(" "));
|
||||
|
||||
boolean inValue = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String name = "";
|
||||
for (int i = fullCommandStr.indexOf(" ") + 1; i < fullCommandStr.length(); i++) {
|
||||
Character c = fullCommandStr.charAt(i);
|
||||
Character cNext = i == fullCommandStr.length() - 1 ? null : fullCommandStr.charAt(i + 1);
|
||||
|
||||
if (inValue) {
|
||||
|
||||
if (c == '/' && cNext == 'n') {
|
||||
sb.append('\n');
|
||||
i++;
|
||||
} else if (c == '/' && cNext == 'r') {
|
||||
sb.append('\r');
|
||||
i++;
|
||||
} else if (c == '\\' && cNext != null) {
|
||||
sb.append(cNext);
|
||||
i++;
|
||||
} else if (c == '"') {
|
||||
String value = sb.toString();
|
||||
parameterNames.add(name);
|
||||
commandValues.add(value);
|
||||
sb = new StringBuilder();
|
||||
inValue = false;
|
||||
i++;
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
} else if (c == '=' && cNext == '"') {
|
||||
inValue = true;
|
||||
name = sb.toString();
|
||||
sb = new StringBuilder();
|
||||
i++;
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getCommandString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(command);
|
||||
sb.append(" ");
|
||||
for (int i = 0; i < parameterNames.size(); i++) {
|
||||
String name = parameterNames.get(i);
|
||||
String value = commandValues.get(i);
|
||||
sb.append(name);
|
||||
sb.append("=\"");
|
||||
sb.append(value.replace("\n", "/n").replace("\r", "/r").replace("\\", "\\\\").replace("\"", "\\\""));
|
||||
sb.append("\"");
|
||||
sb.append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
int type = 0;
|
||||
if (typeMovie) {
|
||||
type |= TYPE_MOVIE;
|
||||
}
|
||||
if (typeButton) {
|
||||
type |= TYPE_BUTTON;
|
||||
}
|
||||
if (typeGraphics) {
|
||||
type |= TYPE_GRAPHICS;
|
||||
}
|
||||
if (typeGlobal) {
|
||||
type |= TYPE_GLOBAL;
|
||||
}
|
||||
sos.writeUI16(type);
|
||||
sos.writeUI16(depth);
|
||||
if (typeGraphics) {
|
||||
int flags = 0;
|
||||
if (flagLoop) {
|
||||
flags |= FLAG_LOOP;
|
||||
}
|
||||
if (flagPlayOnce) {
|
||||
flags |= FLAG_PLAY_ONCE;
|
||||
}
|
||||
if (flagSingleFrame) {
|
||||
flags |= FLAG_SINGLE_FRAME;
|
||||
}
|
||||
sos.writeUI16(flags);
|
||||
sos.writeUI16(frameNum);
|
||||
}
|
||||
sos.writeString(getCommandString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getNameProperties() {
|
||||
Map<String, String> ret = super.getNameProperties();
|
||||
String shortCommand = command;
|
||||
if (shortCommand.contains(".")) {
|
||||
shortCommand = shortCommand.substring(shortCommand.lastIndexOf(".") + 1);
|
||||
}
|
||||
ret.put("cmd", shortCommand);
|
||||
ret.put("dpt", "" + depth);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -28,7 +28,8 @@ import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* NameCharacter tag - undocumented.
|
||||
* NameCharacter tag - Assign a Library name to a character.
|
||||
* Used in Flash Templates.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@@ -39,17 +40,26 @@ public class NameCharacterTag extends Tag implements CharacterIdTag {
|
||||
|
||||
public static final String NAME = "NameCharacter";
|
||||
|
||||
|
||||
public static final int TYPE_BITMAP = 1;
|
||||
public static final int TYPE_SYMBOL = 6;
|
||||
public static final int TYPE_SOUND = 0xFFFF;
|
||||
|
||||
|
||||
/**
|
||||
* ID of character to name
|
||||
*/
|
||||
@SWFType(BasicType.UI16)
|
||||
public int characterId;
|
||||
public int characterId = 0;
|
||||
|
||||
/**
|
||||
* Name of the character
|
||||
*/
|
||||
public String name;
|
||||
public String name = "Symbol";
|
||||
|
||||
@SWFType(BasicType.UI16)
|
||||
public int type = TYPE_SYMBOL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -57,8 +67,6 @@ public class NameCharacterTag extends Tag implements CharacterIdTag {
|
||||
*/
|
||||
public NameCharacterTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
this.characterId = swf.getNextCharacterId();
|
||||
this.name = "unknown";
|
||||
}
|
||||
|
||||
public NameCharacterTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
@@ -70,6 +78,7 @@ public class NameCharacterTag extends Tag implements CharacterIdTag {
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
characterId = sis.readUI16("characterId");
|
||||
name = sis.readString("name");
|
||||
type = sis.readUI16("type");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +91,7 @@ public class NameCharacterTag extends Tag implements CharacterIdTag {
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(characterId);
|
||||
sos.writeString(name);
|
||||
sos.writeUI16(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,13 +30,13 @@ import java.io.IOException;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(from = 3)
|
||||
@SWFVersion(from = 7)
|
||||
public class ProductInfoTag extends Tag {
|
||||
|
||||
public static final int ID = 41;
|
||||
|
||||
public static final String NAME = "ProductInfo";
|
||||
|
||||
public static final String NAME = "ProductInfo";
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
public long productID;
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* SerialNumber tag - Serial number of Flash Generator
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@SWFVersion(to = 6)
|
||||
public class SerialNumberTag extends Tag {
|
||||
|
||||
public static final int ID = 41;
|
||||
|
||||
public static final String NAME = "SerialNumber";
|
||||
|
||||
public String serialNumber = "";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf SWF
|
||||
*/
|
||||
public SerialNumberTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
}
|
||||
|
||||
public SerialNumberTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
serialNumber = sis.readString("serialNumber");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
* @param sos SWF output stream
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
@Override
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeString(serialNumber);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public class ShowFrameTag extends Tag {
|
||||
add(VideoFrameTag.ID);
|
||||
add(SoundStreamBlockTag.ID);
|
||||
add(SetTabIndexTag.ID);
|
||||
add(GenCommandTag.ID);
|
||||
/*add(SoundStreamHeadTag.ID);
|
||||
add(SoundStreamHead2Tag.ID);*/
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
|
||||
private static volatile Integer[] knownTagIds;
|
||||
|
||||
private static volatile Map<Integer, TagTypeInfo> knownTagInfosById;
|
||||
private static volatile Map<Integer, List<TagTypeInfo>> knownTagInfosById;
|
||||
|
||||
private static volatile Map<String, TagTypeInfo> knownTagInfosByName;
|
||||
|
||||
@@ -319,11 +319,11 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
* Gets known classes.
|
||||
* @return Known classes
|
||||
*/
|
||||
public static Map<Integer, TagTypeInfo> getKnownClasses() {
|
||||
public static Map<Integer, List<TagTypeInfo>> getKnownClasses() {
|
||||
if (knownTagInfosById == null) {
|
||||
synchronized (lockObject) {
|
||||
if (knownTagInfosById == null) {
|
||||
Map<Integer, TagTypeInfo> map = new HashMap<>();
|
||||
Map<Integer, List<TagTypeInfo>> map = new HashMap<>();
|
||||
Map<String, TagTypeInfo> map2 = new HashMap<>();
|
||||
addTagInfo(map, map2, CSMSettingsTag.ID, CSMSettingsTag.class, CSMSettingsTag.NAME);
|
||||
addTagInfo(map, map2, DebugIDTag.ID, DebugIDTag.class, DebugIDTag.NAME);
|
||||
@@ -405,6 +405,14 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
addTagInfo(map, map2, DefineSubImage.ID, DefineSubImage.class, DefineSubImage.NAME);
|
||||
addTagInfo(map, map2, ExporterInfo.ID, ExporterInfo.class, ExporterInfo.NAME);
|
||||
addTagInfo(map, map2, FontTextureInfo.ID, FontTextureInfo.class, FontTextureInfo.NAME);
|
||||
|
||||
addTagInfo(map, map2, DefineVideoTag.ID, DefineVideoTag.class, DefineVideoTag.NAME);
|
||||
addTagInfo(map, map2, GenCommandTag.ID, GenCommandTag.class, GenCommandTag.NAME);
|
||||
addTagInfo(map, map2, FontRefTag.ID, FontRefTag.class, FontRefTag.NAME);
|
||||
addTagInfo(map, map2, DefineTextFormatTag.ID, DefineTextFormatTag.class, DefineTextFormatTag.NAME);
|
||||
addTagInfo(map, map2, NameCharacterTag.ID, NameCharacterTag.class, NameCharacterTag.NAME);
|
||||
addTagInfo(map, map2, CharacterSetTag.ID, CharacterSetTag.class, CharacterSetTag.NAME);
|
||||
addTagInfo(map, map2, SerialNumberTag.ID, SerialNumberTag.class, SerialNumberTag.NAME);
|
||||
knownTagInfosById = map;
|
||||
knownTagInfosByName = map2;
|
||||
}
|
||||
@@ -426,8 +434,11 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
return knownTagInfosByName;
|
||||
}
|
||||
|
||||
private static void addTagInfo(Map<Integer, TagTypeInfo> map, Map<String, TagTypeInfo> map2, int id, Class cls, String name) {
|
||||
map.put(id, new TagTypeInfo(id, cls, name));
|
||||
private static void addTagInfo(Map<Integer, List<TagTypeInfo>> map, Map<String, TagTypeInfo> map2, int id, Class cls, String name) {
|
||||
if (!map.containsKey(id)) {
|
||||
map.put(id, new ArrayList<>());
|
||||
}
|
||||
map.get(id).add(new TagTypeInfo(id, cls, name));
|
||||
map2.put(name, new TagTypeInfo(id, cls, name));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -78,9 +80,21 @@ public class TagStub extends Tag {
|
||||
@Override
|
||||
public Map<String, String> getNameProperties() {
|
||||
Map<String, String> ret = super.getNameProperties();
|
||||
Map<Integer, TagTypeInfo> classes = Tag.getKnownClasses();
|
||||
if (classes.containsKey(id)) {
|
||||
ret.put("tcl", classes.get(id).getName());
|
||||
Map<Integer, List<TagTypeInfo>> classes = Tag.getKnownClasses();
|
||||
int swfVersion = getSwf().version;
|
||||
|
||||
if (classes.containsKey(id)) {
|
||||
TagTypeInfo selectedTagTypeInfo = classes.get(id).get(0);
|
||||
if (classes.get(id).size() > 1) {
|
||||
for (TagTypeInfo tagTypeInfo : classes.get(id)) {
|
||||
SWFVersion ver = (SWFVersion) tagTypeInfo.getCls().getAnnotation(SWFVersion.class);
|
||||
if (swfVersion >= ver.from() && swfVersion <= ver.to()) {
|
||||
selectedTagTypeInfo = tagTypeInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.put("tcl", selectedTagTypeInfo.getName());
|
||||
}
|
||||
ret.put("tid", "" + id);
|
||||
return ret;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
* Text tags.
|
||||
* Text tag types.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.text;
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.text.format;
|
||||
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.EnumValue;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ControlTextFormatRecord implements TextFormatRecord {
|
||||
public static final int TYPE_STYLE = 0;
|
||||
public static final int TYPE_FONT_ID = 1;
|
||||
public static final int TYPE_FONT_HEIGHT = 2;
|
||||
public static final int TYPE_COLOR = 3;
|
||||
public static final int TYPE_SCRIPT = 4;
|
||||
public static final int TYPE_KERNING = 5;
|
||||
public static final int TYPE_ALIGN = 8;
|
||||
public static final int TYPE_INDENT = 9;
|
||||
public static final int TYPE_LEFT_MARGIN = 10;
|
||||
public static final int TYPE_RIGHT_MARGIN = 11;
|
||||
public static final int TYPE_LINE_SPACE = 12;
|
||||
|
||||
public static final int STYLE_NORMAL = 0;
|
||||
public static final int STYLE_BOLD = 1;
|
||||
public static final int STYLE_ITALIC = 2;
|
||||
|
||||
|
||||
public static final int SCRIPT_NORMAL = 0;
|
||||
public static final int SCRIPT_SUPERSCRIPT = 1;
|
||||
public static final int SCRIPT_SUBSCRIPT = 2;
|
||||
|
||||
public static final int ALIGN_LEFT = 0;
|
||||
public static final int ALIGN_CENTER = 1;
|
||||
public static final int ALIGN_RIGHT = 2;
|
||||
public static final int ALIGN_JUSTIFY = 3;
|
||||
|
||||
@EnumValue(value = TYPE_STYLE, text = "style")
|
||||
@EnumValue(value = TYPE_FONT_ID, text = "font id")
|
||||
@EnumValue(value = TYPE_FONT_HEIGHT, text = "font height")
|
||||
@EnumValue(value = TYPE_COLOR, text = "color")
|
||||
@EnumValue(value = TYPE_SCRIPT, text = "script")
|
||||
@EnumValue(value = TYPE_KERNING, text = "kerning")
|
||||
@EnumValue(value = TYPE_ALIGN, text = "align")
|
||||
@EnumValue(value = TYPE_INDENT, text = "indent")
|
||||
@EnumValue(value = TYPE_LEFT_MARGIN, text = "left margin")
|
||||
@EnumValue(value = TYPE_RIGHT_MARGIN, text = "right margin")
|
||||
@EnumValue(value = TYPE_LINE_SPACE, text = "line space")
|
||||
public int type;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_STYLE})
|
||||
@SWFType(BasicType.UI8)
|
||||
@EnumValue(value = STYLE_NORMAL, text = "normal")
|
||||
@EnumValue(value = STYLE_BOLD, text = "bold")
|
||||
@EnumValue(value = STYLE_ITALIC, text = "italic")
|
||||
@EnumValue(value = STYLE_BOLD | STYLE_ITALIC, text = "bold + italic")
|
||||
public int style;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_FONT_ID})
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontId;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_FONT_HEIGHT})
|
||||
@SWFType(BasicType.UI16)
|
||||
public int fontHeight;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_COLOR})
|
||||
public RGBA color = new RGBA(Color.BLACK);
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_SCRIPT})
|
||||
@SWFType(BasicType.UI8)
|
||||
@EnumValue(value = SCRIPT_NORMAL, text = "normal")
|
||||
@EnumValue(value = SCRIPT_SUPERSCRIPT, text = "superscript")
|
||||
@EnumValue(value = SCRIPT_SUBSCRIPT, text = "subscript")
|
||||
public int script;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_KERNING})
|
||||
@SWFType(BasicType.SI16)
|
||||
public int kerning;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_ALIGN})
|
||||
@SWFType(BasicType.UI8)
|
||||
@EnumValue(value = ALIGN_LEFT, text = "left")
|
||||
@EnumValue(value = ALIGN_CENTER, text = "center")
|
||||
@EnumValue(value = ALIGN_RIGHT, text = "right")
|
||||
@EnumValue(value = ALIGN_JUSTIFY, text = "justify")
|
||||
public int align;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_INDENT})
|
||||
@SWFType(BasicType.SI16)
|
||||
public int indent;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_LEFT_MARGIN})
|
||||
@SWFType(BasicType.SI16)
|
||||
public int leftMargin;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_RIGHT_MARGIN})
|
||||
@SWFType(BasicType.SI16)
|
||||
public int rightMargin;
|
||||
|
||||
@Conditional(value = "type", options = {TYPE_LINE_SPACE})
|
||||
@SWFType(BasicType.SI16)
|
||||
public int lineSpace;
|
||||
|
||||
@Override
|
||||
public int getFormatRecordId() {
|
||||
return 0x80 + type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.text.format;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class EndTextFormatRecord implements TextFormatRecord {
|
||||
@Override
|
||||
public int getFormatRecordId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.text.format;
|
||||
|
||||
import com.jpexs.helpers.ConcreteClasses;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@ConcreteClasses({ControlTextFormatRecord.class, TextTextFormatRecord.class})
|
||||
public interface TextFormatRecord extends Serializable {
|
||||
public int getFormatRecordId();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.text.format;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TextTextFormatRecord implements TextFormatRecord {
|
||||
public String text = "";
|
||||
|
||||
@Override
|
||||
public int getFormatRecordId() {
|
||||
return text.length();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Text format tag types.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.text.format;
|
||||
Reference in New Issue
Block a user