Fixed #2174 Ignoring PlaceObjects with flagMove on empty depth

This commit is contained in:
Jindra Petřík
2024-08-05 11:17:25 +02:00
parent 57d44dbb46
commit 3ad6c894a7
4 changed files with 147 additions and 211 deletions
@@ -251,7 +251,7 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
}
if (!pot.flagMove() && depthMap.containsKey(pot.getDepth())) {
if (pot.flagMove() != depthMap.containsKey(pot.getDepth())) {
continue;
}
@@ -347,9 +347,9 @@ public class Timeline {
fl.placeFrame = frame;
fl.minPlaceObjectNum = Math.max(fl.minPlaceObjectNum, po.getPlaceObjectNum());
boolean wasEmpty = fl.characterId == -1 && fl.className == null;
boolean wasOccupied = fl.characterId != -1 || fl.className != null;
if (po.flagMove() || wasEmpty) {
if (po.flagMove() == wasOccupied) {
int characterId = po.getCharacterId();
if (characterId != -1) {
fl.characterId = characterId;
@@ -382,64 +382,64 @@ public class Timeline {
} else {
fl.key = characterId != -1 || className != null;
}
}
if (po.flagMove()) {
MATRIX matrix2 = po.getMatrix();
if (matrix2 != null) {
fl.matrix = matrix2;
}
String instanceName2 = po.getInstanceName();
if (instanceName2 != null) {
fl.instanceName = instanceName2;
}
ColorTransform colorTransForm2 = po.getColorTransform();
if (colorTransForm2 != null) {
fl.colorTransForm = colorTransForm2;
}
if (po.flagMove()) {
MATRIX matrix2 = po.getMatrix();
if (matrix2 != null) {
fl.matrix = matrix2;
}
String instanceName2 = po.getInstanceName();
if (instanceName2 != null) {
fl.instanceName = instanceName2;
}
ColorTransform colorTransForm2 = po.getColorTransform();
if (colorTransForm2 != null) {
fl.colorTransForm = colorTransForm2;
}
String className2 = po.getClassName();
if (className2 != null) {
fl.className = className2;
}
String className2 = po.getClassName();
if (className2 != null) {
fl.className = className2;
}
CLIPACTIONS clipActions2 = po.getClipActions();
if (clipActions2 != null) {
fl.clipActions = clipActions2;
}
if (po.cacheAsBitmap()) {
fl.cacheAsBitmap = true;
}
int blendMode2 = po.getBlendMode();
if (blendMode2 > 0) {
fl.blendMode = blendMode2;
}
List<FILTER> filters2 = po.getFilters();
if (filters2 != null) {
fl.filters = filters2;
}
int ratio2 = po.getRatio();
if (ratio2 > -1) {
fl.ratio = ratio2;
}
int clipDepth2 = po.getClipDepth();
if (clipDepth2 > -1) {
fl.clipDepth = clipDepth2;
}
CLIPACTIONS clipActions2 = po.getClipActions();
if (clipActions2 != null) {
fl.clipActions = clipActions2;
fl.isVisible = po.isVisible();
} else {
fl.matrix = po.getMatrix();
fl.instanceName = po.getInstanceName();
fl.colorTransForm = po.getColorTransform();
fl.cacheAsBitmap = po.cacheAsBitmap();
fl.blendMode = po.getBlendMode();
fl.filters = po.getFilters();
fl.ratio = po.getRatio();
fl.clipActions = po.getClipActions();
fl.clipDepth = po.getClipDepth();
fl.isVisible = po.isVisible();
}
if (po.cacheAsBitmap()) {
fl.cacheAsBitmap = true;
}
int blendMode2 = po.getBlendMode();
if (blendMode2 > 0) {
fl.blendMode = blendMode2;
}
List<FILTER> filters2 = po.getFilters();
if (filters2 != null) {
fl.filters = filters2;
}
int ratio2 = po.getRatio();
if (ratio2 > -1) {
fl.ratio = ratio2;
}
int clipDepth2 = po.getClipDepth();
if (clipDepth2 > -1) {
fl.clipDepth = clipDepth2;
}
fl.isVisible = po.isVisible();
} else if (wasEmpty) {
fl.matrix = po.getMatrix();
fl.instanceName = po.getInstanceName();
fl.colorTransForm = po.getColorTransform();
fl.cacheAsBitmap = po.cacheAsBitmap();
fl.blendMode = po.getBlendMode();
fl.filters = po.getFilters();
fl.ratio = po.getRatio();
fl.clipActions = po.getClipActions();
fl.clipDepth = po.getClipDepth();
fl.isVisible = po.isVisible();
}
}
} else if (t instanceof RemoveTag) {
RemoveTag r = (RemoveTag) t;
@@ -1173,7 +1173,7 @@ public class XFLConverter {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
int d = po.getDepth();
if (po.flagMove() || !depthMap.containsKey(d)) {
if (po.flagMove() == depthMap.containsKey(d)) {
if (!po.flagMove()) {
depthHasInstanceName.put(d, false);
depthHasColorTransform.put(d, false);
@@ -1236,7 +1236,7 @@ public class XFLConverter {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
int d = po.getDepth();
if (po.flagMove() || !depthMap.containsKey(d)) {
if (po.flagMove() == depthMap.containsKey(d)) {
int ch = po.getCharacterId();
if (ch == -1) {
if (depthMap.containsKey(d)) {
@@ -3539,6 +3539,8 @@ public class XFLConverter {
Map<PlaceObjectTypeTag, Integer> clipFinishFrames = new HashMap<>();
Map<PlaceObjectTypeTag, Integer> clipStartFrames = new HashMap<>();
Set<Integer> occupiedDepths = new HashSet<>();
int maxDepth = getMaxDepth(timelineTags);
Tag lastTag = null;
for (Tag t : timelineTags) {
@@ -3547,22 +3549,36 @@ public class XFLConverter {
}
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
if (po.getClipDepth() > -1) {
clipStartFrames.put(po, f);
clipPlaces.add(po);
if (depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
if (po.flagMove() == occupiedDepths.contains(po.getDepth())) {
if (po.flagMove()) {
if (po.getCharacterId() != -1 || po.getClassName() != null) {
occupiedDepths.add(po.getDepth());
}
} else {
occupiedDepths.add(po.getDepth());
}
depthToClipPlace.put(po.getDepth(), po);
} else {
if (!po.flagMove() && depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
depthToClipPlace.remove(po.getDepth());
if (po.getClipDepth() > -1) {
clipStartFrames.put(po, f);
clipPlaces.add(po);
if (depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
}
depthToClipPlace.put(po.getDepth(), po);
} else {
if (!po.flagMove() && depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
depthToClipPlace.remove(po.getDepth());
}
}
}
}
}
if (t instanceof RemoveTag) {
RemoveTag re = (RemoveTag) t;
occupiedDepths.remove(re.getDepth());
if (depthToClipPlace.containsKey(re.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(re.getDepth()), f - 1);
depthToClipPlace.remove(re.getDepth());
@@ -3637,38 +3653,44 @@ public class XFLConverter {
boolean removed = false;
int numFrames = 0;
lastTag = null;
Map<Integer, Integer> depthStates = new HashMap<>();
//Map<Integer, Integer> depthStates = new HashMap<>();
occupiedDepths.clear();
for (Tag t : timelineTags) {
if (f < fr) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
if (depthStates.containsKey(place.getDepth()) && !place.flagMove()) {
if (place.flagMove() != occupiedDepths.contains(place.getDepth())) {
continue;
}
if (place.getCharacterId() != -1) {
depthStates.put(place.getDepth(), place.getCharacterId());
if (place.getCharacterId() != -1 && place.getClassName() != null) {
occupiedDepths.add(place.getDepth());
}
}
if (t instanceof RemoveTag) {
depthStates.remove(((RemoveTag) t).getDepth());
occupiedDepths.remove(((RemoveTag) t).getDepth());
}
}
if (f >= fr) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
if (place.getDepth() == secondPlace.getDepth()) {
if (place.flagMove()) {
removed = false;
} else if (place.getClipDepth() == secondPlace.getClipDepth()) {
removed = false;
delegatedPlaces.add(place);
} else {
removed = true;
if (place.flagMove() == occupiedDepths.contains(place.getDepth())) {
if (place.getCharacterId() != -1 && place.getClassName() != null) {
occupiedDepths.add(place.getDepth());
}
if (place.getDepth() == secondPlace.getDepth()) {
if (place.flagMove()) {
removed = false;
} else if (place.getClipDepth() == secondPlace.getClipDepth()) {
removed = false;
delegatedPlaces.add(place);
} else {
removed = true;
}
}
if (!removed && place.getDepth() >= secondPlace.getDepth() && place.getDepth() <= secondPlace.getClipDepth()) {
delegatedTimeline.add(place);
}
}
if (!removed && place.getDepth() >= secondPlace.getDepth() && place.getDepth() <= secondPlace.getClipDepth()) {
delegatedTimeline.add(place);
}
}
if (t instanceof RemoveTag) {
@@ -3676,6 +3698,7 @@ public class XFLConverter {
if (rt.getDepth() == secondPlace.getDepth()) {
removed = true;
}
occupiedDepths.remove(rt.getDepth());
}
}
lastTag = t;
@@ -3695,107 +3718,7 @@ public class XFLConverter {
ShowFrameTag showFrame = new ShowFrameTag(swf);
//set timelined?
delegatedTimeline.add(showFrame);
}
/*
List<Tag> delegatedTimeline2 = Helper.deepCopy(delegatedTimeline);
for (int i = 0; i < delegatedTimeline2.size(); i++) {
delegatedTimeline2.get(i).setSwf(swf);
}
for (Tag t : delegatedTimeline2) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
if (depthStates.containsKey(place.getDepth()) && !place.flagMove()) {
continue;
}
if (place.getCharacterId() != -1) {
depthStates.put(place.getDepth(), place.getCharacterId());
}
if (place.flagMove()) {
place.setCharacterId(depthStates.get(place.getDepth()));
place.setPlaceFlagMove(false);
}
}
if (t instanceof RemoveTag) {
depthStates.remove(((RemoveTag)t).getDepth());
}
}
//find shape looping, find largest loop
int found = -1;
loopi: for (int i = numFrames - 1; i >= 1; i--) {
System.err.println("checking len = " + i);
List<Tag> firstBatch = new ArrayList<>();
Map<Integer, Map<Integer, PlaceObjectTypeTag>> firstFramesDepthStates = new HashMap<>();
Map<Integer, PlaceObjectTypeTag> curDepthStates = new LinkedHashMap<>();
f = 0;
for (Tag t : delegatedTimeline2) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
curDepthStates.put(place.getDepth(), place);
}
if (t instanceof RemoveTag) {
RemoveTag rem = (RemoveTag) t;
curDepthStates.remove(rem.getDepth());
}
if (t instanceof ShowFrameTag) {
firstFramesDepthStates.put(f, new LinkedHashMap<>(curDepthStates));
f++;
if (f == i) {
break;
}
}
}
int numParts = (int) Math.ceil(numFrames / (float) i); //example 4
if (numParts < 2) {
continue;
}
f = 0;
curDepthStates = new LinkedHashMap<>();
boolean same = true;
loopt: for (Tag t : delegatedTimeline2) {
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag place = (PlaceObjectTypeTag) t;
curDepthStates.put(place.getDepth(), place);
}
if (t instanceof RemoveTag) {
RemoveTag rem = (RemoveTag) t;
curDepthStates.remove(rem.getDepth());
}
if (t instanceof ShowFrameTag) {
int firstF = f % i;
Map<Integer, PlaceObjectTypeTag> firstFDepthStates = firstFramesDepthStates.get(firstF);
if (firstFDepthStates.size() == curDepthStates.size()) {
for (int k : curDepthStates.keySet()) {
if (!firstFDepthStates.containsKey(k)) {
same = false;
break loopt;
}
PlaceObjectTypeTag p1 = firstFDepthStates.get(k);
PlaceObjectTypeTag p2 = curDepthStates.get(k);
if (!p1.placeEquals(p2)) {
same = false;
break loopt;
}
}
} else {
same = false;
break loopt;
}
f++;
}
}
if (same) {
System.err.println("same");
found = f;
}
}
System.err.println("clip repeats in " + found);*/
}
addExtractedClip(new ReadOnlyTagList(delegatedTimeline), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, characters, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
placeToMaskedSymbol.put(secondPlace, new MultiLevelClip(secondPlace, nextClipId.getVal(), numFrames));
}
@@ -3999,6 +3922,7 @@ public class XFLConverter {
Map<PlaceObjectTypeTag, Integer> clipFinishFrames = new HashMap<>();
Map<PlaceObjectTypeTag, Integer> clipStartFrames = new HashMap<>();
Map<PlaceObjectTypeTag, Integer> placeToFirstCharacterDepth = new HashMap<>();
Set<Integer> occupiedDepths = new HashSet<>();
Tag lastTag = null;
int tpos = 0;
for (Tag t : sceneTimelineTags) {
@@ -4007,34 +3931,44 @@ public class XFLConverter {
}
if (t instanceof PlaceObjectTypeTag) {
PlaceObjectTypeTag po = (PlaceObjectTypeTag) t;
if (po.getClipDepth() > -1) {
clipFrameSplitters.add(f);
clipStartFrames.put(po, f);
clipPlaces.add(po);
if (depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
if (po.flagMove() == occupiedDepths.contains(po.getDepth())) {
if (po.flagMove()) {
if (po.getCharacterId() != -1 || po.getClassName() != null) {
occupiedDepths.add(po.getDepth());
}
} else {
occupiedDepths.add(po.getDepth());
}
depthToClipPlace.put(po.getDepth(), po);
for (int j = tpos + 1; j <= sceneTimelineTags.size(); j++) {
Tag t2 = sceneTimelineTags.get(j);
if (t2 instanceof PlaceObject2Tag) {
PlaceObject2Tag pl = (PlaceObject2Tag) t2;
int d = pl.getDepth();
if (d >= po.getDepth() && d <= po.getClipDepth()) {
placeToFirstCharacterDepth.put(po, d);
if (po.getClipDepth() > -1) {
clipFrameSplitters.add(f);
clipStartFrames.put(po, f);
clipPlaces.add(po);
if (depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
}
depthToClipPlace.put(po.getDepth(), po);
for (int j = tpos + 1; j <= sceneTimelineTags.size(); j++) {
Tag t2 = sceneTimelineTags.get(j);
if (t2 instanceof PlaceObject2Tag) {
PlaceObject2Tag pl = (PlaceObject2Tag) t2;
int d = pl.getDepth();
if (d >= po.getDepth() && d <= po.getClipDepth()) {
placeToFirstCharacterDepth.put(po, d);
}
}
if (t2 instanceof ShowFrameTag) {
break;
}
}
if (t2 instanceof ShowFrameTag) {
break;
}
}
} else {
if (!po.flagMove() && depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
depthToClipPlace.remove(po.getDepth());
}
} else {
if (!po.flagMove() && depthToClipPlace.containsKey(po.getDepth())) {
clipFinishFrames.put(depthToClipPlace.get(po.getDepth()), f - 1);
depthToClipPlace.remove(po.getDepth());
}
}
}
}
@@ -4044,6 +3978,7 @@ public class XFLConverter {
clipFinishFrames.put(depthToClipPlace.get(re.getDepth()), f - 1);
depthToClipPlace.remove(re.getDepth());
}
occupiedDepths.remove(re.getDepth());
}
lastTag = t;
tpos++;