OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y | |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y | |
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N | |
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
23 */ | |
24 | |
25 #include "config.h" | |
26 | |
27 #include "platform/graphics/GraphicsContext.h" | |
28 | |
29 #include "platform/graphics/BitmapImage.h" | |
30 #include "platform/graphics/DisplayList.h" | |
31 #include "platform/graphics/ImageBuffer.h" | |
32 #include "platform/graphics/skia/NativeImageSkia.h" | |
33 #include "third_party/skia/include/core/SkBitmap.h" | |
34 #include "third_party/skia/include/core/SkCanvas.h" | |
35 #include <gtest/gtest.h> | |
36 | |
37 using namespace WebCore; | |
38 | |
39 namespace { | |
40 | |
41 #define EXPECT_EQ_RECT(a, b) \ | |
42 EXPECT_EQ(a.x(), b.x()); \ | |
43 EXPECT_EQ(a.y(), b.y()); \ | |
44 EXPECT_EQ(a.width(), b.width()); \ | |
45 EXPECT_EQ(a.height(), b.height()); | |
46 | |
47 #define EXPECT_PIXELS_MATCH(bitmap, opaqueRect) \ | |
48 { \ | |
49 SkAutoLockPixels locker(bitmap); \ | |
50 for (int y = opaqueRect.y(); y < opaqueRect.maxY(); ++y) \ | |
51 for (int x = opaqueRect.x(); x < opaqueRect.maxX(); ++x) { \ | |
52 int alpha = *bitmap.getAddr32(x, y) >> 24; \ | |
53 EXPECT_EQ(255, alpha); \ | |
54 } \ | |
55 } | |
56 | |
57 #define EXPECT_PIXELS_MATCH_EXACT(bitmap, opaqueRect) \ | |
58 { \ | |
59 SkAutoLockPixels locker(bitmap); \ | |
60 for (int y = 0; y < bitmap.height(); ++y) \ | |
61 for (int x = 0; x < bitmap.width(); ++x) { \ | |
62 int alpha = *bitmap.getAddr32(x, y) >> 24; \ | |
63 bool opaque = opaqueRect.contains(x, y); \ | |
64 EXPECT_EQ(opaque, alpha == 255); \ | |
65 } \ | |
66 } | |
67 | |
68 TEST(GraphicsContextTest, trackOpaqueTest) | |
69 { | |
70 SkBitmap bitmap; | |
71 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
72 bitmap.eraseColor(0); | |
73 SkCanvas canvas(bitmap); | |
74 | |
75 GraphicsContext context(&canvas); | |
76 context.setTrackOpaqueRegion(true); | |
77 | |
78 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
79 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
80 | |
81 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
82 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
83 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
84 | |
85 context.fillRect(FloatRect(10, 10, 90, 90), alpha, CompositeSourceOver); | |
86 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
87 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
88 | |
89 context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositePlusLighter); | |
90 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
91 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
92 | |
93 context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositeSourceIn); | |
94 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
95 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
96 | |
97 context.fillRect(FloatRect(99, 13, 10, 90), alpha, CompositeSourceIn); | |
98 EXPECT_EQ_RECT(IntRect(10, 10, 89, 90), context.opaqueRegion().asRect()); | |
99 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
100 | |
101 context.fillRect(FloatRect(8, 8, 3, 90), opaque, CompositeSourceOut); | |
102 EXPECT_EQ_RECT(IntRect(11, 10, 88, 90), context.opaqueRegion().asRect()); | |
103 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
104 | |
105 context.fillRect(FloatRect(30, 30, 290, 290), opaque, CompositeSourceOver); | |
106 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect()); | |
107 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
108 | |
109 context.fillRect(FloatRect(40, 20, 290, 50), opaque, CompositeSourceOver); | |
110 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect()); | |
111 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
112 | |
113 context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceIn); | |
114 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect()); | |
115 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
116 | |
117 context.fillRect(FloatRect(10, 10, 390, 50), alpha); | |
118 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect()); | |
119 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
120 | |
121 context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceOver); | |
122 EXPECT_EQ_RECT(IntRect(30, 10, 290, 310), context.opaqueRegion().asRect()); | |
123 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
124 } | |
125 | |
126 TEST(GraphicsContextTest, trackOpaqueClipTest) | |
127 { | |
128 SkBitmap bitmap; | |
129 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
130 SkCanvas canvas(bitmap); | |
131 | |
132 GraphicsContext context(&canvas); | |
133 context.setTrackOpaqueRegion(true); | |
134 | |
135 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
136 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
137 | |
138 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
139 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
140 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
141 | |
142 context.clearRect(FloatRect(10, 10, 90, 90)); | |
143 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
144 | |
145 context.save(); | |
146 context.clip(FloatRect(0, 0, 10, 10)); | |
147 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
148 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
149 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
150 context.restore(); | |
151 | |
152 context.clearRect(FloatRect(10, 10, 90, 90)); | |
153 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
154 | |
155 context.save(); | |
156 context.clip(FloatRect(20, 20, 10, 10)); | |
157 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
158 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
159 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
160 | |
161 context.clearRect(FloatRect(10, 10, 90, 90)); | |
162 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
163 | |
164 // The intersection of the two clips becomes empty. | |
165 context.clip(FloatRect(30, 20, 10, 10)); | |
166 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
167 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
168 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
169 context.restore(); | |
170 | |
171 context.clearRect(FloatRect(10, 10, 90, 90)); | |
172 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
173 | |
174 // The transform and the clip need to interact correctly (transform first) | |
175 context.save(); | |
176 context.translate(10, 10); | |
177 context.clip(FloatRect(20, 20, 10, 10)); | |
178 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
179 EXPECT_EQ_RECT(IntRect(30, 30, 10, 10), context.opaqueRegion().asRect()); | |
180 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
181 context.restore(); | |
182 | |
183 context.clearRect(FloatRect(10, 10, 90, 90)); | |
184 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
185 | |
186 // The transform and the clip need to interact correctly (clip first) | |
187 context.save(); | |
188 context.clip(FloatRect(20, 20, 10, 10)); | |
189 context.translate(10, 10); | |
190 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
191 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
192 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
193 context.restore(); | |
194 | |
195 context.clearRect(FloatRect(10, 10, 90, 90)); | |
196 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
197 | |
198 Path path; | |
199 path.moveTo(FloatPoint(0, 0)); | |
200 path.addLineTo(FloatPoint(100, 0)); | |
201 | |
202 // Non-rectangular clips just cause the paint to be considered non-opaque. | |
203 context.save(); | |
204 context.clipPath(path, RULE_EVENODD); | |
205 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
206 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
207 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
208 context.restore(); | |
209 | |
210 // Another non-rectangular clip. | |
211 context.save(); | |
212 context.clip(IntRect(30, 30, 20, 20)); | |
213 context.clipOut(IntRect(30, 30, 10, 10)); | |
214 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
215 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
216 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
217 context.restore(); | |
218 } | |
219 | |
220 TEST(GraphicsContextTest, trackImageMask) | |
221 { | |
222 SkBitmap bitmap; | |
223 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
224 bitmap.eraseColor(0); | |
225 SkCanvas canvas(bitmap); | |
226 | |
227 GraphicsContext context(&canvas); | |
228 context.setTrackOpaqueRegion(true); | |
229 | |
230 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
231 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
232 | |
233 // Image masks are done by drawing a bitmap into a transparency layer that u
ses DstIn to mask | |
234 // out a transparency layer below that is filled with the mask color. In the
end this should | |
235 // not be marked opaque. | |
236 | |
237 context.setCompositeOperation(CompositeSourceOver); | |
238 context.beginTransparencyLayer(1); | |
239 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver); | |
240 | |
241 context.setCompositeOperation(CompositeDestinationIn); | |
242 context.beginTransparencyLayer(1); | |
243 | |
244 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100)); | |
245 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha); | |
246 | |
247 context.setCompositeOperation(CompositeSourceOver); | |
248 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10)); | |
249 | |
250 context.endLayer(); | |
251 context.endLayer(); | |
252 | |
253 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
254 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
255 } | |
256 | |
257 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect) | |
258 { | |
259 SkBitmap bitmap; | |
260 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
261 bitmap.eraseColor(0); | |
262 SkCanvas canvas(bitmap); | |
263 | |
264 GraphicsContext context(&canvas); | |
265 context.setTrackOpaqueRegion(true); | |
266 | |
267 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
268 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
269 | |
270 // Image masks are done by drawing a bitmap into a transparency layer that u
ses DstIn to mask | |
271 // out a transparency layer below that is filled with the mask color. In the
end this should | |
272 // not be marked opaque. | |
273 | |
274 context.setCompositeOperation(CompositeSourceOver); | |
275 context.beginTransparencyLayer(1); | |
276 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver); | |
277 | |
278 context.setCompositeOperation(CompositeDestinationIn); | |
279 context.beginTransparencyLayer(1); | |
280 | |
281 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100)); | |
282 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha); | |
283 | |
284 context.setCompositeOperation(CompositeSourceOver); | |
285 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10)); | |
286 | |
287 // We can't have an opaque mask actually, but we can pretend here like it wo
uld look if we did. | |
288 context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver); | |
289 | |
290 context.endLayer(); | |
291 context.endLayer(); | |
292 | |
293 EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect()); | |
294 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
295 } | |
296 | |
297 TEST(GraphicsContextTest, trackOpaqueJoinTest) | |
298 { | |
299 SkBitmap bitmap; | |
300 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
301 SkCanvas canvas(bitmap); | |
302 | |
303 GraphicsContext context(&canvas); | |
304 context.setTrackOpaqueRegion(true); | |
305 | |
306 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
307 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
308 | |
309 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
310 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
311 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
312 | |
313 // Doesn't join | |
314 context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver); | |
315 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
316 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
317 | |
318 // Does join | |
319 context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver); | |
320 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect()); | |
321 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
322 | |
323 // Doesn't join | |
324 context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver); | |
325 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect()); | |
326 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
327 | |
328 // Does join | |
329 context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver); | |
330 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect()); | |
331 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
332 | |
333 // Doesn't join | |
334 context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver); | |
335 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect()); | |
336 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
337 | |
338 // Does join | |
339 context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver); | |
340 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect()); | |
341 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
342 | |
343 // Doesn't join | |
344 context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver); | |
345 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect()); | |
346 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
347 | |
348 // Does join | |
349 context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver); | |
350 EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect()); | |
351 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
352 } | |
353 | |
354 TEST(GraphicsContextTest, trackOpaqueLineTest) | |
355 { | |
356 SkBitmap bitmap; | |
357 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
358 bitmap.eraseColor(0); | |
359 SkCanvas canvas(bitmap); | |
360 | |
361 GraphicsContext context(&canvas); | |
362 context.setTrackOpaqueRegion(true); | |
363 | |
364 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
365 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
366 | |
367 context.setShouldAntialias(false); | |
368 context.setMiterLimit(0); | |
369 context.setStrokeThickness(4); | |
370 context.setLineCap(SquareCap); | |
371 context.setStrokeStyle(SolidStroke); | |
372 context.setCompositeOperation(CompositeSourceOver); | |
373 | |
374 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
375 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
376 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
377 | |
378 context.setCompositeOperation(CompositeSourceIn); | |
379 | |
380 context.save(); | |
381 context.setStrokeColor(alpha); | |
382 context.drawLine(IntPoint(0, 0), IntPoint(100, 0)); | |
383 context.restore(); | |
384 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
385 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
386 | |
387 context.save(); | |
388 context.setStrokeColor(opaque); | |
389 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
390 context.restore(); | |
391 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
392 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
393 | |
394 context.save(); | |
395 context.setStrokeColor(alpha); | |
396 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
397 context.restore(); | |
398 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
399 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
400 | |
401 context.save(); | |
402 context.setStrokeColor(alpha); | |
403 context.drawLine(IntPoint(0, 11), IntPoint(100, 11)); | |
404 context.restore(); | |
405 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
406 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
407 | |
408 context.setShouldAntialias(true); | |
409 context.setCompositeOperation(CompositeSourceOver); | |
410 | |
411 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
412 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
413 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
414 | |
415 context.setCompositeOperation(CompositeSourceIn); | |
416 | |
417 context.save(); | |
418 context.setStrokeColor(alpha); | |
419 context.drawLine(IntPoint(0, 0), IntPoint(100, 0)); | |
420 context.restore(); | |
421 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
422 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
423 | |
424 context.setShouldAntialias(false); | |
425 context.save(); | |
426 context.setStrokeColor(opaque); | |
427 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
428 context.restore(); | |
429 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
430 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
431 | |
432 context.setShouldAntialias(true); | |
433 context.save(); | |
434 context.setStrokeColor(opaque); | |
435 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
436 context.restore(); | |
437 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
438 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
439 | |
440 context.save(); | |
441 context.setStrokeColor(alpha); | |
442 context.drawLine(IntPoint(0, 11), IntPoint(100, 11)); | |
443 context.restore(); | |
444 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
445 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
446 } | |
447 | |
448 TEST(GraphicsContextTest, trackOpaquePathTest) | |
449 { | |
450 SkBitmap bitmap; | |
451 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
452 SkCanvas canvas(bitmap); | |
453 | |
454 GraphicsContext context(&canvas); | |
455 context.setTrackOpaqueRegion(true); | |
456 | |
457 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
458 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
459 | |
460 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
461 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
462 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
463 | |
464 context.setShouldAntialias(false); | |
465 context.setMiterLimit(1); | |
466 context.setStrokeThickness(5); | |
467 context.setLineCap(SquareCap); | |
468 context.setStrokeStyle(SolidStroke); | |
469 context.setCompositeOperation(CompositeSourceIn); | |
470 | |
471 Path path; | |
472 | |
473 context.setFillColor(alpha); | |
474 path.moveTo(FloatPoint(0, 0)); | |
475 path.addLineTo(FloatPoint(100, 0)); | |
476 context.fillPath(path); | |
477 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
478 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
479 path.clear(); | |
480 | |
481 context.setFillColor(opaque); | |
482 path.moveTo(FloatPoint(0, 10)); | |
483 path.addLineTo(FloatPoint(100, 13)); | |
484 context.fillPath(path); | |
485 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
486 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
487 path.clear(); | |
488 | |
489 context.setFillColor(alpha); | |
490 path.moveTo(FloatPoint(0, 10)); | |
491 path.addLineTo(FloatPoint(100, 13)); | |
492 context.fillPath(path); | |
493 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
494 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
495 path.clear(); | |
496 | |
497 context.setFillColor(alpha); | |
498 path.moveTo(FloatPoint(0, 14)); | |
499 path.addLineTo(FloatPoint(100, 10)); | |
500 context.fillPath(path); | |
501 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
502 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
503 path.clear(); | |
504 } | |
505 | |
506 TEST(GraphicsContextTest, trackOpaqueImageTest) | |
507 { | |
508 SkBitmap bitmap; | |
509 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
510 SkCanvas canvas(bitmap); | |
511 | |
512 GraphicsContext context(&canvas); | |
513 context.setTrackOpaqueRegion(true); | |
514 | |
515 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
516 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
517 | |
518 SkBitmap opaqueBitmap; | |
519 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */)); | |
520 | |
521 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
522 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
523 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
524 RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::creat
e(opaqueBitmap)); | |
525 EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque()); | |
526 | |
527 SkBitmap alphaBitmap; | |
528 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10)); | |
529 | |
530 for (int y = 0; y < alphaBitmap.height(); ++y) | |
531 for (int x = 0; x < alphaBitmap.width(); ++x) | |
532 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
533 RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create
(alphaBitmap)); | |
534 EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque()); | |
535 | |
536 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
537 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
538 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
539 | |
540 context.drawImage(opaqueImage.get(), IntPoint(0, 0)); | |
541 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
542 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
543 context.drawImage(alphaImage.get(), IntPoint(0, 0)); | |
544 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
545 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
546 | |
547 context.drawImage(opaqueImage.get(), IntPoint(5, 5)); | |
548 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
549 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
550 context.drawImage(alphaImage.get(), IntPoint(5, 5)); | |
551 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
552 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
553 | |
554 context.drawImage(opaqueImage.get(), IntPoint(10, 10)); | |
555 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
556 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
557 context.drawImage(alphaImage.get(), IntPoint(10, 10)); | |
558 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
559 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
560 | |
561 context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn); | |
562 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect()); | |
563 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
564 | |
565 context.save(); | |
566 context.setAlphaAsFloat(0.5); | |
567 context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn); | |
568 context.restore(); | |
569 EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect()); | |
570 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
571 | |
572 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
573 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
574 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
575 | |
576 context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn); | |
577 EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect()); | |
578 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
579 | |
580 context.save(); | |
581 context.setAlphaAsFloat(0.5); | |
582 context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn); | |
583 context.restore(); | |
584 EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect()); | |
585 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
586 } | |
587 | |
588 TEST(GraphicsContextTest, trackOpaqueOvalTest) | |
589 { | |
590 SkBitmap bitmap; | |
591 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
592 bitmap.eraseColor(0); | |
593 SkCanvas canvas(bitmap); | |
594 | |
595 GraphicsContext context(&canvas); | |
596 context.setTrackOpaqueRegion(true); | |
597 | |
598 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
599 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
600 | |
601 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
602 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
603 | |
604 context.drawEllipse(IntRect(10, 10, 90, 90)); | |
605 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
606 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
607 | |
608 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
609 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
610 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
611 | |
612 context.setCompositeOperation(CompositeSourceIn); | |
613 | |
614 context.setShouldAntialias(false); | |
615 | |
616 context.setFillColor(opaque); | |
617 context.drawEllipse(IntRect(10, 10, 50, 30)); | |
618 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
619 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
620 | |
621 context.setFillColor(alpha); | |
622 context.drawEllipse(IntRect(10, 10, 30, 50)); | |
623 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect()); | |
624 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
625 | |
626 context.setShouldAntialias(true); | |
627 | |
628 context.setFillColor(opaque); | |
629 context.drawEllipse(IntRect(10, 10, 50, 30)); | |
630 EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect()); | |
631 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
632 | |
633 context.setFillColor(alpha); | |
634 context.drawEllipse(IntRect(20, 10, 30, 50)); | |
635 EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect()); | |
636 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
637 } | |
638 | |
639 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest) | |
640 { | |
641 SkBitmap bitmap; | |
642 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
643 SkCanvas canvas(bitmap); | |
644 | |
645 GraphicsContext context(&canvas); | |
646 context.setTrackOpaqueRegion(true); | |
647 | |
648 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
649 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
650 IntSize radii(10, 10); | |
651 | |
652 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
653 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
654 | |
655 context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii,
opaque); | |
656 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
657 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
658 | |
659 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
660 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
661 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
662 | |
663 context.setCompositeOperation(CompositeSourceIn); | |
664 context.setShouldAntialias(false); | |
665 | |
666 context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii,
opaque); | |
667 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
668 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
669 | |
670 context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii,
alpha); | |
671 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect()); | |
672 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
673 | |
674 context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii,
alpha); | |
675 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect()); | |
676 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
677 | |
678 context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii,
opaque); | |
679 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect()); | |
680 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
681 } | |
682 | |
683 TEST(GraphicsContextTest, trackOpaqueTextTest) | |
684 { | |
685 int width = 200, height = 200; | |
686 SkBitmap bitmap; | |
687 ASSERT_TRUE(bitmap.allocN32Pixels(width, height)); | |
688 bitmap.eraseColor(0); | |
689 SkCanvas canvas(bitmap); | |
690 SkRect textRect = SkRect::MakeWH(width, height); | |
691 | |
692 GraphicsContext context(&canvas); | |
693 context.setTrackOpaqueRegion(true); | |
694 | |
695 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
696 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
697 | |
698 SkPaint opaquePaint; | |
699 opaquePaint.setColor(opaque.rgb()); | |
700 opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
701 SkPaint alphaPaint; | |
702 alphaPaint.setColor(alpha.rgb()); | |
703 alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
704 | |
705 SkPoint point = SkPoint::Make(0, 0); | |
706 SkScalar pointX = 0; | |
707 SkPath path; | |
708 path.moveTo(SkPoint::Make(0, 0)); | |
709 path.lineTo(SkPoint::Make(100, 0)); | |
710 | |
711 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver); | |
712 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
713 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
714 | |
715 context.drawPosText("A", 1, &point, textRect, opaquePaint); | |
716 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
717 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
718 | |
719 context.drawPosText("A", 1, &point, textRect, alphaPaint); | |
720 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
721 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
722 | |
723 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver); | |
724 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
725 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
726 | |
727 context.drawPosTextH("A", 1, &pointX, 0, textRect, opaquePaint); | |
728 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
729 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
730 | |
731 context.drawPosTextH("A", 1, &pointX, 0, textRect, alphaPaint); | |
732 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
733 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
734 | |
735 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver); | |
736 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
737 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
738 | |
739 context.drawTextOnPath("A", 1, path, textRect, 0, opaquePaint); | |
740 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
741 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
742 | |
743 context.drawTextOnPath("A", 1, path, textRect, 0, alphaPaint); | |
744 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
745 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
746 } | |
747 | |
748 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest) | |
749 { | |
750 SkBitmap bitmap; | |
751 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
752 bitmap.eraseColor(0); | |
753 SkCanvas canvas(bitmap); | |
754 | |
755 GraphicsContext context(&canvas); | |
756 context.setTrackOpaqueRegion(true); | |
757 | |
758 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
759 | |
760 SkBitmap opaqueBitmap; | |
761 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */)); | |
762 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
763 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
764 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
765 | |
766 SkBitmap alphaBitmap; | |
767 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10)); | |
768 for (int y = 0; y < alphaBitmap.height(); ++y) | |
769 for (int x = 0; x < alphaBitmap.width(); ++x) | |
770 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
771 | |
772 SkPaint paint; | |
773 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
774 | |
775 context.writePixels(opaqueBitmap, 50, 50); | |
776 EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect()); | |
777 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
778 | |
779 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
780 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
781 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
782 | |
783 context.writePixels(alphaBitmap, 10, 0); | |
784 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
785 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
786 | |
787 context.writePixels(alphaBitmap, 10, 1); | |
788 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
789 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
790 | |
791 context.writePixels(alphaBitmap, 0, 10); | |
792 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
793 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
794 | |
795 context.writePixels(alphaBitmap, 1, 10); | |
796 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
797 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
798 } | |
799 | |
800 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest) | |
801 { | |
802 SkBitmap bitmap; | |
803 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
804 bitmap.eraseColor(0); | |
805 SkCanvas canvas(bitmap); | |
806 | |
807 GraphicsContext context(&canvas); | |
808 context.setTrackOpaqueRegion(true); | |
809 | |
810 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
811 | |
812 SkBitmap opaqueBitmap; | |
813 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */)); | |
814 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
815 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
816 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
817 | |
818 SkBitmap alphaBitmap; | |
819 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10)); | |
820 for (int y = 0; y < alphaBitmap.height(); ++y) | |
821 for (int x = 0; x < alphaBitmap.width(); ++x) | |
822 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
823 | |
824 SkPaint paint; | |
825 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
826 | |
827 context.drawBitmap(opaqueBitmap, 10, 10, &paint); | |
828 EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect()); | |
829 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
830 | |
831 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
832 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
833 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
834 | |
835 context.drawBitmap(alphaBitmap, 10, 0, &paint); | |
836 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
837 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
838 | |
839 context.drawBitmap(alphaBitmap, 10, 1, &paint); | |
840 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
841 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
842 | |
843 context.drawBitmap(alphaBitmap, 0, 10, &paint); | |
844 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
845 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
846 | |
847 context.drawBitmap(alphaBitmap, 1, 10, &paint); | |
848 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
849 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
850 } | |
851 | |
852 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest) | |
853 { | |
854 SkBitmap bitmap; | |
855 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200)); | |
856 bitmap.eraseColor(0); | |
857 SkCanvas canvas(bitmap); | |
858 | |
859 GraphicsContext context(&canvas); | |
860 context.setTrackOpaqueRegion(true); | |
861 | |
862 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
863 | |
864 SkBitmap opaqueBitmap; | |
865 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */)); | |
866 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
867 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
868 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
869 | |
870 SkBitmap alphaBitmap; | |
871 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10)); | |
872 for (int y = 0; y < alphaBitmap.height(); ++y) | |
873 for (int x = 0; x < alphaBitmap.width(); ++x) | |
874 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
875 | |
876 SkPaint paint; | |
877 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
878 | |
879 context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &p
aint); | |
880 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
881 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
882 | |
883 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &pai
nt); | |
884 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
885 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
886 | |
887 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &pai
nt); | |
888 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
889 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
890 | |
891 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &pai
nt); | |
892 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
893 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
894 | |
895 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &pai
nt); | |
896 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
897 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
898 } | |
899 | |
900 TEST(GraphicsContextTest, contextTransparencyLayerTest) | |
901 { | |
902 SkBitmap bitmap; | |
903 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
904 bitmap.eraseColor(0); | |
905 SkCanvas canvas(bitmap); | |
906 | |
907 GraphicsContext context(&canvas); | |
908 context.setTrackOpaqueRegion(true); | |
909 | |
910 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
911 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
912 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
913 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
914 | |
915 context.clearRect(FloatRect(20, 20, 10, 10)); | |
916 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
917 | |
918 context.beginTransparencyLayer(0.5); | |
919 context.save(); | |
920 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
921 context.restore(); | |
922 context.endLayer(); | |
923 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
924 | |
925 context.clearRect(FloatRect(20, 20, 10, 10)); | |
926 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
927 | |
928 context.beginTransparencyLayer(0.5); | |
929 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
930 context.endLayer(); | |
931 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
932 } | |
933 | |
934 TEST(GraphicsContextTest, UnboundedDrawsAreClipped) | |
935 { | |
936 SkBitmap bitmap; | |
937 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
938 bitmap.eraseColor(0); | |
939 SkCanvas canvas(bitmap); | |
940 | |
941 GraphicsContext context(&canvas); | |
942 context.setTrackOpaqueRegion(true); | |
943 | |
944 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
945 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
946 | |
947 Path path; | |
948 context.setShouldAntialias(false); | |
949 context.setMiterLimit(1); | |
950 context.setStrokeThickness(5); | |
951 context.setLineCap(SquareCap); | |
952 context.setStrokeStyle(SolidStroke); | |
953 | |
954 // Make skia unable to compute fast bounds for our paths. | |
955 DashArray dashArray; | |
956 dashArray.append(1); | |
957 dashArray.append(0); | |
958 context.setLineDash(dashArray, 0); | |
959 | |
960 // Make the device opaque in 10,10 40x40. | |
961 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
962 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
963 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
964 | |
965 // Clip to the left edge of the opaque area. | |
966 context.clip(IntRect(10, 10, 10, 40)); | |
967 | |
968 // Draw a path that gets clipped. This should destroy the opaque area but on
ly inside the clip. | |
969 context.setCompositeOperation(CompositeSourceOut); | |
970 context.setFillColor(alpha); | |
971 path.moveTo(FloatPoint(10, 10)); | |
972 path.addLineTo(FloatPoint(40, 40)); | |
973 context.strokePath(path); | |
974 | |
975 EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect()); | |
976 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
977 } | |
978 | |
979 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer) | |
980 { | |
981 SkBitmap bitmap; | |
982 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
983 bitmap.eraseColor(0); | |
984 SkCanvas canvas(bitmap); | |
985 | |
986 GraphicsContext context(&canvas); | |
987 context.setTrackOpaqueRegion(true); | |
988 | |
989 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
990 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
991 | |
992 Path path; | |
993 context.setShouldAntialias(false); | |
994 context.setMiterLimit(1); | |
995 context.setStrokeThickness(5); | |
996 context.setLineCap(SquareCap); | |
997 context.setStrokeStyle(SolidStroke); | |
998 | |
999 // Make skia unable to compute fast bounds for our paths. | |
1000 DashArray dashArray; | |
1001 dashArray.append(1); | |
1002 dashArray.append(0); | |
1003 context.setLineDash(dashArray, 0); | |
1004 | |
1005 // Make the device opaque in 10,10 40x40. | |
1006 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1007 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
1008 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1009 | |
1010 // Begin a layer that preserves opaque. | |
1011 context.setCompositeOperation(CompositeSourceOver); | |
1012 context.beginTransparencyLayer(0.5); | |
1013 | |
1014 // Begin a layer that does not preserve opaque. | |
1015 context.setCompositeOperation(CompositeSourceOut); | |
1016 context.beginTransparencyLayer(0.5); | |
1017 | |
1018 // This should not destroy the device opaqueness. | |
1019 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1020 | |
1021 // This should not destroy the device opaqueness either. | |
1022 context.setFillColor(opaque); | |
1023 path.moveTo(FloatPoint(10, 10)); | |
1024 path.addLineTo(FloatPoint(40, 40)); | |
1025 context.strokePath(path); | |
1026 | |
1027 context.endLayer(); | |
1028 context.endLayer(); | |
1029 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
1030 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1031 | |
1032 // Now begin a layer that does not preserve opaque and draw through it to th
e device. | |
1033 context.setCompositeOperation(CompositeSourceOut); | |
1034 context.beginTransparencyLayer(0.5); | |
1035 | |
1036 // This should destroy the device opaqueness. | |
1037 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1038 | |
1039 context.endLayer(); | |
1040 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
1041 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1042 | |
1043 // Now we draw with a path for which it cannot compute fast bounds. This sho
uld destroy the entire opaque region. | |
1044 | |
1045 context.setCompositeOperation(CompositeSourceOut); | |
1046 context.beginTransparencyLayer(0.5); | |
1047 | |
1048 // This should nuke the device opaqueness. | |
1049 context.setFillColor(opaque); | |
1050 path.moveTo(FloatPoint(10, 10)); | |
1051 path.addLineTo(FloatPoint(40, 40)); | |
1052 context.strokePath(path); | |
1053 | |
1054 context.endLayer(); | |
1055 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
1056 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1057 } | |
1058 | |
1059 #define DISPATCH(c1, c2, op, params) do { c1.op(params); c2.op(params); } while
(0); | |
1060 | |
1061 TEST(GraphicsContextTest, RecordingTotalMatrix) | |
1062 { | |
1063 SkBitmap bitmap; | |
1064 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400)); | |
1065 bitmap.eraseColor(0); | |
1066 SkCanvas canvas(bitmap); | |
1067 GraphicsContext context(&canvas); | |
1068 | |
1069 SkCanvas controlCanvas(400, 400); | |
1070 GraphicsContext controlContext(&controlCanvas); | |
1071 | |
1072 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1073 DISPATCH(context, controlContext, scale, FloatSize(2, 2)); | |
1074 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1075 | |
1076 controlContext.save(); | |
1077 context.beginRecording(FloatRect(0, 0, 200, 200)); | |
1078 DISPATCH(context, controlContext, translate, FloatSize(10, 10)); | |
1079 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1080 | |
1081 controlContext.save(); | |
1082 context.beginRecording(FloatRect(10, 10, 100, 100)); | |
1083 DISPATCH(context, controlContext, rotate, 45); | |
1084 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1085 | |
1086 controlContext.restore(); | |
1087 context.endRecording(); | |
1088 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1089 | |
1090 controlContext.restore(); | |
1091 context.endRecording(); | |
1092 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1093 } | |
1094 | |
1095 } // namespace | |
OLD | NEW |