Fixed: #1675 Viewport/zoom fix

This commit is contained in:
Jindra Petřík
2021-04-05 10:40:17 +02:00
parent 46f8e9a20c
commit 6b78b2fc44
17 changed files with 58 additions and 43 deletions

View File

@@ -2910,7 +2910,7 @@ public final class SWF implements SWFContainerItem, Timelined {
renderContext.cursorPosition = cursorPosition;
renderContext.mouseButton = mouseButton;
ExportRectangle viewRect = new ExportRectangle(rect);
timeline.toImage(frame, time, renderContext, image, false, m, new Matrix(), m, colorTransform, zoom, false, viewRect, m, true, Timeline.DRAW_MODE_ALL);
timeline.toImage(frame, time, renderContext, image, image, false, m, new Matrix(), m, colorTransform, zoom, false, viewRect, m, true, Timeline.DRAW_MODE_ALL);
return image;
}

View File

@@ -558,7 +558,7 @@ public class FrameExporter {
renderContext.stateUnderCursor = new ArrayList<>();
try {
tim.toImage(fframe, fframe, renderContext, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL);
tim.toImage(fframe, fframe, renderContext, image, image, false, m, new Matrix(), m, null, zoom, true, new ExportRectangle(rect), m, true, Timeline.DRAW_MODE_ALL);
} catch (Exception ex) {
ex.printStackTrace();
}

View File

@@ -123,7 +123,7 @@ public class ShapeExporter {
}
Matrix m = Matrix.getScaleInstance(settings.zoom);
m.translate(-rect.Xmin, -rect.Ymin);
st.toImage(0, 0, 0, new RenderContext(), img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL);
st.toImage(0, 0, 0, new RenderContext(), img, img, false, m, m, m, m, new CXFORMWITHALPHA(), unzoom, false, new ExportRectangle(rect), true, Timeline.DRAW_MODE_ALL);
if (settings.mode == ShapeExportMode.PNG) {
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file);
} else {

View File

@@ -121,4 +121,8 @@ public class ExportRectangle {
}
return true; //?
}
public ExportRectangle toPx() {
return new ExportRectangle(Math.round(xMin / 20), Math.round(yMin / 20), Math.round(xMax / 20), Math.round(yMax / 20));
}
}

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.exporters.commonshape;
import com.jpexs.decompiler.flash.types.MATRIX;
@@ -135,8 +136,8 @@ public final class Matrix implements Cloneable {
public ExportRectangle transform(ExportRectangle rect) {
double minX = Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
double maxX = -Double.MAX_VALUE;
double maxY = -Double.MAX_VALUE;
Point point;
point = transform(rect.xMin, rect.yMin);
if (point.x < minX) {

View File

@@ -961,7 +961,7 @@ public class DefineEditTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
render(TextRenderMode.BITMAP, image, null, null, transformation, colorTransform, 1);
}

View File

@@ -369,8 +369,8 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode);
}
@Override

View File

@@ -98,8 +98,8 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
getTimeline().toImage(frame, time, renderContext, image, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode);
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
getTimeline().toImage(frame, time, renderContext, image, fullImage, isClip, transformation, strokeTransformation, absoluteTransformation, colorTransform, unzoom, sameImage, viewRect, fullTransformation, scaleStrokes, drawMode);
}
@Override

View File

@@ -46,7 +46,7 @@ public abstract class DrawableTag extends CharacterTag implements BoundedTag {
public abstract Shape getOutline(int frame, int time, int ratio, RenderContext renderContext, Matrix transformation, boolean stroked);
public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode);
public abstract void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode);
public abstract void toSVG(SVGExporter exporter, int ratio, ColorTransform colorTransform, int level) throws IOException;

View File

@@ -433,7 +433,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform);
}

View File

@@ -231,7 +231,7 @@ public abstract class ImageTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
BitmapExporter.export(swf, getShape(), null, image, transformation, strokeTransformation, colorTransform, true);
}

View File

@@ -314,7 +314,7 @@ public abstract class MorphShapeTag extends DrawableTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
SHAPEWITHSTYLE shape = getShapeAtRatio(ratio);
// morphShape using shapeNum=3, morphShape2 using shapeNum=4
// todo: Currently the generated image is not cached, because the cache

View File

@@ -172,7 +172,7 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
BitmapExporter.export(swf, getShapes(), null, image, transformation, strokeTransformation, colorTransform, scaleStrokes);
if (Configuration._debugMode.get()) { // show control points
List<GeneralPath> paths = PathExporter.export(swf, getShapes());

View File

@@ -652,7 +652,7 @@ public abstract class StaticTextTag extends TextTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode) {
staticTextToImage(swf, textRecords, getTextNum(), image, textMatrix, transformation, colorTransform);
/*try {
TextTag originalTag = (TextTag) getOriginalTag();

View File

@@ -73,6 +73,7 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -124,7 +125,6 @@ public class Timeline {
public static final int DRAW_MODE_SHAPES = 1;
public static final int DRAW_MODE_SPRITES = 2;
private void ensureInitialized() {
if (!initialized) {
initialize();
@@ -621,7 +621,7 @@ public class Timeline {
toImage(frame, time, renderContext, image, isClip, transforms[i], absoluteTransformation, colorTransform, targetRect[i]);
}
}*/
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode) {
private void drawDrawable(Matrix strokeTransform, DepthState layer, Matrix layerMatrix, Graphics2D g, ColorTransform colorTransForm, int blendMode, List<Clip> clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, DrawableTag drawable, List<FILTER> filters, double unzoom, ColorTransform clrTrans, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode) {
Matrix drawMatrix = new Matrix();
int drawableFrameCount = drawable.getNumFrames();
if (drawableFrameCount == 0) {
@@ -632,31 +632,36 @@ public class Timeline {
ExportRectangle rect = new ExportRectangle(boundRect);
Matrix mat = transformation.concatenate(layerMatrix);
rect = mat.transform(rect);
ExportRectangle viewRectZoom = new ExportRectangle(viewRect);
viewRectZoom.xMin *= unzoom;
viewRectZoom.xMax *= unzoom;
viewRectZoom.yMin *= unzoom;
viewRectZoom.yMax *= unzoom;
ExportRectangle fullRect = fullTransformation.concatenate(layerMatrix).transform(new ExportRectangle(boundRect));
viewRectZoom.xMax -= viewRectZoom.xMin;
viewRectZoom.xMin = 0;
viewRectZoom.yMax -= viewRectZoom.yMin;
viewRectZoom.yMin = 0;
/*viewRectZoom.yMin += 5;
viewRectZoom.xMin += 5;
viewRectZoom.xMax -= 5;
viewRectZoom.yMax -= 5;*/
/*
Graphics2D fg = (Graphics2D) fullImage.getGraphics();
g.setColor(Color.green);
g.setTransform(drawMatrix.toTransform());
fg.setColor(Color.blue);
fg.setStroke(new BasicStroke(1));
fg.setTransform(new AffineTransform());
fg.drawRect((int) (fullRect.xMin / SWF.unitDivisor), (int) (fullRect.yMin / SWF.unitDivisor), (int) (fullRect.getWidth() / SWF.unitDivisor - 5), (int) (fullRect.getHeight() / SWF.unitDivisor - 5));
ExportRectangle fullRect = fullTransformation.concatenate(layerMatrix).transform(new ExportRectangle(boundRect));
fg.setColor(Color.green);
fg.setStroke(new BasicStroke(1));
fg.setTransform(new AffineTransform());
fg.drawRect((int) (viewRectZoom.xMin / SWF.unitDivisor + 5), (int) (viewRectZoom.yMin / SWF.unitDivisor + 5), (int) (viewRectZoom.getWidth() / SWF.unitDivisor - 5), (int) (viewRectZoom.getHeight() / SWF.unitDivisor - 5));
*/
if (!viewRectZoom.intersects(fullRect)) {
//System.err.println("hidden " + layer.characterId);
//System.err.println("hidden " + layer.characterId);
return;
}
@@ -678,7 +683,6 @@ public class Timeline {
g.drawLine(r.Xmin, r.Ymin, r.Xmax, r.Ymax);
g.drawLine(r.Xmax, r.Ymin, r.Xmin, r.Ymax);
g.setComposite(AlphaComposite.Dst);*/
SerializableImage img = null;
if (cacheAsBitmap && renderContext.displayObjectCache != null) {
DisplayObjectCacheKey key = new DisplayObjectCacheKey(layer.placeObjectTag, unzoom, viewRect);
@@ -769,10 +773,9 @@ public class Timeline {
if (clipDepth > -1) {
canUseSameImage = false;
}
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
Matrix mfull = mat.clone();
Matrix mfull = fullTransformation.concatenate(layerMatrix);
if (canUseSameImage && sameImage) {
img = image;
m = mat.clone();
@@ -788,6 +791,9 @@ public class Timeline {
}
};
}*/
} else {
img = new SerializableImage(newWidth, newHeight, SerializableImage.TYPE_INT_ARGB_PRE);
img.fillTransparent();
}
ColorTransform clrTrans2 = clrTrans;
@@ -804,7 +810,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, viewRect2, scaleStrokes, drawMode);
drawable.toImage(dframe, time, ratio, renderContext, img, fullImage, isClip || clipDepth > -1, m, strokeTransform, absMat, mfull, clrTrans2, unzoom, sameImage, viewRect2, scaleStrokes, drawMode);
} else {
// todo: show one time warning
}
@@ -926,6 +932,8 @@ public class Timeline {
if (!(sameImage && canUseSameImage)) {
g.setTransform(drawMatrix.toTransform());
g.drawImage(img.getBufferedImage(), 0, 0, null);
//g.setColor(Color.red);
//g.drawRect(0, 0, img.getWidth(), img.getHeight());
/*try {
ImageIO.write(img.getBufferedImage(), "PNG", new File("out.png"));
} catch (IOException ex) {
@@ -938,7 +946,7 @@ public class Timeline {
}
}
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode) {
public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, Matrix fullTransformation, boolean scaleStrokes, int drawMode) {
//double unzoom = SWF.unitDivisor;
//unzoom = SWF.unitDivisor;
if (getFrameCount() <= frame) {
@@ -947,6 +955,7 @@ public class Timeline {
Frame frameObj = getFrame(frame);
Graphics2D g = (Graphics2D) image.getGraphics();
Graphics2D fullG = (Graphics2D) fullImage.getGraphics();
Shape prevClip = g.getClip();
//if (targetRect != null) {
// g.setClip(new Rectangle2D.Double(targetRect.xMin, targetRect.yMin, targetRect.getWidth(), targetRect.getHeight()));
@@ -956,6 +965,7 @@ public class Timeline {
g.setPaint(frameObj.backgroundColor.toColor());
g.fill(new Rectangle(image.getWidth(), image.getHeight()));
}
sameImage = true;
g.setTransform(transformation.toTransform());
List<Clip> clips = new ArrayList<>();
@@ -1078,7 +1088,7 @@ public class Timeline {
Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight());
g.setClip(r);
drawDrawable(strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, false, DRAW_MODE_SHAPES);
drawDrawable(strokeTransformation, layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, false, DRAW_MODE_SHAPES);
s++;
}
}
@@ -1087,13 +1097,13 @@ public class Timeline {
g.setTransform(origTransform);
//draw all nonshapes (normally scaled) next
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES);
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, scaleStrokes, DRAW_MODE_SPRITES);
} else {
boolean subScaleStrokes = scaleStrokes;
if (character instanceof DefineSpriteTag) {
subScaleStrokes = true;
}
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, subScaleStrokes, DRAW_MODE_ALL);
drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation, isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, fullImage, (DrawableTag) character, layer.filters, unzoom, clrTrans, sameImage, viewRect, fullTransformation, subScaleStrokes, DRAW_MODE_ALL);
}
} else if (character instanceof BoundedTag) {
showPlaceholder = true;