diff options
-rwxr-xr-x | api/current.txt | 2 | ||||
-rw-r--r-- | core/jni/android_graphics_Canvas.cpp | 28 | ||||
-rw-r--r-- | graphics/java/android/graphics/BaseCanvas.java | 57 | ||||
-rw-r--r-- | graphics/java/android/graphics/BaseRecordingCanvas.java | 30 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 45 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 4 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.cpp | 35 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.h | 12 |
9 files changed, 218 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 1b0971000f3a..edf5a87e05ec 100755 --- a/api/current.txt +++ b/api/current.txt @@ -13394,6 +13394,8 @@ package android.graphics { method public void drawCircle(float, float, float, android.graphics.Paint); method public void drawColor(int); method public void drawColor(int, android.graphics.PorterDuff.Mode); + method public void drawDoubleRoundRect(android.graphics.RectF, float, float, android.graphics.RectF, float, float, android.graphics.Paint); + method public void drawDoubleRoundRect(android.graphics.RectF, float[], android.graphics.RectF, float[], android.graphics.Paint); method public void drawLine(float, float, float, float, android.graphics.Paint); method public void drawLines(float[], int, int, android.graphics.Paint); method public void drawLines(float[], android.graphics.Paint); diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 343aef291720..dca2da369540 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -273,6 +273,32 @@ static void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jflo get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint); } +static void drawDoubleRoundRectXY(JNIEnv* env, jobject, jlong canvasHandle, jfloat outerLeft, + jfloat outerTop, jfloat outerRight, jfloat outerBottom, jfloat outerRx, + jfloat outerRy, jfloat innerLeft, jfloat innerTop, jfloat innerRight, + jfloat innerBottom, jfloat innerRx, jfloat innerRy, jlong paintHandle) { + const Paint* paint = reinterpret_cast<Paint*>(paintHandle); + get_canvas(canvasHandle)->drawDoubleRoundRectXY( + outerLeft, outerTop, outerRight, outerBottom, outerRx, outerRy, + innerLeft, innerTop, innerRight, innerBottom, innerRx, innerRy, *paint); +} + +static void drawDoubleRoundRectRadii(JNIEnv* env, jobject, jlong canvasHandle, jfloat outerLeft, + jfloat outerTop, jfloat outerRight, jfloat outerBottom, jfloatArray jouterRadii, + jfloat innerLeft, jfloat innerTop, jfloat innerRight, + jfloat innerBottom, jfloatArray jinnerRadii, jlong paintHandle) { + const Paint* paint = reinterpret_cast<Paint*>(paintHandle); + + float outerRadii[8]; + float innerRadii[8]; + env->GetFloatArrayRegion(jouterRadii, 0, 8, outerRadii); + env->GetFloatArrayRegion(jinnerRadii, 0, 8, innerRadii); + get_canvas(canvasHandle)->drawDoubleRoundRectRadii( + outerLeft, outerTop, outerRight, outerBottom, outerRadii, + innerLeft, innerTop, innerRight, innerBottom, innerRadii, *paint); + +} + static void drawRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong regionHandle, jlong paintHandle) { const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle); @@ -651,6 +677,8 @@ static const JNINativeMethod gDrawMethods[] = { {"nDrawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect}, {"nDrawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion }, {"nDrawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect}, + {"nDrawDoubleRoundRect", "(JFFFFFFFFFFFFJ)V", (void*) CanvasJNI::drawDoubleRoundRectXY}, + {"nDrawDoubleRoundRect", "(JFFFF[FFFFF[FJ)V", (void*) CanvasJNI::drawDoubleRoundRectRadii}, {"nDrawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle}, {"nDrawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval}, {"nDrawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc}, diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index fa37bedb06c4..0885a05c74f3 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -376,6 +376,53 @@ public abstract class BaseCanvas { drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint); } + /** + * Make lint happy. + * See {@link Canvas#drawDoubleRoundRect(RectF, float, float, RectF, float, float, Paint)} + */ + public void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy, + @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) { + throwIfHasHwBitmapInSwMode(paint); + float outerLeft = outer.left; + float outerTop = outer.top; + float outerRight = outer.right; + float outerBottom = outer.bottom; + + float innerLeft = inner.left; + float innerTop = inner.top; + float innerRight = inner.right; + float innerBottom = inner.bottom; + nDrawDoubleRoundRect(mNativeCanvasWrapper, outerLeft, outerTop, outerRight, outerBottom, + outerRx, outerRy, innerLeft, innerTop, innerRight, innerBottom, innerRx, innerRy, + paint.getNativeInstance()); + } + + /** + * Make lint happy. + * See {@link Canvas#drawDoubleRoundRect(RectF, float[], RectF, float[], Paint)} + */ + public void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii, + @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) { + throwIfHasHwBitmapInSwMode(paint); + if (innerRadii == null || outerRadii == null + || innerRadii.length != 8 || outerRadii.length != 8) { + throw new IllegalArgumentException("Both inner and outer radii arrays must contain " + + "exactly 8 values"); + } + float outerLeft = outer.left; + float outerTop = outer.top; + float outerRight = outer.right; + float outerBottom = outer.bottom; + + float innerLeft = inner.left; + float innerTop = inner.top; + float innerRight = inner.right; + float innerBottom = inner.bottom; + nDrawDoubleRoundRect(mNativeCanvasWrapper, outerLeft, outerTop, outerRight, + outerBottom, outerRadii, innerLeft, innerTop, innerRight, innerBottom, innerRadii, + paint.getNativeInstance()); + } + public void drawText(@NonNull char[] text, int index, int count, float x, float y, @NonNull Paint paint) { if ((index | count | (index + count) | @@ -631,6 +678,16 @@ public abstract class BaseCanvas { private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right, float bottom, float rx, float ry, long nativePaint); + private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft, + float outerTop, float outerRight, float outerBottom, float outerRx, float outerRy, + float innerLeft, float innerTop, float innerRight, float innerBottom, float innerRx, + float innerRy, long nativePaint); + + private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft, + float outerTop, float outerRight, float outerBottom, float[] outerRadii, + float innerLeft, float innerTop, float innerRight, float innerBottom, + float[] innerRadii, long nativePaint); + private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint); private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint); diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java index 6e936910ef40..fb30ca2d4090 100644 --- a/graphics/java/android/graphics/BaseRecordingCanvas.java +++ b/graphics/java/android/graphics/BaseRecordingCanvas.java @@ -377,6 +377,24 @@ public class BaseRecordingCanvas extends Canvas { } @Override + public final void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy, + @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) { + nDrawDoubleRoundRect(mNativeCanvasWrapper, + outer.left, outer.top, outer.right, outer.bottom, outerRx, outerRy, + inner.left, inner.top, inner.right, inner.bottom, innerRx, innerRy, + paint.getNativeInstance()); + } + + @Override + public final void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii, + @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) { + nDrawDoubleRoundRect(mNativeCanvasWrapper, + outer.left, outer.top, outer.right, outer.bottom, outerRadii, + inner.left, inner.top, inner.right, inner.bottom, innerRadii, + paint.getNativeInstance()); + } + + @Override public final void drawText(@NonNull char[] text, int index, int count, float x, float y, @NonNull Paint paint) { if ((index | count | (index + count) @@ -593,6 +611,18 @@ public class BaseRecordingCanvas extends Canvas { float bottom, float rx, float ry, long nativePaint); @FastNative + private static native void nDrawDoubleRoundRect(long nativeCanvas, + float outerLeft, float outerTop, float outerRight, float outerBottom, + float outerRx, float outerRy, float innerLeft, float innerTop, float innerRight, + float innerBottom, float innerRx, float innerRy, long nativePaint); + + @FastNative + private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft, + float outerTop, float outerRight, float outerBottom, float[] outerRadii, + float innerLeft, float innerTop, float innerRight, float innerBottom, + float[] innerRadii, long nativePaint); + + @FastNative private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint); @FastNative diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 36c1c2133c2c..e35a3be6dbbf 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1877,6 +1877,51 @@ public class Canvas extends BaseCanvas { } /** + * Draws a double rounded rectangle using the specified paint. The resultant round rect + * will be filled in the area defined between the outer and inner rectangular bounds if + * the {@link Paint} configured with {@link Paint.Style#FILL}. + * Otherwise if {@link Paint.Style#STROKE} is used, then 2 rounded rect strokes will + * be drawn at the outer and inner rounded rectangles + * + * @param outer The outer rectangular bounds of the roundRect to be drawn + * @param outerRx The x-radius of the oval used to round the corners on the outer rectangle + * @param outerRy The y-radius of the oval used to round the corners on the outer rectangle + * @param inner The inner rectangular bounds of the roundRect to be drawn + * @param innerRx The x-radius of the oval used to round the corners on the inner rectangle + * @param innerRy The y-radius of the oval used to round the corners on the outer rectangle + * @param paint The paint used to draw the double roundRect + */ + @Override + public void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy, + @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) { + super.drawDoubleRoundRect(outer, outerRx, outerRy, inner, innerRx, innerRy, paint); + } + + /** + * Draws a double rounded rectangle using the specified paint. The resultant round rect + * will be filled in the area defined between the outer and inner rectangular bounds if + * the {@link Paint} configured with {@link Paint.Style#FILL}. + * Otherwise if {@link Paint.Style#STROKE} is used, then 2 rounded rect strokes will + * be drawn at the outer and inner rounded rectangles + * + * @param outer The outer rectangular bounds of the roundRect to be drawn + * @param outerRadii Array of 8 float representing the x, y corner radii for top left, + * top right, bottom right, bottom left corners respectively on the outer + * rounded rectangle + * + * @param inner The inner rectangular bounds of the roundRect to be drawn + * @param innerRadii Array of 8 float representing the x, y corner radii for top left, + * top right, bottom right, bottom left corners respectively on the + * outer rounded rectangle + * @param paint The paint used to draw the double roundRect + */ + @Override + public void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii, + @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) { + super.drawDoubleRoundRect(outer, outerRadii, inner, innerRadii, paint); + } + + /** * Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted * based on the Align setting in the paint. * diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 17f1a3b4db3c..2e5aef5347d5 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -504,6 +504,11 @@ void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, mCanvas->drawRoundRect(rect, rx, ry, *filterPaint(paint)); } +void SkiaCanvas::drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + mCanvas->drawDRRect(outer, inner, *filterPaint(paint)); +} + void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return; mCanvas->drawCircle(x, y, radius, *filterPaint(paint)); diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 24b7ec6d5c7b..3a877cf84010 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -107,6 +107,10 @@ public: virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override; virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) override; + + virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) override; + virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override; virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint) override; diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index af7f013e27b1..e2ea2bc37375 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -178,6 +178,41 @@ void Canvas::drawText(const uint16_t* text, int textSize, int start, int count, MinikinUtils::forFontRun(layout, &paint, f); } +void Canvas::drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight, + float outerBottom, float outerRx, float outerRy, float innerLeft, + float innerTop, float innerRight, float innerBottom, float innerRx, + float innerRy, const SkPaint& paint) { + if (CC_UNLIKELY(paint.nothingToDraw())) return; + SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom); + SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom); + + SkRRect outerRRect; + outerRRect.setRectXY(outer, outerRx, outerRy); + + SkRRect innerRRect; + innerRRect.setRectXY(inner, innerRx, innerRy); + drawDoubleRoundRect(outerRRect, innerRRect, paint); +} + +void Canvas::drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight, + float outerBottom, const float* outerRadii, float innerLeft, + float innerTop, float innerRight, float innerBottom, + const float* innerRadii, const SkPaint& paint) { + static_assert(sizeof(SkVector) == sizeof(float) * 2); + if (CC_UNLIKELY(paint.nothingToDraw())) return; + SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom); + SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom); + + SkRRect outerRRect; + const SkVector* outerSkVector = reinterpret_cast<const SkVector*>(outerRadii); + outerRRect.setRectRadii(outer, outerSkVector); + + SkRRect innerRRect; + const SkVector* innerSkVector = reinterpret_cast<const SkVector*>(innerRadii); + innerRRect.setRectRadii(inner, innerSkVector); + drawDoubleRoundRect(outerRRect, innerRRect, paint); +} + class DrawTextOnPathFunctor { public: DrawTextOnPathFunctor(const minikin::Layout& layout, Canvas* canvas, float hOffset, diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index b9af7de26721..e99742bc2eba 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -236,6 +236,8 @@ public: virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0; virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, const SkPaint& paint) = 0; + virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) = 0; virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0; virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint) = 0; @@ -284,6 +286,16 @@ public: const SkPath& path, float hOffset, float vOffset, const Paint& paint, const Typeface* typeface); + void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight, + float outerBottom, float outerRx, float outerRy, float innerLeft, + float innerTop, float innerRight, float innerBottom, float innerRx, + float innerRy, const SkPaint& paint); + + void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight, + float outerBottom, const float* outerRadii, float innerLeft, + float innerTop, float innerRight, float innerBottom, + const float* innerRadii, const SkPaint& paint); + static int GetApiLevel() { return sApiLevel; } protected: |