From afc728a20355e3fa89542dc649e936802d4580e4 Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Fri, 18 Mar 2016 20:46:09 +0100 Subject: [PATCH] #1205: clipping fixed (only for bitmap export, probably it should be fixed for svg, canvas...) --- .../decompiler/flash/timeline/Timeline.java | 120 ++++++++++-------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 6128909a4..471513630 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.FrameExporter; import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; -import com.jpexs.decompiler.flash.exporters.commonshape.Point; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.tags.DefineScalingGridTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; @@ -66,7 +65,6 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -74,9 +72,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.imageio.ImageIO; /** * @@ -557,47 +552,47 @@ public class Timeline { } /*public void toImage(int frame, int time, RenderContext renderContext, SerializableImage image, boolean isClip, Matrix transformation, Matrix prevTransformation, Matrix absoluteTransformation, ColorTransform colorTransform) { - ExportRectangle scalingGrid = null; - if (timelined instanceof CharacterTag) { - DefineScalingGridTag sgt = ((CharacterTag) timelined).getScalingGridTag(); - if (sgt != null) { - scalingGrid = new ExportRectangle(sgt.splitter); - } - } + ExportRectangle scalingGrid = null; + if (timelined instanceof CharacterTag) { + DefineScalingGridTag sgt = ((CharacterTag) timelined).getScalingGridTag(); + if (sgt != null) { + scalingGrid = new ExportRectangle(sgt.splitter); + } + } - if (scalingGrid == null || transformation.rotateSkew0 != 0 || transformation.rotateSkew1 != 0) { - toImage(frame, time, renderContext, image, isClip, transformation, absoluteTransformation, colorTransform, null); - return; - } + if (scalingGrid == null || transformation.rotateSkew0 != 0 || transformation.rotateSkew1 != 0) { + toImage(frame, time, renderContext, image, isClip, transformation, absoluteTransformation, colorTransform, null); + return; + } - //9-slice scaling using DefineScalingGrid - Matrix diffTransform = prevTransformation.inverse().preConcatenate(transformation); - transformation = diffTransform; + //9-slice scaling using DefineScalingGrid + Matrix diffTransform = prevTransformation.inverse().preConcatenate(transformation); + transformation = diffTransform; - Matrix prevScale = new Matrix(); - prevScale.scaleX = prevTransformation.scaleX; - prevScale.scaleY = prevTransformation.scaleY; + Matrix prevScale = new Matrix(); + prevScale.scaleX = prevTransformation.scaleX; + prevScale.scaleY = prevTransformation.scaleY; - ExportRectangle boundsRect = new ExportRectangle(timelined.getRect()); + ExportRectangle boundsRect = new ExportRectangle(timelined.getRect()); - 0 | 1 | 2 - ------------ - 3 | 4 | 5 - ------------ - 6 | 7 | 8 + 0 | 1 | 2 + ------------ + 3 | 4 | 5 + ------------ + 6 | 7 | 8 - ExportRectangle targetRect[] = new ExportRectangle[9]; - ExportRectangle sourceRect[] = new ExportRectangle[9]; - Matrix transforms[] = new Matrix[9]; + ExportRectangle targetRect[] = new ExportRectangle[9]; + ExportRectangle sourceRect[] = new ExportRectangle[9]; + Matrix transforms[] = new Matrix[9]; - DefineScalingGridTag.getSlices(transformation, prevScale, boundsRect, scalingGrid, sourceRect, targetRect, transforms); + DefineScalingGridTag.getSlices(transformation, prevScale, boundsRect, scalingGrid, sourceRect, targetRect, transforms); - for (int i = 0; i < targetRect.length; i++) { - 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 clips, List prevClips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List filters, double unzoom, ColorTransform clrTrans) { + for (int i = 0; i < targetRect.length; i++) { + 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 clips, Matrix transformation, boolean isClip, int clipDepth, Matrix absMat, int time, int ratio, RenderContext renderContext, SerializableImage image, DrawableTag drawable, List filters, double unzoom, ColorTransform clrTrans) { Matrix drawMatrix = new Matrix(); int drawableFrameCount = drawable.getNumFrames(); if (drawableFrameCount == 0) { @@ -764,8 +759,7 @@ public class Timeline { gm.drawImage(img.getBufferedImage(), 0, 0, null); Clip clip = new Clip(Helper.imageToShape(mask), clipDepth); // Maybe we can get current outline instead converting from image (?) clips.add(clip); - prevClips.add(g.getClip()); - g.setTransform(AffineTransform.getTranslateInstance(0, 0)); + g.setTransform(new AffineTransform()); g.setClip(clip.shape); } else { if (renderContext.cursorPosition != null) { @@ -789,8 +783,20 @@ public class Timeline { g2.draw(shape); } + Shape prevClip = g.getClip(); + if (prevClip != null) { + g.setTransform(new AffineTransform()); + g.setClip(prevClip); + + // draw clip border +// g.setPaint(Color.red); +// g.setStroke(new BasicStroke(2)); +// g.draw(prevClip); + } + g.setTransform(trans); g.drawImage(img.getBufferedImage(), 0, 0, null); + g.setClip(prevClip); } } @@ -812,17 +818,25 @@ public class Timeline { g.setTransform(transformation.toTransform()); List clips = new ArrayList<>(); - List prevClips = new ArrayList<>(); int maxDepth = getMaxDepth(); for (int i = 1; i <= maxDepth; i++) { + boolean clipChanged = false; for (int c = 0; c < clips.size(); c++) { - if (clips.get(c).depth == i) { - g.setClip(prevClips.get(c)); - prevClips.remove(c); + if (clips.get(c).depth < i) { clips.remove(c); + clipChanged = true; } } + + if (clipChanged) { + if (clips.size() > 0) { + g.setClip(clips.get(clips.size() - 1).shape); // todo: merge clips? + } else { + g.setClip(null); + } + } + if (!frameObj.layers.containsKey(i)) { continue; } @@ -873,25 +887,25 @@ public class Timeline { Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight()); g.setClip(r); - drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, prevClips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans); + drawDrawable(strokeTransformation.preConcatenate(layerMatrix), layer, transforms[s], g, colorTransform, layer.blendMode, clips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans); } g.setClip(c); /* - for (int s = 0; s < 9; s++) { - g.setTransform(new AffineTransform()); - ExportRectangle p1 = transformation.transform(targetRect[s]); - g.setClip(c); + for (int s = 0; s < 9; s++) { + g.setTransform(new AffineTransform()); + ExportRectangle p1 = transformation.transform(targetRect[s]); + g.setClip(c); - Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight()); - g.setColor(Color.blue); - g.draw(r); + Rectangle2D r = new Rectangle2D.Double(p1.xMin, p1.yMin, p1.getWidth(), p1.getHeight()); + g.setColor(Color.blue); + g.draw(r); - }*/ + }*/ g.setTransform(origTransform); } else { - drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, prevClips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans); + drawDrawable(strokeTransformation, layer, layerMatrix, g, colorTransform, layer.blendMode, clips, transformation.clone(), isClip, layer.clipDepth, absMat, time, layer.ratio, renderContext, image, (DrawableTag) character, layer.filters, unzoom, clrTrans); } } else if (character instanceof BoundedTag) { showPlaceholder = true;