mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-26 19:46:48 +00:00
Merge origin/master
This commit is contained in:
@@ -157,10 +157,10 @@ public class IdentifiersDeobfuscation {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void deobfuscateInstanceNames(boolean as3, HashMap<DottedChain, DottedChain> namesMap, RenameType renameType, List<Tag> tags, Map<DottedChain, DottedChain> selected) {
|
||||
public void deobfuscateInstanceNames(boolean as3, HashMap<DottedChain, DottedChain> namesMap, RenameType renameType, Iterable<Tag> tags, Map<DottedChain, DottedChain> selected) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
deobfuscateInstanceNames(as3, namesMap, renameType, ((DefineSpriteTag) t).subTags, selected);
|
||||
deobfuscateInstanceNames(as3, namesMap, renameType, ((DefineSpriteTag) t).getTags(), selected);
|
||||
}
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ReadOnlyTagList implements Iterable<Tag> {
|
||||
|
||||
public static final ReadOnlyTagList EMPTY = new ReadOnlyTagList(new ArrayList<>());
|
||||
|
||||
private final List<Tag> list;
|
||||
|
||||
public ReadOnlyTagList(List<Tag> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Tag> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
public Tag get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
public int indexOf(Tag tag) {
|
||||
return list.indexOf(tag);
|
||||
}
|
||||
|
||||
public ArrayList<Tag> toArrayList() {
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,7 @@ import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
|
||||
import com.jpexs.decompiler.flash.types.filters.FILTER;
|
||||
import com.jpexs.decompiler.flash.xfl.FLAVersion;
|
||||
@@ -207,9 +208,12 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
/**
|
||||
* Tags inside of file
|
||||
*/
|
||||
public List<Tag> tags = new ArrayList<>();
|
||||
@SWFField
|
||||
private List<Tag> tags = new ArrayList<>();
|
||||
|
||||
@Internal
|
||||
public ReadOnlyTagList readOnlyTags;
|
||||
|
||||
public boolean hasEndTag = true;
|
||||
|
||||
/**
|
||||
@@ -293,6 +297,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SWF.class.getName());
|
||||
|
||||
@Internal
|
||||
private boolean isModified;
|
||||
|
||||
@Internal
|
||||
private Timeline timeline;
|
||||
|
||||
@@ -346,14 +353,16 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
resetTimelines(this);
|
||||
updateCharacters();
|
||||
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag spriteTag = (DefineSpriteTag) tag;
|
||||
for (Tag tag1 : spriteTag.subTags) {
|
||||
for (Tag tag1 : spriteTag.getTags()) {
|
||||
tag1.setSwf(null);
|
||||
}
|
||||
|
||||
spriteTag.subTags.clear();
|
||||
for (int i = spriteTag.getTags().size() - 1; i >= 0; i--) {
|
||||
spriteTag.removeTag(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (tag instanceof DefineBinaryDataTag) {
|
||||
@@ -401,7 +410,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
synchronized (this) {
|
||||
if (characters == null) {
|
||||
Map<Integer, CharacterTag> chars = new HashMap<>();
|
||||
parseCharacters(tags, chars);
|
||||
parseCharacters(getTags(), chars);
|
||||
characters = Collections.unmodifiableMap(chars);
|
||||
}
|
||||
}
|
||||
@@ -415,7 +424,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
synchronized (this) {
|
||||
if (dependentCharacters == null) {
|
||||
Map<Integer, Set<Integer>> dep = new HashMap<>();
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof CharacterTag) {
|
||||
int characterId = ((CharacterTag) tag).getCharacterId();
|
||||
Set<Integer> needed = new HashSet<>();
|
||||
@@ -529,7 +538,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
synchronized (this) {
|
||||
if (abcList == null) {
|
||||
ArrayList<ABCContainerTag> newAbcList = new ArrayList<>();
|
||||
getAbcTags(tags, newAbcList);
|
||||
getAbcTags(getTags(), newAbcList);
|
||||
abcList = newAbcList;
|
||||
}
|
||||
}
|
||||
@@ -544,7 +553,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public MetadataTag getMetadata() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof MetadataTag) {
|
||||
return (MetadataTag) t;
|
||||
}
|
||||
@@ -554,7 +563,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public FileAttributesTag getFileAttributes() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof FileAttributesTag) {
|
||||
return (FileAttributesTag) t;
|
||||
}
|
||||
@@ -564,7 +573,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public SetBackgroundColorTag getBackgroundColor() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof SetBackgroundColorTag) {
|
||||
return (SetBackgroundColorTag) t;
|
||||
}
|
||||
@@ -574,7 +583,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public EnableTelemetryTag getEnableTelemetry() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof EnableTelemetryTag) {
|
||||
return (EnableTelemetryTag) t;
|
||||
}
|
||||
@@ -597,7 +606,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (jtt == null) {
|
||||
synchronized (this) {
|
||||
if (jtt == null) {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof JPEGTablesTag) {
|
||||
jtt = (JPEGTablesTag) t;
|
||||
break;
|
||||
@@ -611,7 +620,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public String getDocumentClass() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof SymbolClassTag) {
|
||||
SymbolClassTag sc = (SymbolClassTag) t;
|
||||
for (int i = 0; i < sc.tags.size(); i++) {
|
||||
@@ -672,7 +681,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
public void resetTimelines(Timelined timelined) {
|
||||
timelined.resetTimeline();
|
||||
if (timelined instanceof SWF) {
|
||||
for (Tag t : ((SWF) timelined).tags) {
|
||||
for (Tag t : ((SWF) timelined).getTags()) {
|
||||
if (t instanceof Timelined) {
|
||||
resetTimelines((Timelined) t);
|
||||
}
|
||||
@@ -680,7 +689,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCharacters(List<Tag> list, Map<Integer, CharacterTag> characters) {
|
||||
private void parseCharacters(Iterable<Tag> list, Map<Integer, CharacterTag> characters) {
|
||||
for (Tag t : list) {
|
||||
if (t instanceof CharacterTag) {
|
||||
int characterId = ((CharacterTag) t).getCharacterId();
|
||||
@@ -693,7 +702,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
parseCharacters(((DefineSpriteTag) t).getSubTags(), characters);
|
||||
parseCharacters(((DefineSpriteTag) t).getTags(), characters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -717,7 +726,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return false;
|
||||
}
|
||||
path.add(sprite.spriteId);
|
||||
for (Tag t : sprite.subTags) {
|
||||
for (Tag t : sprite.getTags()) {
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
if (!isSpriteValid((DefineSpriteTag) t, path)) {
|
||||
return false;
|
||||
@@ -751,7 +760,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
*/
|
||||
public List<Tag> getTagData(int tagId) {
|
||||
List<Tag> ret = new ArrayList<>();
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag.getId() == tagId) {
|
||||
ret.add(tag);
|
||||
}
|
||||
@@ -817,7 +826,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
sos.writeFIXED8(frameRate);
|
||||
sos.writeUI16(frameCount);
|
||||
|
||||
sos.writeTags(tags);
|
||||
sos.writeTags(getTags());
|
||||
if (hasEndTag) {
|
||||
sos.writeUI16(0);
|
||||
}
|
||||
@@ -940,7 +949,11 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
for (Tag tag : tags) {
|
||||
if (isModified) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag.isModified()) {
|
||||
return true;
|
||||
}
|
||||
@@ -948,14 +961,21 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
isModified = value;
|
||||
}
|
||||
|
||||
public void clearModified() {
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag.isModified()) {
|
||||
tag.createOriginalData();
|
||||
tag.setModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
isModified = false;
|
||||
|
||||
try {
|
||||
uncompressedData = saveToByteArray();
|
||||
} catch (IOException ex) {
|
||||
@@ -1093,6 +1113,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
hasEndTag = false;
|
||||
}
|
||||
this.tags = tags;
|
||||
readOnlyTags = null;
|
||||
if (!checkOnly) {
|
||||
checkInvalidSprites();
|
||||
updateCharacters();
|
||||
@@ -1174,10 +1195,10 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
private static void getAbcTags(List<Tag> list, List<ABCContainerTag> actionScripts) {
|
||||
private static void getAbcTags(Iterable<Tag> list, List<ABCContainerTag> actionScripts) {
|
||||
for (Tag t : list) {
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
getAbcTags(((DefineSpriteTag) t).getSubTags(), actionScripts);
|
||||
getAbcTags(((DefineSpriteTag) t).getTags(), actionScripts);
|
||||
}
|
||||
if (t instanceof ABCContainerTag) {
|
||||
actionScripts.add((ABCContainerTag) t);
|
||||
@@ -1187,7 +1208,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public void assignExportNamesToSymbols() {
|
||||
HashMap<Integer, String> exportNames = new HashMap<>();
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof ExportAssetsTag) {
|
||||
ExportAssetsTag eat = (ExportAssetsTag) t;
|
||||
for (int i = 0; i < eat.tags.size(); i++) {
|
||||
@@ -1199,7 +1220,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof CharacterTag) {
|
||||
CharacterTag ct = (CharacterTag) t;
|
||||
if (exportNames.containsKey(ct.getCharacterId())) {
|
||||
@@ -1211,7 +1232,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public void assignClassesToSymbols() {
|
||||
HashMap<Integer, String> classes = new HashMap<>();
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof SymbolClassTag) {
|
||||
SymbolClassTag sct = (SymbolClassTag) t;
|
||||
for (int i = 0; i < sct.tags.size(); i++) {
|
||||
@@ -1221,7 +1242,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof CharacterTag) {
|
||||
CharacterTag ct = (CharacterTag) t;
|
||||
if (classes.containsKey(ct.getCharacterId())) {
|
||||
@@ -1608,7 +1629,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public final void addEventListener(EventListener listener) {
|
||||
listeners.add(listener);
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof ABCContainerTag) {
|
||||
(((ABCContainerTag) t).getABC()).addEventListener(listener);
|
||||
}
|
||||
@@ -1617,7 +1638,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public final void removeEventListener(EventListener listener) {
|
||||
listeners.remove(listener);
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof ABCContainerTag) {
|
||||
(((ABCContainerTag) t).getABC()).removeEventListener(listener);
|
||||
}
|
||||
@@ -1630,13 +1651,13 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
public static void populateVideoFrames(int streamId, List<Tag> tags, HashMap<Integer, VideoFrameTag> output) {
|
||||
public static void populateVideoFrames(int streamId, Iterable<Tag> tags, HashMap<Integer, VideoFrameTag> output) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof VideoFrameTag) {
|
||||
output.put(((VideoFrameTag) t).frameNum, (VideoFrameTag) t);
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
populateVideoFrames(streamId, ((DefineSpriteTag) t).getSubTags(), output);
|
||||
populateVideoFrames(streamId, ((DefineSpriteTag) t).getTags(), output);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1907,7 +1928,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void getVariables(List<Tag> tags, String path, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
private void getVariables(Iterable<Tag> tags, String path, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, HashMap<ASMSource, ActionList> actionsMap, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, HashMap<DirectValueActionItem, String> usageTypes) throws InterruptedException {
|
||||
List<String> processed = new ArrayList<>();
|
||||
for (Tag t : tags) {
|
||||
String subPath = path + "/" + t.toString();
|
||||
@@ -1921,7 +1942,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
getVariables(((DefineSpriteTag) t).getSubTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes);
|
||||
getVariables(((DefineSpriteTag) t).getTags(), path + "/" + t.toString(), variables, actionsMap, functions, strings, usageTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1964,19 +1985,19 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public int deobfuscateAS3Identifiers(RenameType renameType) {
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, true);
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
((ABCContainerTag) tag).getABC().deobfuscateIdentifiers(deobfuscated, renameType, false);
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof SymbolClassTag) {
|
||||
SymbolClassTag sc = (SymbolClassTag) tag;
|
||||
for (int i = 0; i < sc.names.size(); i++) {
|
||||
@@ -1988,7 +2009,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
sc.setModified(true);
|
||||
}
|
||||
}
|
||||
deobfuscation.deobfuscateInstanceNames(true, deobfuscated, renameType, tags, new HashMap<>());
|
||||
deobfuscation.deobfuscateInstanceNames(true, deobfuscated, renameType, getTags(), new HashMap<>());
|
||||
return deobfuscated.size();
|
||||
}
|
||||
|
||||
@@ -2026,7 +2047,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
HashMap<DirectValueActionItem, String> usageTypes = new HashMap<>();
|
||||
|
||||
int ret = 0;
|
||||
getVariables(tags, "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes);
|
||||
getVariables(getTags(), "", allVariableNames, actionsMap, allFunctions, allStrings, usageTypes);
|
||||
informListeners("rename", "");
|
||||
int fc = 0;
|
||||
for (MyEntry<DirectValueActionItem, ConstantPool> it : allVariableNames) {
|
||||
@@ -2036,13 +2057,13 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
informListeners("rename", "classes");
|
||||
int classCount = 0;
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof DoInitActionTag) {
|
||||
classCount++;
|
||||
}
|
||||
}
|
||||
int cnt = 0;
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof DoInitActionTag) {
|
||||
cnt++;
|
||||
informListeners("rename", "class " + cnt + "/" + classCount);
|
||||
@@ -2252,7 +2273,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
src.setModified();
|
||||
}
|
||||
|
||||
deobfuscation.deobfuscateInstanceNames(false, deobfuscated, renameType, tags, selected);
|
||||
deobfuscation.deobfuscateInstanceNames(false, deobfuscated, renameType, getTags(), selected);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2303,7 +2324,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
public void clearImageCache() {
|
||||
frameCache.clear();
|
||||
rectCache.clear();
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ImageTag) {
|
||||
((ImageTag) tag).clearCache();
|
||||
}
|
||||
@@ -2317,10 +2338,20 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
IdentifiersDeobfuscation.clearCache();
|
||||
}
|
||||
|
||||
public void clearReadOnlyListCache() {
|
||||
readOnlyTags = null;
|
||||
for (Tag tag : tags) {
|
||||
if (tag instanceof DefineSpriteTag) {
|
||||
((DefineSpriteTag) tag).clearReadOnlyListCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllCache() {
|
||||
characters = null;
|
||||
abcList = null;
|
||||
timeline = null;
|
||||
clearReadOnlyListCache();
|
||||
clearImageCache();
|
||||
clearScriptCache();
|
||||
Cache.clearAll();
|
||||
@@ -2876,13 +2907,15 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
private void removeTagWithDependenciesFromTimeline(Tag toRemove, Timeline timeline) {
|
||||
Map<Integer, Integer> stage = new HashMap<>();
|
||||
Set<Integer> dependingChars = new HashSet<>();
|
||||
Timelined timelined = timeline.timelined;
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
if (toRemove instanceof CharacterTag) {
|
||||
int characterId = ((CharacterTag) toRemove).getCharacterId();
|
||||
|
||||
if (characterId != 0) {
|
||||
dependingChars.add(characterId);
|
||||
for (int i = 0; i < timeline.tags.size(); i++) {
|
||||
Tag t = timeline.tags.get(i);
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof CharacterIdTag) {
|
||||
CharacterIdTag c = (CharacterIdTag) t;
|
||||
Set<Integer> needed = new HashSet<>();
|
||||
@@ -2895,8 +2928,8 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < timeline.tags.size(); i++) {
|
||||
Tag t = timeline.tags.get(i);
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof RemoveTag) {
|
||||
RemoveTag rt = (RemoveTag) t;
|
||||
int depth = rt.getDepth();
|
||||
@@ -2904,7 +2937,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
int currentCharId = stage.get(depth);
|
||||
stage.remove(depth);
|
||||
if (dependingChars.contains(currentCharId)) {
|
||||
timeline.tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -2917,7 +2950,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (placeCharId != 0) {
|
||||
stage.put(depth, placeCharId);
|
||||
if (dependingChars.contains(placeCharId)) {
|
||||
timeline.tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -2926,7 +2959,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (t instanceof CharacterIdTag) {
|
||||
CharacterIdTag c = (CharacterIdTag) t;
|
||||
if (dependingChars.contains(c.getCharacterId())) {
|
||||
timeline.tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -2935,13 +2968,13 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
t.getNeededCharacters(needed);
|
||||
for (int dep : dependingChars) {
|
||||
if (needed.contains(dep)) {
|
||||
timeline.tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
//continue;
|
||||
}
|
||||
}
|
||||
if (t == toRemove) {
|
||||
timeline.tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -2958,10 +2991,12 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
characterId = ((CharacterTag) toRemove).getCharacterId();
|
||||
modified = timeline.removeCharacter(characterId);
|
||||
}
|
||||
for (int i = 0; i < timeline.tags.size(); i++) {
|
||||
Tag t = timeline.tags.get(i);
|
||||
Timelined timelined = timeline.timelined;
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t == toRemove) {
|
||||
timeline.tags.remove(t);
|
||||
timelined.removeTag(t);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
@@ -3002,6 +3037,16 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
clearImageCache();
|
||||
}
|
||||
|
||||
public void removeTag(int index) {
|
||||
setModified(true);
|
||||
tags.remove(index);
|
||||
}
|
||||
|
||||
public void removeTag(Tag tag) {
|
||||
setModified(true);
|
||||
tags.remove(tag);
|
||||
}
|
||||
|
||||
public void removeTag(Tag tag, boolean removeDependencies) {
|
||||
Timelined timelined = tag.getTimelined();
|
||||
removeTagInternal(timelined, tag, removeDependencies);
|
||||
@@ -3012,39 +3057,75 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
private void removeTagInternal(Timelined timelined, Tag tag, boolean removeDependencies) {
|
||||
if (tag instanceof ShowFrameTag || ShowFrameTag.isNestedTagType(tag.getId())) {
|
||||
List<Tag> tags;
|
||||
if (timelined instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) timelined;
|
||||
tags = sprite.getSubTags();
|
||||
} else {
|
||||
tags = this.tags;
|
||||
}
|
||||
tags.remove(tag);
|
||||
if (timelined instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) timelined;
|
||||
sprite.setModified(true);
|
||||
}
|
||||
timelined.removeTag(tag);
|
||||
timelined.setModified(true);
|
||||
timelined.resetTimeline();
|
||||
} else {
|
||||
// timeline should be always the swf here
|
||||
if (removeDependencies) {
|
||||
removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline());
|
||||
if (timelined instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) timelined;
|
||||
sprite.setModified(true);
|
||||
}
|
||||
timelined.setModified(true);
|
||||
} else {
|
||||
removeTagFromTimeline(tag, timelined.getTimeline());
|
||||
boolean modified = removeTagFromTimeline(tag, timelined.getTimeline());
|
||||
if (modified) {
|
||||
timelined.setModified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
if (readOnlyTags == null) {
|
||||
readOnlyTags = new ReadOnlyTagList(tags);
|
||||
}
|
||||
|
||||
return readOnlyTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to the SWF
|
||||
*
|
||||
* @param tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
setModified(true);
|
||||
tags.add(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to the SWF
|
||||
*
|
||||
* @param index
|
||||
* @param tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
setModified(true);
|
||||
tags.add(index, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a tag in the SWF
|
||||
*
|
||||
* @param oldTag
|
||||
* @param newTag
|
||||
*/
|
||||
public void replaceTag(Tag oldTag, Tag newTag) {
|
||||
setModified(true);
|
||||
int index = tags.indexOf(oldTag);
|
||||
if (index != -1) {
|
||||
tags.set(index, newTag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag to the SWF
|
||||
* If targetTreeItem is:
|
||||
* - Frame: adds the tag to the Frame. Frame can be a frame of the main
|
||||
* timeline or a DefineSprite frame
|
||||
* - DefineSprite: adds the tag to the and of the DefineSprite's tag list
|
||||
* - DefineSprite: adds the tag to the end of the DefineSprite's tag list
|
||||
* - Any other tag in the SWF: adds the new tag exactly before the specified
|
||||
* tag
|
||||
* - Other: adds the tag to the end of the SWF's tag list
|
||||
@@ -3064,13 +3145,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
tag.setTimelined(timelined);
|
||||
|
||||
List<Tag> tags;
|
||||
if (timelined instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) timelined;
|
||||
tags = sprite.subTags;
|
||||
} else {
|
||||
tags = swf.tags;
|
||||
}
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
|
||||
int index;
|
||||
if (frame != null) {
|
||||
@@ -3082,11 +3157,11 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
} else if (timelined instanceof DefineSpriteTag) {
|
||||
index = -1;
|
||||
} else if (targetTreeItem instanceof Tag) {
|
||||
if (tag instanceof CharacterIdTag && targetTreeItem instanceof CharacterTag) {
|
||||
if (tag instanceof CharacterIdTag && !(tag instanceof CharacterTag) && targetTreeItem instanceof CharacterTag) {
|
||||
((CharacterIdTag) tag).setCharacterId(((CharacterTag) targetTreeItem).getCharacterId());
|
||||
}
|
||||
|
||||
index = tags.indexOf(targetTreeItem); // todo: honfika: why not index + 1?
|
||||
index = tags.indexOf((Tag) targetTreeItem); // todo: honfika: why not index + 1?
|
||||
} else {
|
||||
index = -1;
|
||||
if (tag instanceof CharacterTag) {
|
||||
@@ -3101,9 +3176,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
if (index > -1) {
|
||||
tags.add(index, tag);
|
||||
timelined.addTag(index, tag);
|
||||
} else {
|
||||
tags.add(tag);
|
||||
timelined.addTag(tag);
|
||||
}
|
||||
|
||||
timelined.resetTimeline();
|
||||
@@ -3147,7 +3222,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
int maxId = Math.max(tags.size(), getNextCharacterId());
|
||||
int id = maxId;
|
||||
// first set the chatacter ids to surely not used ids
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof CharacterTag) {
|
||||
CharacterTag characterTag = (CharacterTag) tag;
|
||||
replaceCharacter(characterTag.getCharacterId(), id++);
|
||||
@@ -3155,7 +3230,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
// then set them to 1,2,3...
|
||||
id = 1;
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof CharacterTag) {
|
||||
CharacterTag characterTag = (CharacterTag) tag;
|
||||
replaceCharacter(characterTag.getCharacterId(), id++);
|
||||
@@ -3165,7 +3240,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (Tag tag : tags) {
|
||||
for (Tag tag : getTags()) {
|
||||
boolean modified2 = false;
|
||||
if (tag instanceof CharacterIdTag) {
|
||||
CharacterIdTag characterIdTag = (CharacterIdTag) tag;
|
||||
@@ -3343,7 +3418,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
* @return the tag or null if not found
|
||||
*/
|
||||
public DebugIDTag getDebugId() {
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof DebugIDTag) {
|
||||
return (DebugIDTag) t;
|
||||
}
|
||||
|
||||
@@ -1081,7 +1081,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
// out.println(Utils.formatHex((int)tag.getPos(), 8) + ": " + Utils.indent(level, "") + Utils.format(tag.toString(), 25 - 2*level) + " tagId="+tag.getId()+" len="+tag.getOrigDataLength()+": "+Utils.bytesToHexString(64, tag.getData(version), 0));
|
||||
if (tag instanceof DefineSpriteTag) {
|
||||
int i = 0;
|
||||
for (Tag subTag : ((DefineSpriteTag) tag).getSubTags()) {
|
||||
for (Tag subTag : ((DefineSpriteTag) tag).getTags()) {
|
||||
dumpTag(out, subTag, i++, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @param tags List of tag values
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeTags(List<Tag> tags) throws IOException {
|
||||
public void writeTags(Iterable<Tag> tags) throws IOException {
|
||||
for (Tag tag : tags) {
|
||||
tag.writeTag(this);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class SWFSearch {
|
||||
SWF swf = noCheck ? new SWF(pmi) : new SWF(pmi, null, null, null, false, true, true);
|
||||
boolean valid = swf.fileSize > 0
|
||||
&& swf.version > 0
|
||||
&& (!swf.tags.isEmpty() || noCheck)
|
||||
&& (!swf.getTags().isEmpty() || noCheck)
|
||||
&& swf.version <= SWF.MAX_VERSION;
|
||||
if (valid) {
|
||||
long limit = pmi.getPos();
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
@@ -38,7 +39,7 @@ import java.util.List;
|
||||
*/
|
||||
public class BinaryDataExporter {
|
||||
|
||||
public List<File> exportBinaryData(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, BinaryDataExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportBinaryData(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, BinaryDataExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.typography.font.tools.conversion.woff.WoffWriter;
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.ApplicationInfo;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
@@ -57,7 +58,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class FontExporter {
|
||||
|
||||
public List<File> exportFonts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final FontExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportFonts(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, final FontExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.helpers.BMPFile;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
@@ -144,7 +145,7 @@ public class FrameExporter {
|
||||
|
||||
public List<File> exportFrames(AbortRetryIgnoreHandler handler, String outdir, final SWF swf, int containerId, List<Integer> frames, final FrameExportSettings settings, final EventListener evl) throws IOException, InterruptedException {
|
||||
final List<File> ret = new ArrayList<>();
|
||||
if (swf.tags.isEmpty()) {
|
||||
if (swf.getTags().isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
Timeline tim0;
|
||||
@@ -180,7 +181,8 @@ public class FrameExporter {
|
||||
if (settings.mode == FrameExportMode.SVG) {
|
||||
for (int i = 0; i < frames.size(); i++) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("frame", i + 1, frames.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
Tag parentTag = tim.getParentTag();
|
||||
evl.handleExportingEvent("frame", i + 1, frames.size(), parentTag == null ? "" : parentTag.getName());
|
||||
}
|
||||
|
||||
final int fi = i;
|
||||
@@ -205,7 +207,8 @@ public class FrameExporter {
|
||||
}, handler).run();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("frame", i + 1, frames.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
Tag parentTag = tim.getParentTag();
|
||||
evl.handleExportedEvent("frame", i + 1, frames.size(), parentTag == null ? "" : parentTag.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +217,8 @@ public class FrameExporter {
|
||||
|
||||
if (settings.mode == FrameExportMode.CANVAS) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("canvas", 1, 1, tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
Tag parentTag = tim.getParentTag();
|
||||
evl.handleExportingEvent("canvas", 1, 1, parentTag == null ? "" : parentTag.getName());
|
||||
}
|
||||
|
||||
final Timeline ftim = tim;
|
||||
@@ -319,7 +323,8 @@ public class FrameExporter {
|
||||
}, handler).run();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("canvas", 1, 1, tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
Tag parentTag = tim.getParentTag();
|
||||
evl.handleExportedEvent("canvas", 1, 1, parentTag == null ? "" : parentTag.getName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -346,14 +351,17 @@ public class FrameExporter {
|
||||
return null;
|
||||
}
|
||||
|
||||
Tag parentTag = tim.getParentTag();
|
||||
String tagName = parentTag == null ? "" : parentTag.getName();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
evl.handleExportingEvent("frame", pos + 1, fframes.size(), tagName);
|
||||
}
|
||||
|
||||
BufferedImage result = SWF.frameToImageGet(ftim, fframes.get(pos++), 0, null, 0, ftim.displayRect, new Matrix(), new ColorTransform(), fbackgroundColor, false, settings.zoom).getBufferedImage();
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("frame", pos, fframes.size(), tim.parentTag == null ? "" : tim.parentTag.getName());
|
||||
evl.handleExportedEvent("frame", pos, fframes.size(), tagName);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.ImageExportSettings;
|
||||
@@ -42,7 +43,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ImageExporter {
|
||||
|
||||
public List<File> exportImages(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, ImageExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportImages(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, ImageExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
@@ -51,7 +52,7 @@ import java.util.Set;
|
||||
public class MorphShapeExporter {
|
||||
|
||||
//TODO: implement morphshape export. How to handle 65536 frames?
|
||||
public List<File> exportMorphShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final MorphShapeExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportMorphShapes(AbortRetryIgnoreHandler handler, final String outdir, ReadOnlyTagList tags, final MorphShapeExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
@@ -49,7 +50,7 @@ import java.util.List;
|
||||
*/
|
||||
public class MovieExporter {
|
||||
|
||||
public List<File> exportMovies(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final MovieExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportMovies(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, final MovieExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -97,7 +98,7 @@ public class MovieExporter {
|
||||
public byte[] exportMovie(DefineVideoStreamTag videoStream, MovieExportMode mode) throws IOException {
|
||||
SWF swf = videoStream.getSwf();
|
||||
HashMap<Integer, VideoFrameTag> frames = new HashMap<>();
|
||||
SWF.populateVideoFrames(videoStream.characterID, swf.tags, frames);
|
||||
SWF.populateVideoFrames(videoStream.characterID, swf.getTags(), frames);
|
||||
if (frames.isEmpty()) {
|
||||
return SWFInputStream.BYTE_ARRAY_EMPTY;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
@@ -29,7 +30,6 @@ import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
|
||||
import com.jpexs.decompiler.flash.helpers.BMPFile;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
@@ -57,7 +57,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class ShapeExporter {
|
||||
|
||||
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, List<Tag> tags, final ShapeExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportShapes(AbortRetryIgnoreHandler handler, final String outdir, ReadOnlyTagList tags, final ShapeExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
@@ -80,28 +80,25 @@ public class ShapeExporter {
|
||||
int currentIndex = 1;
|
||||
for (final Tag t : tags) {
|
||||
if (t instanceof ShapeTag) {
|
||||
final ShapeTag st = (ShapeTag) t;
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("shape", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
int characterID = 0;
|
||||
if (t instanceof CharacterTag) {
|
||||
characterID = ((CharacterTag) t).getCharacterId();
|
||||
}
|
||||
String ext = "svg";
|
||||
int characterID = st.getCharacterId();
|
||||
String ext = ".svg";
|
||||
if (settings.mode == ShapeExportMode.PNG) {
|
||||
ext = "png";
|
||||
ext = ".png";
|
||||
}
|
||||
if (settings.mode == ShapeExportMode.BMP) {
|
||||
ext = "bmp";
|
||||
ext = ".bmp";
|
||||
}
|
||||
if (settings.mode == ShapeExportMode.CANVAS) {
|
||||
ext = "html";
|
||||
ext = ".html";
|
||||
}
|
||||
|
||||
final File file = new File(outdir + File.separator + characterID + "." + ext);
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName() + ext));
|
||||
new RetryTask(() -> {
|
||||
ShapeTag st = (ShapeTag) t;
|
||||
switch (settings.mode) {
|
||||
case SVG:
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
@@ -52,7 +53,7 @@ import java.util.List;
|
||||
*/
|
||||
public class SoundExporter {
|
||||
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final SoundExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, final SoundExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
@@ -39,7 +40,7 @@ public class SymbolClassExporter {
|
||||
|
||||
public static final String SYMBOL_CLASS_EXPORT_FILENAME = "symbols.csv";
|
||||
|
||||
public List<File> exportNames(final String outdir, List<Tag> tags, EventListener evl) throws IOException {
|
||||
public List<File> exportNames(final String outdir, ReadOnlyTagList tags, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
@@ -48,7 +49,7 @@ public class TextExporter {
|
||||
|
||||
public static final String TEXT_EXPORT_FILENAME_PLAIN = "textsplain.txt";
|
||||
|
||||
public List<File> exportTexts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final TextExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
public List<File> exportTexts(AbortRetryIgnoreHandler handler, String outdir, ReadOnlyTagList tags, final TextExportSettings settings, EventListener evl) throws IOException, InterruptedException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
|
||||
@@ -240,6 +240,18 @@ public final class Matrix implements Cloneable {
|
||||
+ rotateSkew1 + ", " + scaleY + ", " + translateX + ", " + translateY + ")";
|
||||
}
|
||||
|
||||
public static String[] parseSvgNumberList(String params) {
|
||||
while (params.contains(" ")) {
|
||||
params = params.replaceAll(" ", " ");
|
||||
}
|
||||
|
||||
params = params.trim();
|
||||
params = params.replace(", ", ",");
|
||||
params = params.replace(" ", ",");
|
||||
String[] args = params.split(",");
|
||||
return args;
|
||||
}
|
||||
|
||||
public static Matrix parseSvgMatrix(String transformStr, double translateDivisor, double unitDivisor) {
|
||||
Matrix ret = new Matrix();
|
||||
while (transformStr != null && transformStr.length() > 0) {
|
||||
@@ -247,14 +259,7 @@ public final class Matrix implements Cloneable {
|
||||
transformStr = transformStr.substring(funcName.length() + 1);
|
||||
String params = transformStr.split("\\)")[0];
|
||||
transformStr = transformStr.substring(params.length() + 1).trim();
|
||||
while (params.contains(" ")) {
|
||||
params = params.replaceAll(" ", " ");
|
||||
}
|
||||
|
||||
params = params.trim();
|
||||
params = params.replace(", ", ",");
|
||||
params = params.replace(" ", ",");
|
||||
String[] args = params.split(",");
|
||||
String[] args = parseSvgNumberList(params);
|
||||
funcName = funcName.trim();
|
||||
switch (funcName) {
|
||||
case "matrix":
|
||||
|
||||
@@ -52,6 +52,8 @@ public class SWFDecompilerPlugin {
|
||||
|
||||
private static final List<SWFDecompilerListener> listeners = new ArrayList<>();
|
||||
|
||||
public static String[] customParameters = new String[0];
|
||||
|
||||
public static File getPluginsDir() {
|
||||
File pluginPath = null;
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ public class ImageImporter extends TagImporter {
|
||||
}
|
||||
|
||||
imageTag.setModified(true);
|
||||
swf.tags.set(swf.tags.indexOf(it), imageTag);
|
||||
swf.replaceTag(it, imageTag);
|
||||
swf.updateCharacters();
|
||||
return imageTag;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -142,6 +142,7 @@ public class SwfXmlImporter {
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
|
||||
processElement(doc.getDocumentElement(), swf, swf, null);
|
||||
swf.clearAllCache();
|
||||
} catch (ParserConfigurationException | SAXException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SymbolClassImporter {
|
||||
nameMap.put(characterId, name);
|
||||
}
|
||||
|
||||
for (Tag tag : swf.tags) {
|
||||
for (Tag tag : swf.getTags()) {
|
||||
if (tag instanceof ExportAssetsTag) {
|
||||
ExportAssetsTag eat = (ExportAssetsTag) tag;
|
||||
for (int i = 0; i < eat.tags.size(); i++) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgBitmapFill extends SvgFill {
|
||||
|
||||
public String patternTransform;
|
||||
|
||||
public int characterId;
|
||||
|
||||
@Override
|
||||
public Color toColor() {
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgColor extends SvgFill {
|
||||
|
||||
public Color color;
|
||||
|
||||
public SvgColor(int r, int g, int b, int opacity) {
|
||||
this(new Color(r, g, b, opacity));
|
||||
}
|
||||
|
||||
public SvgColor(int r, int g, int b) {
|
||||
this(new Color(r, g, b));
|
||||
}
|
||||
|
||||
public SvgColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color toColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public static SvgColor parse(String colorString) {
|
||||
if (colorString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// named colors from: http://www.w3.org/TR/SVG/types.html#ColorKeywords
|
||||
switch (colorString) {
|
||||
case "aliceblue":
|
||||
return new SvgColor(240, 248, 255);
|
||||
case "antiquewhite":
|
||||
return new SvgColor(250, 235, 215);
|
||||
case "aqua":
|
||||
return new SvgColor(0, 255, 255);
|
||||
case "aquamarine":
|
||||
return new SvgColor(127, 255, 212);
|
||||
case "azure":
|
||||
return new SvgColor(240, 255, 255);
|
||||
case "beige":
|
||||
return new SvgColor(245, 245, 220);
|
||||
case "bisque":
|
||||
return new SvgColor(255, 228, 196);
|
||||
case "black":
|
||||
return new SvgColor(0, 0, 0);
|
||||
case "blanchedalmond":
|
||||
return new SvgColor(255, 235, 205);
|
||||
case "blue":
|
||||
return new SvgColor(0, 0, 255);
|
||||
case "blueviolet":
|
||||
return new SvgColor(138, 43, 226);
|
||||
case "brown":
|
||||
return new SvgColor(165, 42, 42);
|
||||
case "burlywood":
|
||||
return new SvgColor(222, 184, 135);
|
||||
case "cadetblue":
|
||||
return new SvgColor(95, 158, 160);
|
||||
case "chartreuse":
|
||||
return new SvgColor(127, 255, 0);
|
||||
case "chocolate":
|
||||
return new SvgColor(210, 105, 30);
|
||||
case "coral":
|
||||
return new SvgColor(255, 127, 80);
|
||||
case "cornflowerblue":
|
||||
return new SvgColor(100, 149, 237);
|
||||
case "cornsilk":
|
||||
return new SvgColor(255, 248, 220);
|
||||
case "crimson":
|
||||
return new SvgColor(220, 20, 60);
|
||||
case "cyan":
|
||||
return new SvgColor(0, 255, 255);
|
||||
case "darkblue":
|
||||
return new SvgColor(0, 0, 139);
|
||||
case "darkcyan":
|
||||
return new SvgColor(0, 139, 139);
|
||||
case "darkgoldenrod":
|
||||
return new SvgColor(184, 134, 11);
|
||||
case "darkgray":
|
||||
return new SvgColor(169, 169, 169);
|
||||
case "darkgreen":
|
||||
return new SvgColor(0, 100, 0);
|
||||
case "darkgrey":
|
||||
return new SvgColor(169, 169, 169);
|
||||
case "darkkhaki":
|
||||
return new SvgColor(189, 183, 107);
|
||||
case "darkmagenta":
|
||||
return new SvgColor(139, 0, 139);
|
||||
case "darkolivegreen":
|
||||
return new SvgColor(85, 107, 47);
|
||||
case "darkorange":
|
||||
return new SvgColor(255, 140, 0);
|
||||
case "darkorchid":
|
||||
return new SvgColor(153, 50, 204);
|
||||
case "darkred":
|
||||
return new SvgColor(139, 0, 0);
|
||||
case "darksalmon":
|
||||
return new SvgColor(233, 150, 122);
|
||||
case "darkseagreen":
|
||||
return new SvgColor(143, 188, 143);
|
||||
case "darkslateblue":
|
||||
return new SvgColor(72, 61, 139);
|
||||
case "darkslategray":
|
||||
return new SvgColor(47, 79, 79);
|
||||
case "darkslategrey":
|
||||
return new SvgColor(47, 79, 79);
|
||||
case "darkturquoise":
|
||||
return new SvgColor(0, 206, 209);
|
||||
case "darkviolet":
|
||||
return new SvgColor(148, 0, 211);
|
||||
case "deeppink":
|
||||
return new SvgColor(255, 20, 147);
|
||||
case "deepskyblue":
|
||||
return new SvgColor(0, 191, 255);
|
||||
case "dimgray":
|
||||
return new SvgColor(105, 105, 105);
|
||||
case "dimgrey":
|
||||
return new SvgColor(105, 105, 105);
|
||||
case "dodgerblue":
|
||||
return new SvgColor(30, 144, 255);
|
||||
case "firebrick":
|
||||
return new SvgColor(178, 34, 34);
|
||||
case "floralwhite":
|
||||
return new SvgColor(255, 250, 240);
|
||||
case "forestgreen":
|
||||
return new SvgColor(34, 139, 34);
|
||||
case "fuchsia":
|
||||
return new SvgColor(255, 0, 255);
|
||||
case "gainsboro":
|
||||
return new SvgColor(220, 220, 220);
|
||||
case "ghostwhite":
|
||||
return new SvgColor(248, 248, 255);
|
||||
case "gold":
|
||||
return new SvgColor(255, 215, 0);
|
||||
case "goldenrod":
|
||||
return new SvgColor(218, 165, 32);
|
||||
case "gray":
|
||||
return new SvgColor(128, 128, 128);
|
||||
case "grey":
|
||||
return new SvgColor(128, 128, 128);
|
||||
case "green":
|
||||
return new SvgColor(0, 128, 0);
|
||||
case "greenyellow":
|
||||
return new SvgColor(173, 255, 47);
|
||||
case "honeydew":
|
||||
return new SvgColor(240, 255, 240);
|
||||
case "hotpink":
|
||||
return new SvgColor(255, 105, 180);
|
||||
case "indianred":
|
||||
return new SvgColor(205, 92, 92);
|
||||
case "indigo":
|
||||
return new SvgColor(75, 0, 130);
|
||||
case "ivory":
|
||||
return new SvgColor(255, 255, 240);
|
||||
case "khaki":
|
||||
return new SvgColor(240, 230, 140);
|
||||
case "lavender":
|
||||
return new SvgColor(230, 230, 250);
|
||||
case "lavenderblush":
|
||||
return new SvgColor(255, 240, 245);
|
||||
case "lawngreen":
|
||||
return new SvgColor(124, 252, 0);
|
||||
case "lemonchiffon":
|
||||
return new SvgColor(255, 250, 205);
|
||||
case "lightblue":
|
||||
return new SvgColor(173, 216, 230);
|
||||
case "lightcoral":
|
||||
return new SvgColor(240, 128, 128);
|
||||
case "lightcyan":
|
||||
return new SvgColor(224, 255, 255);
|
||||
case "lightgoldenrodyellow":
|
||||
return new SvgColor(250, 250, 210);
|
||||
case "lightgray":
|
||||
return new SvgColor(211, 211, 211);
|
||||
case "lightgreen":
|
||||
return new SvgColor(144, 238, 144);
|
||||
case "lightgrey":
|
||||
return new SvgColor(211, 211, 211);
|
||||
case "lightpink":
|
||||
return new SvgColor(255, 182, 193);
|
||||
case "lightsalmon":
|
||||
return new SvgColor(255, 160, 122);
|
||||
case "lightseagreen":
|
||||
return new SvgColor(32, 178, 170);
|
||||
case "lightskyblue":
|
||||
return new SvgColor(135, 206, 250);
|
||||
case "lightslategray":
|
||||
return new SvgColor(119, 136, 153);
|
||||
case "lightslategrey":
|
||||
return new SvgColor(119, 136, 153);
|
||||
case "lightsteelblue":
|
||||
return new SvgColor(176, 196, 222);
|
||||
case "lightyellow":
|
||||
return new SvgColor(255, 255, 224);
|
||||
case "lime":
|
||||
return new SvgColor(0, 255, 0);
|
||||
case "limegreen":
|
||||
return new SvgColor(50, 205, 50);
|
||||
case "linen":
|
||||
return new SvgColor(250, 240, 230);
|
||||
case "magenta":
|
||||
return new SvgColor(255, 0, 255);
|
||||
case "maroon":
|
||||
return new SvgColor(128, 0, 0);
|
||||
case "mediumaquamarine":
|
||||
return new SvgColor(102, 205, 170);
|
||||
case "mediumblue":
|
||||
return new SvgColor(0, 0, 205);
|
||||
case "mediumorchid":
|
||||
return new SvgColor(186, 85, 211);
|
||||
case "mediumpurple":
|
||||
return new SvgColor(147, 112, 219);
|
||||
case "mediumseagreen":
|
||||
return new SvgColor(60, 179, 113);
|
||||
case "mediumslateblue":
|
||||
return new SvgColor(123, 104, 238);
|
||||
case "mediumspringgreen":
|
||||
return new SvgColor(0, 250, 154);
|
||||
case "mediumturquoise":
|
||||
return new SvgColor(72, 209, 204);
|
||||
case "mediumvioletred":
|
||||
return new SvgColor(199, 21, 133);
|
||||
case "midnightblue":
|
||||
return new SvgColor(25, 25, 112);
|
||||
case "mintcream":
|
||||
return new SvgColor(245, 255, 250);
|
||||
case "mistyrose":
|
||||
return new SvgColor(255, 228, 225);
|
||||
case "moccasin":
|
||||
return new SvgColor(255, 228, 181);
|
||||
case "navajowhite":
|
||||
return new SvgColor(255, 222, 173);
|
||||
case "navy":
|
||||
return new SvgColor(0, 0, 128);
|
||||
case "oldlace":
|
||||
return new SvgColor(253, 245, 230);
|
||||
case "olive":
|
||||
return new SvgColor(128, 128, 0);
|
||||
case "olivedrab":
|
||||
return new SvgColor(107, 142, 35);
|
||||
case "orange":
|
||||
return new SvgColor(255, 165, 0);
|
||||
case "orangered":
|
||||
return new SvgColor(255, 69, 0);
|
||||
case "orchid":
|
||||
return new SvgColor(218, 112, 214);
|
||||
case "palegoldenrod":
|
||||
return new SvgColor(238, 232, 170);
|
||||
case "palegreen":
|
||||
return new SvgColor(152, 251, 152);
|
||||
case "paleturquoise":
|
||||
return new SvgColor(175, 238, 238);
|
||||
case "palevioletred":
|
||||
return new SvgColor(219, 112, 147);
|
||||
case "papayawhip":
|
||||
return new SvgColor(255, 239, 213);
|
||||
case "peachpuff":
|
||||
return new SvgColor(255, 218, 185);
|
||||
case "peru":
|
||||
return new SvgColor(205, 133, 63);
|
||||
case "pink":
|
||||
return new SvgColor(255, 192, 203);
|
||||
case "plum":
|
||||
return new SvgColor(221, 160, 221);
|
||||
case "powderblue":
|
||||
return new SvgColor(176, 224, 230);
|
||||
case "purple":
|
||||
return new SvgColor(128, 0, 128);
|
||||
case "red":
|
||||
return new SvgColor(255, 0, 0);
|
||||
case "rosybrown":
|
||||
return new SvgColor(188, 143, 143);
|
||||
case "royalblue":
|
||||
return new SvgColor(65, 105, 225);
|
||||
case "saddlebrown":
|
||||
return new SvgColor(139, 69, 19);
|
||||
case "salmon":
|
||||
return new SvgColor(250, 128, 114);
|
||||
case "sandybrown":
|
||||
return new SvgColor(244, 164, 96);
|
||||
case "seagreen":
|
||||
return new SvgColor(46, 139, 87);
|
||||
case "seashell":
|
||||
return new SvgColor(255, 245, 238);
|
||||
case "sienna":
|
||||
return new SvgColor(160, 82, 45);
|
||||
case "silver":
|
||||
return new SvgColor(192, 192, 192);
|
||||
case "skyblue":
|
||||
return new SvgColor(135, 206, 235);
|
||||
case "slateblue":
|
||||
return new SvgColor(106, 90, 205);
|
||||
case "slategray":
|
||||
return new SvgColor(112, 128, 144);
|
||||
case "slategrey":
|
||||
return new SvgColor(112, 128, 144);
|
||||
case "snow":
|
||||
return new SvgColor(255, 250, 250);
|
||||
case "springgreen":
|
||||
return new SvgColor(0, 255, 127);
|
||||
case "steelblue":
|
||||
return new SvgColor(70, 130, 180);
|
||||
case "tan":
|
||||
return new SvgColor(210, 180, 140);
|
||||
case "teal":
|
||||
return new SvgColor(0, 128, 128);
|
||||
case "thistle":
|
||||
return new SvgColor(216, 191, 216);
|
||||
case "tomato":
|
||||
return new SvgColor(255, 99, 71);
|
||||
case "turquoise":
|
||||
return new SvgColor(64, 224, 208);
|
||||
case "violet":
|
||||
return new SvgColor(238, 130, 238);
|
||||
case "wheat":
|
||||
return new SvgColor(245, 222, 179);
|
||||
case "white":
|
||||
return new SvgColor(255, 255, 255);
|
||||
case "whitesmoke":
|
||||
return new SvgColor(245, 245, 245);
|
||||
case "yellow":
|
||||
return new SvgColor(255, 255, 0);
|
||||
case "yellowgreen":
|
||||
return new SvgColor(154, 205, 50);
|
||||
}
|
||||
|
||||
if (colorString.startsWith("#")) {
|
||||
String s = colorString.substring(1);
|
||||
if (s.length() == 3) {
|
||||
s = "" + s.charAt(0) + s.charAt(0) + s.charAt(1) + s.charAt(1) + s.charAt(2) + s.charAt(2);
|
||||
}
|
||||
|
||||
int i = Integer.parseInt(s, 16);
|
||||
return new SvgColor(new Color(i, false));
|
||||
} else if (colorString.startsWith("rgb")) {
|
||||
colorString = colorString.substring(3).trim();
|
||||
if (colorString.startsWith("(") && colorString.endsWith(")")) {
|
||||
colorString = colorString.substring(1, colorString.length() - 1);
|
||||
String[] args = colorString.split(",");
|
||||
if (args.length == 3) {
|
||||
String a0 = args[0].trim();
|
||||
String a1 = args[1].trim();
|
||||
String a2 = args[2].trim();
|
||||
if (a0.endsWith("%") && a1.endsWith("%") && a2.endsWith("%")) {
|
||||
int r = (int) Math.round(Double.parseDouble(a0.substring(0, a0.length() - 1)) * 255.0 / 100);
|
||||
int g = (int) Math.round(Double.parseDouble(a1.substring(0, a1.length() - 1)) * 255.0 / 100);
|
||||
int b = (int) Math.round(Double.parseDouble(a2.substring(0, a2.length() - 1)) * 255.0 / 100);
|
||||
return new SvgColor(r, g, b);
|
||||
} else {
|
||||
int r = Integer.parseInt(a0);
|
||||
int g = Integer.parseInt(a1);
|
||||
int b = Integer.parseInt(a2);
|
||||
return new SvgColor(r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
abstract class SvgFill implements Cloneable {
|
||||
|
||||
public abstract Color toColor();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
abstract class SvgGradient extends SvgFill {
|
||||
|
||||
public List<SvgStop> stops;
|
||||
|
||||
public SvgGradientUnits gradientUnits;
|
||||
|
||||
public String gradientTransform;
|
||||
|
||||
public SvgSpreadMethod spreadMethod;
|
||||
|
||||
public SvgInterpolation interpolation;
|
||||
|
||||
@Override
|
||||
public Color toColor() {
|
||||
if (stops.isEmpty()) {
|
||||
return Color.BLACK;
|
||||
}
|
||||
return stops.get(0).color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
enum SvgGradientUnits {
|
||||
|
||||
USER_SPACE_ON_USE, OBJECT_BOUNDING_BOX
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
enum SvgInterpolation {
|
||||
|
||||
SRGB, LINEAR_RGB
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
enum SvgLineCap {
|
||||
|
||||
BUTT, ROUND, SQUARE
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
enum SvgLineJoin {
|
||||
|
||||
MITER, ROUND, BEVEL
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgLinearGradient extends SvgGradient {
|
||||
|
||||
public String x1;
|
||||
|
||||
public String y1;
|
||||
|
||||
public String x2;
|
||||
|
||||
public String y2;
|
||||
//xlink?
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
package com.jpexs.decompiler.flash.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgRadialGradient extends SvgGradient {
|
||||
|
||||
public String cx;
|
||||
|
||||
public String cy;
|
||||
|
||||
public String r;
|
||||
|
||||
public String fx;
|
||||
|
||||
public String fy;
|
||||
//xlink?
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
enum SvgSpreadMethod {
|
||||
|
||||
PAD, REFLECT, REPEAT
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgStop implements Comparable<SvgStop> {
|
||||
|
||||
public Color color;
|
||||
|
||||
public double offset;
|
||||
|
||||
public SvgStop(Color color, double offset) {
|
||||
this.color = color;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SvgStop o) {
|
||||
return (int) Math.signum(offset - o.offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,680 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import com.jpexs.decompiler.flash.importers.ShapeImporter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgStyle {
|
||||
|
||||
private final Element element;
|
||||
|
||||
private final SvgImporter importer;
|
||||
|
||||
private final Map<String, Element> idMap;
|
||||
|
||||
private final double epsilon = 0.001;
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
public SvgStyle(SvgImporter importer, Map<String, Element> idMap, Element element) {
|
||||
this.importer = importer;
|
||||
this.idMap = idMap;
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
private Map<String, String> getStyleAttributeValues(Element element) {
|
||||
// todo: cache
|
||||
Map<String, String> styleValues = new HashMap<>();
|
||||
if (element.hasAttribute("style")) {
|
||||
String[] styleDefs = element.getAttribute("style").split(";");
|
||||
for (String styleDef : styleDefs) {
|
||||
if (!styleDef.contains(":")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] parts = styleDef.split(":", 2);
|
||||
String name = parts[0].trim();
|
||||
String value = parts[1].trim();
|
||||
SvgStyleProperty styleProperty = SvgStyleProperty.getByName(name);
|
||||
if (styleProperty == null) {
|
||||
importer.showWarning(name + "StyleNotSupported", "The style '" + name + "' is not supported.");
|
||||
} else {
|
||||
styleValues.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return styleValues;
|
||||
}
|
||||
|
||||
private <E> E getValue(Element element, String name) {
|
||||
return getValue(element, name, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <E> E getValue(Element element, String name, boolean inherit) {
|
||||
Map<String, String> styleValues = getStyleAttributeValues(element);
|
||||
if (styleValues.containsKey(name)) {
|
||||
String value = styleValues.get(name);
|
||||
if ("inherit".equals(value)) {
|
||||
if (element.getParentNode() instanceof Element) {
|
||||
return getValue((Element) element.getParentNode(), name, true);
|
||||
}
|
||||
} else {
|
||||
Object result = getStyleValue(this, name, value);
|
||||
if (result != null) {
|
||||
return (E) result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (element.hasAttribute(name)) {
|
||||
String value = element.getAttribute(name).trim();
|
||||
if ("inherit".equals(value)) {
|
||||
if (element.getParentNode() instanceof Element) {
|
||||
return getValue((Element) element.getParentNode(), name, true);
|
||||
}
|
||||
} else {
|
||||
Object result = getStyleValue(this, name, value);
|
||||
if (result != null) {
|
||||
return (E) result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SvgStyleProperty p = SvgStyleProperty.getByName(name);
|
||||
if (inherit || p.isInherited() && element.getParentNode() instanceof Element) {
|
||||
return getValue((Element) element.getParentNode(), name);
|
||||
}
|
||||
|
||||
return (E) p.getInitialValue();
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return getValue(element, "color");
|
||||
}
|
||||
|
||||
public SvgFill getFill() {
|
||||
return getValue(element, "fill");
|
||||
}
|
||||
|
||||
public double getFillOpacity() {
|
||||
return getValue(element, "fill-opacity");
|
||||
}
|
||||
|
||||
public SvgFill getStroke() {
|
||||
return getValue(element, "stroke");
|
||||
}
|
||||
|
||||
public double getStrokeWidth() {
|
||||
return getValue(element, "stroke-width");
|
||||
}
|
||||
|
||||
public double getStrokeOpacity() {
|
||||
return getValue(element, "stroke-opacity");
|
||||
}
|
||||
|
||||
public SvgLineCap getStrokeLineCap() {
|
||||
return getValue(element, "stroke-linecap");
|
||||
}
|
||||
|
||||
public SvgLineJoin getStrokeLineJoin() {
|
||||
return getValue(element, "stroke-linejoin");
|
||||
}
|
||||
|
||||
public double getStrokeMiterLimit() {
|
||||
return getValue(element, "stroke-miterlimit");
|
||||
}
|
||||
|
||||
public double getOpacity() {
|
||||
return getValue(element, "opacity");
|
||||
}
|
||||
|
||||
public Color getStopColor() {
|
||||
return getValue(element, "stop-color");
|
||||
}
|
||||
|
||||
public double getStopOpacity() {
|
||||
return getValue(element, "stop-opacity");
|
||||
}
|
||||
|
||||
public SvgFill getFillWithOpacity() {
|
||||
SvgFill fill = getFill();
|
||||
if (fill == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(fill instanceof SvgColor)) {
|
||||
return fill;
|
||||
}
|
||||
Color fillColor = ((SvgColor) fill).color;
|
||||
|
||||
int opacity = (int) Math.round(getOpacity() * getFillOpacity() * 255);
|
||||
if (opacity > 255) {
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
if (opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
if (opacity == 255) {
|
||||
return fill;
|
||||
}
|
||||
|
||||
return new SvgColor(fillColor.getRed(), fillColor.getGreen(), fillColor.getBlue(), opacity);
|
||||
}
|
||||
|
||||
public SvgFill getStrokeFillWithOpacity() {
|
||||
SvgFill strokeFill = getStroke();
|
||||
if (strokeFill == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(strokeFill instanceof SvgColor)) {
|
||||
return strokeFill;
|
||||
}
|
||||
Color strokeFillColor = ((SvgColor) strokeFill).color;
|
||||
|
||||
int opacity = (int) Math.round(getOpacity() * getStopOpacity() * 255);
|
||||
if (opacity > 255) {
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
if (opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
if (opacity == 255) {
|
||||
return strokeFill;
|
||||
}
|
||||
|
||||
return new SvgColor(strokeFillColor.getRed(), strokeFillColor.getGreen(), strokeFillColor.getBlue(), opacity);
|
||||
}
|
||||
|
||||
public SvgFill getStrokeColorWithOpacity() {
|
||||
SvgFill strokeFill = getStroke();
|
||||
if (strokeFill == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(strokeFill instanceof SvgColor)) {
|
||||
return strokeFill;
|
||||
}
|
||||
|
||||
Color strokeColor = ((SvgColor) strokeFill).color;
|
||||
|
||||
int opacity = (int) Math.round(getOpacity() * getStrokeOpacity() * 255);
|
||||
if (opacity == 255) {
|
||||
return strokeFill;
|
||||
}
|
||||
|
||||
return new SvgColor(strokeColor.getRed(), strokeColor.getGreen(), strokeColor.getBlue(), opacity);
|
||||
}
|
||||
|
||||
//FIXME - matrices
|
||||
private SvgFill parseGradient(Map<String, Element> idMap, Element el) {
|
||||
SvgGradientUnits gradientUnits = null;
|
||||
String gradientTransform = null;
|
||||
SvgSpreadMethod spreadMethod = null;
|
||||
SvgInterpolation interpolation = null;
|
||||
|
||||
String x1 = null;
|
||||
String y1 = null;
|
||||
String x2 = null;
|
||||
String y2 = null;
|
||||
|
||||
String cx = null;
|
||||
String cy = null;
|
||||
String fx = null;
|
||||
String fy = null;
|
||||
String r = null;
|
||||
|
||||
List<SvgStop> stops = new ArrayList<>();
|
||||
//inheritance:
|
||||
if (el.hasAttribute("xlink:href")) {
|
||||
String parent = el.getAttribute("xlink:href");
|
||||
if (parent.startsWith("#")) {
|
||||
String parentId = parent.substring(1);
|
||||
Element parent_el = idMap.get(parentId);
|
||||
if (parent_el == null) {
|
||||
importer.showWarning("fillNotSupported", "Parent gradient not found.");
|
||||
return new SvgColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
|
||||
}
|
||||
|
||||
if ("linearGradient".equals(el.getTagName()) && parent_el.getTagName().equals(el.getTagName())) {
|
||||
SvgLinearGradient parentFill = (SvgLinearGradient) parseGradient(idMap, parent_el);
|
||||
gradientUnits = parentFill.gradientUnits;
|
||||
gradientTransform = parentFill.gradientTransform;
|
||||
spreadMethod = parentFill.spreadMethod;
|
||||
|
||||
x1 = parentFill.x1;
|
||||
y1 = parentFill.y1;
|
||||
x2 = parentFill.x2;
|
||||
y2 = parentFill.y2;
|
||||
interpolation = parentFill.interpolation;
|
||||
stops = parentFill.stops;
|
||||
}
|
||||
if ("radialGradient".equals(el.getTagName()) && parent_el.getTagName().equals(el.getTagName())) {
|
||||
SvgRadialGradient parentFill = (SvgRadialGradient) parseGradient(idMap, parent_el);
|
||||
gradientUnits = parentFill.gradientUnits;
|
||||
gradientTransform = parentFill.gradientTransform;
|
||||
spreadMethod = parentFill.spreadMethod;
|
||||
|
||||
cx = parentFill.cx;
|
||||
cy = parentFill.cy;
|
||||
fx = parentFill.fx;
|
||||
fy = parentFill.fy;
|
||||
r = parentFill.r;
|
||||
interpolation = parentFill.interpolation;
|
||||
stops = parentFill.stops;
|
||||
}
|
||||
|
||||
} else {
|
||||
importer.showWarning("fillNotSupported", "Parent gradient invalid.");
|
||||
return new SvgColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
|
||||
}
|
||||
}
|
||||
|
||||
if (el.hasAttribute("gradientUnits")) {
|
||||
switch (el.getAttribute("gradientUnits")) {
|
||||
case "userSpaceOnUse":
|
||||
gradientUnits = SvgGradientUnits.USER_SPACE_ON_USE;
|
||||
break;
|
||||
case "objectBoundingBox":
|
||||
gradientUnits = SvgGradientUnits.OBJECT_BOUNDING_BOX;
|
||||
break;
|
||||
default:
|
||||
importer.showWarning("fillNotSupported", "Unsupported gradientUnits: " + el.getAttribute("gradientUnits"));
|
||||
return new SvgColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
|
||||
}
|
||||
|
||||
}
|
||||
if (el.hasAttribute("gradientTransform")) {
|
||||
gradientTransform = el.getAttribute("gradientTransform");
|
||||
}
|
||||
if (el.hasAttribute("spreadMethod")) {
|
||||
switch (el.getAttribute("spreadMethod")) {
|
||||
case "pad":
|
||||
spreadMethod = SvgSpreadMethod.PAD;
|
||||
break;
|
||||
case "reflect":
|
||||
spreadMethod = SvgSpreadMethod.REFLECT;
|
||||
break;
|
||||
case "repeat":
|
||||
spreadMethod = SvgSpreadMethod.REPEAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (el.hasAttribute("x1")) {
|
||||
x1 = el.getAttribute("x1").trim();
|
||||
}
|
||||
if (el.hasAttribute("y1")) {
|
||||
y1 = el.getAttribute("y1").trim();
|
||||
}
|
||||
if (el.hasAttribute("x2")) {
|
||||
x2 = el.getAttribute("x2").trim();
|
||||
}
|
||||
if (el.hasAttribute("y2")) {
|
||||
y2 = el.getAttribute("y2").trim();
|
||||
}
|
||||
|
||||
if (el.hasAttribute("cx")) {
|
||||
cx = el.getAttribute("cx").trim();
|
||||
}
|
||||
if (el.hasAttribute("cy")) {
|
||||
cy = el.getAttribute("cy").trim();
|
||||
}
|
||||
if (el.hasAttribute("fx")) {
|
||||
fx = el.getAttribute("fx").trim();
|
||||
}
|
||||
if (el.hasAttribute("fy")) {
|
||||
fy = el.getAttribute("fy").trim();
|
||||
}
|
||||
if (el.hasAttribute("r")) {
|
||||
r = el.getAttribute("r").trim();
|
||||
}
|
||||
if (el.hasAttribute("color-interpolation") && interpolation == null) { //prefer inherit
|
||||
switch (el.getAttribute("color-interpolation")) {
|
||||
case "sRGB":
|
||||
interpolation = SvgInterpolation.SRGB;
|
||||
break;
|
||||
case "linearRGB":
|
||||
interpolation = SvgInterpolation.LINEAR_RGB;
|
||||
break;
|
||||
case "auto": //without preference, put SRGB there
|
||||
interpolation = SvgInterpolation.SRGB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (interpolation == null) {
|
||||
interpolation = SvgInterpolation.SRGB;
|
||||
}
|
||||
|
||||
if (gradientUnits == null) {
|
||||
gradientUnits = SvgGradientUnits.OBJECT_BOUNDING_BOX;
|
||||
}
|
||||
if (spreadMethod == null) {
|
||||
spreadMethod = SvgSpreadMethod.PAD;
|
||||
}
|
||||
|
||||
if (x1 == null) {
|
||||
x1 = "0%";
|
||||
}
|
||||
if (y1 == null) {
|
||||
y1 = "0%";
|
||||
}
|
||||
|
||||
if (x2 == null) {
|
||||
x2 = "100%";
|
||||
}
|
||||
if (y2 == null) {
|
||||
y2 = "0%";
|
||||
}
|
||||
|
||||
if (cx == null) {
|
||||
cx = "50%";
|
||||
}
|
||||
if (cy == null) {
|
||||
cy = "50%";
|
||||
}
|
||||
|
||||
if (r == null) {
|
||||
r = "50%";
|
||||
}
|
||||
if (fx == null) {
|
||||
fx = cx;
|
||||
}
|
||||
if (fy == null) {
|
||||
fy = cy;
|
||||
}
|
||||
|
||||
NodeList stopNodes = el.getElementsByTagName("stop");
|
||||
boolean stopsCleared = false;
|
||||
for (int i = 0; i < stopNodes.getLength(); i++) {
|
||||
Node node = stopNodes.item(i);
|
||||
if (node instanceof Element) {
|
||||
Element stopEl = (Element) node;
|
||||
SvgStyle newStyle = new SvgStyle(importer, idMap, stopEl);
|
||||
|
||||
String offsetStr = stopEl.getAttribute("offset");
|
||||
double offset = importer.parseNumberOrPercent(offsetStr);
|
||||
Color color = newStyle.getStopColor();
|
||||
if (color == null) {
|
||||
color = Color.BLACK;
|
||||
}
|
||||
|
||||
int alpha = (int) Math.round(newStyle.getStopOpacity() * 255);
|
||||
color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
|
||||
if (!stopsCleared) { //It has some stop nodes -> remove all inherited stops
|
||||
stopsCleared = true;
|
||||
stops = new ArrayList<>();
|
||||
}
|
||||
stops.add(new SvgStop(color, offset));
|
||||
}
|
||||
}
|
||||
|
||||
if ("linearGradient".equals(el.getTagName())) {
|
||||
SvgLinearGradient ret = new SvgLinearGradient();
|
||||
ret.x1 = x1;
|
||||
ret.y1 = y1;
|
||||
ret.x2 = x2;
|
||||
ret.y2 = y2;
|
||||
ret.spreadMethod = spreadMethod;
|
||||
ret.gradientTransform = gradientTransform;
|
||||
ret.gradientUnits = gradientUnits;
|
||||
ret.stops = fixStops(stops);
|
||||
ret.interpolation = interpolation;
|
||||
return ret;
|
||||
} else if ("radialGradient".equals(el.getTagName())) {
|
||||
SvgRadialGradient ret = new SvgRadialGradient();
|
||||
ret.cx = cx;
|
||||
ret.cy = cy;
|
||||
ret.fx = fx;
|
||||
ret.fy = fy;
|
||||
ret.r = r;
|
||||
ret.spreadMethod = spreadMethod;
|
||||
ret.gradientTransform = gradientTransform;
|
||||
ret.gradientUnits = gradientUnits;
|
||||
ret.stops = fixStops(stops);
|
||||
ret.interpolation = interpolation;
|
||||
return ret;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<SvgStop> fixStops(List<SvgStop> stops) {
|
||||
if (stops.isEmpty()) {
|
||||
stops.add(new SvgStop(SvgTransparentFill.INSTANCE.toColor(), 0));
|
||||
stops.add(new SvgStop(SvgTransparentFill.INSTANCE.toColor(), 1));
|
||||
} else if (stops.size() == 1) {
|
||||
SvgStop stop0 = stops.get(0);
|
||||
stop0.offset = 0;
|
||||
stops.add(new SvgStop(stop0.color, 1));
|
||||
}
|
||||
|
||||
double offset = 0;
|
||||
for (SvgStop stop : stops) {
|
||||
if (stop.offset < offset) {
|
||||
stop.offset = offset;
|
||||
}
|
||||
|
||||
if (stop.offset > 1) {
|
||||
stop.offset = 1;
|
||||
}
|
||||
|
||||
offset = stop.offset;
|
||||
}
|
||||
|
||||
if (Math.abs(offset - 1) > epsilon) {
|
||||
stops.add(new SvgStop(stops.get(stops.size() - 1).color, 1));
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
private SvgFill parseFill(Map<String, Element> idMap, String fillStr) {
|
||||
if (fillStr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (fillStr.equals("none")) {
|
||||
return SvgTransparentFill.INSTANCE;
|
||||
}
|
||||
|
||||
Pattern idPat = Pattern.compile("url\\(#([^)]+)\\).*");
|
||||
java.util.regex.Matcher mPat = idPat.matcher(fillStr);
|
||||
|
||||
if (mPat.matches()) {
|
||||
String elementId = mPat.group(1);
|
||||
Element e = idMap.get(elementId);
|
||||
if (e != null) {
|
||||
String tagName = e.getTagName();
|
||||
if ("linearGradient".equals(tagName)) {
|
||||
return parseGradient(idMap, e);
|
||||
}
|
||||
|
||||
if ("radialGradient".equals(tagName)) {
|
||||
return parseGradient(idMap, e);
|
||||
}
|
||||
|
||||
if ("pattern".equals(tagName)) {
|
||||
Element element = null;
|
||||
NodeList childNodes = e.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
if (childNodes.item(i) instanceof Element) {
|
||||
if (element != null) {
|
||||
element = null;
|
||||
break;
|
||||
}
|
||||
|
||||
element = (Element) childNodes.item(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (element != null && "image".equals(element.getTagName())) {
|
||||
String attr = element.getAttribute("xlink:href").trim();
|
||||
// this is ugly, but supports the format which is exported by FFDec
|
||||
if (attr.startsWith("data:image/") && attr.contains("base64,")) {
|
||||
String base64 = attr.substring(attr.indexOf("base64,") + 7);
|
||||
byte[] data = Helper.base64StringToByteArray(base64);
|
||||
try {
|
||||
ImageTag imageTag = new ShapeImporter().addImage(importer.shapeTag, data, 0);
|
||||
SvgBitmapFill bitmapFill = new SvgBitmapFill();
|
||||
bitmapFill.characterId = imageTag.characterID;
|
||||
if (e.hasAttribute("patternTransform")) {
|
||||
bitmapFill.patternTransform = e.getAttribute("patternTransform");
|
||||
}
|
||||
|
||||
return bitmapFill;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ShapeImporter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
importer.showWarning("fillNotSupported", "Unknown fill style. Random color assigned.");
|
||||
return new SvgColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
|
||||
}
|
||||
|
||||
fillStr = fillStr.substring(elementId.length() + 6).trim(); // remove url(#...)
|
||||
}
|
||||
|
||||
SvgColor result = SvgColor.parse(fillStr);
|
||||
if (result == null) {
|
||||
importer.showWarning("fillNotSupported", "Unknown fill style. Random color assigned.");
|
||||
return new SvgColor(random.nextInt(256), random.nextInt(256), random.nextInt(256));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object getStyleValue(SvgStyle style, String name, String value) {
|
||||
if (value == null || value.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (name) {
|
||||
case "color": {
|
||||
Color color = SvgColor.parse(value).toColor();
|
||||
if (color != null) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "fill": {
|
||||
if ("currentColor".equals(value)) {
|
||||
return new SvgColor(style.getColor());
|
||||
} else {
|
||||
SvgFill fill = parseFill(idMap, value);
|
||||
if (fill != null) {
|
||||
return fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "fill-opacity": {
|
||||
double opacity = Double.parseDouble(value);
|
||||
return opacity;
|
||||
}
|
||||
case "stroke": {
|
||||
if ("currentColor".equals(value)) {
|
||||
return new SvgColor(style.getColor());
|
||||
} else {
|
||||
SvgFill stroke = parseFill(idMap, value);
|
||||
if (stroke != null) {
|
||||
return stroke;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "stroke-width": {
|
||||
double strokeWidth = Double.parseDouble(value);
|
||||
return strokeWidth;
|
||||
}
|
||||
case "stroke-opacity": {
|
||||
double opacity = Double.parseDouble(value);
|
||||
return opacity;
|
||||
}
|
||||
case "stroke-linecap": {
|
||||
switch (value) {
|
||||
case "butt":
|
||||
return SvgLineCap.BUTT;
|
||||
case "round":
|
||||
return SvgLineCap.ROUND;
|
||||
case "square":
|
||||
return SvgLineCap.SQUARE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "stroke-linejoin": {
|
||||
switch (value) {
|
||||
case "miter":
|
||||
return SvgLineJoin.MITER;
|
||||
case "round":
|
||||
return SvgLineJoin.ROUND;
|
||||
case "bevel":
|
||||
return SvgLineJoin.BEVEL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "stroke-miterlimit": {
|
||||
double strokeMiterLimit = Double.parseDouble(value);
|
||||
return strokeMiterLimit;
|
||||
}
|
||||
case "opacity": {
|
||||
double opacity = Double.parseDouble(value);
|
||||
return opacity;
|
||||
}
|
||||
case "stop-color": {
|
||||
if ("currentColor".equals(value)) {
|
||||
return style.getColor();
|
||||
} else {
|
||||
return SvgColor.parse(value).toColor();
|
||||
}
|
||||
}
|
||||
case "stop-opacity": {
|
||||
double stopOpacity = Double.parseDouble(value);
|
||||
return stopOpacity;
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SvgStyleProperty {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final boolean inherited;
|
||||
|
||||
private final Object initial;
|
||||
|
||||
public SvgStyleProperty(String name, boolean inherited, Object initial) {
|
||||
this.name = name;
|
||||
this.inherited = inherited;
|
||||
this.initial = initial;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isInherited() {
|
||||
return inherited;
|
||||
}
|
||||
|
||||
public Object getInitialValue() {
|
||||
return initial;
|
||||
}
|
||||
|
||||
private static final Map<String, SvgStyleProperty> properties;
|
||||
|
||||
static {
|
||||
Map<String, SvgStyleProperty> p = new HashMap<>();
|
||||
p.put("color", new SvgStyleProperty("color", true, Color.BLACK /* depends on user agent */));
|
||||
p.put("fill", new SvgStyleProperty("fill", true, new SvgColor(Color.BLACK)));
|
||||
p.put("fill-opacity", new SvgStyleProperty("fill-opacity", true, 1.0));
|
||||
p.put("stroke", new SvgStyleProperty("stroke", true, null));
|
||||
p.put("stroke-width", new SvgStyleProperty("stroke-width", true, 1.0));
|
||||
p.put("stroke-opacity", new SvgStyleProperty("stroke-opacity", true, 1.0));
|
||||
p.put("stroke-linecap", new SvgStyleProperty("stroke-linecap", true, SvgLineCap.BUTT));
|
||||
p.put("stroke-linejoin", new SvgStyleProperty("stroke-linejoin", true, SvgLineJoin.MITER));
|
||||
p.put("stroke-miterlimit", new SvgStyleProperty("stroke-miterlimit", true, 4.0));
|
||||
p.put("opacity", new SvgStyleProperty("opacity", false, 1.0));
|
||||
p.put("stop-color", new SvgStyleProperty("stop-color", false, Color.BLACK));
|
||||
p.put("stop-opacity", new SvgStyleProperty("stop-opacity", false, 1.0));
|
||||
properties = p;
|
||||
}
|
||||
|
||||
public static Collection<SvgStyleProperty> getProperties() {
|
||||
return properties.values();
|
||||
}
|
||||
|
||||
public static SvgStyleProperty getByName(String name) {
|
||||
return properties.get(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.importers.svg;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
class SvgTransparentFill extends SvgFill {
|
||||
|
||||
private static final Color TRANSPARENT = new Color(0, true);
|
||||
|
||||
public static SvgTransparentFill INSTANCE = new SvgTransparentFill();
|
||||
|
||||
private SvgTransparentFill() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color toColor() {
|
||||
return TRANSPARENT;
|
||||
}
|
||||
}
|
||||
@@ -80,12 +80,6 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
*/
|
||||
public List<BUTTONCONDACTION> actions = new ArrayList<>();
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -258,40 +252,7 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
protected void initTimeline(Timeline timeline) {
|
||||
int maxDepth = 0;
|
||||
Frame frameUp = new Frame(timeline, 0);
|
||||
Frame frameDown = new Frame(timeline, 0);
|
||||
|
||||
@@ -78,12 +78,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
@@ -322,21 +316,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
return writer;
|
||||
@@ -358,27 +337,9 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, new ArrayList<>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, new ArrayList<>(), buttonId, getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimeline(Timeline timeline) {
|
||||
protected void initTimeline(Timeline timeline) {
|
||||
ColorTransform clrTrans = null;
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DefineButtonCxformTag) {
|
||||
DefineButtonCxformTag cx = (DefineButtonCxformTag) t;
|
||||
clrTrans = cx.buttonColorTransform;
|
||||
@@ -417,17 +378,23 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
}
|
||||
|
||||
timeline.addFrame(frameUp);
|
||||
|
||||
if (frameOver.layers.isEmpty()) {
|
||||
frameOver = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameOver);
|
||||
|
||||
if (frameDown.layers.isEmpty()) {
|
||||
frameDown = frameOver;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameDown);
|
||||
|
||||
if (frameHit.layers.isEmpty()) {
|
||||
frameHit = frameUp;
|
||||
}
|
||||
|
||||
timeline.addFrame(frameHit);
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ public class DefineFont2Tag extends FontTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
public String getCharacters() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i : codeTable) {
|
||||
ret.append((char) i);
|
||||
|
||||
@@ -396,12 +396,12 @@ public class DefineFont3Tag extends FontTag {
|
||||
public void addCharacter(char character, Font font) {
|
||||
|
||||
//Font Align Zones will be removed as adding new character zones is not supported:-(
|
||||
for (int i = 0; i < swf.tags.size(); i++) {
|
||||
Tag t = swf.tags.get(i);
|
||||
for (int i = 0; i < swf.getTags().size(); i++) {
|
||||
Tag t = swf.getTags().get(i);
|
||||
if (t instanceof DefineFontAlignZonesTag) {
|
||||
DefineFontAlignZonesTag fa = (DefineFontAlignZonesTag) t;
|
||||
if (fa.fontID == fontId) {
|
||||
swf.tags.remove(i);
|
||||
swf.removeTag(t);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
@@ -467,7 +467,7 @@ public class DefineFont3Tag extends FontTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
public String getCharacters() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i : codeTable) {
|
||||
ret.append((char) i);
|
||||
|
||||
@@ -139,7 +139,7 @@ public class DefineFontTag extends FontTag {
|
||||
|
||||
private void ensureFontInfo() {
|
||||
if (fontInfoTag == null) {
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DefineFontInfoTag) {
|
||||
if (((DefineFontInfoTag) t).fontId == fontId) {
|
||||
fontInfoTag = (DefineFontInfoTag) t;
|
||||
@@ -331,7 +331,7 @@ public class DefineFontTag extends FontTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
public String getCharacters() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ensureFontInfo();
|
||||
if (fontInfoTag != null) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -33,6 +34,8 @@ import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFField;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
@@ -74,7 +77,11 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
/**
|
||||
* A series of tags
|
||||
*/
|
||||
public List<Tag> subTags;
|
||||
@SWFField
|
||||
private List<Tag> subTags;
|
||||
|
||||
@Internal
|
||||
public ReadOnlyTagList readOnlyTags;
|
||||
|
||||
public boolean hasEndTag;
|
||||
|
||||
@@ -121,6 +128,7 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
subTags.remove(subTags.size() - 1);
|
||||
}
|
||||
this.subTags = subTags;
|
||||
readOnlyTags = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +141,7 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
public void getData(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(spriteId);
|
||||
sos.writeUI16(frameCount);
|
||||
sos.writeTags(subTags);
|
||||
sos.writeTags(getTags());
|
||||
if (hasEndTag) {
|
||||
sos.writeUI16(0);
|
||||
}
|
||||
@@ -142,7 +150,7 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline == null) {
|
||||
timeline = new Timeline(swf, this, subTags, spriteId, getRect());
|
||||
timeline = new Timeline(swf, this, spriteId, getRect());
|
||||
}
|
||||
return timeline;
|
||||
}
|
||||
@@ -150,7 +158,7 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, subTags, spriteId, getRect());
|
||||
timeline.reset(swf, this, spriteId, getRect());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +216,7 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
ret = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
HashMap<Integer, Integer> depthMap = new HashMap<>();
|
||||
boolean foundSomething = false;
|
||||
for (Tag t : subTags) {
|
||||
for (Tag t : getTags()) {
|
||||
MATRIX m = null;
|
||||
int characterId = -1;
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
@@ -268,14 +276,10 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Tag> getSubTags() {
|
||||
return subTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean value) {
|
||||
if (!value) {
|
||||
for (Tag subTag : subTags) {
|
||||
for (Tag subTag : getTags()) {
|
||||
subTag.setModified(false);
|
||||
}
|
||||
}
|
||||
@@ -283,17 +287,50 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
super.setModified(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
if (readOnlyTags == null) {
|
||||
readOnlyTags = new ReadOnlyTagList(subTags);
|
||||
}
|
||||
|
||||
return readOnlyTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(int index) {
|
||||
setModified(true);
|
||||
subTags.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(Tag tag) {
|
||||
setModified(true);
|
||||
subTags.remove(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
setModified(true);
|
||||
subTags.add(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
setModified(true);
|
||||
subTags.add(index, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOriginalData() {
|
||||
super.createOriginalData();
|
||||
for (Tag subTag : subTags) {
|
||||
for (Tag subTag : getTags()) {
|
||||
subTag.createOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (Tag t : subTags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof CharacterIdTag) {
|
||||
needed.add(((CharacterIdTag) t).getCharacterId());
|
||||
}
|
||||
@@ -374,11 +411,15 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
if (super.isModified()) {
|
||||
return true;
|
||||
}
|
||||
for (Tag t : subTags) {
|
||||
for (Tag t : getTags()) {
|
||||
if (t.isModified()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clearReadOnlyListCache() {
|
||||
readOnlyTags = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
if (deep) {
|
||||
if (this instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) this;
|
||||
for (Tag subTag : sprite.subTags) {
|
||||
for (Tag subTag : sprite.getTags()) {
|
||||
subTag.setSwf(swf);
|
||||
}
|
||||
}
|
||||
@@ -426,6 +426,10 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
return SWFInputStream.resolveTag(copy, 0, false, true, false);
|
||||
}
|
||||
|
||||
public boolean canUndo() {
|
||||
return originalRange != null && isModified();
|
||||
}
|
||||
|
||||
public void undo() throws InterruptedException, IOException {
|
||||
byte[] data = getOriginalData();
|
||||
if (data == null) { //If the tag is newly created in GUI it has no original data
|
||||
@@ -534,8 +538,9 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
}
|
||||
|
||||
public void setModified(boolean value) {
|
||||
boolean oldValue = modified;
|
||||
modified = value;
|
||||
if (value) {
|
||||
if (value && oldValue != value) {
|
||||
informListeners();
|
||||
}
|
||||
}
|
||||
@@ -607,7 +612,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
}
|
||||
|
||||
public void getDependentCharacters(Set<Integer> dependent) {
|
||||
for (Tag tag : swf.tags) {
|
||||
for (Tag tag : swf.getTags()) {
|
||||
if (tag instanceof CharacterTag) {
|
||||
Set<Integer> needed = new HashSet<>();
|
||||
tag.getNeededCharactersDeep(needed);
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButtonSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.timeline.Timeline;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.ColorTransform;
|
||||
@@ -47,6 +49,12 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
|
||||
|
||||
public static int FRAME_HITTEST = 3;
|
||||
|
||||
private Timeline timeline;
|
||||
|
||||
private boolean isSingleFrameInitialized;
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
public ButtonTag(SWF swf, int id, String name, ByteArrayRange data) {
|
||||
super(swf, id, name, data);
|
||||
}
|
||||
@@ -81,7 +89,7 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
|
||||
}
|
||||
|
||||
public DefineButtonSoundTag getSounds() {
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DefineButtonSoundTag) {
|
||||
DefineButtonSoundTag st = (DefineButtonSoundTag) t;
|
||||
if (st.buttonId == getCharacterId()) {
|
||||
@@ -96,4 +104,61 @@ public abstract class ButtonTag extends CharacterTag implements DrawableTag, Tim
|
||||
public void toHtmlCanvas(StringBuilder result, double unitDivisor) {
|
||||
getTimeline().toHtmlCanvas(result, unitDivisor, Arrays.asList(0)); //TODO: handle states?
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
initialiteIsSingleFrame();
|
||||
}
|
||||
return isSingleFrame;
|
||||
}
|
||||
|
||||
private synchronized void initialiteIsSingleFrame() {
|
||||
if (!isSingleFrameInitialized) {
|
||||
isSingleFrame = getTimeline().isSingleFrame();
|
||||
isSingleFrameInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getTimeline() {
|
||||
if (timeline != null) {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
timeline = new Timeline(swf, this, getCharacterId(), getRect());
|
||||
initTimeline(timeline);
|
||||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTimeline() {
|
||||
if (timeline != null) {
|
||||
timeline.reset(swf, this, getCharacterId(), getRect());
|
||||
initTimeline(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void initTimeline(Timeline timeline);
|
||||
|
||||
@Override
|
||||
public ReadOnlyTagList getTags() {
|
||||
return ReadOnlyTagList.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(int index) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTag(Tag tag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
return fontStyle;
|
||||
}
|
||||
|
||||
public abstract String getCharacters(List<Tag> tags);
|
||||
public abstract String getCharacters();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -209,7 +209,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
}
|
||||
|
||||
protected void shiftGlyphIndices(int fontId, int startIndex) {
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
List<TEXTRECORD> textRecords = null;
|
||||
if (t instanceof StaticTextTag) {
|
||||
textRecords = ((StaticTextTag) t).textRecords;
|
||||
@@ -379,7 +379,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
}
|
||||
|
||||
public DefineFontNameTag getFontNameTag() {
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DefineFontNameTag) {
|
||||
DefineFontNameTag dfn = (DefineFontNameTag) t;
|
||||
if (dfn.fontId == getFontId()) {
|
||||
|
||||
@@ -21,7 +21,6 @@ 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.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LANGCODE;
|
||||
@@ -316,7 +315,7 @@ public final class DefineCompactedFont extends FontTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters(List<Tag> tags) {
|
||||
public String getCharacters() {
|
||||
FontType ft = fonts.get(0);
|
||||
StringBuilder ret = new StringBuilder(ft.glyphInfo.size());
|
||||
for (GlyphInfoType gi : ft.glyphInfo) {
|
||||
|
||||
@@ -70,14 +70,10 @@ public class Timeline {
|
||||
|
||||
public Timelined timelined;
|
||||
|
||||
public Tag parentTag;
|
||||
|
||||
public int maxDepth;
|
||||
|
||||
public int fontFrameNum = -1;
|
||||
|
||||
public List<Tag> tags;
|
||||
|
||||
private final List<Frame> frames = new ArrayList<>();
|
||||
|
||||
private final Map<Integer, Integer> depthMaxFrame = new HashMap<>();
|
||||
@@ -135,11 +131,15 @@ public class Timeline {
|
||||
return soundStramBlocks.get(head);
|
||||
}
|
||||
|
||||
public void reset(SWF swf) {
|
||||
reset(swf, null, swf.tags, 0, swf.displayRect);
|
||||
public Tag getParentTag() {
|
||||
return timelined instanceof Tag ? (Tag) timelined : null;
|
||||
}
|
||||
|
||||
public void reset(SWF swf, Tag parentTag, List<Tag> tags, int id, RECT displayRect) {
|
||||
public void reset(SWF swf) {
|
||||
reset(swf, swf, 0, swf.displayRect);
|
||||
}
|
||||
|
||||
public void reset(SWF swf, Timelined timelined, int id, RECT displayRect) {
|
||||
initialized = false;
|
||||
frames.clear();
|
||||
depthMaxFrame.clear();
|
||||
@@ -152,9 +152,7 @@ public class Timeline {
|
||||
this.swf = swf;
|
||||
this.displayRect = displayRect;
|
||||
this.frameRate = swf.frameRate;
|
||||
this.timelined = parentTag == null ? swf : (Timelined) parentTag;
|
||||
this.parentTag = parentTag;
|
||||
this.tags = tags;
|
||||
this.timelined = timelined;
|
||||
as2RootPackage = new AS2Package(null, null, swf);
|
||||
}
|
||||
|
||||
@@ -207,17 +205,15 @@ public class Timeline {
|
||||
}
|
||||
|
||||
public Timeline(SWF swf) {
|
||||
this(swf, null, swf.tags, 0, swf.displayRect);
|
||||
this(swf, swf, 0, swf.displayRect);
|
||||
}
|
||||
|
||||
public Timeline(SWF swf, Tag parentTag, List<Tag> tags, int id, RECT displayRect) {
|
||||
public Timeline(SWF swf, Timelined timelined, int id, RECT displayRect) {
|
||||
this.id = id;
|
||||
this.swf = swf;
|
||||
this.displayRect = displayRect;
|
||||
this.frameRate = swf.frameRate;
|
||||
this.timelined = parentTag == null ? swf : (Timelined) parentTag;
|
||||
this.parentTag = parentTag;
|
||||
this.tags = tags;
|
||||
this.timelined = timelined;
|
||||
as2RootPackage = new AS2Package(null, null, swf);
|
||||
}
|
||||
|
||||
@@ -226,7 +222,7 @@ public class Timeline {
|
||||
Frame frame = new Frame(this, frameIdx++);
|
||||
frame.layersChanged = true;
|
||||
boolean newFrameNeeded = false;
|
||||
for (Tag t : tags) {
|
||||
for (Tag t : timelined.getTags()) {
|
||||
boolean isNested = ShowFrameTag.isNestedTagType(t.getId());
|
||||
if (isNested) {
|
||||
newFrameNeeded = true;
|
||||
@@ -348,9 +344,9 @@ public class Timeline {
|
||||
calculateMaxDepthFrames();
|
||||
|
||||
createASPackages();
|
||||
if (parentTag == null) {
|
||||
if (timelined instanceof SWF) {
|
||||
// popuplate only for main timeline
|
||||
populateSoundStreamBlocks(0, tags);
|
||||
populateSoundStreamBlocks(0, timelined.getTags());
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
@@ -433,7 +429,7 @@ public class Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
private void populateSoundStreamBlocks(int containerId, List<Tag> tags) {
|
||||
private void populateSoundStreamBlocks(int containerId, Iterable<Tag> tags) {
|
||||
List<SoundStreamBlockTag> blocks = null;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundStreamHeadTypeTag) {
|
||||
@@ -446,7 +442,7 @@ public class Timeline {
|
||||
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
populateSoundStreamBlocks(sprite.getCharacterId(), sprite.getSubTags());
|
||||
populateSoundStreamBlocks(sprite.getCharacterId(), sprite.getTags());
|
||||
}
|
||||
|
||||
if (blocks == null) {
|
||||
@@ -487,8 +483,8 @@ public class Timeline {
|
||||
|
||||
public boolean replaceCharacter(int oldCharacterId, int newCharacterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
for (int i = 0; i < timelined.getTags().size(); i++) {
|
||||
Tag t = timelined.getTags().get(i);
|
||||
if (t instanceof CharacterIdTag && ((CharacterIdTag) t).getCharacterId() == oldCharacterId) {
|
||||
((CharacterIdTag) t).setCharacterId(newCharacterId);
|
||||
((Tag) t).setModified(true);
|
||||
@@ -500,10 +496,10 @@ public class Timeline {
|
||||
|
||||
public boolean removeCharacter(int characterId) {
|
||||
boolean modified = false;
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
for (int i = 0; i < timelined.getTags().size(); i++) {
|
||||
Tag t = timelined.getTags().get(i);
|
||||
if (t instanceof CharacterIdTag && ((CharacterIdTag) t).getCharacterId() == characterId) {
|
||||
tags.remove(i);
|
||||
timelined.removeTag(i);
|
||||
i--;
|
||||
modified = true;
|
||||
}
|
||||
@@ -726,7 +722,7 @@ public class Timeline {
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Timeline) {
|
||||
Timeline timelineObj = (Timeline) obj;
|
||||
return timelined.equals(timelineObj.timelined) && parentTag == timelineObj.parentTag;
|
||||
return timelined.equals(timelineObj.timelined);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
|
||||
/**
|
||||
@@ -27,4 +29,16 @@ public interface Timelined extends BoundedTag {
|
||||
public Timeline getTimeline();
|
||||
|
||||
public void resetTimeline();
|
||||
|
||||
public void setModified(boolean value);
|
||||
|
||||
public ReadOnlyTagList getTags();
|
||||
|
||||
public void removeTag(int index);
|
||||
|
||||
public void removeTag(Tag tag);
|
||||
|
||||
public void addTag(Tag tag);
|
||||
|
||||
public void addTag(int index, Tag tag);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.xfl;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFCompression;
|
||||
@@ -216,8 +217,8 @@ public class XFLConverter {
|
||||
+ "<SolidColor color=\"")
|
||||
.append(ls.color.toHexRGB()).append("\"")
|
||||
.append(shapeNum == 3 ? " alpha=\"" + ((RGBA) ls.color).getAlphaFloat() + "\"" : "").append(" />"
|
||||
+ "</fill>"
|
||||
+ "</SolidStroke>");
|
||||
+ "</fill>"
|
||||
+ "</SolidStroke>");
|
||||
}
|
||||
|
||||
private static void convertLineStyle(HashMap<Integer, CharacterTag> characters, LINESTYLE2 ls, int shapeNum, StringBuilder ret) {
|
||||
@@ -759,7 +760,7 @@ public class XFLConverter {
|
||||
return layers;
|
||||
}
|
||||
|
||||
private static int getLayerCount(List<Tag> tags) {
|
||||
private static int getLayerCount(ReadOnlyTagList tags) {
|
||||
int maxDepth = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
@@ -776,11 +777,11 @@ public class XFLConverter {
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
private static void walkShapeUsages(List<Tag> timeLineTags, HashMap<Integer, CharacterTag> characters, HashMap<Integer, Integer> usages) {
|
||||
private static void walkShapeUsages(ReadOnlyTagList timeLineTags, HashMap<Integer, CharacterTag> characters, HashMap<Integer, Integer> usages) {
|
||||
for (Tag t : timeLineTags) {
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) t;
|
||||
walkShapeUsages(sprite.subTags, characters, usages);
|
||||
walkShapeUsages(sprite.getTags(), characters, usages);
|
||||
}
|
||||
if (t instanceof PlaceObjectTypeTag) {
|
||||
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
|
||||
@@ -811,7 +812,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Integer> getNonLibraryShapes(List<Tag> tags, HashMap<Integer, CharacterTag> characters) {
|
||||
private static List<Integer> getNonLibraryShapes(ReadOnlyTagList tags, HashMap<Integer, CharacterTag> characters) {
|
||||
HashMap<Integer, Integer> usages = new HashMap<>();
|
||||
walkShapeUsages(tags, characters, usages);
|
||||
List<Integer> ret = new ArrayList<>();
|
||||
@@ -829,7 +830,7 @@ public class XFLConverter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static HashMap<Integer, CharacterTag> getCharacters(List<Tag> tags) {
|
||||
private static HashMap<Integer, CharacterTag> getCharacters(ReadOnlyTagList tags) {
|
||||
HashMap<Integer, CharacterTag> ret = new HashMap<>();
|
||||
int maxId = 0;
|
||||
for (Tag t : tags) {
|
||||
@@ -1029,7 +1030,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertSymbolInstance(String name, MATRIX matrix, ColorTransform colorTransform, boolean cacheAsBitmap, int blendMode, List<FILTER> filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap<Integer, CharacterTag> characters, List<Tag> tags, FLAVersion flaVersion) {
|
||||
private static String convertSymbolInstance(String name, MATRIX matrix, ColorTransform colorTransform, boolean cacheAsBitmap, int blendMode, List<FILTER> filters, boolean isVisible, RGBA backgroundColor, CLIPACTIONS clipActions, CharacterTag tag, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, FLAVersion flaVersion) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
if (matrix == null) {
|
||||
matrix = new MATRIX();
|
||||
@@ -1167,7 +1168,7 @@ public class XFLConverter {
|
||||
return date.getTime() / 1000;
|
||||
}
|
||||
|
||||
private static void convertLibrary(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> nonLibraryShapes, String backgroundColor, List<Tag> tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, StringBuilder ret) {
|
||||
private static void convertLibrary(SWF swf, Map<Integer, String> characterVariables, Map<Integer, String> characterClasses, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<Integer, CharacterTag> characters, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, StringBuilder ret) {
|
||||
|
||||
//TODO: Imported assets
|
||||
//linkageImportForRS="true" linkageIdentifier="xxx" linkageURL="yyy.swf"
|
||||
@@ -1303,10 +1304,10 @@ public class XFLConverter {
|
||||
symbolStr.append("</DOMTimeline>");
|
||||
} else if (symbol instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) symbol;
|
||||
if (sprite.subTags.isEmpty()) { //probably AS2 class
|
||||
if (sprite.getTags().isEmpty()) { //probably AS2 class
|
||||
continue;
|
||||
}
|
||||
symbolStr.append(convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getSubTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files));
|
||||
symbolStr.append(convertTimeline(sprite.spriteId, nonLibraryShapes, backgroundColor, tags, sprite.getTags(), characters, "Symbol " + symbol.getCharacterId(), flaVersion, files));
|
||||
} else if (symbol instanceof ShapeTag) {
|
||||
itemIcon = "1";
|
||||
ShapeTag shape = (ShapeTag) symbol;
|
||||
@@ -1632,7 +1633,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertFrame(boolean shapeTween, HashMap<Integer, CharacterTag> characters, List<Tag> tags, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, int duration, String actionScript, String elements, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
private static void convertFrame(boolean shapeTween, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, SoundStreamHeadTypeTag soundStreamHead, StartSoundTag startSound, int frame, int duration, String actionScript, String elements, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
DefineSoundTag sound = null;
|
||||
if (startSound != null) {
|
||||
for (Tag t : tags) {
|
||||
@@ -1759,7 +1760,7 @@ public class XFLConverter {
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
private static void convertFrames(String prevStr, String afterStr, List<Integer> nonLibraryShapes, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, int depth, FLAVersion flaVersion, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
private static void convertFrames(String prevStr, String afterStr, List<Integer> nonLibraryShapes, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, int depth, FLAVersion flaVersion, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
StringBuilder ret2 = new StringBuilder();
|
||||
prevStr += "<frames>";
|
||||
int frame = -1;
|
||||
@@ -1785,7 +1786,7 @@ public class XFLConverter {
|
||||
MorphShapeTag shapeTweener = null;
|
||||
|
||||
//Add ShowFrameTag to the end when there is one last missing
|
||||
List<Tag> timTags = new ArrayList<>(timelineTags);
|
||||
List<Tag> timTags = timelineTags.toArrayList();
|
||||
boolean needsFrameAdd = false;
|
||||
SWF swf = null;
|
||||
for (int i = timTags.size() - 1; i >= 0; i--) {
|
||||
@@ -1933,7 +1934,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertFonts(List<Tag> tags, StringBuilder ret) {
|
||||
private static void convertFonts(ReadOnlyTagList tags, StringBuilder ret) {
|
||||
StringBuilder ret2 = new StringBuilder();
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
@@ -1960,13 +1961,21 @@ public class XFLConverter {
|
||||
}
|
||||
String embedRanges = "";
|
||||
|
||||
String fontChars = font.getCharacters(tags);
|
||||
String fontChars = font.getCharacters();
|
||||
if ("".equals(fontChars)) {
|
||||
continue;
|
||||
}
|
||||
String embeddedCharacters = fontChars;
|
||||
embeddedCharacters = embeddedCharacters.replace("\u00A0", ""); //nonbreak space
|
||||
embeddedCharacters = embeddedCharacters.replace(".", "");
|
||||
embeddedCharacters = embeddedCharacters.replace("\u00A0", ""); // nonbreak space
|
||||
embeddedCharacters = embeddedCharacters.replace(".", ""); // todo: honfika: why?
|
||||
for (char i = 0; i < 32; i++) {
|
||||
if (i == 9 || i == 10 || i == 13) {
|
||||
continue;
|
||||
}
|
||||
|
||||
embeddedCharacters = embeddedCharacters.replace("" + i, ""); // not supported in xml
|
||||
}
|
||||
|
||||
boolean hasAllRanges = false;
|
||||
for (int r = 0; r < CharacterRanges.rangeCount(); r++) {
|
||||
int[] codes = CharacterRanges.rangeCodes(r);
|
||||
@@ -2003,7 +2012,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static String convertActionScriptLayer(int spriteId, List<Tag> tags, List<Tag> timeLineTags, String backgroundColor) {
|
||||
private static String convertActionScriptLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
String script = "";
|
||||
@@ -2065,7 +2074,7 @@ public class XFLConverter {
|
||||
return retStr;
|
||||
}
|
||||
|
||||
private static String convertLabelsLayer(int spriteId, List<Tag> tags, List<Tag> timeLineTags, String backgroundColor) {
|
||||
private static String convertLabelsLayer(int spriteId, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, String backgroundColor) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
int duration = 0;
|
||||
int frame = 0;
|
||||
@@ -2121,7 +2130,7 @@ public class XFLConverter {
|
||||
return retStr;
|
||||
}
|
||||
|
||||
private static void convertSoundLayer(int layerIndex, String backgroundColor, HashMap<Integer, CharacterTag> characters, List<Tag> tags, List<Tag> timeLineTags, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
private static void convertSoundLayer(int layerIndex, String backgroundColor, HashMap<Integer, CharacterTag> characters, ReadOnlyTagList tags, ReadOnlyTagList timeLineTags, HashMap<String, byte[]> files, StringBuilder ret) {
|
||||
StringBuilder ret2 = new StringBuilder();
|
||||
StartSoundTag lastStartSound = null;
|
||||
SoundStreamHeadTypeTag lastSoundStreamHead = null;
|
||||
@@ -2179,7 +2188,7 @@ public class XFLConverter {
|
||||
if (ret2.length() > 0) {
|
||||
ret.append("<DOMLayer name=\"Layer ").append(layerIndex).append("\" color=\"").append(randomOutlineColor()).append("\">"
|
||||
+ "<frames>").append(ret2).append("</frames>"
|
||||
+ "</DOMLayer>");
|
||||
+ "</DOMLayer>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2193,7 +2202,7 @@ public class XFLConverter {
|
||||
return outlineColor.toHexRGB();
|
||||
}
|
||||
|
||||
private static String convertTimeline(int spriteId, List<Integer> nonLibraryShapes, String backgroundColor, List<Tag> tags, List<Tag> timelineTags, HashMap<Integer, CharacterTag> characters, String name, FLAVersion flaVersion, HashMap<String, byte[]> files) {
|
||||
private static String convertTimeline(int spriteId, List<Integer> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, ReadOnlyTagList timelineTags, HashMap<Integer, CharacterTag> characters, String name, FLAVersion flaVersion, HashMap<String, byte[]> files) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("<DOMTimeline name=\"").append(name).append("\">");
|
||||
ret.append("<layers>");
|
||||
@@ -2292,7 +2301,7 @@ public class XFLConverter {
|
||||
}, handler).run();
|
||||
}
|
||||
|
||||
private static Map<Integer, String> getCharacterClasses(List<Tag> tags) {
|
||||
private static Map<Integer, String> getCharacterClasses(ReadOnlyTagList tags) {
|
||||
Map<Integer, String> ret = new HashMap<>();
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SymbolClassTag) {
|
||||
@@ -2307,7 +2316,7 @@ public class XFLConverter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static Map<Integer, String> getCharacterVariables(List<Tag> tags) {
|
||||
private static Map<Integer, String> getCharacterVariables(ReadOnlyTagList tags) {
|
||||
Map<Integer, String> ret = new HashMap<>();
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof ExportAssetsTag) {
|
||||
@@ -2337,7 +2346,7 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
SWF swf = tag.getSwf();
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof CSMTextSettingsTag) {
|
||||
CSMTextSettingsTag c = (CSMTextSettingsTag) t;
|
||||
if (c.textID == tag.getCharacterId()) {
|
||||
@@ -2427,7 +2436,7 @@ public class XFLConverter {
|
||||
fontName = null;
|
||||
textHeight = rec.textHeight;
|
||||
font = swf.getFont(fontId);
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DefineFontNameTag) {
|
||||
if (((DefineFontNameTag) t).fontId == fontId) {
|
||||
fontName = ((DefineFontNameTag) t).fontName;
|
||||
@@ -2552,7 +2561,7 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
if (det.html) {
|
||||
ret.append(convertHTMLText(swf.tags, det, txt));
|
||||
ret.append(convertHTMLText(swf.getTags(), det, txt));
|
||||
} else {
|
||||
ret.append("<DOMTextRun>");
|
||||
ret.append("<characters>").append(xmlString(txt)).append("</characters>");
|
||||
@@ -2571,7 +2580,7 @@ public class XFLConverter {
|
||||
}
|
||||
if (det.hasFont) {
|
||||
String fontName = null;
|
||||
for (Tag u : swf.tags) {
|
||||
for (Tag u : swf.getTags()) {
|
||||
if (u instanceof DefineFontNameTag) {
|
||||
if (((DefineFontNameTag) u).fontId == det.fontId) {
|
||||
fontName = ((DefineFontNameTag) u).fontName;
|
||||
@@ -2677,10 +2686,10 @@ public class XFLConverter {
|
||||
}
|
||||
final HashMap<String, byte[]> files = new HashMap<>();
|
||||
final HashMap<String, byte[]> datfiles = new HashMap<>();
|
||||
HashMap<Integer, CharacterTag> characters = getCharacters(swf.tags);
|
||||
List<Integer> nonLibraryShapes = getNonLibraryShapes(swf.tags, characters);
|
||||
Map<Integer, String> characterClasses = getCharacterClasses(swf.tags);
|
||||
Map<Integer, String> characterVariables = getCharacterVariables(swf.tags);
|
||||
HashMap<Integer, CharacterTag> characters = getCharacters(swf.getTags());
|
||||
List<Integer> nonLibraryShapes = getNonLibraryShapes(swf.getTags(), characters);
|
||||
Map<Integer, String> characterClasses = getCharacterClasses(swf.getTags());
|
||||
Map<Integer, String> characterVariables = getCharacterVariables(swf.getTags());
|
||||
|
||||
String backgroundColor = "#ffffff";
|
||||
SetBackgroundColorTag setBgColorTag = swf.getBackgroundColor();
|
||||
@@ -2701,22 +2710,22 @@ public class XFLConverter {
|
||||
domDocument.append(" height=\"").append(doubleToString(height)).append("\"");
|
||||
}
|
||||
domDocument.append(">");
|
||||
convertFonts(swf.tags, domDocument);
|
||||
convertLibrary(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, swf.tags, characters, files, datfiles, flaVersion, domDocument);
|
||||
convertFonts(swf.getTags(), domDocument);
|
||||
convertLibrary(swf, characterVariables, characterClasses, nonLibraryShapes, backgroundColor, swf.getTags(), characters, files, datfiles, flaVersion, domDocument);
|
||||
domDocument.append("<timelines>");
|
||||
domDocument.append(convertTimeline(0, nonLibraryShapes, backgroundColor, swf.tags, swf.tags, characters, "Scene 1", flaVersion, files));
|
||||
domDocument.append(convertTimeline(0, nonLibraryShapes, backgroundColor, swf.getTags(), swf.getTags(), characters, "Scene 1", flaVersion, files));
|
||||
domDocument.append("</timelines>");
|
||||
domDocument.append("</DOMDocument>");
|
||||
String domDocumentStr = prettyFormatXML(domDocument.toString());
|
||||
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoInitActionTag) {
|
||||
DoInitActionTag dia = (DoInitActionTag) t;
|
||||
int chid = dia.getCharacterId();
|
||||
if (characters.containsKey(chid)) {
|
||||
if (characters.get(chid) instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag sprite = (DefineSpriteTag) characters.get(chid);
|
||||
if (sprite.subTags.isEmpty()) {
|
||||
if (sprite.getTags().isEmpty()) {
|
||||
String data = convertActionScript(dia);
|
||||
String expName = dia.getSwf().getExportName(dia.spriteId);
|
||||
expName = expName != null ? expName : "_unk_";
|
||||
@@ -3136,7 +3145,7 @@ public class XFLConverter {
|
||||
ret.append("<AdjustColorFilter brightness=\"").append(normBrightness(b)).append("\" contrast=\"").append(normContrast(c)).append("\" saturation=\"").append(normSaturation(s)).append("\" hue=\"").append(normHue(h)).append("\"/>");
|
||||
}
|
||||
|
||||
private static String convertHTMLText(List<Tag> tags, DefineEditTextTag det, String html) {
|
||||
private static String convertHTMLText(ReadOnlyTagList tags, DefineEditTextTag det, String html) {
|
||||
HTMLTextParser tparser = new HTMLTextParser(tags, det);
|
||||
XMLReader parser;
|
||||
try {
|
||||
@@ -3190,7 +3199,7 @@ public class XFLConverter {
|
||||
|
||||
private String alignment = null;
|
||||
|
||||
private final List<Tag> tags;
|
||||
private final ReadOnlyTagList tags;
|
||||
|
||||
private boolean bold = false;
|
||||
|
||||
@@ -3216,7 +3225,7 @@ public class XFLConverter {
|
||||
public void warning(SAXParseException e) throws SAXException {
|
||||
}
|
||||
|
||||
public HTMLTextParser(List<Tag> tags, DefineEditTextTag det) {
|
||||
public HTMLTextParser(ReadOnlyTagList tags, DefineEditTextTag det) {
|
||||
if (det.hasFont) {
|
||||
String fontName = null;
|
||||
FontTag ft = null;
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ActionScript2Test extends ActionScript2TestBase {
|
||||
int f = 0;
|
||||
DoActionTag lastDoa = null;
|
||||
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoActionTag) {
|
||||
lastDoa = (DoActionTag) t;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ public class ActionScript2TestBase extends ActionScriptTestBase {
|
||||
protected SWF swf;
|
||||
|
||||
protected DoActionTag getFirstActionTag() {
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoActionTag) {
|
||||
return (DoActionTag) t;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ActionScript3ExecuteTest {
|
||||
swf = new SWF(is, false);
|
||||
}*/
|
||||
DoABC2Tag tag = null;
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoABC2Tag) {
|
||||
tag = (DoABC2Tag) t;
|
||||
break;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ActionScript3Test extends ActionScriptTestBase {
|
||||
//Main.initLogging(false);
|
||||
swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/as3/as3.swf")), false);
|
||||
DoABC2Tag tag = null;
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoABC2Tag) {
|
||||
tag = (DoABC2Tag) t;
|
||||
break;
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RecompileTest extends FileTestBase {
|
||||
try {
|
||||
Configuration.debugCopy.set(false);
|
||||
SWF swf = new SWF(new BufferedInputStream(new FileInputStream(filePath)), false, false);
|
||||
for (Tag tag : swf.tags) {
|
||||
for (Tag tag : swf.getTags()) {
|
||||
if (!(tag instanceof TagStub)) {
|
||||
Tag tag2 = tag.cloneTag();
|
||||
if (tag2 instanceof TagStub) {
|
||||
|
||||
@@ -99,13 +99,13 @@ public class SwfXmlExportImportTest extends FileTestBase {
|
||||
SWF swf2 = new SWF();
|
||||
new SwfXmlImporter().importSwf(swf2, xml);
|
||||
|
||||
if (swf.tags.size() != swf2.tags.size()) {
|
||||
if (swf.getTags().size() != swf2.getTags().size()) {
|
||||
throw new NotSameException(0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < swf.tags.size(); i++) {
|
||||
Tag oldTag = swf.tags.get(i);
|
||||
Tag newTag = swf2.tags.get(i);
|
||||
for (int i = 0; i < swf.getTags().size(); i++) {
|
||||
Tag oldTag = swf.getTags().get(i);
|
||||
Tag newTag = swf2.getTags().get(i);
|
||||
if (oldTag.getClass() != newTag.getClass()) {
|
||||
throw new NotSameException(0);
|
||||
}
|
||||
@@ -113,12 +113,12 @@ public class SwfXmlExportImportTest extends FileTestBase {
|
||||
if (oldTag instanceof DefineSpriteTag) {
|
||||
DefineSpriteTag oldSprite = (DefineSpriteTag) oldTag;
|
||||
DefineSpriteTag newSprite = (DefineSpriteTag) newTag;
|
||||
if (oldSprite.subTags.size() != newSprite.subTags.size()) {
|
||||
if (oldSprite.getTags().size() != newSprite.getTags().size()) {
|
||||
throw new NotSameException(0);
|
||||
}
|
||||
|
||||
for (int k = 0; k < oldSprite.subTags.size(); k++) {
|
||||
compareTags(oldSprite.subTags.get(k), newSprite.subTags.get(k));
|
||||
for (int k = 0; k < oldSprite.getTags().size(); k++) {
|
||||
compareTags(oldSprite.getTags().get(k), newSprite.getTags().get(k));
|
||||
}
|
||||
} else if (!(oldTag instanceof FontTag)) {
|
||||
compareTags(oldTag, newTag);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.
|
||||
*/
|
||||
@@ -45,7 +45,7 @@ public class AS2Generator {
|
||||
DoActionTag doa = null;
|
||||
int frame = 0;
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoActionTag) {
|
||||
doa = (DoActionTag) t;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class AS3Generator {
|
||||
Configuration.autoDeobfuscate.set(false);
|
||||
SWF swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/as3/as3.swf")), false);
|
||||
DoABC2Tag tag = null;
|
||||
for (Tag t : swf.tags) {
|
||||
for (Tag t : swf.getTags()) {
|
||||
if (t instanceof DoABC2Tag) {
|
||||
tag = (DoABC2Tag) t;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user