diff options
| -rw-r--r-- | tools/layoutlib/bridge/src/android/view/RectShadowPainter.java | 16 | ||||
| -rw-r--r-- | tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java | 30 |
2 files changed, 43 insertions, 3 deletions
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java index d15cb4865544..fad35d2102d8 100644 --- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java +++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java @@ -16,6 +16,7 @@ package android.view; +import com.android.layoutlib.bridge.impl.GcSnapshot; import com.android.layoutlib.bridge.impl.ResourceHelper; import android.graphics.Canvas; @@ -32,6 +33,8 @@ import android.graphics.RectF; import android.graphics.Region.Op; import android.graphics.Shader.TileMode; +import java.awt.Rectangle; + /** * Paints shadow for rounded rectangles. Inspiration from CardView. Couldn't use that directly, * since it modifies the size of the content, that we can't do. @@ -127,9 +130,16 @@ public class RectShadowPainter { int saved = canvas.save(); // Usually canvas has been translated to the top left corner of the view when this is // called. So, setting a clip rect at 0,0 will clip the top left part of the shadow. - // Thus, we just expand in each direction by width and height of the canvas. - canvas.clipRect(-canvas.getWidth(), -canvas.getHeight(), canvas.getWidth(), - canvas.getHeight(), Op.REPLACE); + // Thus, we just expand in each direction by width and height of the canvas, while staying + // inside the original drawing region. + GcSnapshot snapshot = Canvas_Delegate.getDelegate(canvas).getSnapshot(); + Rectangle originalClip = snapshot.getOriginalClip(); + if (originalClip != null) { + canvas.clipRect(originalClip.x, originalClip.y, originalClip.x + originalClip.width, + originalClip.y + originalClip.height, Op.REPLACE); + canvas.clipRect(-canvas.getWidth(), -canvas.getHeight(), canvas.getWidth(), + canvas.getHeight(), Op.INTERSECT); + } canvas.translate(0, shadowSize / 2f); return saved; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java index 769ee338a713..e80cbf27f232 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java @@ -40,6 +40,7 @@ import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; +import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.ArrayList; @@ -870,4 +871,33 @@ public class GcSnapshot { dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7])); } + /** + * Returns the clip of the oldest snapshot of the stack, appropriately translated to be + * expressed in the coordinate system of the latest snapshot. + */ + public Rectangle getOriginalClip() { + GcSnapshot originalSnapshot = this; + while (originalSnapshot.mPrevious != null) { + originalSnapshot = originalSnapshot.mPrevious; + } + if (originalSnapshot.mLayers.isEmpty()) { + return null; + } + Graphics2D graphics2D = originalSnapshot.mLayers.get(0).getGraphics(); + Rectangle bounds = graphics2D.getClipBounds(); + if (bounds == null) { + return null; + } + try { + AffineTransform originalTransform = + ((Graphics2D) graphics2D.create()).getTransform().createInverse(); + AffineTransform latestTransform = getTransform().createInverse(); + bounds.x += latestTransform.getTranslateX() - originalTransform.getTranslateX(); + bounds.y += latestTransform.getTranslateY() - originalTransform.getTranslateY(); + } catch (NoninvertibleTransformException e) { + Bridge.getLog().warning(null, "Non invertible transformation", null); + } + return bounds; + } + } |