Fixed: #2595 FLA export - incorrect handling of imported fonts

Fixed: FLA export - incorrect handling of imported sprites
This commit is contained in:
Jindra Petřík
2026-01-03 10:25:07 +01:00
parent df70665b02
commit ebf31a40c8
57 changed files with 375 additions and 170 deletions

View File

@@ -42,7 +42,8 @@ public class DefineBeforeUsageFixer {
for (int i = 0; i < tags.size(); i++) {
Tag t = tags.get(i);
Set<Integer> needed = new LinkedHashSet<>();
t.getNeededCharactersDeep(needed);
Set<String> neededClasses = new LinkedHashSet<>();
t.getNeededCharactersDeep(needed, neededClasses);
for (int chId : needed) {
if (walkedCharacters.contains(chId)) {
continue;
@@ -76,5 +77,5 @@ public class DefineBeforeUsageFixer {
}
}
return i;
}
}
}

View File

@@ -392,6 +392,12 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
*/
@Internal
private volatile Map<Integer, Set<Integer>> dependentFrames;
/**
* Map of class to Set of dependent frame numbers.
*/
@Internal
private volatile Map<String, Set<Integer>> dependentClassFrames;
/**
* List of ABC container tags.
@@ -1106,7 +1112,9 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
int characterId = ((CharacterTag) tag).getCharacterId();
if (characterId != -1) {
Set<Integer> needed = new HashSet<>();
tag.getNeededCharacters(needed, this);
Set<String> neededClasses = new HashSet<>();
//TODO: compute classes
tag.getNeededCharacters(needed, neededClasses, this);
for (Integer needed1 : needed) {
Set<Integer> s = dep.get(needed1);
if (s == null) {
@@ -1197,23 +1205,35 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
*/
public void computeDependentFrames() {
Map<Integer, Set<Integer>> dep = new HashMap<>();
Map<String, Set<Integer>> depCls = new HashMap<>();
Timeline tim = getTimeline();
for (int i = 0; i < tim.getFrameCount(); i++) {
Frame frame = tim.getFrame(i);
Set<Integer> needed = new HashSet<>();
frame.getNeededCharactersDeep(needed);
Set<String> neededClasses = new HashSet<>();
frame.getNeededCharactersDeep(needed, neededClasses);
for (Integer needed1 : needed) {
Set<Integer> s = dep.get(needed1);
Set<Integer> s = dep.get(needed1);
if (s == null) {
s = new HashSet<>();
dep.put(needed1, s);
}
s.add(i);
}
for (String needed1 : neededClasses) {
Set<Integer> s = depCls.get(needed1);
if (s == null) {
s = new HashSet<>();
depCls.put(needed1, s);
}
s.add(i);
}
}
dependentFrames = dep;
dependentClassFrames = depCls;
}
/**
@@ -1234,6 +1254,24 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
return dependentFrames.get(characterId);
}
/**
* Gets dependent frames for specified AS3 class.
*
* @param characterClass Character id
* @return Set of dependent characterids
*/
public Set<Integer> getDependentFramesByClass(String characterClass) {
if (dependentClassFrames == null) {
synchronized (this) {
if (dependentClassFrames == null) {
computeDependentFrames();
}
}
}
return dependentClassFrames.get(characterClass);
}
/**
* Gets character tag by character id
*
@@ -6185,14 +6223,16 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
}
Set<Integer> ct = new HashSet<>();
Map<Integer, Set<Integer>> characterToNeeded = new HashMap<>();
for (Tag t : getTags()) {
if (t instanceof CharacterTag) {
CharacterTag cht = (CharacterTag) t;
if (cht.getCharacterId() != -1) {
Set<Integer> needed = new HashSet<>();
cht.getNeededCharacters(needed, this);
characterToNeeded.put(cht.getCharacterId(), needed);
Set<String> neededClasses = new HashSet<>();
cht.getNeededCharacters(needed, neededClasses, this);
//TODO: check cyclic classes
characterToNeeded.put(cht.getCharacterId(), needed);
}
}
}

View File

@@ -397,8 +397,9 @@ public class FrameExporter {
fos.write(Utf8Helper.getBytes("\r\n"));
fos.write(Utf8Helper.getBytes("var scalingGrids = {};\r\nvar boundRects = {};\r\n"));
Set<Integer> library = new HashSet<>();
ftim.getNeededCharacters(fframes, library);
Set<String> libraryClasses = new HashSet<>();
ftim.getNeededCharacters(fframes, library, libraryClasses);
//FIXME!!! Handle Library Classes
SWF.libraryToHtmlCanvas(fswf, library, fos);
String currentName = ftim.id == 0 ? "main" : SWF.getTypePrefix(fswf.getCharacter(ftim.id)) + ftim.id;

View File

@@ -254,10 +254,12 @@ public class MorphShapeExporter {
CanvasMorphShapeExporter cse = new CanvasMorphShapeExporter(mst.getShapeNum(), ((Tag) mst).getSwf(), mst.getShapeAtRatio(0), mst.getShapeAtRatio(DefineMorphShapeTag.MAX_RATIO), new CXFORMWITHALPHA(), SWF.unitDivisor, deltaX, deltaY);
cse.export();
Set<Integer> needed = new HashSet<>();
Set<String> neededClasses = new HashSet<>();
CharacterTag ct = ((CharacterTag) mst);
needed.add(ct.getCharacterId());
ct.getNeededCharactersDeep(needed);
ct.getNeededCharactersDeep(needed, neededClasses);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//FIXME!!! Handle Library Classes
SWF.libraryToHtmlCanvas(ct.getSwf(), needed, baos);
fos.write(Utf8Helper.getBytes(cse.getHtml(new String(baos.toByteArray(), Utf8Helper.charset), SWF.getTypePrefix(mst) + mst.getCharacterId(), mst.getRect())));
}

View File

@@ -366,6 +366,7 @@ public class PreviewExporter {
}
Set<Integer> doneCharacters = new LinkedHashSet<>();
Set<String> doneCharacterClasses = new LinkedHashSet<>();
if (treeItem instanceof Frame) {
Frame fn = (Frame) treeItem;
Timelined parent = fn.timeline.timelined;
@@ -384,7 +385,7 @@ public class PreviewExporter {
}
Set<Integer> needed = new LinkedHashSet<>();
t.getNeededCharactersDeep(needed);
t.getNeededCharactersDeep(needed, new LinkedHashSet<>());
for (int n : needed) {
if (!doneCharacters.contains(n)) {
writeTag(swf.getCharacter(n), sos2, doneCharacters);
@@ -398,7 +399,7 @@ public class PreviewExporter {
int characterId = ((CharacterTag) t).getCharacterId();
if (characterId != -1) {
writeTag(t, sos2, doneCharacters);
}
}
}
}
@@ -432,7 +433,7 @@ public class PreviewExporter {
//empty
} else {
Set<Integer> needed = new HashSet<>();
((Tag) treeItem).getNeededCharactersDeep(needed);
((Tag) treeItem).getNeededCharactersDeep(needed, new HashSet<>());
for (int n : needed) {
if (isSprite && chtId == n) {
continue;
@@ -706,7 +707,7 @@ public class PreviewExporter {
}
doneCharacters.add(chId);
}
t.writeTagNoScripts(sos);
if (t instanceof CharacterIdTag) {
List<CharacterIdTag> chIdTags = t.getSwf().getCharacterIdTags(((CharacterIdTag) t).getCharacterId());
@@ -715,7 +716,7 @@ public class PreviewExporter {
if (!(chIdTag instanceof PlaceObjectTypeTag || chIdTag instanceof RemoveTag)) {
Set<Integer> needed = new LinkedHashSet<>();
((Tag) chIdTag).getNeededCharactersDeep(needed);
((Tag) chIdTag).getNeededCharactersDeep(needed, new HashSet<>());
for (int n : needed) {
if (!doneCharacters.contains(n)) {
writeTag(((Tag) chIdTag).getSwf().getCharacter(n), sos, doneCharacters);

View File

@@ -173,9 +173,11 @@ public class ShapeExporter {
CanvasShapeExporter cse = new CanvasShapeExporter(st.getWindingRule(), st.getShapeNum(), null, SWF.unitDivisor / settings.zoom, ((Tag) st).getSwf(), shp, new CXFORMWITHALPHA(), deltaX, deltaY);
cse.export();
Set<Integer> needed = new HashSet<>();
Set<String> neededClasses = new HashSet<>();
needed.add(st.getCharacterId());
st.getNeededCharactersDeep(needed);
st.getNeededCharactersDeep(needed, neededClasses);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//FIXME!!! Handle Library Classes
SWF.libraryToHtmlCanvas(st.getSwf(), needed, baos);
fos.write(Utf8Helper.getBytes(cse.getHtml(new String(baos.toByteArray(), Utf8Helper.charset), SWF.getTypePrefix(st) + st.getCharacterId(), st.getRect())));
}

View File

@@ -684,12 +684,16 @@ public class AS3ScriptExporter {
}
Set<Integer> neededCharacters = new LinkedHashSet<>();
Set<String> neededCharacterClasses = new LinkedHashSet<>();
List<Integer> symbolClassIds = new ArrayList<>();
List<String> symbolClassNames = new ArrayList<>();
for (CharacterTag st : assetsTagList) {
st.getNeededCharactersDeep(neededCharacters);
st.getNeededCharactersDeep(neededCharacters, neededCharacterClasses);
neededCharacters.add(swf.getCharacterId(st));
}
//TODO: handle neededCharacterClasses?
for (int n : neededCharacters) {
CharacterTag ct = (CharacterTag) swf.getCharacter(n);
if (ct == null) {

View File

@@ -69,7 +69,9 @@ public class SpriteImporter {
Set<Integer> dependentCharacters = swf.getDependentCharacters(ch);
if (dependentCharacters.isEmpty()) {
Set<Integer> needed = new LinkedHashSet<>();
ct.getNeededCharacters(needed, swf);
Set<String> neededClasses = new LinkedHashSet<>();
ct.getNeededCharacters(needed, neededClasses, swf);
//TODO: handle classes?
List<CharacterIdTag> attachedTags = swf.getCharacterIdTags(ch);
for (CharacterIdTag cit : attachedTags) {
if (cit instanceof Tag) {

View File

@@ -131,7 +131,7 @@ public class CSMSettingsTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(textID);
}
}

View File

@@ -370,7 +370,7 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (BUTTONRECORD rec : characters) {
needed.add(rec.characterId);
}

View File

@@ -104,7 +104,7 @@ public class DefineButtonCxformTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(buttonId);
}
}

View File

@@ -144,7 +144,7 @@ public class DefineButtonSoundTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (buttonSoundChar0 != 0) {
needed.add(buttonSoundChar0);
}

View File

@@ -323,7 +323,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (BUTTONRECORD rec : characters) {
needed.add(rec.characterId);
}

View File

@@ -1237,16 +1237,24 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (hasFont) {
needed.add(fontId);
needed.add(fontId);
}
if (hasFontClass) {
neededClasses.add(fontClass);
}
if (html && hasText) {
List<CharacterWithStyle> chs = getTextWithStyle();
for (CharacterWithStyle ch : chs) {
if (ch.style.font != null) {
needed.add(swf.getCharacterId(ch.style.font));
}
int subFontId = swf.getCharacterId(ch.style.font);
if (subFontId != -1) {
needed.add(subFontId);
} else {
neededClasses.addAll(ch.style.font.getClassNames());
}
}
}
}
}

View File

@@ -123,7 +123,7 @@ public class DefineFontAlignZonesTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -188,7 +188,7 @@ public class DefineFontInfo2Tag extends FontInfoTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -189,7 +189,7 @@ public class DefineFontInfoTag extends FontInfoTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(fontID);
}
}

View File

@@ -101,7 +101,7 @@ public class DefineFontNameTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(fontId);
}
}

View File

@@ -231,7 +231,7 @@ public class DefineScalingGridTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(characterId);
}

View File

@@ -419,7 +419,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (Tag t : getTags()) {
if (
(t instanceof PlaceObjectTypeTag)
@@ -427,7 +427,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
|| (t instanceof StartSound2Tag)
|| (t instanceof VideoFrameTag)
) {
t.getNeededCharacters(needed, swf);
t.getNeededCharacters(needed, neededClasses, swf);
}
}
}
@@ -538,15 +538,13 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public Set<Integer> getMissingNeededCharacters(Set<Integer> needed) {
Set<Integer> ret = new LinkedHashSet<>();
public void getMissingNeededCharacters(Set<Integer> needed, Set<String> neededClasses, Set<Integer> resultNeeded, Set<String> resultNeededClasses) {
for (Tag tag : getTags()) {
Set<Integer> subNeeded = new HashSet<>();
tag.getNeededCharactersDeep(subNeeded);
Set<Integer> sub = tag.getMissingNeededCharacters(subNeeded);
ret.addAll(sub);
}
return ret;
Set<String> subNeededClasses = new HashSet<>();
tag.getNeededCharactersDeep(subNeeded, subNeededClasses);
tag.getMissingNeededCharacters(subNeeded, subNeededClasses, resultNeeded, resultNeededClasses);
}
}
@Override

View File

@@ -294,7 +294,7 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(spriteId);
}

View File

@@ -155,7 +155,7 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.addAll(tags);
}

View File

@@ -87,7 +87,7 @@ public class FreeCharacterTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(characterId);
}

View File

@@ -105,7 +105,7 @@ public class NameCharacterTag extends Tag implements CharacterModifier {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(characterId);
}
}

View File

@@ -327,7 +327,7 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}

View File

@@ -543,7 +543,7 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}
@@ -551,6 +551,8 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
int chId = swf.getCharacterId(swf.getCharacterByClass(className));
if (chId != -1) {
needed.add(chId);
} else {
neededClasses.add(className);
}
}
}

View File

@@ -564,7 +564,7 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (placeFlagHasCharacter) {
needed.add(characterId);
}
@@ -572,6 +572,8 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
int chId = swf.getCharacterId(swf.getCharacterByClass(className));
if (chId != -1) {
needed.add(chId);
} else {
neededClasses.add(className);
}
}
}

View File

@@ -143,7 +143,7 @@ public class PlaceObjectTag extends PlaceObjectTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(characterId);
}

View File

@@ -112,7 +112,7 @@ public class RemoveObjectTag extends RemoveTag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(characterId);
}
}

View File

@@ -92,7 +92,7 @@ public class StartSound2Tag extends Tag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
int characterId = swf.getCharacterId(swf.getCharacterByClass(soundClassName));
needed.add(characterId);
}

View File

@@ -104,7 +104,7 @@ public class StartSoundTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(soundId);
}
}

View File

@@ -145,7 +145,7 @@ public class SymbolClassTag extends SymbolClassTypeTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (int t : tags) {
if (t != 0) { //main class
needed.add(t);

View File

@@ -842,41 +842,51 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
}
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
}
/**
* Gets missing needed characters.
* @param needed Needed
* @return Missing needed characters
* @param neededClasses Needed classes
*/
public Set<Integer> getMissingNeededCharacters(Set<Integer> needed) {
public void getMissingNeededCharacters(Set<Integer> needed, Set<String> neededClasses, Set<Integer> resultNeeded, Set<String> resultNeededClasses) {
Set<Integer> needed2 = new LinkedHashSet<>(needed);
if (needed2.isEmpty()) {
return new LinkedHashSet<>();
Set<String> needed2Classes = new LinkedHashSet<>(neededClasses);
if (needed2.isEmpty() && needed2Classes.isEmpty()) {
resultNeeded.clear();
resultNeededClasses.clear();
return;
}
Timelined tim = getTimelined();
if (tim == null) {
return needed2;
resultNeeded.addAll(needed2);
resultNeededClasses.addAll(needed2Classes);
return;
}
ReadOnlyTagList tags = tim.getTags();
for (int i = tags.indexOf(this) - 1; i >= 0; i--) {
if (tags.get(i) instanceof ImportTag) {
ImportTag it = (ImportTag) tags.get(i);
needed2.removeAll(it.getAssets().keySet());
if (needed2.isEmpty()) {
return needed2;
if (needed2.isEmpty() && needed2Classes.isEmpty()) {
resultNeeded.addAll(needed2);
resultNeededClasses.addAll(needed2Classes);
return;
}
}
if (tags.get(i) instanceof CharacterTag) {
int charId = ((CharacterTag) tags.get(i)).getCharacterId();
needed2.remove(charId);
if (needed2.isEmpty()) {
return needed2;
needed2.remove(charId);
needed2Classes.removeAll(((CharacterTag) tags.get(i)).getClassNames());
if (needed2.isEmpty() && needed2Classes.isEmpty()) {
resultNeeded.addAll(needed2);
resultNeededClasses.addAll(needed2Classes);
return;
}
}
}
return needed2;
}
}
@Override
@@ -888,16 +898,17 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
public boolean removeCharacter(int characterId) {
return false;
}
/**
* Gets needed characters deep.
* @param needed Needed
* @param needed Needed character ids
* @param neededClasses Needed classes
*/
public void getNeededCharactersDeep(Set<Integer> needed) {
public void getNeededCharactersDeep(Set<Integer> needed, Set<String> neededClasses) {
Set<Integer> needed2 = new LinkedHashSet<>();
getNeededCharacters(needed2, swf);
getNeededCharacters(needed2, neededClasses, swf);
List<Integer> needed3 = new ArrayList<>(needed2);
for (int i = 0; i < needed3.size(); i++) {
int characterId = needed3.get(i);
if (swf == null) {
@@ -909,7 +920,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
if (character.isImported()) {
continue;
}
character.getNeededCharacters(needed4, swf);
character.getNeededCharacters(needed4, neededClasses, swf);
List<Integer> newItems = new ArrayList<>();
for (int n : needed4) {
int index = needed3.indexOf((Integer) n);
@@ -937,12 +948,13 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
}
}
private void getDependentCharactersOnTimelined(Timelined timelined, Set<Integer> dependent) {
private void getDependentCharactersOnTimelined(Timelined timelined, Set<Integer> dependent, Set<String> dependentClasses) {
for (Tag tag : timelined.getTags()) {
if (tag instanceof CharacterTag) {
if (((CharacterTag) tag).getCharacterId() != -1) {
Set<Integer> needed = new HashSet<>();
tag.getNeededCharactersDeep(needed);
Set<String> neededClasses = new HashSet<>();
tag.getNeededCharactersDeep(needed, neededClasses);
for (int dep : dependent) {
if (needed.contains(dep)) {
dependent.add(((CharacterTag) tag).getCharacterId());
@@ -952,17 +964,18 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
}
}
if (tag instanceof DefineSpriteTag) {
getDependentCharactersOnTimelined((DefineSpriteTag) tag, dependent);
getDependentCharactersOnTimelined((DefineSpriteTag) tag, dependent, dependentClasses);
}
}
}
/**
* Gets dependent characters.
* @param dependent Result
* @param dependent Result - dependent character ids
* @param dependentClasses Result - dependent classes
*/
public void getDependentCharacters(Set<Integer> dependent) {
getDependentCharactersOnTimelined(swf, dependent);
public void getDependentCharacters(Set<Integer> dependent, Set<String> dependentClasses) {
getDependentCharactersOnTimelined(swf, dependent, dependentClasses);
}
/**

View File

@@ -100,7 +100,7 @@ public class VideoFrameTag extends Tag implements CharacterIdTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
needed.add(streamID);
}
}

View File

@@ -99,7 +99,7 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
public abstract boolean trackAsMenu();
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (BUTTONRECORD r : getRecords()) {
needed.add(r.characterId);
}

View File

@@ -149,10 +149,10 @@ public abstract class MorphShapeTag extends DrawableTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
morphFillStyles.getNeededCharacters(needed, swf);
startEdges.getNeededCharacters(needed, swf);
endEdges.getNeededCharacters(needed, swf);
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
morphFillStyles.getNeededCharacters(needed, neededClasses, swf);
startEdges.getNeededCharacters(needed, neededClasses, swf);
endEdges.getNeededCharacters(needed, neededClasses, swf);
}
@Override

View File

@@ -29,10 +29,11 @@ public interface NeedsCharacters {
/**
* Get needed characters.
*
* @param needed Result
* @param needed Result - needed character ids
* @param neededClasses Result - needed classes
* @param swf SWF file
*/
public void getNeededCharacters(Set<Integer> needed, SWF swf);
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf);
/**
* Replace character.

View File

@@ -139,10 +139,10 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
SHAPEWITHSTYLE shapes = getShapes();
if (shapes != null) {
getShapes().getNeededCharacters(needed, swf);
getShapes().getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -982,11 +982,11 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (TEXTRECORD tr : textRecords) {
if (tr.styleFlagsHasFont) {
needed.add(tr.fontId);
}
}
}
}

View File

@@ -262,9 +262,10 @@ public class Frame implements TreeItem, Exportable {
/**
* Get needed characters for this frame to deepest level.
*
* @param needed Result
* @param needed Result - needed character ids
* @param neededClasses Result - needed classes
*/
public void getNeededCharactersDeep(Set<Integer> needed) {
public void getNeededCharactersDeep(Set<Integer> needed, Set<String> neededClasses) {
for (Tag t : innerTags) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
@@ -272,7 +273,7 @@ public class Frame implements TreeItem, Exportable {
if (characterId != -1) {
CharacterTag character = place.getSwf().getCharacter(characterId);
if (character != null) {
character.getNeededCharactersDeep(needed);
character.getNeededCharactersDeep(needed, neededClasses);
}
needed.add(characterId);
}

View File

@@ -957,11 +957,12 @@ public class Timeline {
/**
* Gets needed characters for this timeline.
*
* @param usedCharacters Result
* @param usedCharacters Result - used characters
* @param usedClasses Result - used classes
*/
public void getNeededCharacters(Set<Integer> usedCharacters) {
public void getNeededCharacters(Set<Integer> usedCharacters, Set<String> usedClasses) {
for (int i = 0; i < getFrameCount(); i++) {
getNeededCharacters(i, usedCharacters);
getNeededCharacters(i, usedCharacters, usedClasses);
}
}
@@ -969,11 +970,12 @@ public class Timeline {
* Gets needed characters for this timeline.
*
* @param frames List of frames
* @param usedCharacters Result
* @param usedCharacters Result - used character ids
* @param usedClasses Result - used classes
*/
public void getNeededCharacters(List<Integer> frames, Set<Integer> usedCharacters) {
public void getNeededCharacters(List<Integer> frames, Set<Integer> usedCharacters, Set<String> usedClasses) {
for (int frame = 0; frame < getFrameCount(); frame++) {
getNeededCharacters(frame, usedCharacters);
getNeededCharacters(frame, usedCharacters, usedClasses);
}
}
@@ -981,9 +983,10 @@ public class Timeline {
* Gets needed characters for a frame.
*
* @param frame Frame index
* @param usedCharacters Result
* @param usedCharacters Result - used character ids
* @param usedClasses Result - used classes
*/
public void getNeededCharacters(int frame, Set<Integer> usedCharacters) {
public void getNeededCharacters(int frame, Set<Integer> usedCharacters, Set<String> usedClasses) {
Frame frameObj = getFrame(frame);
for (int depth : frameObj.layers.keySet()) {
DepthState layer = frameObj.layers.get(depth);
@@ -992,7 +995,8 @@ public class Timeline {
continue;
}
usedCharacters.add(ch.getCharacterId());
ch.getNeededCharactersDeep(usedCharacters);
usedClasses.addAll(ch.getClassNames());
ch.getNeededCharactersDeep(usedCharacters, usedClasses);
}
}

View File

@@ -137,7 +137,7 @@ public class FILLSTYLE implements NeedsCharacters, FieldChangeObserver, Serializ
public MATRIX bitmapMatrix;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if ((fillStyleType == REPEATING_BITMAP)
|| (fillStyleType == CLIPPED_BITMAP)
|| (fillStyleType == NON_SMOOTHED_REPEATING_BITMAP)

View File

@@ -56,9 +56,9 @@ public class FILLSTYLEARRAY implements NeedsCharacters, Serializable {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (FILLSTYLE fs : fillStyles) {
fs.getNeededCharacters(needed, swf);
fs.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -46,7 +46,7 @@ public class LINESTYLE implements NeedsCharacters, Serializable, ILINESTYLE {
public RGB color;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
}
@Override

View File

@@ -149,9 +149,9 @@ public class LINESTYLE2 implements NeedsCharacters, Serializable, ILINESTYLE {
public FILLSTYLE fillType;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (hasFillFlag) {
fillType.getNeededCharacters(needed, swf);
fillType.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -102,15 +102,15 @@ public class LINESTYLEARRAY implements NeedsCharacters, Serializable {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (lineStyles != null) {
for (ILINESTYLE ls : lineStyles) {
ls.getNeededCharacters(needed, swf);
ls.getNeededCharacters(needed, neededClasses, swf);
}
}
if (lineStyles != null) {
for (ILINESTYLE ls : lineStyles2) {
ls.getNeededCharacters(needed, swf);
ls.getNeededCharacters(needed, neededClasses, swf);
}
}
}

View File

@@ -136,7 +136,7 @@ public class MORPHFILLSTYLE implements NeedsCharacters, Serializable {
public MATRIX endBitmapMatrix;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if ((fillStyleType == REPEATING_BITMAP)
|| (fillStyleType == CLIPPED_BITMAP)
|| (fillStyleType == NON_SMOOTHED_REPEATING_BITMAP)

View File

@@ -34,9 +34,9 @@ public class MORPHFILLSTYLEARRAY implements NeedsCharacters, Serializable {
public MORPHFILLSTYLE[] fillStyles;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (MORPHFILLSTYLE fs : fillStyles) {
fs.getNeededCharacters(needed, swf);
fs.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -69,9 +69,9 @@ public class SHAPE implements NeedsCharacters, Serializable {
}
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed, swf);
r.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -47,11 +47,11 @@ public class SHAPEWITHSTYLE extends SHAPE implements NeedsCharacters, Serializab
public LINESTYLEARRAY lineStyles;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
fillStyles.getNeededCharacters(needed, swf);
lineStyles.getNeededCharacters(needed, swf);
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
fillStyles.getNeededCharacters(needed, neededClasses, swf);
lineStyles.getNeededCharacters(needed, neededClasses, swf);
for (SHAPERECORD r : shapeRecords) {
r.getNeededCharacters(needed, swf);
r.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -62,7 +62,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
public abstract void calculateBits();
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
}
@Override

View File

@@ -85,9 +85,9 @@ public final class StyleChangeRecord extends SHAPERECORD implements Cloneable {
public int numLineBits;
@Override
public void getNeededCharacters(Set<Integer> needed, SWF swf) {
public void getNeededCharacters(Set<Integer> needed, Set<String> neededClasses, SWF swf) {
if (stateNewStyles) {
fillStyles.getNeededCharacters(needed, swf);
fillStyles.getNeededCharacters(needed, neededClasses, swf);
}
}

View File

@@ -528,7 +528,7 @@ public class XFLConverter {
ImageTag it = (ImageTag) bitmapCh;
writer.writeStartElement("BitmapFill");
writer.writeAttribute("bitmapPath", getSymbolName(lastImportedId, characterNameMap, swf, bitmapCh, "Bitmap") + it.getImageFormat().getExtension());
writer.writeAttribute("bitmapPath", getSymbolName(lastImportedId, characterNameMap, swf, bitmapCh, "Bitmap", true) + it.getImageFormat().getExtension());
if ((fs.fillStyleType == FILLSTYLE.CLIPPED_BITMAP) || (fs.fillStyleType == FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP)) {
writer.writeAttribute("bitmapIsClipped", true);
@@ -1123,6 +1123,7 @@ public class XFLConverter {
return ret;
}
private static void walkNeededClasses(Set<CharacterTag> ret, ReadOnlyTagList tags) {
for (Tag t : tags) {
if (t instanceof DefineSpriteTag) {
@@ -1144,10 +1145,12 @@ public class XFLConverter {
}
}
}
private static void walkNeededCharacters(Set<CharacterTag> result, CharacterTag ct) {
Set<Integer> needed = new HashSet<>();
ct.getNeededCharactersDeep(needed);
Set<String> neededClasses = new HashSet<>();
ct.getNeededCharactersDeep(needed, neededClasses);
for (int n : needed) {
CharacterTag nc = ct.getSwf().getCharacter(n);
if (result.contains(nc)) {
@@ -1155,10 +1158,23 @@ public class XFLConverter {
}
result.add(nc);
walkNeededCharacters(result, nc);
/*if (nc instanceof DefineSpriteTag) {
DefineSpriteTag sp = (DefineSpriteTag) nc;
walkNeededClasses(result, sp.getTags());
}*/
}
for (String n : neededClasses) {
CharacterTag nc = ct.getSwf().getCharacterByClass(n);
if (result.contains(nc)) {
continue;
}
result.add(nc);
/*walkNeededCharacters(result, nc);
if (nc instanceof DefineSpriteTag) {
DefineSpriteTag sp = (DefineSpriteTag) nc;
walkNeededClasses(result, sp.getTags());
}
}*/
}
}
@@ -1337,24 +1353,43 @@ public class XFLConverter {
}
private static String getSymbolName(Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, CharacterTag tag) {
return getSymbolName(lastImportedId, characterNameMap, swf, tag, "Symbol");
return getSymbolName(lastImportedId, characterNameMap, swf, tag, true);
}
private static String getSymbolName(Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, CharacterTag tag, boolean fullPath) {
return getSymbolName(lastImportedId, characterNameMap, swf, tag, "Symbol", fullPath);
}
private static String getSymbolName(Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, CharacterTag tag, String kind) {
return getSymbolName(lastImportedId, characterNameMap, swf, tag, kind, true);
}
private static String getSymbolName(Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, CharacterTag tag, String kind, boolean fullPath) {
if (tag == null) {
return "null";
}
if (characterNameMap.containsKey(tag)) {
return characterNameMap.get(tag);
if (!characterNameMap.containsKey(tag)) {
int characterId = swf.getCharacterId(tag);
if (characterId == -1) {
lastImportedId.setVal(lastImportedId.getVal() + 1);
if (tag instanceof FontTag) {
//The font must have unique name (without folder)
characterNameMap.put(tag, "imported/Imported Font " + lastImportedId.getVal());
} else {
characterNameMap.put(tag, "imported/" + kind + " " + lastImportedId.getVal());
}
} else {
characterNameMap.put(tag, kind + " " + characterId);
}
}
int characterId = swf.getCharacterId(tag);
if (characterId == -1) {
lastImportedId.setVal(lastImportedId.getVal() + 1);
characterNameMap.put(tag, "imported/" + kind + " " + lastImportedId.getVal());
} else {
characterNameMap.put(tag, kind + " " + characterId);
String ret = characterNameMap.get(tag);
if (ret.contains("/") && !fullPath) {
return ret.substring(ret.lastIndexOf("/") + 1);
}
return characterNameMap.get(tag);
return ret;
}
private String getMaskedSymbolName(int symbolId) { //FIXME: Does this work with importassets???
@@ -1628,7 +1663,7 @@ public class XFLConverter {
if (symbol instanceof ButtonTag) {
symbolStr.writeStartElement("timeline");
itemIcon = "0";
symbolStr.writeStartElement("DOMTimeline", new String[]{"name", getSymbolName(lastImportedId, characterNameMap, swf, symbol), "currentFrame", "0"});
symbolStr.writeStartElement("DOMTimeline", new String[]{"name", getSymbolName(lastImportedId, characterNameMap, swf, symbol, false), "currentFrame", "0"});
symbolStr.writeStartElement("layers");
ButtonTag button = (ButtonTag) symbol;
@@ -1840,7 +1875,7 @@ public class XFLConverter {
symbolStr.writeStartElement("timeline");
itemIcon = "1";
ShapeTag shape = (ShapeTag) symbol;
symbolStr.writeStartElement("DOMTimeline", new String[]{"name", getSymbolName(lastImportedId, characterNameMap, swf, symbol), "currentFrame", "0"});
symbolStr.writeStartElement("DOMTimeline", new String[]{"name", getSymbolName(lastImportedId, characterNameMap, swf, symbol, false), "currentFrame", "0"});
symbolStr.writeStartElement("layers");
SHAPEWITHSTYLE shapeWithStyle = shape.getShapes();
if (shapeWithStyle != null) {
@@ -2099,7 +2134,8 @@ public class XFLConverter {
for (Tag tag : swf.getTags()) {
if (tag instanceof ShapeTag) {
Set<Integer> needed = new HashSet<>();
tag.getNeededCharacters(needed, swf);
Set<String> neededClasses = new HashSet<>();
tag.getNeededCharacters(needed, neededClasses, swf);
ShapeTag sht = (ShapeTag) tag;
if (needed.contains(imageTag.getCharacterId())) {
List<FILLSTYLE> fs = new ArrayList<>();
@@ -4499,7 +4535,7 @@ public class XFLConverter {
if (classNames.size() == 1) {
writer.writeAttribute("linkageClassName", classNames.get(0));
}
if (symbolId == -1) {
if (sprite == null && symbolId == -1) {
writer.writeStartElement("timelines");
} else {
writer.writeStartElement("timeline");
@@ -4525,7 +4561,7 @@ public class XFLConverter {
if (!lastShowFrame) {
fc++;
}
if (symbolId == -1) {
if (sprite == null && symbolId == -1) {
if (sceneLabelTag != null) {
for (int i = 0; i < sceneLabelTag.sceneOffsets.length; i++) {
scenes.add(new Scene(
@@ -4578,7 +4614,11 @@ public class XFLConverter {
scenes.add(scene);
}
} else {
Scene scene = new Scene(0, fc - 1, spriteName);
String simpleSpriteName = spriteName;
if (simpleSpriteName.contains("/")) {
simpleSpriteName = spriteName.substring(spriteName.lastIndexOf("/") + 1);
}
Scene scene = new Scene(0, fc - 1, simpleSpriteName);
scene.timelineSubTags = timelineTags;
scenes.add(scene);
}
@@ -5211,7 +5251,7 @@ public class XFLConverter {
}
if (font != null && characterImportLinkageURL.containsKey(font)) {
psFontName = getSymbolName(lastImportedId, characterNameMap, swf, font, "Font") + "*";
psFontName = getSymbolName(lastImportedId, characterNameMap, swf, font, "Font", false) + "*";
}
}
newline = false;
@@ -5257,7 +5297,12 @@ public class XFLConverter {
} else if (tag instanceof DefineEditTextTag) {
DefineEditTextTag det = (DefineEditTextTag) tag;
String tagName;
FontTag ft = det.getSwf().getFont(det.fontId);
FontTag ft = null;
if (det.hasFont) {
ft = det.getSwf().getFont(det.fontId);
} else if (det.hasFontClass) {
ft = det.getSwf().getFontByClass(det.fontClass);
}
if (normalizedFonts.containsKey(det.fontId)) {
ft = normalizedFonts.get(det.fontId);
@@ -5354,8 +5399,8 @@ public class XFLConverter {
RGBA textColor = null;
if (det.hasTextColor) {
textColor = det.textColor;
}
if (det.hasFont) {
}
if (det.hasFont || det.hasFontClass) {
String fontName = null;
if (ft != null) {
DefineFontNameTag dfn = (DefineFontNameTag) ft.getSwf().getCharacterIdTag(ft.getCharacterId(), DefineFontNameTag.ID);
@@ -5379,7 +5424,7 @@ public class XFLConverter {
fontFace = new Font(installedFont, (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0) | (!italic && !bold ? Font.PLAIN : 0), size < 0 ? 10 : size).getPSName();
}
if (characterImportLinkageURL.containsKey(ft)) {
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font") + "*";
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font", false) + "*";
}
}
}
@@ -5559,6 +5604,7 @@ public class XFLConverter {
double width = twipToPixel(swf.displayRect.getWidth());
double height = twipToPixel(swf.displayRect.getHeight());
boolean hasImport = false;
XFLXmlWriter domDocument = new XFLXmlWriter();
try {
@@ -5625,7 +5671,8 @@ public class XFLConverter {
CharacterTag cht = swf.getCharacter(chid);
characterImportLinkageURL.put(cht, it.getUrl());
}
}
hasImport = true;
}
if (frame == 1) {
if (tag instanceof ExportAssetsTag) {
ExportAssetsTag et = (ExportAssetsTag) tag;
@@ -5663,6 +5710,19 @@ public class XFLConverter {
}
}
}
if (hasImport) {
domDocument.writeStartElement("folders");
domDocument.writeStartElement("DOMFolderItem", new String[] {
"name", "imported",
"itemID", generateItemId(lastItemIdNumber),
"isExpanded", "false"
});
domDocument.writeEndElement();
domDocument.writeEndElement(); //folders
}
convertFonts(lastItemIdNumber, lastImportedId, characterNameMap, swf, characters, domDocument, statusStack, characterVariables, characterClasses, charactersExportedInFirstFrame, characterImportLinkageURL);
Set<ShapeTag> smallShapes = getSmallShapes(swf);
@@ -6114,12 +6174,17 @@ public class XFLConverter {
}
final String outfileF = zipfile;
final boolean fHasImport = hasImport;
new RetryTask(() -> {
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outfileF))) {
out.putNextEntry(new ZipEntry("DOMDocument.xml"));
out.write(Utf8Helper.getBytes(domDocumentF));
out.putNextEntry(new ZipEntry("PublishSettings.xml"));
out.write(Utf8Helper.getBytes(publishSettingsF));
out.putNextEntry(new ZipEntry("LIBRARY/"));
if (fHasImport) {
out.putNextEntry(new ZipEntry("LIBRARY/imported/"));
}
for (String fileName : files.keySet()) {
out.putNextEntry(new ZipEntry("LIBRARY/" + fileName));
out.write(files.get(fileName));
@@ -6141,6 +6206,10 @@ public class XFLConverter {
writeFile(handler, Utf8Helper.getBytes(publishSettingsStr), xflDataDir.getAbsolutePath() + File.separator + "PublishSettings.xml");
File libraryDir = new File(xflDataDir.getAbsolutePath() + File.separator + "LIBRARY");
libraryDir.mkdir();
if (hasImport) {
File importedDir = new File(xflDataDir.getAbsolutePath() + File.separator + "LIBRARY" + File.separator + "imported");
importedDir.mkdir();
}
File binDir = new File(xflDataDir.getAbsolutePath() + File.separator + "bin");
binDir.mkdir();
for (String fileName : files.keySet()) {
@@ -6302,9 +6371,15 @@ public class XFLConverter {
Map<CharacterTag, String> characterNameMap,
SWF swf
) {
if (det.hasFont) {
if (det.hasFont || det.hasFontClass) {
String fontName = null;
FontTag ft = (FontTag) det.getSwf().getCharacter(det.fontId);
FontTag ft = null;
if (det.hasFont) {
ft = (FontTag) det.getSwf().getCharacter(det.fontId);
}
if (det.hasFontClass) {
ft = det.getSwf().getFontByClass(det.fontClass);
}
if (ft != null) {
DefineFontNameTag fnt = ft.getFontNameTag();
if (fnt != null) {
@@ -6329,7 +6404,7 @@ public class XFLConverter {
}
if (characterImportLinkageURL.containsKey(ft)) {
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font") + "*";
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font", false) + "*";
}
fontFaceStack.push(fontFace);
fontSizeStack.push(size);
@@ -6459,7 +6534,7 @@ public class XFLConverter {
}
if (characterImportLinkageURL.containsKey(ft)) {
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font") + "*";
fontFace = getSymbolName(lastImportedId, characterNameMap, swf, ft, "Font", false) + "*";
}
break;
}