diff options
author | Chris Craik <ccraik@google.com> | 2014-04-25 16:22:26 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-25 16:22:26 +0000 |
commit | 07f0b8ee730be00a2a4bccf797bd8cb71e556546 (patch) | |
tree | e629c241f25ca4996800f818c90346491b088a22 /graphics | |
parent | c806d5393f22e514c621f8a8a335156f7d45a299 (diff) | |
parent | e6a39b12656ab8d5c77d8366b24aa6410fd42e11 (diff) | |
download | frameworks_base-07f0b8ee730be00a2a4bccf797bd8cb71e556546.zip frameworks_base-07f0b8ee730be00a2a4bccf797bd8cb71e556546.tar.gz frameworks_base-07f0b8ee730be00a2a4bccf797bd8cb71e556546.tar.bz2 |
Merge "Refactor Drawable outline production, flesh out Outline methods"
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/java/android/graphics/Outline.java | 58 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/Drawable.java | 25 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/GradientDrawable.java | 45 |
3 files changed, 77 insertions, 51 deletions
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 4ea7ec7..d3aac79 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -16,18 +16,19 @@ package android.graphics; +import android.graphics.drawable.Drawable; import android.view.View; /** * Defines an area of content. * - * Can be used with a View or Drawable to drive the shape of shadows cast by a + * Can be used with a View, or computed by a Drawable, to drive the shape of shadows cast by a * View, and allowing Views to clip inner content. * * @see View#setOutline(Outline) - * @see View#setClipToOutline(boolean) + * @see Drawable#getOutline(Outline) */ -public class Outline { +public final class Outline { /** @hide */ public Rect mRect; @@ -44,19 +45,26 @@ public class Outline { public Outline() {} /** - * Returns whether the Outline is valid for use with a View. - * <p> - * Outlines are invalid when constructed until a setter method is called. + * Constructs an Outline with a copy of the data in src. */ - public final boolean isValid() { - return mRect != null || mPath != null; + public Outline(Outline src) { + set(src); + } + + /** @hide */ + public void markInvalid() { + mRadius = 0; + mRect = null; + mPath = null; } /** - * @hide + * Returns whether the Outline is valid for use with a View. + * <p> + * Outlines are invalid when constructed until a setter method is called. */ - public final boolean canClip() { - return mPath == null; + public boolean isValid() { + return mRect != null || mPath != null; } /** @@ -81,9 +89,20 @@ public class Outline { /** * Sets the Outline to the rounded rect defined by the input rect, and corner radius. - * <p> - * Outlines produced by this method support - * {@link View#setClipToOutline(boolean) View clipping.} + */ + public void setRect(int left, int top, int right, int bottom) { + setRoundRect(left, top, right, bottom, 0.0f); + } + + /** + * Convenience for {@link #setRect(int, int, int, int)} + */ + public void setRect(Rect rect) { + setRect(rect.left, rect.top, rect.right, rect.bottom); + } + + /** + * Sets the Outline to the rounded rect defined by the input rect, and corner radius. */ public void setRoundRect(int left, int top, int right, int bottom, float radius) { if (mRect == null) mRect = new Rect(); @@ -93,9 +112,16 @@ public class Outline { } /** + * Convenience for {@link #setRoundRect(int, int, int, int, float)} + * @param rect + * @param radius + */ + public void setRoundRect(Rect rect, float radius) { + setRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius); + } + + /** * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}. - * - * @hide */ public void setConvexPath(Path convexPath) { if (!convexPath.isConvex()) { diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 74d1219..b9d5e19 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -864,22 +864,21 @@ public abstract class Drawable { } /** - * Returns the outline for this drawable if defined, null if not. + * Called to get the drawable to populate the Outline. * <p> - * This method will be called by a View on its background Drawable after - * bounds change, if the View's Outline isn't set explicitly. This allows - * the background Drawable to provide the shape of the shadow casting - * portion of the View. It can also serve to clip the area of the View if - * if {@link View#setClipToOutline(boolean)} is set on the View. - * <p> - * The Outline queried by the View will not be modified, and is treated as - * a static shape that only needs to be requeried when the drawable's bounds - * change. + * This method will be called by a View on its background Drawable after bounds change, or its + * Drawable is invalidated, if the View's Outline isn't set explicitly. This allows the + * background Drawable to define the shape of the shadow cast by the View. + * + * The default behavior defines the outline to be the bounding rectangle. Subclasses that wish + * to convey a different shape must override this method. * - * @see View#setOutline(android.view.Outline) - * @see View#setClipToOutline(boolean) + * @see View#setOutline(android.graphics.Outline) */ - public Outline getOutline() { return null; } + public boolean getOutline(Outline outline) { + outline.setRect(getBounds()); + return true; + } /** * Make this drawable mutable. This operation cannot be reversed. A mutable diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 1b5cefe..708c8b0 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -139,8 +139,7 @@ public class GradientDrawable extends Drawable { private final Path mPath = new Path(); private final RectF mRect = new RectF(); - private Outline mOutline; - + private Paint mLayerPaint; // internal, used if we use saveLayer() private boolean mRectIsDirty; // internal state private boolean mMutated; @@ -573,15 +572,11 @@ public class GradientDrawable extends Drawable { mStrokePaint.setColorFilter(mColorFilter); } } - + switch (st.mShape) { case RECTANGLE: if (st.mRadiusArray != null) { - if (mPathIsDirty || mRectIsDirty) { - mPath.reset(); - mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); - mPathIsDirty = mRectIsDirty = false; - } + buildPathIfDirty(); canvas.drawPath(mPath, mFillPaint); if (haveStroke) { canvas.drawPath(mPath, mStrokePaint); @@ -638,7 +633,16 @@ public class GradientDrawable extends Drawable { } } } - + + private void buildPathIfDirty() { + final GradientState st = mGradientState; + if (mPathIsDirty || mRectIsDirty) { + mPath.reset(); + mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); + mPathIsDirty = mRectIsDirty = false; + } + } + private Path buildRing(GradientState st) { if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath; mPathIsDirty = false; @@ -1428,42 +1432,39 @@ public class GradientDrawable extends Drawable { } @Override - public Outline getOutline() { + public boolean getOutline(Outline outline) { final GradientState st = mGradientState; final Rect bounds = getBounds(); switch (st.mShape) { case RECTANGLE: if (st.mRadiusArray != null) { - return null; + buildPathIfDirty(); + outline.setConvexPath(mPath); + return true; } + float rad = 0; if (st.mRadius > 0.0f) { // clamp the radius based on width & height, matching behavior in draw() rad = Math.min(st.mRadius, Math.min(bounds.width(), bounds.height()) * 0.5f); } - if (mOutline == null) { - mOutline = new Outline(); - } - mOutline.setRoundRect(bounds.left, bounds.top, + outline.setRoundRect(bounds.left, bounds.top, bounds.right, bounds.bottom, rad); - return mOutline; + return true; case LINE: { float halfStrokeWidth = mStrokePaint.getStrokeWidth() * 0.5f; float centerY = bounds.centerY(); int top = (int) Math.floor(centerY - halfStrokeWidth); int bottom = (int) Math.ceil(centerY + halfStrokeWidth); - if (mOutline == null) { - mOutline = new Outline(); - } - mOutline.setRoundRect(bounds.left, top, bounds.right, bottom, 0); - return mOutline; + outline.setRect(bounds.left, top, bounds.right, bottom); + return true; } default: // TODO: investigate - return null; + return false; } } |