All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.graphics.Outline Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics;

import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.graphics.drawable.Drawable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Defines a simple shape, used for bounding graphical regions.
 * 

* Can be computed for a View, or computed by a Drawable, to drive the shape of * shadows cast by a View, or to clip the contents of the View. * * @see android.view.ViewOutlineProvider * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider) * @see Drawable#getOutline(Outline) */ public final class Outline { private static final float RADIUS_UNDEFINED = Float.NEGATIVE_INFINITY; /** @hide */ public static final int MODE_EMPTY = 0; /** @hide */ public static final int MODE_ROUND_RECT = 1; /** @hide */ public static final int MODE_CONVEX_PATH = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = false, value = { MODE_EMPTY, MODE_ROUND_RECT, MODE_CONVEX_PATH, }) public @interface Mode {} /** @hide */ @Mode public int mMode = MODE_EMPTY; /** * Only guaranteed to be non-null when mode == MODE_CONVEX_PATH * * @hide */ public Path mPath; /** @hide */ @UnsupportedAppUsage public final Rect mRect = new Rect(); /** @hide */ public float mRadius = RADIUS_UNDEFINED; /** @hide */ public float mAlpha; /** * Constructs an empty Outline. Call one of the setter methods to make * the outline valid for use with a View. */ public Outline() {} /** * Constructs an Outline with a copy of the data in src. */ public Outline(@NonNull Outline src) { set(src); } /** * Sets the outline to be empty. * * @see #isEmpty() */ public void setEmpty() { if (mPath != null) { // rewind here to avoid thrashing the allocations, but could alternately clear ref mPath.rewind(); } mMode = MODE_EMPTY; mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; } /** * Returns whether the Outline is empty. *

* Outlines are empty when constructed, or if {@link #setEmpty()} is called, * until a setter method is called * * @see #setEmpty() */ public boolean isEmpty() { return mMode == MODE_EMPTY; } /** * Returns whether the outline can be used to clip a View. *

* Currently, only Outlines that can be represented as a rectangle, circle, * or round rect support clipping. * * @see android.view.View#setClipToOutline(boolean) */ public boolean canClip() { return mMode != MODE_CONVEX_PATH; } /** * Sets the alpha represented by the Outline - the degree to which the * producer is guaranteed to be opaque over the Outline's shape. *

* An alpha value of 0.0f either represents completely * transparent content, or content that isn't guaranteed to fill the shape * it publishes. *

* Content producing a fully opaque (alpha = 1.0f) outline is * assumed by the drawing system to fully cover content beneath it, * meaning content beneath may be optimized away. */ public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) { mAlpha = alpha; } /** * Returns the alpha represented by the Outline. */ public float getAlpha() { return mAlpha; } /** * Replace the contents of this Outline with the contents of src. * * @param src Source outline to copy from. */ public void set(@NonNull Outline src) { mMode = src.mMode; if (src.mMode == MODE_CONVEX_PATH) { if (mPath == null) { mPath = new Path(); } mPath.set(src.mPath); } mRect.set(src.mRect); mRadius = src.mRadius; mAlpha = src.mAlpha; } /** * Sets the Outline to the rounded rect defined by the input rect, and * corner radius. */ 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(@NonNull 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. *

* Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)} */ public void setRoundRect(int left, int top, int right, int bottom, float radius) { if (left >= right || top >= bottom) { setEmpty(); return; } if (mMode == MODE_CONVEX_PATH) { // rewind here to avoid thrashing the allocations, but could alternately clear ref mPath.rewind(); } mMode = MODE_ROUND_RECT; mRect.set(left, top, right, bottom); mRadius = radius; } /** * Convenience for {@link #setRoundRect(int, int, int, int, float)} */ public void setRoundRect(@NonNull Rect rect, float radius) { setRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius); } /** * Populates {@code outBounds} with the outline bounds, if set, and returns * {@code true}. If no outline bounds are set, or if a path has been set * via {@link #setConvexPath(Path)}, returns {@code false}. * * @param outRect the rect to populate with the outline bounds, if set * @return {@code true} if {@code outBounds} was populated with outline * bounds, or {@code false} if no outline bounds are set */ public boolean getRect(@NonNull Rect outRect) { if (mMode != MODE_ROUND_RECT) { return false; } outRect.set(mRect); return true; } /** * Returns the rounded rect radius, if set, or a value less than 0 if a path has * been set via {@link #setConvexPath(Path)}. A return value of {@code 0} * indicates a non-rounded rect. * * @return the rounded rect radius, or value < 0 */ public float getRadius() { return mRadius; } /** * Sets the outline to the oval defined by input rect. */ public void setOval(int left, int top, int right, int bottom) { if (left >= right || top >= bottom) { setEmpty(); return; } if ((bottom - top) == (right - left)) { // represent circle as round rect, for efficiency, and to enable clipping setRoundRect(left, top, right, bottom, (bottom - top) / 2.0f); return; } if (mPath == null) { mPath = new Path(); } else { mPath.rewind(); } mMode = MODE_CONVEX_PATH; mPath.addOval(left, top, right, bottom, Path.Direction.CW); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; } /** * Convenience for {@link #setOval(int, int, int, int)} */ public void setOval(@NonNull Rect rect) { setOval(rect.left, rect.top, rect.right, rect.bottom); } /** * Sets the Outline to a * {@link android.graphics.Path#isConvex() convex path}. * * @param convexPath used to construct the Outline. As of * {@link android.os.Build.VERSION_CODES#Q}, it is no longer required to be * convex. */ public void setConvexPath(@NonNull Path convexPath) { if (convexPath.isEmpty()) { setEmpty(); return; } if (mPath == null) { mPath = new Path(); } mMode = MODE_CONVEX_PATH; mPath.set(convexPath); mRect.setEmpty(); mRadius = RADIUS_UNDEFINED; } /** * Offsets the Outline by (dx,dy) */ public void offset(int dx, int dy) { if (mMode == MODE_ROUND_RECT) { mRect.offset(dx, dy); } else if (mMode == MODE_CONVEX_PATH) { mPath.offset(dx, dy); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy