Merge change 9520 into donut
* changes:
Integrate unsubmitted cupcake change 131131: CTS: add test cases for graphics.LinearGradient, PaintFlagsDrawFilter, PathDashPathEffect, PixelXorXfermode and PorterDuffColorFilter
diff --git a/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java b/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java
new file mode 100644
index 0000000..2f26272
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Bitmap.Config;
+import android.graphics.Shader.TileMode;
+import android.test.AndroidTestCase;
+
+@TestTargetClass(LinearGradient.class)
+public class LinearGradientTest extends AndroidTestCase {
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "LinearGradient",
+ args = {float.class, float.class, float.class, float.class, int[].class, float[].class,
+ android.graphics.Shader.TileMode.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "LinearGradient",
+ args = {float.class, float.class, float.class, float.class, int.class, int.class,
+ android.graphics.Shader.TileMode.class}
+ )
+ })
+ public void testLinearGradient() {
+ Bitmap b;
+ LinearGradient lg;
+ int[] color = { Color.BLUE, Color.GREEN, Color.RED };
+ float[] position = { 0.0f, 1.0f / 3.0f, 2.0f / 3.0f };
+
+ lg = new LinearGradient(0, 0, 0, 40, color, position, TileMode.CLAMP);
+ b = drawLinearGradient(lg);
+
+ // The pixels in same gradient line should be equivalent
+ assertEquals(b.getPixel(10, 10), b.getPixel(20, 10));
+ // BLUE -> GREEN, B sub-value decreasing while G sub-value increasing
+ assertTrue(Color.blue(b.getPixel(10, 0)) > Color.blue(b.getPixel(10, 5)));
+ assertTrue(Color.blue(b.getPixel(10, 5)) > Color.blue(b.getPixel(10, 10)));
+ assertTrue(Color.green(b.getPixel(10, 0)) < Color.green(b.getPixel(10, 5)));
+ assertTrue(Color.green(b.getPixel(10, 5)) < Color.green(b.getPixel(10, 10)));
+ // GREEN -> RED, G sub-value decreasing while R sub-value increasing
+ assertTrue(Color.green(b.getPixel(10, 15)) > Color.green(b.getPixel(10, 20)));
+ assertTrue(Color.green(b.getPixel(10, 20)) > Color.green(b.getPixel(10, 25)));
+ assertTrue(Color.red(b.getPixel(10, 15)) < Color.red(b.getPixel(10, 20)));
+ assertTrue(Color.red(b.getPixel(10, 20)) < Color.red(b.getPixel(10, 25)));
+
+ lg = new LinearGradient(0, 0, 0, 40, Color.RED, Color.BLUE, TileMode.CLAMP);
+ b= drawLinearGradient(lg);
+
+ // The pixels in same gradient line should be equivalent
+ assertEquals(b.getPixel(10, 10), b.getPixel(20, 10));
+ // RED -> BLUE, R sub-value decreasing while B sub-value increasing
+ assertTrue(Color.red(b.getPixel(10, 0)) > Color.red(b.getPixel(10, 15)));
+ assertTrue(Color.red(b.getPixel(10, 15)) > Color.red(b.getPixel(10, 30)));
+ assertTrue(Color.blue(b.getPixel(10, 0)) < Color.blue(b.getPixel(10, 15)));
+ assertTrue(Color.blue(b.getPixel(10, 15)) < Color.blue(b.getPixel(10, 30)));
+ }
+
+ private Bitmap drawLinearGradient(LinearGradient lg) {
+ Paint paint = new Paint();
+ paint.setShader(lg);
+ Bitmap b = Bitmap.createBitmap(40, 40, Config.ARGB_8888);
+ b.eraseColor(Color.BLACK);
+ Canvas canvas = new Canvas(b);
+ canvas.drawPaint(paint);
+ return b;
+ }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java
new file mode 100644
index 0000000..bf39818
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintFlagsDrawFilterTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.Rect;
+import android.graphics.Bitmap.Config;
+import android.graphics.Paint.Align;
+import android.test.AndroidTestCase;
+
+@TestTargetClass(PaintFlagsDrawFilter.class)
+public class PaintFlagsDrawFilterTest extends AndroidTestCase {
+
+ private static final float TEXT_SIZE = 20;
+ private static final float TEXT_X = 50;
+ private static final float TEXT_Y = 50;
+ private static final String TEXT = "Test";
+ private static final int BITMAP_WIDTH = 100;
+ private static final int BITMAP_HEIGHT = 100;
+ private float mTextWidth;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "PaintFlagsDrawFilter",
+ args = {int.class, int.class}
+ )
+ public void testPaintFlagsDrawFilter() {
+
+ Bitmap bitmapWithoutFilter = drawText(null);
+
+ PaintFlagsDrawFilter filter = new PaintFlagsDrawFilter(Paint.UNDERLINE_TEXT_FLAG, 0);
+ Bitmap bitmapWithFilter = drawText(filter);
+
+ Bitmap combined = delta(bitmapWithoutFilter, bitmapWithFilter);
+ assertUnderline(combined);
+ }
+
+ private Bitmap drawText(PaintFlagsDrawFilter filter) {
+ Paint p = new Paint(Paint.UNDERLINE_TEXT_FLAG);
+ p.setColor(Color.RED);
+ p.setTextSize(TEXT_SIZE);
+ p.setTextAlign(Align.CENTER);
+ mTextWidth = p.measureText(TEXT);
+ Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ c.setDrawFilter(filter);
+ c.drawColor(Color.BLACK);
+ c.drawText(TEXT, TEXT_X, TEXT_Y, p);
+ return b;
+ }
+
+ private Bitmap delta(Bitmap bitmapWithoutFilter, Bitmap bitmapWithFilter) {
+ Bitmap combinedBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888);
+ combinedBitmap.eraseColor(Color.BLACK);
+ int pixelWithoutFilter;
+ int pixelWithFilter;
+ for (int i = 0; i < BITMAP_WIDTH; i++) {
+ for (int j = 0; j < BITMAP_HEIGHT; j++) {
+ pixelWithoutFilter = bitmapWithoutFilter.getPixel(i, j);
+ pixelWithFilter = bitmapWithFilter.getPixel(i, j);
+ if (pixelWithoutFilter != pixelWithFilter) {
+ assertEquals(Color.RED, pixelWithoutFilter);
+ assertEquals(Color.BLACK, pixelWithFilter);
+ combinedBitmap.setPixel(i, j, Color.RED);
+ }
+ }
+ }
+ return combinedBitmap;
+ }
+
+ private void assertUnderline(Bitmap bitmap) {
+ // Find smallest rectangle containing all RED pixels
+ Rect rect = new Rect(BITMAP_WIDTH, BITMAP_HEIGHT, 0, 0);
+ for (int y = 0; y < BITMAP_HEIGHT; y++) {
+ for (int x = 0; x < BITMAP_WIDTH; x++) {
+ int pixel = bitmap.getPixel(x, y);
+ if (pixel == Color.RED) {
+ rect.left = Math.min(rect.left, x);
+ rect.right = Math.max(rect.right, x);
+ rect.top = Math.min(rect.top, y);
+ rect.bottom = Math.max(rect.bottom, y);
+ }
+ }
+ }
+ // underline is at least one pixel high
+ assertTrue(rect.top <= rect.bottom);
+ // underline is roughly the same length at the text (5% tolerance)
+ assertEquals(mTextWidth, rect.right - rect.left, mTextWidth * 0.05);
+ // underline is under the text or at least at the bottom of it
+ assertTrue(rect.top >= TEXT_Y);
+ }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PathDashPathEffectTest.java b/tests/tests/graphics/src/android/graphics/cts/PathDashPathEffectTest.java
new file mode 100644
index 0000000..eadd932
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/PathDashPathEffectTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathDashPathEffect;
+import android.graphics.RectF;
+import android.graphics.Bitmap.Config;
+import android.graphics.Path.Direction;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(PathDashPathEffect.class)
+public class PathDashPathEffectTest extends TestCase {
+
+ private static final int SQUARE = 10;
+ private static final int ADVANCE = 30;
+ private static final int WIDTH = 100;
+ private static final int HEIGHT = 100;
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ method = "PathDashPathEffect",
+ args = {android.graphics.Path.class, float.class, float.class,
+ android.graphics.PathDashPathEffect.Style.class}
+ )
+ public void testPathDashPathEffect() {
+ Bitmap b = Bitmap.createBitmap(WIDTH, HEIGHT, Config.ARGB_8888);
+ b.eraseColor(Color.BLACK);
+ PathDashPathEffect effect = new PathDashPathEffect(shape(), ADVANCE, 0,
+ PathDashPathEffect.Style.TRANSLATE);
+ Canvas canvas = new Canvas(b);
+ Paint p = new Paint();
+ p.setPathEffect(effect);
+ p.setColor(Color.RED);
+ canvas.drawPath(path(), p);
+
+ Bitmap expected = Bitmap.createBitmap(WIDTH, HEIGHT, Config.ARGB_8888);
+ expected.eraseColor(Color.BLACK);
+ canvas = new Canvas(expected);
+ p = new Paint();
+ p.setColor(Color.RED);
+ RectF rect = new RectF(0, HEIGHT / 2 - SQUARE, 0, HEIGHT / 2 + SQUARE);
+ for (int i = 0; i <= WIDTH + SQUARE; i += ADVANCE) {
+ rect.left = i - SQUARE;
+ rect.right = i + SQUARE;
+ canvas.drawRect(rect, p);
+ }
+
+ int diffCount = 0;
+ for (int y = 0; y < HEIGHT; y++) {
+ for (int x = 0; x < WIDTH; x++) {
+ if (expected.getPixel(x, y) != b.getPixel(x, y)) {
+ diffCount += 1;
+ }
+ }
+ }
+ assertEquals(0, diffCount);
+ }
+
+ private static Path path() {
+ Path p = new Path();
+ p.moveTo(0, HEIGHT / 2);
+ p.lineTo(WIDTH, HEIGHT / 2);
+ return p;
+ }
+
+ private static Path shape() {
+ Path p = new Path();
+ p.addRect(new RectF(-SQUARE, -SQUARE, SQUARE, SQUARE), Direction.CCW);
+ return p;
+ }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java b/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
new file mode 100644
index 0000000..780e49a
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelXorXfermode;
+import android.graphics.Bitmap.Config;
+import android.test.AndroidTestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(PixelXorXfermode.class)
+public class PixelXorXfermodeTest extends AndroidTestCase {
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "PixelXorXfermode",
+ args = {int.class}
+ )
+ public void testPixelXorXfermode() {
+ int width = 100;
+ int height = 100;
+ Bitmap b1 = Bitmap.createBitmap(width / 2, height, Config.ARGB_8888);
+ b1.eraseColor(Color.WHITE);
+ Bitmap b2 = Bitmap.createBitmap(width, height / 2, Config.ARGB_8888);
+ b2.eraseColor(Color.CYAN);
+
+ Bitmap target = Bitmap.createBitmap(width, height, Config.ARGB_8888);
+ target.eraseColor(Color.BLACK);
+ Canvas canvas = new Canvas(target);
+ Paint p = new Paint();
+ canvas.drawBitmap(b1, 0, 0, p);
+ p.setXfermode(new PixelXorXfermode(Color.GREEN));
+ canvas.drawBitmap(b2, 0, height / 2, p);
+ assertEquals(Color.WHITE, target.getPixel(width / 4, height / 4));
+ // white ^ green ^ cyan = yellow
+ assertEquals(Color.YELLOW, target.getPixel(width / 4, height * 3 / 4));
+ // black ^ green ^ cyan = blue
+ assertEquals(Color.BLUE, target.getPixel(width * 3 / 4, height * 3 / 4));
+
+ // XOR transfer always results in an opaque image
+ p.setXfermode(new PixelXorXfermode(alphaColor(Color.GREEN, 25)));
+ target.eraseColor(alphaColor(Color.BLACK, 42));
+ p.setColor(alphaColor(Color.CYAN, 5));
+ canvas.drawPaint(p);
+ // result is always opaque, even though all inputs have alpha
+ assertEquals(255, Color.alpha(target.getPixel(0, 0)));
+ }
+
+ private int alphaColor(int color, int alpha) {
+ int red = Color.red(color);
+ int green = Color.green(color);
+ int blue = Color.blue(color);
+ return Color.argb(alpha, red, green, blue);
+ }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/PorterDuffColorFilterTest.java b/tests/tests/graphics/src/android/graphics/cts/PorterDuffColorFilterTest.java
new file mode 100644
index 0000000..e0f5bd2
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/PorterDuffColorFilterTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Bitmap.Config;
+import android.test.AndroidTestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(PorterDuffColorFilter.class)
+public class PorterDuffColorFilterTest extends AndroidTestCase {
+
+ private static final int TOLERANCE = 5;
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "PorterDuffColorFilter",
+ args = {int.class, PorterDuff.Mode.class}
+ )
+ public void testPorterDuffColorFilter() {
+ int width = 100;
+ int height = 100;
+ Bitmap b1 = Bitmap.createBitmap(width / 2, height, Config.ARGB_8888);
+ b1.eraseColor(Color.RED);
+ Bitmap b2 = Bitmap.createBitmap(width, height / 2, Config.ARGB_8888);
+ b2.eraseColor(Color.BLUE);
+
+ Bitmap target = Bitmap.createBitmap(width, height, Config.ARGB_8888);
+ target.eraseColor(Color.TRANSPARENT);
+ Canvas canvas = new Canvas(target);
+ // semi-transparent green
+ int filterColor = Color.argb(0x80, 0, 0xFF, 0);
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(filterColor, PorterDuff.Mode.SRC);
+ Paint p = new Paint();
+ canvas.drawBitmap(b1, 0, 0, p);
+ p.setColorFilter(filter);
+ canvas.drawBitmap(b2, 0, height / 2, p);
+ assertEquals(Color.RED, target.getPixel(width / 4, height / 4));
+ int lowerLeft = target.getPixel(width / 4, height * 3 / 4);
+ assertEquals(0x80, Color.red(lowerLeft), TOLERANCE);
+ assertEquals(0x80, Color.green(lowerLeft), TOLERANCE);
+ int lowerRight = target.getPixel(width * 3 / 4, height * 3 / 4);
+ assertEquals(filterColor, lowerRight);
+
+ target.eraseColor(Color.BLACK);
+ filter = new PorterDuffColorFilter(filterColor, PorterDuff.Mode.DST);
+ p.setColorFilter(null);
+ canvas.drawBitmap(b1, 0, 0, p);
+ p.setColorFilter(filter);
+ canvas.drawBitmap(b2, 0, height / 2, p);
+ assertEquals(Color.RED, target.getPixel(width / 4, height / 4));
+ assertEquals(Color.BLUE, target.getPixel(width / 4, height * 3 / 4));
+ assertEquals(Color.BLUE, target.getPixel(width * 3 / 4, height * 3 / 4));
+
+ target.eraseColor(Color.BLACK);
+ filter = new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SCREEN);
+ p.setColorFilter(null);
+ canvas.drawBitmap(b1, 0, 0, p);
+ p.setColorFilter(filter);
+ canvas.drawBitmap(b2, 0, height / 2, p);
+ assertEquals(Color.RED, target.getPixel(width / 4, height / 4));
+ assertEquals(Color.CYAN, target.getPixel(width / 4, height * 3 / 4));
+ assertEquals(Color.CYAN, target.getPixel(width * 3 / 4, height * 3 / 4));
+ }
+}