Loading api/current.txt +8 −3 Original line number Diff line number Diff line Loading @@ -10023,11 +10023,16 @@ package android.graphics { method public void setPaint(android.graphics.Paint); } public class Outline { public final class Outline { ctor public Outline(); method public final boolean isValid(); ctor public Outline(android.graphics.Outline); method public boolean isValid(); method public void set(android.graphics.Outline); method public void setConvexPath(android.graphics.Path); method public void setRect(int, int, int, int); method public void setRect(android.graphics.Rect); method public void setRoundRect(int, int, int, int, float); method public void setRoundRect(android.graphics.Rect, float); } public class Paint { Loading Loading @@ -10750,7 +10755,7 @@ package android.graphics.drawable { method public int getMinimumHeight(); method public int getMinimumWidth(); method public abstract int getOpacity(); method public android.graphics.Outline getOutline(); method public boolean getOutline(android.graphics.Outline); method public boolean getPadding(android.graphics.Rect); method public int[] getState(); method public android.graphics.Region getTransparentRegion(); core/java/android/view/View.java +30 −54 Original line number Diff line number Diff line Loading @@ -2374,25 +2374,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_CALLED_SUPER = 0x10; /** * Flag indicating that an view will be clipped to its outline. */ static final int PFLAG3_CLIP_TO_OUTLINE = 0x20; /** * Flag indicating that a view's outline has been specifically defined. */ static final int PFLAG3_OUTLINE_DEFINED = 0x40; static final int PFLAG3_OUTLINE_DEFINED = 0x20; /** * Flag indicating that we're in the process of applying window insets. */ static final int PFLAG3_APPLYING_INSETS = 0x80; static final int PFLAG3_APPLYING_INSETS = 0x40; /** * Flag indicating that we're in the process of fitting system windows using the old method. */ static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x100; static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80; /** * Flag indicating that nested scrolling is enabled for this view. Loading Loading @@ -3258,9 +3253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Stores the outline of the view, passed down to the DisplayList level for * defining shadow shape and clipping. * * TODO: once RenderNode is long-lived, remove this and rely on native copy. * defining shadow shape. */ private Outline mOutline; Loading Loading @@ -10572,16 +10565,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Sets the outline of the view, which defines the shape of the shadow it * casts, and can used for clipping. * casts. * <p> * If the outline is not set or is null, shadows will be cast from the * bounds of the View, and clipToOutline will be ignored. * bounds of the View. * * @param outline The new outline of the view. * Must be {@link android.graphics.Outline#isValid() valid.} * * @see #getClipToOutline() * @see #setClipToOutline(boolean) */ public void setOutline(@Nullable Outline outline) { if (outline != null && !outline.isValid()) { Loading @@ -10595,46 +10585,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { // always copy the path since caller may reuse if (mOutline == null) { mOutline = new Outline(); mOutline = new Outline(outline); } mOutline.set(outline); } mRenderNode.setOutline(mOutline); } /** * Returns whether the outline of the View will be used for clipping. * * @see #setOutline(Outline) */ public final boolean getClipToOutline() { return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0); } // TODO: remove public final boolean getClipToOutline() { return false; } public void setClipToOutline(boolean clipToOutline) {} /** * Sets whether the outline of the View will be used for clipping. * <p> * The current implementation of outline clipping uses * {@link Canvas#clipPath(Path) path clipping}, * and thus does not support anti-aliasing, and is expensive in terms of * graphics performance. Therefore, it is strongly recommended that this * property only be set temporarily, as in an animation. For the same * reasons, there is no parallel XML attribute for this property. * <p> * If the outline of the view is not set or is empty, no clipping will be * performed. * * @see #setOutline(Outline) */ public void setClipToOutline(boolean clipToOutline) { // TODO : Add a fast invalidation here. if (getClipToOutline() != clipToOutline) { if (clipToOutline) { mPrivateFlags3 |= PFLAG3_CLIP_TO_OUTLINE; private void queryOutlineFromBackgroundIfUndefined() { if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) { // Outline not currently defined, query from background if (mOutline == null) { mOutline = new Outline(); } else { mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE; mOutline.markInvalid(); } if (mBackground.getOutline(mOutline)) { if (!mOutline.isValid()) { throw new IllegalStateException("Background drawable failed to build outline"); } mRenderNode.setOutline(mOutline); } else { mRenderNode.setOutline(null); } mRenderNode.setClipToOutline(clipToOutline); } } Loading Loading @@ -14893,11 +14869,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mBackgroundSizeChanged) { background.setBounds(0, 0, mRight - mLeft, mBottom - mTop); mBackgroundSizeChanged = false; if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) { // Outline not currently define, query from background mOutline = background.getOutline(); mRenderNode.setOutline(mOutline); } queryOutlineFromBackgroundIfUndefined(); } // Attempt to use a display list if requested. Loading Loading @@ -15299,7 +15271,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param drawable the drawable to invalidate */ @Override public void invalidateDrawable(Drawable drawable) { public void invalidateDrawable(@NonNull Drawable drawable) { if (verifyDrawable(drawable)) { final Rect dirty = drawable.getDirtyBounds(); final int scrollX = mScrollX; Loading @@ -15307,6 +15279,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, invalidate(dirty.left + scrollX, dirty.top + scrollY, dirty.right + scrollX, dirty.bottom + scrollY); if (drawable == mBackground) { queryOutlineFromBackgroundIfUndefined(); } } } graphics/java/android/graphics/Outline.java +42 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } /** Loading @@ -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(); Loading @@ -92,10 +111,17 @@ public class Outline { mPath = null; } /** * 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()) { Loading graphics/java/android/graphics/drawable/Drawable.java +12 −13 Original line number Diff line number Diff line Loading @@ -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 Loading graphics/java/android/graphics/drawable/GradientDrawable.java +23 −22 Original line number Diff line number Diff line Loading @@ -139,7 +139,6 @@ 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 Loading Loading @@ -577,11 +576,7 @@ public class GradientDrawable extends Drawable { 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); Loading Loading @@ -639,6 +634,15 @@ 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; Loading Loading @@ -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; } } Loading Loading
api/current.txt +8 −3 Original line number Diff line number Diff line Loading @@ -10023,11 +10023,16 @@ package android.graphics { method public void setPaint(android.graphics.Paint); } public class Outline { public final class Outline { ctor public Outline(); method public final boolean isValid(); ctor public Outline(android.graphics.Outline); method public boolean isValid(); method public void set(android.graphics.Outline); method public void setConvexPath(android.graphics.Path); method public void setRect(int, int, int, int); method public void setRect(android.graphics.Rect); method public void setRoundRect(int, int, int, int, float); method public void setRoundRect(android.graphics.Rect, float); } public class Paint { Loading Loading @@ -10750,7 +10755,7 @@ package android.graphics.drawable { method public int getMinimumHeight(); method public int getMinimumWidth(); method public abstract int getOpacity(); method public android.graphics.Outline getOutline(); method public boolean getOutline(android.graphics.Outline); method public boolean getPadding(android.graphics.Rect); method public int[] getState(); method public android.graphics.Region getTransparentRegion();
core/java/android/view/View.java +30 −54 Original line number Diff line number Diff line Loading @@ -2374,25 +2374,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_CALLED_SUPER = 0x10; /** * Flag indicating that an view will be clipped to its outline. */ static final int PFLAG3_CLIP_TO_OUTLINE = 0x20; /** * Flag indicating that a view's outline has been specifically defined. */ static final int PFLAG3_OUTLINE_DEFINED = 0x40; static final int PFLAG3_OUTLINE_DEFINED = 0x20; /** * Flag indicating that we're in the process of applying window insets. */ static final int PFLAG3_APPLYING_INSETS = 0x80; static final int PFLAG3_APPLYING_INSETS = 0x40; /** * Flag indicating that we're in the process of fitting system windows using the old method. */ static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x100; static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80; /** * Flag indicating that nested scrolling is enabled for this view. Loading Loading @@ -3258,9 +3253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Stores the outline of the view, passed down to the DisplayList level for * defining shadow shape and clipping. * * TODO: once RenderNode is long-lived, remove this and rely on native copy. * defining shadow shape. */ private Outline mOutline; Loading Loading @@ -10572,16 +10565,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Sets the outline of the view, which defines the shape of the shadow it * casts, and can used for clipping. * casts. * <p> * If the outline is not set or is null, shadows will be cast from the * bounds of the View, and clipToOutline will be ignored. * bounds of the View. * * @param outline The new outline of the view. * Must be {@link android.graphics.Outline#isValid() valid.} * * @see #getClipToOutline() * @see #setClipToOutline(boolean) */ public void setOutline(@Nullable Outline outline) { if (outline != null && !outline.isValid()) { Loading @@ -10595,46 +10585,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { // always copy the path since caller may reuse if (mOutline == null) { mOutline = new Outline(); mOutline = new Outline(outline); } mOutline.set(outline); } mRenderNode.setOutline(mOutline); } /** * Returns whether the outline of the View will be used for clipping. * * @see #setOutline(Outline) */ public final boolean getClipToOutline() { return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0); } // TODO: remove public final boolean getClipToOutline() { return false; } public void setClipToOutline(boolean clipToOutline) {} /** * Sets whether the outline of the View will be used for clipping. * <p> * The current implementation of outline clipping uses * {@link Canvas#clipPath(Path) path clipping}, * and thus does not support anti-aliasing, and is expensive in terms of * graphics performance. Therefore, it is strongly recommended that this * property only be set temporarily, as in an animation. For the same * reasons, there is no parallel XML attribute for this property. * <p> * If the outline of the view is not set or is empty, no clipping will be * performed. * * @see #setOutline(Outline) */ public void setClipToOutline(boolean clipToOutline) { // TODO : Add a fast invalidation here. if (getClipToOutline() != clipToOutline) { if (clipToOutline) { mPrivateFlags3 |= PFLAG3_CLIP_TO_OUTLINE; private void queryOutlineFromBackgroundIfUndefined() { if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) { // Outline not currently defined, query from background if (mOutline == null) { mOutline = new Outline(); } else { mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE; mOutline.markInvalid(); } if (mBackground.getOutline(mOutline)) { if (!mOutline.isValid()) { throw new IllegalStateException("Background drawable failed to build outline"); } mRenderNode.setOutline(mOutline); } else { mRenderNode.setOutline(null); } mRenderNode.setClipToOutline(clipToOutline); } } Loading Loading @@ -14893,11 +14869,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mBackgroundSizeChanged) { background.setBounds(0, 0, mRight - mLeft, mBottom - mTop); mBackgroundSizeChanged = false; if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) { // Outline not currently define, query from background mOutline = background.getOutline(); mRenderNode.setOutline(mOutline); } queryOutlineFromBackgroundIfUndefined(); } // Attempt to use a display list if requested. Loading Loading @@ -15299,7 +15271,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param drawable the drawable to invalidate */ @Override public void invalidateDrawable(Drawable drawable) { public void invalidateDrawable(@NonNull Drawable drawable) { if (verifyDrawable(drawable)) { final Rect dirty = drawable.getDirtyBounds(); final int scrollX = mScrollX; Loading @@ -15307,6 +15279,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, invalidate(dirty.left + scrollX, dirty.top + scrollY, dirty.right + scrollX, dirty.bottom + scrollY); if (drawable == mBackground) { queryOutlineFromBackgroundIfUndefined(); } } }
graphics/java/android/graphics/Outline.java +42 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } /** Loading @@ -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(); Loading @@ -92,10 +111,17 @@ public class Outline { mPath = null; } /** * 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()) { Loading
graphics/java/android/graphics/drawable/Drawable.java +12 −13 Original line number Diff line number Diff line Loading @@ -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 Loading
graphics/java/android/graphics/drawable/GradientDrawable.java +23 −22 Original line number Diff line number Diff line Loading @@ -139,7 +139,6 @@ 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 Loading Loading @@ -577,11 +576,7 @@ public class GradientDrawable extends Drawable { 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); Loading Loading @@ -639,6 +634,15 @@ 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; Loading Loading @@ -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; } } Loading