1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.uirendering.cts.testclasses;
18
19import android.graphics.Canvas;
20import android.graphics.Color;
21import android.graphics.Paint;
22import android.graphics.Path;
23import android.graphics.Picture;
24import android.graphics.PorterDuff;
25import android.graphics.Rect;
26import android.graphics.drawable.NinePatchDrawable;
27import android.support.test.filters.MediumTest;
28import android.support.test.runner.AndroidJUnit4;
29import android.uirendering.cts.R;
30import android.uirendering.cts.bitmapcomparers.BitmapComparer;
31import android.uirendering.cts.bitmapcomparers.ExactComparer;
32import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
33import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
34import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
35import android.uirendering.cts.bitmapverifiers.RectVerifier;
36import android.uirendering.cts.testinfrastructure.ActivityTestBase;
37
38import org.junit.Test;
39import org.junit.runner.RunWith;
40
41@MediumTest
42@RunWith(AndroidJUnit4.class)
43public class ExactCanvasTests extends ActivityTestBase {
44    private final BitmapComparer mExactComparer = new ExactComparer();
45
46    @Test
47    public void testBlueRect() {
48        final Rect rect = new Rect(10, 10, 80, 80);
49        createTest()
50                .addCanvasClient((canvas, width, height) -> {
51                    Paint p = new Paint();
52                    p.setAntiAlias(false);
53                    p.setColor(Color.BLUE);
54                    canvas.drawRect(rect, p);
55                })
56                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
57    }
58
59    @Test
60    public void testPoints() {
61        createTest()
62                .addCanvasClient((canvas, width, height) -> {
63                    Paint p = new Paint();
64                    p.setAntiAlias(false);
65                    p.setStrokeWidth(1f);
66                    p.setColor(Color.BLACK);
67                    for (int i = 0; i < 10; i++) {
68                        canvas.drawPoint(i * 10, i * 10, p);
69                    }
70                })
71                .runWithComparer(mExactComparer);
72    }
73
74    @Test
75    public void testBlackRectWithStroke() {
76        createTest()
77                .addCanvasClient((canvas, width, height) -> {
78                    Paint p = new Paint();
79                    p.setColor(Color.RED);
80                    canvas.drawRect(0, 0, ActivityTestBase.TEST_WIDTH,
81                            ActivityTestBase.TEST_HEIGHT, p);
82                    p.setColor(Color.BLACK);
83                    p.setStrokeWidth(5);
84                    canvas.drawRect(10, 10, 80, 80, p);
85                })
86                .runWithComparer(mExactComparer);
87    }
88
89    @Test
90    public void testBlackLineOnGreenBack() {
91        createTest()
92                .addCanvasClient((canvas, width, height) -> {
93                    canvas.drawColor(Color.GREEN);
94                    Paint p = new Paint();
95                    p.setColor(Color.BLACK);
96                    p.setStrokeWidth(10);
97                    canvas.drawLine(0, 0, 50, 0, p);
98                })
99                .runWithComparer(mExactComparer);
100    }
101
102    @Test
103    public void testDrawRedRectOnBlueBack() {
104        createTest()
105                .addCanvasClient((canvas, width, height) -> {
106                    canvas.drawColor(Color.BLUE);
107                    Paint p = new Paint();
108                    p.setColor(Color.RED);
109                    canvas.drawRect(10, 10, 40, 40, p);
110                })
111                .runWithComparer(mExactComparer);
112    }
113
114    @Test
115    public void testDrawLine() {
116        createTest()
117                .addCanvasClient((canvas, width, height) -> {
118                    Paint p = new Paint();
119                    canvas.drawColor(Color.WHITE);
120                    p.setColor(Color.BLACK);
121                    float[] pts = {
122                            0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
123                    };
124                    canvas.drawLines(pts, p);
125                })
126                .runWithComparer(mExactComparer);
127    }
128
129    @Test
130    public void testDrawWhiteScreen() {
131        createTest()
132                .addCanvasClient((canvas, width, height) -> canvas.drawColor(Color.WHITE))
133                .runWithComparer(mExactComparer);
134    }
135
136    @Test
137    public void testBasicText() {
138        final String testString = "THIS IS A TEST";
139        createTest()
140                .addCanvasClient((canvas, width, height) -> {
141                    Paint p = new Paint();
142                    canvas.drawColor(Color.BLACK);
143                    p.setColor(Color.WHITE);
144                    p.setStrokeWidth(5);
145                    canvas.drawText(testString, 30, 50, p);
146                })
147                .runWithComparer(mExactComparer);
148    }
149
150    private void drawTestTextOnPath(Canvas canvas) {
151        final String testString = "THIS IS A TEST ON A CIRCLE PATH";
152        Path path = new Path();
153        path.addCircle(45, 45, 30, Path.Direction.CW);
154        Paint p = new Paint();
155        p.setColor(Color.BLACK);
156        p.setAntiAlias(true);
157        canvas.drawTextOnPath(testString, path, 0f, 0f, p);
158    }
159
160    @Test
161    public void testTextOnPath() {
162        createTest()
163                .addCanvasClient((canvas, width, height) -> {
164                    drawTestTextOnPath(canvas);
165                })
166                .runWithVerifier(new GoldenImageVerifier(getActivity(),
167                    // HWUI's texts are blurry, so we lower the threshold.
168                    // Note that 0.7 will fail the test.
169                    R.drawable.text_on_path, new MSSIMComparer(0.6)));
170    }
171
172    @Test
173    public void testTextOnPathUsingPicture() {
174        createTest()
175                .addCanvasClient((canvas, width, height) -> {
176                    Picture picture = new Picture();
177                    Canvas pictureCanvas = picture.beginRecording(90, 90);
178                    drawTestTextOnPath(pictureCanvas);
179                    picture.endRecording();
180                    picture.draw(canvas);
181                })
182                .runWithVerifier(new GoldenImageVerifier(getActivity(),
183                    // HWUI's texts are blurry, so we lower the threshold.
184                    // Note that 0.7 will fail the test.
185                    R.drawable.text_on_path, new MSSIMComparer(0.6)));
186    }
187
188    @Test
189    public void testBasicColorXfermode() {
190        createTest()
191                .addCanvasClient((canvas, width, height) -> {
192                    canvas.drawColor(Color.GRAY);
193                    canvas.drawColor(Color.BLUE, PorterDuff.Mode.MULTIPLY);
194                })
195                .runWithComparer(mExactComparer);
196    }
197
198    @Test
199    public void testBluePaddedSquare() {
200        final NinePatchDrawable ninePatchDrawable = (NinePatchDrawable)
201            getActivity().getResources().getDrawable(R.drawable.blue_padded_square);
202        ninePatchDrawable.setBounds(0, 0, 90, 90);
203
204        BitmapVerifier verifier = new RectVerifier(Color.WHITE, Color.BLUE,
205                new Rect(10, 10, 80, 80));
206
207        createTest()
208                // The border of the square is somehow blurred in HWUI OpenGL hardware mode with
209                // picture recording/playback. Maybe this is related to bug:31456967
210                // Hence disable picture mode for now.
211                .addCanvasClientWithoutUsingPicture((canvas, width, height) -> {
212                    canvas.drawColor(Color.WHITE);
213                    Paint p = new Paint();
214                    p.setColor(Color.BLUE);
215                    canvas.drawRect(10, 10, 80, 80, p);
216                })
217                .addCanvasClientWithoutUsingPicture(
218                        (canvas, width, height) -> ninePatchDrawable.draw(canvas))
219                .addLayout(R.layout.blue_padded_square, null)
220                .runWithVerifier(verifier);
221    }
222
223    @Test
224    public void testEmptyLayer() {
225        createTest()
226                .addCanvasClient((canvas, width, height) -> {
227                    canvas.drawColor(Color.CYAN);
228                    Paint p = new Paint();
229                    p.setColor(Color.BLACK);
230                    canvas.saveLayer(10, 10, 80, 80, p);
231                    canvas.restore();
232                })
233                .runWithComparer(mExactComparer);
234    }
235
236    @Test
237    public void testSaveLayerRounding() {
238        createTest()
239                .addCanvasClient((canvas, width, height) -> {
240                    canvas.saveLayerAlpha(10.5f, 10.5f, 79.5f, 79.5f, 255);
241                    canvas.drawRect(20, 20, 70, 70, new Paint());
242                    canvas.restore();
243                })
244                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLACK,
245                        new Rect(20, 20, 70, 70)));
246    }
247
248    @Test
249    public void testUnclippedSaveLayerRounding() {
250        createTest()
251                .addCanvasClient((canvas, width, height) -> {
252                    canvas.saveLayerAlpha(10.5f, 10.5f, 79.5f, 79.5f, 255, 0);
253                    canvas.drawRect(20, 20, 70, 70, new Paint());
254                    canvas.restore();
255                })
256                .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLACK,
257                        new Rect(20, 20, 70, 70)));
258    }
259}
260