cache display object as it is written in SWF documentation (placeobject cache flag or has filters)

This commit is contained in:
honfika@gmail.com
2016-04-09 14:23:51 +02:00
parent ded2675b37
commit 729b78ceda
3 changed files with 80 additions and 69 deletions

View File

@@ -328,6 +328,9 @@ public final class SWF implements SWFContainerItem, Timelined {
@Internal
private final Cache<String, SerializableImage> frameCache = Cache.getInstance(false, false, "frame");
@Internal
private final Cache<PlaceObjectTypeTag, SerializableImage> displayObjectCache = Cache.getInstance(false, false, "displayObject");
@Internal
private final Cache<CharacterTag, RECT> rectCache = Cache.getInstance(true, true, "rect");
@@ -399,6 +402,7 @@ public final class SWF implements SWFContainerItem, Timelined {
as2Cache.clear();
as3Cache.clear();
frameCache.clear();
displayObjectCache.clear();
soundCache.clear();
timeline = null;
@@ -2483,6 +2487,13 @@ public final class SWF implements SWFContainerItem, Timelined {
return null;
}
public SerializableImage getFromCache(PlaceObjectTypeTag key) {
if (displayObjectCache.contains(key)) {
return displayObjectCache.get(key);
}
return null;
}
public byte[] getFromCache(SoundTag soundTag) {
if (soundCache.contains(soundTag)) {
return soundCache.get(soundTag);
@@ -2496,12 +2507,17 @@ public final class SWF implements SWFContainerItem, Timelined {
}
}
public void putToCache(PlaceObjectTypeTag key, SerializableImage img) {
displayObjectCache.put(key, img);
}
public void putToCache(SoundTag soundTag, byte[] data) {
soundCache.put(soundTag, data);
}
public void clearImageCache() {
frameCache.clear();
displayObjectCache.clear();
rectCache.clear();
for (Tag tag : getTags()) {
if (tag instanceof ImageTag) {

View File

@@ -19,9 +19,7 @@ package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.helpers.SerializableImage;
import java.awt.Point;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
@@ -37,7 +35,5 @@ public class RenderContext {
public ButtonTag mouseOverButton;
public Map<String, SerializableImage> shapeCache = new HashMap<>();
public SerializableImage borderImage;
}

View File

@@ -606,7 +606,7 @@ public class Timeline {
Matrix mat = transformation.concatenate(layerMatrix);
rect = mat.transform(rect);
boolean cacheAsBitmap = layer.cacheAsBitmap() && drawable.isSingleFrame();
boolean cacheAsBitmap = layer.cacheAsBitmap() && layer.placeObjectTag != null && drawable.isSingleFrame();
/* // draw bounds
AffineTransform trans = mat.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).toTransform();
g.setTransform(trans);
@@ -622,50 +622,12 @@ public class Timeline {
g.drawLine(r.Xmax, r.Ymin, r.Xmin, r.Ymax);
g.setComposite(AlphaComposite.Dst);*/
if (filters != null && filters.size() > 0) {
// calculate size after applying the filters
double deltaXMax = 0;
double deltaYMax = 0;
for (FILTER filter : filters) {
double x = filter.getDeltaX();
double y = filter.getDeltaY();
deltaXMax = Math.max(x, deltaXMax);
deltaYMax = Math.max(y, deltaYMax);
}
rect.xMin -= deltaXMax * unzoom;
rect.xMax += deltaXMax * unzoom;
rect.yMin -= deltaYMax * unzoom;
rect.yMax += deltaYMax * unzoom;
}
rect.xMin -= 1 * unzoom;
rect.yMin -= 1 * unzoom;
rect.xMin = Math.max(0, rect.xMin);
rect.yMin = Math.max(0, rect.yMin);
int newWidth = (int) (rect.getWidth() / unzoom);
int newHeight = (int) (rect.getHeight() / unzoom);
int deltaX = (int) (rect.xMin / unzoom);
int deltaY = (int) (rect.yMin / unzoom);
newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1;
newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1;
if (newWidth <= 0 || newHeight <= 0) {
return;
}
Matrix m = mat.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
//strokeTransform = strokeTransform.clone();
//strokeTransform.translate(-rect.xMin, -rect.yMin);
drawMatrix.translate(rect.xMin, rect.yMin);
SerializableImage img = null;
String cacheKey = null;
if (drawable instanceof ShapeTag) {
cacheKey = ((ShapeTag) drawable).getCharacterId() + m.toString() + (clrTrans == null ? "" : clrTrans.toString());
//img = renderContext.shapeCache.get(cacheKey);
if (cacheAsBitmap) {
swf.getFromCache(layer.placeObjectTag);
}
int stateCount = renderContext.stateUnderCursor == null ? 0 : renderContext.stateUnderCursor.size();
int dframe;
if (fontFrameNum != -1) {
dframe = fontFrameNum;
@@ -673,40 +635,77 @@ public class Timeline {
dframe = time % drawableFrameCount;
}
if (drawable instanceof ButtonTag) {
dframe = ButtonTag.FRAME_UP;
if (renderContext.cursorPosition != null) {
Shape buttonShape = drawable.getOutline(ButtonTag.FRAME_HITTEST, time, ratio, renderContext, absMat, true);
if (buttonShape.contains(renderContext.cursorPosition)) {
renderContext.mouseOverButton = (ButtonTag) drawable;
if (renderContext.mouseButton > 0) {
dframe = ButtonTag.FRAME_DOWN;
} else {
dframe = ButtonTag.FRAME_OVER;
if (img == null) {
if (filters != null && filters.size() > 0) {
// calculate size after applying the filters
double deltaXMax = 0;
double deltaYMax = 0;
for (FILTER filter : filters) {
double x = filter.getDeltaX();
double y = filter.getDeltaY();
deltaXMax = Math.max(x, deltaXMax);
deltaYMax = Math.max(y, deltaYMax);
}
rect.xMin -= deltaXMax * unzoom;
rect.xMax += deltaXMax * unzoom;
rect.yMin -= deltaYMax * unzoom;
rect.yMax += deltaYMax * unzoom;
}
rect.xMin -= 1 * unzoom;
rect.yMin -= 1 * unzoom;
rect.xMin = Math.max(0, rect.xMin);
rect.yMin = Math.max(0, rect.yMin);
int newWidth = (int) (rect.getWidth() / unzoom);
int newHeight = (int) (rect.getHeight() / unzoom);
int deltaX = (int) (rect.xMin / unzoom);
int deltaY = (int) (rect.yMin / unzoom);
newWidth = Math.min(image.getWidth() - deltaX, newWidth) + 1;
newHeight = Math.min(image.getHeight() - deltaY, newHeight) + 1;
if (newWidth <= 0 || newHeight <= 0) {
return;
}
Matrix m = mat.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
//strokeTransform = strokeTransform.clone();
//strokeTransform.translate(-rect.xMin, -rect.yMin);
drawMatrix.translate(rect.xMin, rect.yMin);
if (drawable instanceof ButtonTag) {
dframe = ButtonTag.FRAME_UP;
if (renderContext.cursorPosition != null) {
Shape buttonShape = drawable.getOutline(ButtonTag.FRAME_HITTEST, time, ratio, renderContext, absMat, true);
if (buttonShape.contains(renderContext.cursorPosition)) {
renderContext.mouseOverButton = (ButtonTag) drawable;
if (renderContext.mouseButton > 0) {
dframe = ButtonTag.FRAME_DOWN;
} else {
dframe = ButtonTag.FRAME_OVER;
}
}
}
}
}
int stateCount = renderContext.stateUnderCursor == null ? 0 : renderContext.stateUnderCursor.size();
if (img == null) {
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB);
img.fillTransparent();
drawable.toImage(dframe, time, ratio, renderContext, img, isClip || clipDepth > -1, m, strokeTransform, absMat, clrTrans);
if (cacheKey != null) {
renderContext.shapeCache.put(cacheKey, img);
if (filters != null) {
for (FILTER filter : filters) {
img = filter.apply(img);
}
}
}
if (filters != null) {
for (FILTER filter : filters) {
img = filter.apply(img);
if (blendMode > 1) {
if (colorTransForm != null) {
img = colorTransForm.apply(img);
}
}
}
if (blendMode > 1) {
if (colorTransForm != null) {
img = colorTransForm.apply(img);
if (cacheAsBitmap) {
swf.putToCache(layer.placeObjectTag, img);
}
}