2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
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 ANY
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 ON
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.
27 #include "platform/graphics/GraphicsContext.h"
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 "third_party/skia/include/core/SkPicture.h"
36 #include <gtest/gtest.h>
38 using namespace blink;
42 #define EXPECT_EQ_RECT(a, b) \
43 EXPECT_EQ(a.x(), b.x()); \
44 EXPECT_EQ(a.y(), b.y()); \
45 EXPECT_EQ(a.width(), b.width()); \
46 EXPECT_EQ(a.height(), b.height());
48 #define EXPECT_PIXELS_MATCH(bitmap, opaqueRect) \
50 SkAutoLockPixels locker(bitmap); \
51 for (int y = opaqueRect.y(); y < opaqueRect.maxY(); ++y) \
52 for (int x = opaqueRect.x(); x < opaqueRect.maxX(); ++x) { \
53 int alpha = *bitmap.getAddr32(x, y) >> 24; \
54 EXPECT_EQ(255, alpha); \
58 #define EXPECT_PIXELS_MATCH_EXACT(bitmap, opaqueRect) \
60 SkAutoLockPixels locker(bitmap); \
61 for (int y = 0; y < bitmap.height(); ++y) \
62 for (int x = 0; x < bitmap.width(); ++x) { \
63 int alpha = *bitmap.getAddr32(x, y) >> 24; \
64 bool opaque = opaqueRect.contains(x, y); \
65 EXPECT_EQ(opaque, alpha == 255); \
69 TEST(GraphicsContextTest, trackOpaqueTest)
72 bitmap.allocN32Pixels(400, 400);
74 SkCanvas canvas(bitmap);
76 GraphicsContext context(&canvas);
77 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
79 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
80 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
82 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
83 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
84 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
86 context.fillRect(FloatRect(10, 10, 90, 90), alpha, CompositeSourceOver);
87 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
88 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
90 context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositePlusLighter);
91 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
92 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
94 context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositeSourceIn);
95 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
96 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
98 context.fillRect(FloatRect(99, 13, 10, 90), alpha, CompositeSourceIn);
99 EXPECT_EQ_RECT(IntRect(10, 10, 89, 90), context.opaqueRegion().asRect());
100 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
102 context.fillRect(FloatRect(8, 8, 3, 90), opaque, CompositeSourceOut);
103 EXPECT_EQ_RECT(IntRect(11, 10, 88, 90), context.opaqueRegion().asRect());
104 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
106 context.fillRect(FloatRect(30, 30, 290, 290), opaque, CompositeSourceOver);
107 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
108 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
110 context.fillRect(FloatRect(40, 20, 290, 50), opaque, CompositeSourceOver);
111 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
112 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
114 context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceIn);
115 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
116 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
118 context.fillRect(FloatRect(10, 10, 390, 50), alpha);
119 EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
120 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
122 context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceOver);
123 EXPECT_EQ_RECT(IntRect(30, 10, 290, 310), context.opaqueRegion().asRect());
124 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
127 TEST(GraphicsContextTest, trackOpaqueClipTest)
130 bitmap.allocN32Pixels(400, 400);
131 SkCanvas canvas(bitmap);
133 GraphicsContext context(&canvas);
134 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
136 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
137 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
139 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
140 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
141 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
143 context.clearRect(FloatRect(10, 10, 90, 90));
144 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
147 context.clip(FloatRect(0, 0, 10, 10));
148 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
149 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
150 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
153 context.clearRect(FloatRect(10, 10, 90, 90));
154 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
157 context.clip(FloatRect(20, 20, 10, 10));
158 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
159 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
160 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
162 context.clearRect(FloatRect(10, 10, 90, 90));
163 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
165 // The intersection of the two clips becomes empty.
166 context.clip(FloatRect(30, 20, 10, 10));
167 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
168 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
169 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
172 context.clearRect(FloatRect(10, 10, 90, 90));
173 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
175 // The transform and the clip need to interact correctly (transform first)
177 context.translate(10, 10);
178 context.clip(FloatRect(20, 20, 10, 10));
179 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
180 EXPECT_EQ_RECT(IntRect(30, 30, 10, 10), context.opaqueRegion().asRect());
181 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
184 context.clearRect(FloatRect(10, 10, 90, 90));
185 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
187 // The transform and the clip need to interact correctly (clip first)
189 context.clip(FloatRect(20, 20, 10, 10));
190 context.translate(10, 10);
191 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
192 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
193 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
196 context.clearRect(FloatRect(10, 10, 90, 90));
197 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
200 path.moveTo(FloatPoint(0, 0));
201 path.addLineTo(FloatPoint(100, 0));
203 // Non-rectangular clips just cause the paint to be considered non-opaque.
205 context.clipPath(path, RULE_EVENODD);
206 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
207 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
208 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
211 // Another non-rectangular clip.
213 context.clip(IntRect(30, 30, 20, 20));
214 context.clipOut(IntRect(30, 30, 10, 10));
215 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
216 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
217 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
221 TEST(GraphicsContextTest, trackImageMask)
224 bitmap.allocN32Pixels(400, 400);
225 bitmap.eraseColor(0);
226 SkCanvas canvas(bitmap);
228 GraphicsContext context(&canvas);
229 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
231 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
232 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
234 // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
235 // out a transparency layer below that is filled with the mask color. In the end this should
236 // not be marked opaque.
238 context.setCompositeOperation(CompositeSourceOver);
239 context.beginTransparencyLayer(1);
240 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
242 context.setCompositeOperation(CompositeDestinationIn);
243 context.beginTransparencyLayer(1);
245 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
246 EXPECT_FALSE(!alphaImage);
247 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
249 context.setCompositeOperation(CompositeSourceOver);
250 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
255 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
256 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
259 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
262 bitmap.allocN32Pixels(400, 400);
263 bitmap.eraseColor(0);
264 SkCanvas canvas(bitmap);
266 GraphicsContext context(&canvas);
267 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
269 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
270 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
272 // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
273 // out a transparency layer below that is filled with the mask color. In the end this should
274 // not be marked opaque.
276 context.setCompositeOperation(CompositeSourceOver);
277 context.beginTransparencyLayer(1);
278 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
280 context.setCompositeOperation(CompositeDestinationIn);
281 context.beginTransparencyLayer(1);
283 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
284 EXPECT_FALSE(!alphaImage);
285 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
287 context.setCompositeOperation(CompositeSourceOver);
288 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
290 // We can't have an opaque mask actually, but we can pretend here like it would look if we did.
291 context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver);
296 EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
297 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
300 TEST(GraphicsContextTest, trackOpaqueJoinTest)
303 bitmap.allocN32Pixels(400, 400);
304 SkCanvas canvas(bitmap);
306 GraphicsContext context(&canvas);
307 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
309 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
310 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
312 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
313 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
314 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
317 context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver);
318 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
319 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
322 context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver);
323 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
324 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
327 context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver);
328 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
329 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
332 context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver);
333 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
334 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
337 context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver);
338 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
339 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
342 context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver);
343 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
344 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
347 context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver);
348 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
349 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
352 context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver);
353 EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect());
354 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
357 TEST(GraphicsContextTest, trackOpaqueLineTest)
360 bitmap.allocN32Pixels(200, 200);
361 bitmap.eraseColor(0);
362 SkCanvas canvas(bitmap);
364 GraphicsContext context(&canvas);
365 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
367 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
368 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
370 context.setShouldAntialias(false);
371 context.setMiterLimit(0);
372 context.setStrokeThickness(4);
373 context.setLineCap(SquareCap);
374 context.setStrokeStyle(SolidStroke);
375 context.setCompositeOperation(CompositeSourceOver);
377 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
378 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
379 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
381 context.setCompositeOperation(CompositeSourceIn);
384 context.setStrokeColor(alpha);
385 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
387 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
388 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
391 context.setStrokeColor(opaque);
392 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
394 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
395 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
398 context.setStrokeColor(alpha);
399 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
401 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
402 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
405 context.setStrokeColor(alpha);
406 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
408 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
409 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
411 context.setShouldAntialias(true);
412 context.setCompositeOperation(CompositeSourceOver);
414 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
415 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
416 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
418 context.setCompositeOperation(CompositeSourceIn);
421 context.setStrokeColor(alpha);
422 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
424 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
425 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
427 context.setShouldAntialias(false);
429 context.setStrokeColor(opaque);
430 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
432 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
433 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
435 context.setShouldAntialias(true);
437 context.setStrokeColor(opaque);
438 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
440 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
441 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
444 context.setStrokeColor(alpha);
445 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
447 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
448 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
451 TEST(GraphicsContextTest, trackOpaquePathTest)
454 bitmap.allocN32Pixels(200, 200);
455 SkCanvas canvas(bitmap);
457 GraphicsContext context(&canvas);
458 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
460 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
461 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
463 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
464 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
465 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
467 context.setShouldAntialias(false);
468 context.setMiterLimit(1);
469 context.setStrokeThickness(5);
470 context.setLineCap(SquareCap);
471 context.setStrokeStyle(SolidStroke);
472 context.setCompositeOperation(CompositeSourceIn);
476 context.setFillColor(alpha);
477 path.moveTo(FloatPoint(0, 0));
478 path.addLineTo(FloatPoint(100, 0));
479 context.fillPath(path);
480 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
481 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
484 context.setFillColor(opaque);
485 path.moveTo(FloatPoint(0, 10));
486 path.addLineTo(FloatPoint(100, 13));
487 context.fillPath(path);
488 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
489 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
492 context.setFillColor(alpha);
493 path.moveTo(FloatPoint(0, 10));
494 path.addLineTo(FloatPoint(100, 13));
495 context.fillPath(path);
496 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
497 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
500 context.setFillColor(alpha);
501 path.moveTo(FloatPoint(0, 14));
502 path.addLineTo(FloatPoint(100, 10));
503 context.fillPath(path);
504 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
505 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
509 TEST(GraphicsContextTest, trackOpaqueImageTest)
512 bitmap.allocN32Pixels(200, 200);
513 SkCanvas canvas(bitmap);
515 GraphicsContext context(&canvas);
516 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
518 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
519 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
521 SkBitmap opaqueBitmap;
522 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
524 for (int y = 0; y < opaqueBitmap.height(); ++y)
525 for (int x = 0; x < opaqueBitmap.width(); ++x)
526 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
527 RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::create(opaqueBitmap));
528 EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
530 SkBitmap alphaBitmap;
531 alphaBitmap.allocN32Pixels(10, 10);
533 for (int y = 0; y < alphaBitmap.height(); ++y)
534 for (int x = 0; x < alphaBitmap.width(); ++x)
535 *alphaBitmap.getAddr32(x, y) = 0x00000000;
536 RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create(alphaBitmap));
537 EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque());
539 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
540 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
541 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
543 context.drawImage(opaqueImage.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 context.drawImage(alphaImage.get(), IntPoint(0, 0));
547 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
548 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
550 context.drawImage(opaqueImage.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 context.drawImage(alphaImage.get(), IntPoint(5, 5));
554 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
555 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
557 context.drawImage(opaqueImage.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 context.drawImage(alphaImage.get(), IntPoint(10, 10));
561 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
562 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
564 context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn);
565 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect());
566 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
569 context.setAlphaAsFloat(0.5);
570 context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
572 EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
573 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
575 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
576 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
577 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
579 context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn);
580 EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect());
581 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
584 context.setAlphaAsFloat(0.5);
585 context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
587 EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
588 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
591 TEST(GraphicsContextTest, trackOpaqueOvalTest)
594 bitmap.allocN32Pixels(200, 200);
595 bitmap.eraseColor(0);
596 SkCanvas canvas(bitmap);
598 GraphicsContext context(&canvas);
599 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
601 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
602 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
604 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
605 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
607 context.fillEllipse(FloatRect(10, 10, 90, 90));
608 context.strokeEllipse(FloatRect(10, 10, 90, 90));
609 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
610 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
612 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
613 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
614 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
616 context.setCompositeOperation(CompositeSourceIn);
618 context.setShouldAntialias(false);
620 context.setFillColor(opaque);
621 context.fillEllipse(FloatRect(10, 10, 50, 30));
622 context.strokeEllipse(FloatRect(10, 10, 50, 30));
623 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
624 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
626 context.setFillColor(alpha);
627 context.fillEllipse(FloatRect(10, 10, 30, 50));
628 context.strokeEllipse(FloatRect(10, 10, 30, 50));
629 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
630 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
632 context.setShouldAntialias(true);
634 context.setFillColor(opaque);
635 context.fillEllipse(FloatRect(10, 10, 50, 30));
636 context.strokeEllipse(FloatRect(10, 10, 50, 30));
637 EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect());
638 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
640 context.setFillColor(alpha);
641 context.fillEllipse(FloatRect(20, 10, 30, 50));
642 context.strokeEllipse(FloatRect(20, 10, 30, 50));
643 EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect());
644 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
647 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
650 bitmap.allocN32Pixels(200, 200);
651 SkCanvas canvas(bitmap);
653 GraphicsContext context(&canvas);
654 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
656 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
657 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
658 IntSize radii(10, 10);
660 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
661 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
663 context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii, opaque);
664 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
665 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
667 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
668 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
669 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
671 context.setCompositeOperation(CompositeSourceIn);
672 context.setShouldAntialias(false);
674 context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii, opaque);
675 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
676 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
678 context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii, alpha);
679 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
680 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
682 context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii, alpha);
683 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
684 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
686 context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii, opaque);
687 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
688 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
691 TEST(GraphicsContextTest, trackOpaqueTextTest)
693 int width = 200, height = 200;
695 bitmap.allocN32Pixels(width, height);
696 bitmap.eraseColor(0);
697 SkCanvas canvas(bitmap);
698 SkRect textRect = SkRect::MakeWH(width, height);
700 GraphicsContext context(&canvas);
701 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
703 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
704 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
707 opaquePaint.setColor(opaque.rgb());
708 opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
710 alphaPaint.setColor(alpha.rgb());
711 alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
713 SkPoint point = SkPoint::Make(0, 0);
715 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
716 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
717 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
719 context.drawPosText("A", 1, &point, textRect, opaquePaint);
720 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
721 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
723 context.drawPosText("A", 1, &point, textRect, alphaPaint);
724 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
725 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
727 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
728 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
729 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
731 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
732 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
733 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
736 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
739 bitmap.allocN32Pixels(200, 200);
740 bitmap.eraseColor(0);
741 SkCanvas canvas(bitmap);
743 GraphicsContext context(&canvas);
744 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
746 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
748 SkBitmap opaqueBitmap;
749 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
750 for (int y = 0; y < opaqueBitmap.height(); ++y)
751 for (int x = 0; x < opaqueBitmap.width(); ++x)
752 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
754 SkBitmap alphaBitmap;
755 alphaBitmap.allocN32Pixels(10, 10);
756 for (int y = 0; y < alphaBitmap.height(); ++y)
757 for (int x = 0; x < alphaBitmap.width(); ++x)
758 *alphaBitmap.getAddr32(x, y) = 0x00000000;
761 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
763 context.writePixels(opaqueBitmap, 50, 50);
764 EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect());
765 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
767 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
768 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
769 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
771 context.writePixels(alphaBitmap, 10, 0);
772 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
773 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
775 context.writePixels(alphaBitmap, 10, 1);
776 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
777 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
779 context.writePixels(alphaBitmap, 0, 10);
780 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
781 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
783 context.writePixels(alphaBitmap, 1, 10);
784 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
785 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
788 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
791 bitmap.allocN32Pixels(200, 200);
792 bitmap.eraseColor(0);
793 SkCanvas canvas(bitmap);
795 GraphicsContext context(&canvas);
796 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
798 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
800 SkBitmap opaqueBitmap;
801 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
802 for (int y = 0; y < opaqueBitmap.height(); ++y)
803 for (int x = 0; x < opaqueBitmap.width(); ++x)
804 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
806 SkBitmap alphaBitmap;
807 alphaBitmap.allocN32Pixels(10, 10);
808 for (int y = 0; y < alphaBitmap.height(); ++y)
809 for (int x = 0; x < alphaBitmap.width(); ++x)
810 *alphaBitmap.getAddr32(x, y) = 0x00000000;
813 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
815 context.drawBitmap(opaqueBitmap, 10, 10, &paint);
816 EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect());
817 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
819 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
820 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
821 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
823 context.drawBitmap(alphaBitmap, 10, 0, &paint);
824 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
825 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
827 context.drawBitmap(alphaBitmap, 10, 1, &paint);
828 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
829 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
831 context.drawBitmap(alphaBitmap, 0, 10, &paint);
832 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
833 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
835 context.drawBitmap(alphaBitmap, 1, 10, &paint);
836 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
837 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
840 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
843 bitmap.allocN32Pixels(200, 200);
844 bitmap.eraseColor(0);
845 SkCanvas canvas(bitmap);
847 GraphicsContext context(&canvas);
848 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
850 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
852 SkBitmap opaqueBitmap;
853 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
854 for (int y = 0; y < opaqueBitmap.height(); ++y)
855 for (int x = 0; x < opaqueBitmap.width(); ++x)
856 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
858 SkBitmap alphaBitmap;
859 alphaBitmap.allocN32Pixels(10, 10);
860 for (int y = 0; y < alphaBitmap.height(); ++y)
861 for (int x = 0; x < alphaBitmap.width(); ++x)
862 *alphaBitmap.getAddr32(x, y) = 0x00000000;
865 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
867 context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &paint);
868 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
869 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
871 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &paint);
872 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
873 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
875 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &paint);
876 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
877 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
879 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &paint);
880 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
881 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
883 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &paint);
884 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
885 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
888 TEST(GraphicsContextTest, contextTransparencyLayerTest)
891 bitmap.allocN32Pixels(400, 400);
892 bitmap.eraseColor(0);
893 SkCanvas canvas(bitmap);
895 GraphicsContext context(&canvas);
896 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
898 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
899 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
900 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
901 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
903 context.clearRect(FloatRect(20, 20, 10, 10));
904 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
906 context.beginTransparencyLayer(0.5);
908 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
911 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
913 context.clearRect(FloatRect(20, 20, 10, 10));
914 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
916 context.beginTransparencyLayer(0.5);
917 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
919 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
922 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
925 bitmap.allocN32Pixels(400, 400);
926 bitmap.eraseColor(0);
927 SkCanvas canvas(bitmap);
929 GraphicsContext context(&canvas);
930 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
932 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
933 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
936 context.setShouldAntialias(false);
937 context.setMiterLimit(1);
938 context.setStrokeThickness(5);
939 context.setLineCap(SquareCap);
940 context.setStrokeStyle(SolidStroke);
942 // Make skia unable to compute fast bounds for our paths.
946 context.setLineDash(dashArray, 0);
948 // Make the device opaque in 10,10 40x40.
949 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
950 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
951 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
953 // Clip to the left edge of the opaque area.
954 context.clip(IntRect(10, 10, 10, 40));
956 // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
957 context.setCompositeOperation(CompositeSourceOut);
958 context.setFillColor(alpha);
959 path.moveTo(FloatPoint(10, 10));
960 path.addLineTo(FloatPoint(40, 40));
961 context.strokePath(path);
963 EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
964 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
967 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
970 bitmap.allocN32Pixels(400, 400);
971 bitmap.eraseColor(0);
972 SkCanvas canvas(bitmap);
974 GraphicsContext context(&canvas);
975 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
977 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
978 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
981 context.setShouldAntialias(false);
982 context.setMiterLimit(1);
983 context.setStrokeThickness(5);
984 context.setLineCap(SquareCap);
985 context.setStrokeStyle(SolidStroke);
987 // Make skia unable to compute fast bounds for our paths.
991 context.setLineDash(dashArray, 0);
993 // Make the device opaque in 10,10 40x40.
994 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
995 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
996 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
998 // Begin a layer that preserves opaque.
999 context.setCompositeOperation(CompositeSourceOver);
1000 context.beginTransparencyLayer(0.5);
1002 // Begin a layer that does not preserve opaque.
1003 context.setCompositeOperation(CompositeSourceOut);
1004 context.beginTransparencyLayer(0.5);
1006 // This should not destroy the device opaqueness.
1007 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1009 // This should not destroy the device opaqueness either.
1010 context.setFillColor(opaque);
1011 path.moveTo(FloatPoint(10, 10));
1012 path.addLineTo(FloatPoint(40, 40));
1013 context.strokePath(path);
1017 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1018 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1020 // Now begin a layer that does not preserve opaque and draw through it to the device.
1021 context.setCompositeOperation(CompositeSourceOut);
1022 context.beginTransparencyLayer(0.5);
1024 // This should destroy the device opaqueness.
1025 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1028 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1029 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1031 // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
1033 context.setCompositeOperation(CompositeSourceOut);
1034 context.beginTransparencyLayer(0.5);
1036 // This should nuke the device opaqueness.
1037 context.setFillColor(opaque);
1038 path.moveTo(FloatPoint(10, 10));
1039 path.addLineTo(FloatPoint(40, 40));
1040 context.strokePath(path);
1043 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1044 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1047 TEST(GraphicsContextTest, OpaqueRegionForLayerWithNonRectDeviceClip)
1050 bitmap.allocN32Pixels(100, 100);
1051 bitmap.eraseColor(0);
1052 SkCanvas canvas(bitmap);
1054 GraphicsContext context(&canvas);
1055 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1056 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1058 context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1060 context.setCompositeOperation(CompositeSourceOver);
1061 context.beginTransparencyLayer(0.5);
1063 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1066 path.moveTo(FloatPoint(0, 0));
1067 path.addLineTo(FloatPoint(50, 50));
1069 // For opaque preserving mode and deviceClip is not rect
1070 // we will not alter opaque rect.
1071 context.clipPath(path, RULE_EVENODD);
1073 context.setCompositeOperation(CompositeSourceOver);
1074 context.beginTransparencyLayer(0.5);
1076 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1078 // For non-opaque preserving mode and deviceClip is not rect
1079 // we will mark opaque rect as empty.
1080 context.setCompositeOperation(CompositeSourceOut);
1081 context.beginTransparencyLayer(0.5);
1084 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1087 TEST(GraphicsContextTest, OpaqueRegionForLayerWithRectDeviceClip)
1090 bitmap.allocN32Pixels(100, 100);
1091 bitmap.eraseColor(0);
1092 SkCanvas canvas(bitmap);
1094 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1096 GraphicsContext context(&canvas);
1097 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1099 context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1100 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1102 // For non-opaque preserving mode and deviceClip is rect
1103 // we will mark device clip rect as non opaque.
1104 context.setCompositeOperation(CompositeSourceOut);
1105 context.beginTransparencyLayer(0.5);
1107 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1108 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1110 context.clip(FloatRect(0, 0, 50, 50));
1111 context.fillRect(FloatRect(20, 20, 100, 100), opaque, CompositeSourceOver);
1113 // For opaque preserving mode and deviceClip is rect
1114 // we will intersect device clip rect with src opaque rect.
1115 context.setCompositeOperation(CompositeSourceOver);
1116 context.beginTransparencyLayer(0.5);
1118 EXPECT_EQ_RECT(IntRect(20, 20, 30, 30), context.opaqueRegion().asRect());
1119 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1122 #define DISPATCH1(c1, c2, op, param1) do { c1.op(param1); c2.op(param1); } while (0);
1123 #define DISPATCH2(c1, c2, op, param1, param2) do { c1.op(param1, param2); c2.op(param1, param2); } while (0);
1125 TEST(GraphicsContextTest, RecordingTotalMatrix)
1128 bitmap.allocN32Pixels(400, 400);
1129 bitmap.eraseColor(0);
1130 SkCanvas canvas(bitmap);
1131 GraphicsContext context(&canvas);
1133 SkCanvas controlCanvas(400, 400);
1134 GraphicsContext controlContext(&controlCanvas);
1136 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1137 DISPATCH2(context, controlContext, scale, 2, 2);
1138 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1140 controlContext.save();
1141 context.beginRecording(FloatRect(0, 0, 200, 200));
1142 DISPATCH2(context, controlContext, translate, 10, 10);
1143 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1145 controlContext.save();
1146 context.beginRecording(FloatRect(10, 10, 100, 100));
1147 DISPATCH1(context, controlContext, rotate, 45);
1148 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1150 controlContext.restore();
1151 context.endRecording();
1152 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1154 controlContext.restore();
1155 context.endRecording();
1156 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1159 TEST(GraphicsContextTest, RecordingCanvas)
1162 bitmap.allocN32Pixels(1, 1);
1163 bitmap.eraseColor(0);
1164 SkCanvas canvas(bitmap);
1165 GraphicsContext context(&canvas);
1167 FloatRect rect(0, 0, 1, 1);
1169 // Two beginRecordings in a row generate two canvases.
1170 // Unfortunately the new one could be allocated in the same
1171 // spot as the old one so ref the first one to prolong its life.
1172 context.beginRecording(rect);
1173 SkCanvas* canvas1 = context.canvas();
1174 EXPECT_TRUE(canvas1);
1175 context.beginRecording(rect);
1176 SkCanvas* canvas2 = context.canvas();
1177 EXPECT_TRUE(canvas2);
1179 EXPECT_NE(canvas1, canvas2);
1180 EXPECT_EQ(1, canvas1->getRefCnt());
1182 // endRecording finally makes the picture accessible
1183 RefPtr<DisplayList> dl = context.endRecording();
1184 SkPicture* pic = dl->picture();
1186 EXPECT_EQ(1, pic->getRefCnt());
1188 context.endRecording();