1 /*
2  * Copyright (C) 2008 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 
17 package android.graphics.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.graphics.Bitmap;
24 import android.graphics.Canvas;
25 import android.graphics.Color;
26 import android.graphics.Matrix;
27 import android.graphics.Paint;
28 import android.graphics.Paint.Style;
29 import android.graphics.Picture;
30 import android.graphics.Rect;
31 
32 import androidx.test.filters.SmallTest;
33 import androidx.test.runner.AndroidJUnit4;
34 
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 @SmallTest
39 @RunWith(AndroidJUnit4.class)
40 public class PictureTest {
41     private static final int TEST_WIDTH = 4; // must be >= 2
42     private static final int TEST_HEIGHT = 3; // must >= 2
43 
44     private final Rect mClipRect = new Rect(0, 0, 2, 2);
45 
46     // This method tests out some edge cases w.r.t. Picture creation.
47     // In particular, this test verifies that, in the following situations,
48     // the created picture (effectively) has balanced saves and restores:
49     //   - copy constructed picture from actively recording picture
50     //   - actively recording picture after draw call
51     @Test
testSaveRestoreBalance()52     public void testSaveRestoreBalance() {
53         Picture original = new Picture();
54         Canvas canvas = original.beginRecording(TEST_WIDTH, TEST_HEIGHT);
55         assertNotNull(canvas);
56         createImbalance(canvas);
57 
58         int expectedSaveCount = canvas.getSaveCount();
59 
60         Picture copy = new Picture(original);
61         verifyBalance(copy);
62 
63         assertEquals(expectedSaveCount, canvas.getSaveCount());
64 
65         Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
66         Canvas drawDest = new Canvas(bitmap);
67         original.draw(drawDest);
68         verifyBalance(original);
69     }
70 
71     // Add an extra save with a transform and clip
createImbalance(Canvas canvas)72     private void createImbalance(Canvas canvas) {
73         canvas.save();
74         canvas.clipRect(mClipRect);
75         canvas.translate(1.0f, 1.0f);
76         Paint paint = new Paint();
77         paint.setColor(Color.GREEN);
78         canvas.drawRect(0, 0, 10, 10, paint);
79     }
80 
verifyBalance(Picture picture)81     private void verifyBalance(Picture picture) {
82         Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
83         Canvas canvas = new Canvas(bitmap);
84 
85         int beforeSaveCount = canvas.getSaveCount();
86 
87         final Matrix beforeMatrix = canvas.getMatrix();
88 
89         Rect beforeClip = new Rect();
90         assertTrue(canvas.getClipBounds(beforeClip));
91 
92         canvas.drawPicture(picture);
93 
94         assertEquals(beforeSaveCount, canvas.getSaveCount());
95 
96         assertTrue(beforeMatrix.equals(canvas.getMatrix()));
97 
98         Rect afterClip = new Rect();
99 
100         assertTrue(canvas.getClipBounds(afterClip));
101         assertEquals(beforeClip, afterClip);
102     }
103 
104     @Test
testPicture()105     public void testPicture() {
106         Picture picture = new Picture();
107 
108         Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
109         assertNotNull(canvas);
110         drawPicture(canvas);
111         picture.endRecording();
112 
113         Bitmap bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
114         canvas = new Canvas(bitmap);
115         picture.draw(canvas);
116         verifySize(picture);
117         verifyBitmap(bitmap);
118 
119         Picture pic = new Picture(picture);
120         bitmap = Bitmap.createBitmap(TEST_WIDTH, TEST_HEIGHT, Bitmap.Config.ARGB_8888);
121         canvas = new Canvas(bitmap);
122         pic.draw(canvas);
123         verifySize(pic);
124         verifyBitmap(bitmap);
125     }
126 
127     @Test(expected = IllegalStateException.class)
testBeginRecordingTwice()128     public void testBeginRecordingTwice() {
129         Picture picture = new Picture();
130         picture.beginRecording(10, 10);
131         picture.beginRecording(10, 10);
132     }
133 
verifySize(Picture picture)134     private void verifySize(Picture picture) {
135         assertEquals(TEST_WIDTH, picture.getWidth());
136         assertEquals(TEST_HEIGHT, picture.getHeight());
137     }
138 
drawPicture(Canvas canvas)139     private void drawPicture(Canvas canvas) {
140         Paint paint = new Paint();
141         // GREEN rectangle covering the entire canvas
142         paint.setColor(Color.GREEN);
143         paint.setStyle(Style.FILL);
144         paint.setAntiAlias(false);
145         canvas.drawRect(0, 0, TEST_WIDTH, TEST_HEIGHT, paint);
146         // horizontal red line starting from (0,0); overwrites first line of the rectangle
147         paint.setColor(Color.RED);
148         canvas.drawLine(0, 0, TEST_WIDTH, 0, paint);
149         // overwrite (0,0) with a blue dot
150         paint.setColor(Color.BLUE);
151         canvas.drawPoint(0, 0, paint);
152     }
153 
verifyBitmap(Bitmap bitmap)154     private void verifyBitmap(Bitmap bitmap) {
155         // first pixel is BLUE, rest of the line is RED
156         assertEquals(Color.BLUE, bitmap.getPixel(0, 0));
157         for (int x = 1; x < TEST_WIDTH; x++) {
158             assertEquals(Color.RED, bitmap.getPixel(x, 0));
159         }
160         // remaining lines are all green
161         for (int y = 1; y < TEST_HEIGHT; y++) {
162             for (int x = 0; x < TEST_WIDTH; x++) {
163                 assertEquals(Color.GREEN, bitmap.getPixel(x, y));
164             }
165         }
166     }
167 }
168