Fixed: #1675 caching as bitmap / filters vs zoom

This commit is contained in:
Jindra Petřík
2021-04-04 13:23:23 +02:00
parent 558b5f08e4
commit 9b4507c2b9
5 changed files with 93 additions and 9 deletions

View File

@@ -0,0 +1,54 @@
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class DisplayObjectCacheKey {
public PlaceObjectTypeTag placeObject;
public double zoom;
public ExportRectangle viewRect;
public DisplayObjectCacheKey(PlaceObjectTypeTag placeObject, double zoom, ExportRectangle viewRect) {
this.placeObject = placeObject;
this.zoom = zoom;
this.viewRect = viewRect;
}
@Override
public int hashCode() {
int hash = 3;
hash = 79 * hash + Objects.hashCode(this.placeObject);
hash = 79 * hash + (int) (Double.doubleToLongBits(this.zoom) ^ (Double.doubleToLongBits(this.zoom) >>> 32));
hash = 79 * hash + Objects.hashCode(this.viewRect);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DisplayObjectCacheKey other = (DisplayObjectCacheKey) obj;
if (Double.doubleToLongBits(this.zoom) != Double.doubleToLongBits(other.zoom)) {
return false;
}
if (!Objects.equals(this.placeObject, other.placeObject)) {
return false;
}
if (!Objects.equals(this.viewRect, other.viewRect)) {
return false;
}
return true;
}
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.timeline.DepthState;
@@ -37,5 +38,13 @@ public class RenderContext {
public SerializableImage borderImage;
public Cache<DisplayObjectCacheKey, SerializableImage> displayObjectCache;
public void clearPlaceObjectCache(PlaceObjectTypeTag placeObject) {
for (DisplayObjectCacheKey k : displayObjectCache.keys()) {
if (k.placeObject == placeObject) {
displayObjectCache.remove(k);
}
}
}
}

View File

@@ -39,6 +39,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DisplayObjectCacheKey;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
@@ -662,6 +663,7 @@ public class Timeline {
strokeTransform = strokeTransform.concatenate(layerMatrix);
boolean cacheAsBitmap = layer.cacheAsBitmap() && layer.placeObjectTag != null && drawable.isSingleFrame();
/* // draw bounds
AffineTransform trans = mat.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).toTransform();
g.setTransform(trans);
@@ -679,7 +681,8 @@ public class Timeline {
SerializableImage img = null;
if (cacheAsBitmap && renderContext.displayObjectCache != null) {
img = renderContext.displayObjectCache.get(layer.placeObjectTag);
DisplayObjectCacheKey key = new DisplayObjectCacheKey(layer.placeObjectTag, unzoom, viewRect);
img = renderContext.displayObjectCache.get(key);
}
int stateCount = renderContext.stateUnderCursor == null ? 0 : renderContext.stateUnderCursor.size();
@@ -690,6 +693,8 @@ public class Timeline {
dframe = time % drawableFrameCount;
}
ExportRectangle viewRect2 = new ExportRectangle(viewRect);
if (filters != null && filters.size() > 0) {
// calculate size after applying the filters
double deltaXMax = 0;
@@ -704,12 +709,16 @@ public class Timeline {
rect.xMax += deltaXMax * unzoom * SWF.unitDivisor;
rect.yMin -= deltaYMax * unzoom * SWF.unitDivisor;
rect.yMax += deltaYMax * unzoom * SWF.unitDivisor;
viewRect2.xMin -= deltaXMax * SWF.unitDivisor;
viewRect2.xMax += deltaXMax * SWF.unitDivisor;
viewRect2.yMin -= deltaXMax * SWF.unitDivisor;
viewRect2.yMax += deltaXMax * SWF.unitDivisor;
}
rect.xMin -= SWF.unitDivisor;
rect.yMin -= SWF.unitDivisor;
rect.xMin = Math.max(0, rect.xMin);
rect.yMin = Math.max(0, rect.yMin);
/*rect.xMin = Math.max(0, rect.xMin);
rect.yMin = Math.max(0, rect.yMin);*/
drawMatrix.translate(rect.xMin, rect.yMin);
drawMatrix.translateX /= SWF.unitDivisor;
drawMatrix.translateY /= SWF.unitDivisor;
@@ -795,7 +804,7 @@ public class Timeline {
}
if (!(drawable instanceof ImageTag) || (swf.isAS3() && layer.hasImage)) {
drawable.toImage(dframe, time, ratio, renderContext, img, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, clrTrans2, unzoom, sameImage, viewRect, scaleStrokes, drawMode);
drawable.toImage(dframe, time, ratio, renderContext, img, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, clrTrans2, unzoom, sameImage, viewRect2, scaleStrokes, drawMode);
} else {
// todo: show one time warning
}
@@ -812,7 +821,8 @@ public class Timeline {
}
if (!sameImage && cacheAsBitmap && renderContext.displayObjectCache != null) {
renderContext.displayObjectCache.put(layer.placeObjectTag, img);
renderContext.clearPlaceObjectCache(layer.placeObjectTag);
renderContext.displayObjectCache.put(new DisplayObjectCacheKey(layer.placeObjectTag, unzoom, viewRect), img);
}
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.helpers;
import com.jpexs.decompiler.flash.helpers.Freed;
@@ -21,8 +22,11 @@ import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.WeakHashMap;
/**
@@ -169,4 +173,10 @@ public class Cache<K, V> implements Freed {
((Freed) cache).free();
}
}
public Set<K> keys() {
Set<K> ret = new HashSet<>();
ret.addAll(cache.keySet());
return ret;
}
}