OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // TODO(awalker): clean up the const/non-const reference handling in this test | |
6 | |
7 #include "build/build_config.h" | |
8 | |
9 #if defined(OS_WIN) | |
10 #include <windows.h> | |
11 #else | |
12 #include <unistd.h> | |
13 #endif | |
14 | |
15 #include "base/gfx/platform_canvas.h" | |
16 #include "base/gfx/platform_device.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 #include "SkColor.h" | |
20 | |
21 namespace gfx { | |
22 | |
23 namespace { | |
24 | |
25 // Return true if the canvas is filled to canvas_color, | |
26 // and contains a single rectangle filled to rect_color. | |
27 bool VerifyRect(const PlatformCanvas& canvas, | |
28 uint32_t canvas_color, uint32_t rect_color, | |
29 int x, int y, int w, int h) { | |
30 PlatformDevice& device = canvas.getTopPlatformDevice(); | |
31 const SkBitmap& bitmap = device.accessBitmap(false); | |
32 SkAutoLockPixels lock(bitmap); | |
33 | |
34 for (int cur_y = 0; cur_y < bitmap.height(); cur_y++) { | |
35 for (int cur_x = 0; cur_x < bitmap.width(); cur_x++) { | |
36 if (cur_x >= x && cur_x < x + w && | |
37 cur_y >= y && cur_y < y + h) { | |
38 // Inside the square should be rect_color | |
39 if (*bitmap.getAddr32(cur_x, cur_y) != rect_color) | |
40 return false; | |
41 } else { | |
42 // Outside the square should be canvas_color | |
43 if (*bitmap.getAddr32(cur_x, cur_y) != canvas_color) | |
44 return false; | |
45 } | |
46 } | |
47 } | |
48 return true; | |
49 } | |
50 | |
51 // Checks whether there is a white canvas with a black square at the given | |
52 // location in pixels (not in the canvas coordinate system). | |
53 // TODO(ericroman): rename Square to Rect | |
54 bool VerifyBlackSquare(const PlatformCanvas& canvas, int x, int y, int w, int h)
{ | |
55 return VerifyRect(canvas, SK_ColorWHITE, SK_ColorBLACK, x, y, w, h); | |
56 } | |
57 | |
58 // Check that every pixel in the canvas is a single color. | |
59 bool VerifyCanvasColor(const PlatformCanvas& canvas, uint32_t canvas_color) { | |
60 return VerifyRect(canvas, canvas_color, 0, 0, 0, 0, 0); | |
61 } | |
62 | |
63 #if defined(OS_WIN) | |
64 void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { | |
65 HDC dc = canvas.beginPlatformPaint(); | |
66 | |
67 RECT inner_rc; | |
68 inner_rc.left = x; | |
69 inner_rc.top = y; | |
70 inner_rc.right = x + w; | |
71 inner_rc.bottom = y + h; | |
72 FillRect(dc, &inner_rc, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)))
; | |
73 | |
74 canvas.endPlatformPaint(); | |
75 } | |
76 #elif defined(OS_MACOSX) | |
77 void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { | |
78 CGContextRef context = canvas.beginPlatformPaint(); | |
79 | |
80 CGRect inner_rc = CGRectMake(x, y, w, h); | |
81 // RGBA opaque black | |
82 CGColorRef black = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0); | |
83 CGContextSetFillColorWithColor(context, black); | |
84 CGColorRelease(black); | |
85 CGContextFillRect(context, inner_rc); | |
86 | |
87 canvas.endPlatformPaint(); | |
88 } | |
89 #else | |
90 void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) { | |
91 NOTIMPLEMENTED(); | |
92 } | |
93 #endif | |
94 | |
95 // Clips the contents of the canvas to the given rectangle. This will be | |
96 // intersected with any existing clip. | |
97 void AddClip(PlatformCanvas& canvas, int x, int y, int w, int h) { | |
98 SkRect rect; | |
99 rect.set(SkIntToScalar(x), SkIntToScalar(y), | |
100 SkIntToScalar(x + w), SkIntToScalar(y + h)); | |
101 canvas.clipRect(rect); | |
102 } | |
103 | |
104 class LayerSaver { | |
105 public: | |
106 LayerSaver(PlatformCanvas& canvas, int x, int y, int w, int h) | |
107 : canvas_(canvas), | |
108 x_(x), | |
109 y_(y), | |
110 w_(w), | |
111 h_(h) { | |
112 SkRect bounds; | |
113 bounds.set(SkIntToScalar(x_), SkIntToScalar(y_), | |
114 SkIntToScalar(right()), SkIntToScalar(bottom())); | |
115 canvas_.saveLayer(&bounds, NULL); | |
116 } | |
117 | |
118 ~LayerSaver() { | |
119 canvas_.getTopPlatformDevice().fixupAlphaBeforeCompositing(); | |
120 canvas_.restore(); | |
121 } | |
122 | |
123 int x() const { return x_; } | |
124 int y() const { return y_; } | |
125 int w() const { return w_; } | |
126 int h() const { return h_; } | |
127 | |
128 // Returns the EXCLUSIVE far bounds of the layer. | |
129 int right() const { return x_ + w_; } | |
130 int bottom() const { return y_ + h_; } | |
131 | |
132 private: | |
133 PlatformCanvas& canvas_; | |
134 int x_, y_, w_, h_; | |
135 }; | |
136 | |
137 // Size used for making layers in many of the below tests. | |
138 const int kLayerX = 2; | |
139 const int kLayerY = 3; | |
140 const int kLayerW = 9; | |
141 const int kLayerH = 7; | |
142 | |
143 // Size used by some tests to draw a rectangle inside the layer. | |
144 const int kInnerX = 4; | |
145 const int kInnerY = 5; | |
146 const int kInnerW = 2; | |
147 const int kInnerH = 3; | |
148 | |
149 } | |
150 | |
151 // This just checks that our checking code is working properly, it just uses | |
152 // regular skia primitives. | |
153 TEST(PlatformCanvas, SkLayer) { | |
154 // Create the canvas initialized to opaque white. | |
155 PlatformCanvas canvas(16, 16, true); | |
156 canvas.drawColor(SK_ColorWHITE); | |
157 | |
158 // Make a layer and fill it completely to make sure that the bounds are | |
159 // correct. | |
160 { | |
161 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
162 canvas.drawColor(SK_ColorBLACK); | |
163 } | |
164 EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX, kLayerY, kLayerW, kLayerH)); | |
165 } | |
166 | |
167 // Test native clipping. | |
168 TEST(PlatformCanvas, ClipRegion) { | |
169 // Initialize a white canvas | |
170 PlatformCanvas canvas(16, 16, true); | |
171 canvas.drawColor(SK_ColorWHITE); | |
172 EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE)); | |
173 | |
174 // Test that initially the canvas has no clip region, by filling it | |
175 // with a black rectangle. | |
176 // Note: Don't use LayerSaver, since internally it sets a clip region. | |
177 DrawNativeRect(canvas, 0, 0, 16, 16); | |
178 canvas.getTopPlatformDevice().fixupAlphaBeforeCompositing(); | |
179 EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorBLACK)); | |
180 | |
181 // Test that intersecting disjoint clip rectangles sets an empty clip region | |
182 canvas.drawColor(SK_ColorWHITE); | |
183 EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE)); | |
184 { | |
185 LayerSaver layer(canvas, 0, 0, 16, 16); | |
186 AddClip(canvas, 2, 3, 4, 5); | |
187 AddClip(canvas, 4, 9, 10, 10); | |
188 DrawNativeRect(canvas, 0, 0, 16, 16); | |
189 } | |
190 EXPECT_TRUE(VerifyCanvasColor(canvas, SK_ColorWHITE)); | |
191 } | |
192 | |
193 // Test the layers get filled properly by native rendering. | |
194 TEST(PlatformCanvas, FillLayer) { | |
195 // Create the canvas initialized to opaque white. | |
196 PlatformCanvas canvas(16, 16, true); | |
197 | |
198 // Make a layer and fill it completely to make sure that the bounds are | |
199 // correct. | |
200 canvas.drawColor(SK_ColorWHITE); | |
201 { | |
202 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
203 DrawNativeRect(canvas, 0, 0, 100, 100); | |
204 } | |
205 EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX, kLayerY, kLayerW, kLayerH)); | |
206 | |
207 // Make a layer and fill it partially to make sure the translation is correct. | |
208 canvas.drawColor(SK_ColorWHITE); | |
209 { | |
210 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
211 DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
212 } | |
213 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH)); | |
214 | |
215 // Add a clip on the layer and fill to make sure clip is correct. | |
216 canvas.drawColor(SK_ColorWHITE); | |
217 { | |
218 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
219 canvas.save(); | |
220 AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
221 DrawNativeRect(canvas, 0, 0, 100, 100); | |
222 canvas.restore(); | |
223 } | |
224 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH)); | |
225 | |
226 // Add a clip and then make the layer to make sure the clip is correct. | |
227 canvas.drawColor(SK_ColorWHITE); | |
228 canvas.save(); | |
229 AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
230 { | |
231 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
232 DrawNativeRect(canvas, 0, 0, 100, 100); | |
233 } | |
234 canvas.restore(); | |
235 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX, kInnerY, kInnerW, kInnerH)); | |
236 } | |
237 | |
238 // Test that translation + make layer works properly. | |
239 TEST(PlatformCanvas, TranslateLayer) { | |
240 // Create the canvas initialized to opaque white. | |
241 PlatformCanvas canvas(16, 16, true); | |
242 | |
243 // Make a layer and fill it completely to make sure that the bounds are | |
244 // correct. | |
245 canvas.drawColor(SK_ColorWHITE); | |
246 canvas.save(); | |
247 canvas.translate(1, 1); | |
248 { | |
249 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
250 DrawNativeRect(canvas, 0, 0, 100, 100); | |
251 } | |
252 canvas.restore(); | |
253 EXPECT_TRUE(VerifyBlackSquare(canvas, kLayerX + 1, kLayerY + 1, | |
254 kLayerW, kLayerH)); | |
255 | |
256 // Translate then make the layer. | |
257 canvas.drawColor(SK_ColorWHITE); | |
258 canvas.save(); | |
259 canvas.translate(1, 1); | |
260 { | |
261 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
262 DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
263 } | |
264 canvas.restore(); | |
265 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 1, kInnerY + 1, | |
266 kInnerW, kInnerH)); | |
267 | |
268 // Make the layer then translate. | |
269 canvas.drawColor(SK_ColorWHITE); | |
270 canvas.save(); | |
271 { | |
272 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
273 canvas.translate(1, 1); | |
274 DrawNativeRect(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
275 } | |
276 canvas.restore(); | |
277 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 1, kInnerY + 1, | |
278 kInnerW, kInnerH)); | |
279 | |
280 // Translate both before and after, and have a clip. | |
281 canvas.drawColor(SK_ColorWHITE); | |
282 canvas.save(); | |
283 canvas.translate(1, 1); | |
284 { | |
285 LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); | |
286 canvas.translate(1, 1); | |
287 AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH); | |
288 DrawNativeRect(canvas, 0, 0, 100, 100); | |
289 } | |
290 canvas.restore(); | |
291 EXPECT_TRUE(VerifyBlackSquare(canvas, kInnerX + 2, kInnerY + 2, | |
292 kInnerW, kInnerH)); | |
293 } | |
294 | |
295 } // namespace | |
296 | |
OLD | NEW |