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 WebCore;
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 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
74 SkCanvas canvas(bitmap);
76 GraphicsContext context(&canvas);
77 context.setTrackOpaqueRegion(true);
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 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
131 SkCanvas canvas(bitmap);
133 GraphicsContext context(&canvas);
134 context.setTrackOpaqueRegion(true);
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 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
225 bitmap.eraseColor(0);
226 SkCanvas canvas(bitmap);
228 GraphicsContext context(&canvas);
229 context.setTrackOpaqueRegion(true);
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 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
248 context.setCompositeOperation(CompositeSourceOver);
249 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
254 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
255 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
258 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
261 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
262 bitmap.eraseColor(0);
263 SkCanvas canvas(bitmap);
265 GraphicsContext context(&canvas);
266 context.setTrackOpaqueRegion(true);
268 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
269 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
271 // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
272 // out a transparency layer below that is filled with the mask color. In the end this should
273 // not be marked opaque.
275 context.setCompositeOperation(CompositeSourceOver);
276 context.beginTransparencyLayer(1);
277 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
279 context.setCompositeOperation(CompositeDestinationIn);
280 context.beginTransparencyLayer(1);
282 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
283 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
285 context.setCompositeOperation(CompositeSourceOver);
286 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
288 // We can't have an opaque mask actually, but we can pretend here like it would look if we did.
289 context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver);
294 EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
295 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
298 TEST(GraphicsContextTest, trackOpaqueJoinTest)
301 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
302 SkCanvas canvas(bitmap);
304 GraphicsContext context(&canvas);
305 context.setTrackOpaqueRegion(true);
307 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
308 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
310 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
311 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
312 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
315 context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver);
316 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
317 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
320 context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver);
321 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
322 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
325 context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver);
326 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
327 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
330 context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver);
331 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
332 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
335 context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver);
336 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
337 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
340 context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver);
341 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
342 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
345 context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver);
346 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
347 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
350 context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver);
351 EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect());
352 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
355 TEST(GraphicsContextTest, trackOpaqueLineTest)
358 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
359 bitmap.eraseColor(0);
360 SkCanvas canvas(bitmap);
362 GraphicsContext context(&canvas);
363 context.setTrackOpaqueRegion(true);
365 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
366 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
368 context.setShouldAntialias(false);
369 context.setMiterLimit(0);
370 context.setStrokeThickness(4);
371 context.setLineCap(SquareCap);
372 context.setStrokeStyle(SolidStroke);
373 context.setCompositeOperation(CompositeSourceOver);
375 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
376 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
377 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
379 context.setCompositeOperation(CompositeSourceIn);
382 context.setStrokeColor(alpha);
383 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
385 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
386 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
389 context.setStrokeColor(opaque);
390 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
392 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
393 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
396 context.setStrokeColor(alpha);
397 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
399 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
400 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
403 context.setStrokeColor(alpha);
404 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
406 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
407 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
409 context.setShouldAntialias(true);
410 context.setCompositeOperation(CompositeSourceOver);
412 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
413 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
414 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
416 context.setCompositeOperation(CompositeSourceIn);
419 context.setStrokeColor(alpha);
420 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
422 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
423 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
425 context.setShouldAntialias(false);
427 context.setStrokeColor(opaque);
428 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
430 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
431 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
433 context.setShouldAntialias(true);
435 context.setStrokeColor(opaque);
436 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
438 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
439 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
442 context.setStrokeColor(alpha);
443 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
445 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
446 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
449 TEST(GraphicsContextTest, trackOpaquePathTest)
452 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
453 SkCanvas canvas(bitmap);
455 GraphicsContext context(&canvas);
456 context.setTrackOpaqueRegion(true);
458 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
459 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
461 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
462 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
463 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
465 context.setShouldAntialias(false);
466 context.setMiterLimit(1);
467 context.setStrokeThickness(5);
468 context.setLineCap(SquareCap);
469 context.setStrokeStyle(SolidStroke);
470 context.setCompositeOperation(CompositeSourceIn);
474 context.setFillColor(alpha);
475 path.moveTo(FloatPoint(0, 0));
476 path.addLineTo(FloatPoint(100, 0));
477 context.fillPath(path);
478 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
479 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
482 context.setFillColor(opaque);
483 path.moveTo(FloatPoint(0, 10));
484 path.addLineTo(FloatPoint(100, 13));
485 context.fillPath(path);
486 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
487 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
490 context.setFillColor(alpha);
491 path.moveTo(FloatPoint(0, 10));
492 path.addLineTo(FloatPoint(100, 13));
493 context.fillPath(path);
494 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
495 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
498 context.setFillColor(alpha);
499 path.moveTo(FloatPoint(0, 14));
500 path.addLineTo(FloatPoint(100, 10));
501 context.fillPath(path);
502 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
503 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
507 TEST(GraphicsContextTest, trackOpaqueImageTest)
510 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
511 SkCanvas canvas(bitmap);
513 GraphicsContext context(&canvas);
514 context.setTrackOpaqueRegion(true);
516 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
517 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
519 SkBitmap opaqueBitmap;
520 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
522 for (int y = 0; y < opaqueBitmap.height(); ++y)
523 for (int x = 0; x < opaqueBitmap.width(); ++x)
524 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
525 RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::create(opaqueBitmap));
526 EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
528 SkBitmap alphaBitmap;
529 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
531 for (int y = 0; y < alphaBitmap.height(); ++y)
532 for (int x = 0; x < alphaBitmap.width(); ++x)
533 *alphaBitmap.getAddr32(x, y) = 0x00000000;
534 RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create(alphaBitmap));
535 EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque());
537 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
538 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
539 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
541 context.drawImage(opaqueImage.get(), IntPoint(0, 0));
542 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
543 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
544 context.drawImage(alphaImage.get(), IntPoint(0, 0));
545 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
546 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
548 context.drawImage(opaqueImage.get(), IntPoint(5, 5));
549 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
550 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
551 context.drawImage(alphaImage.get(), IntPoint(5, 5));
552 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
553 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
555 context.drawImage(opaqueImage.get(), IntPoint(10, 10));
556 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
557 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
558 context.drawImage(alphaImage.get(), IntPoint(10, 10));
559 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
560 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
562 context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn);
563 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect());
564 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
567 context.setAlphaAsFloat(0.5);
568 context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
570 EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
571 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
573 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
574 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
575 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
577 context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn);
578 EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect());
579 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
582 context.setAlphaAsFloat(0.5);
583 context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
585 EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
586 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
589 TEST(GraphicsContextTest, trackOpaqueOvalTest)
592 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
593 bitmap.eraseColor(0);
594 SkCanvas canvas(bitmap);
596 GraphicsContext context(&canvas);
597 context.setTrackOpaqueRegion(true);
599 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
600 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
602 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
603 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
605 context.fillEllipse(FloatRect(10, 10, 90, 90));
606 context.strokeEllipse(FloatRect(10, 10, 90, 90));
607 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
608 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
610 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
611 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
612 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
614 context.setCompositeOperation(CompositeSourceIn);
616 context.setShouldAntialias(false);
618 context.setFillColor(opaque);
619 context.fillEllipse(FloatRect(10, 10, 50, 30));
620 context.strokeEllipse(FloatRect(10, 10, 50, 30));
621 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
622 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
624 context.setFillColor(alpha);
625 context.fillEllipse(FloatRect(10, 10, 30, 50));
626 context.strokeEllipse(FloatRect(10, 10, 30, 50));
627 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
628 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
630 context.setShouldAntialias(true);
632 context.setFillColor(opaque);
633 context.fillEllipse(FloatRect(10, 10, 50, 30));
634 context.strokeEllipse(FloatRect(10, 10, 50, 30));
635 EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect());
636 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
638 context.setFillColor(alpha);
639 context.fillEllipse(FloatRect(20, 10, 30, 50));
640 context.strokeEllipse(FloatRect(20, 10, 30, 50));
641 EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect());
642 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
645 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
648 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
649 SkCanvas canvas(bitmap);
651 GraphicsContext context(&canvas);
652 context.setTrackOpaqueRegion(true);
654 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
655 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
656 IntSize radii(10, 10);
658 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
659 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
661 context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii, opaque);
662 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
663 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
665 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
666 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
667 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
669 context.setCompositeOperation(CompositeSourceIn);
670 context.setShouldAntialias(false);
672 context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii, opaque);
673 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
674 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
676 context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii, alpha);
677 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
678 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
680 context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii, alpha);
681 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
682 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
684 context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii, opaque);
685 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
686 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
689 TEST(GraphicsContextTest, trackOpaqueTextTest)
691 int width = 200, height = 200;
693 ASSERT_TRUE(bitmap.allocN32Pixels(width, height));
694 bitmap.eraseColor(0);
695 SkCanvas canvas(bitmap);
696 SkRect textRect = SkRect::MakeWH(width, height);
698 GraphicsContext context(&canvas);
699 context.setTrackOpaqueRegion(true);
701 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
702 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
705 opaquePaint.setColor(opaque.rgb());
706 opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
708 alphaPaint.setColor(alpha.rgb());
709 alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
711 SkPoint point = SkPoint::Make(0, 0);
713 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
714 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
715 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
717 context.drawPosText("A", 1, &point, textRect, opaquePaint);
718 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
719 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
721 context.drawPosText("A", 1, &point, textRect, alphaPaint);
722 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
723 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
725 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
726 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
727 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
729 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
730 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
731 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
734 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
737 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
738 bitmap.eraseColor(0);
739 SkCanvas canvas(bitmap);
741 GraphicsContext context(&canvas);
742 context.setTrackOpaqueRegion(true);
744 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
746 SkBitmap opaqueBitmap;
747 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
748 for (int y = 0; y < opaqueBitmap.height(); ++y)
749 for (int x = 0; x < opaqueBitmap.width(); ++x)
750 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
752 SkBitmap alphaBitmap;
753 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
754 for (int y = 0; y < alphaBitmap.height(); ++y)
755 for (int x = 0; x < alphaBitmap.width(); ++x)
756 *alphaBitmap.getAddr32(x, y) = 0x00000000;
759 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
761 context.writePixels(opaqueBitmap, 50, 50);
762 EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect());
763 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
765 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
766 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
767 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
769 context.writePixels(alphaBitmap, 10, 0);
770 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
771 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
773 context.writePixels(alphaBitmap, 10, 1);
774 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
775 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
777 context.writePixels(alphaBitmap, 0, 10);
778 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
779 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
781 context.writePixels(alphaBitmap, 1, 10);
782 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
783 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
786 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
789 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
790 bitmap.eraseColor(0);
791 SkCanvas canvas(bitmap);
793 GraphicsContext context(&canvas);
794 context.setTrackOpaqueRegion(true);
796 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
798 SkBitmap opaqueBitmap;
799 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
800 for (int y = 0; y < opaqueBitmap.height(); ++y)
801 for (int x = 0; x < opaqueBitmap.width(); ++x)
802 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
804 SkBitmap alphaBitmap;
805 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
806 for (int y = 0; y < alphaBitmap.height(); ++y)
807 for (int x = 0; x < alphaBitmap.width(); ++x)
808 *alphaBitmap.getAddr32(x, y) = 0x00000000;
811 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
813 context.drawBitmap(opaqueBitmap, 10, 10, &paint);
814 EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect());
815 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
817 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
818 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
819 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
821 context.drawBitmap(alphaBitmap, 10, 0, &paint);
822 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
823 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
825 context.drawBitmap(alphaBitmap, 10, 1, &paint);
826 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
827 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
829 context.drawBitmap(alphaBitmap, 0, 10, &paint);
830 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
831 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
833 context.drawBitmap(alphaBitmap, 1, 10, &paint);
834 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
835 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
838 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
841 ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
842 bitmap.eraseColor(0);
843 SkCanvas canvas(bitmap);
845 GraphicsContext context(&canvas);
846 context.setTrackOpaqueRegion(true);
848 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
850 SkBitmap opaqueBitmap;
851 ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
852 for (int y = 0; y < opaqueBitmap.height(); ++y)
853 for (int x = 0; x < opaqueBitmap.width(); ++x)
854 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
856 SkBitmap alphaBitmap;
857 ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
858 for (int y = 0; y < alphaBitmap.height(); ++y)
859 for (int x = 0; x < alphaBitmap.width(); ++x)
860 *alphaBitmap.getAddr32(x, y) = 0x00000000;
863 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
865 context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &paint);
866 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
867 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
869 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &paint);
870 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
871 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
873 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &paint);
874 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
875 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
877 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &paint);
878 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
879 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
881 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &paint);
882 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
883 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
886 TEST(GraphicsContextTest, contextTransparencyLayerTest)
889 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
890 bitmap.eraseColor(0);
891 SkCanvas canvas(bitmap);
893 GraphicsContext context(&canvas);
894 context.setTrackOpaqueRegion(true);
896 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
897 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
898 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
899 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
901 context.clearRect(FloatRect(20, 20, 10, 10));
902 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
904 context.beginTransparencyLayer(0.5);
906 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
909 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
911 context.clearRect(FloatRect(20, 20, 10, 10));
912 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
914 context.beginTransparencyLayer(0.5);
915 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
917 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
920 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
923 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
924 bitmap.eraseColor(0);
925 SkCanvas canvas(bitmap);
927 GraphicsContext context(&canvas);
928 context.setTrackOpaqueRegion(true);
930 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
931 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
934 context.setShouldAntialias(false);
935 context.setMiterLimit(1);
936 context.setStrokeThickness(5);
937 context.setLineCap(SquareCap);
938 context.setStrokeStyle(SolidStroke);
940 // Make skia unable to compute fast bounds for our paths.
944 context.setLineDash(dashArray, 0);
946 // Make the device opaque in 10,10 40x40.
947 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
948 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
949 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
951 // Clip to the left edge of the opaque area.
952 context.clip(IntRect(10, 10, 10, 40));
954 // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
955 context.setCompositeOperation(CompositeSourceOut);
956 context.setFillColor(alpha);
957 path.moveTo(FloatPoint(10, 10));
958 path.addLineTo(FloatPoint(40, 40));
959 context.strokePath(path);
961 EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
962 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
965 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
968 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
969 bitmap.eraseColor(0);
970 SkCanvas canvas(bitmap);
972 GraphicsContext context(&canvas);
973 context.setTrackOpaqueRegion(true);
975 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
976 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
979 context.setShouldAntialias(false);
980 context.setMiterLimit(1);
981 context.setStrokeThickness(5);
982 context.setLineCap(SquareCap);
983 context.setStrokeStyle(SolidStroke);
985 // Make skia unable to compute fast bounds for our paths.
989 context.setLineDash(dashArray, 0);
991 // Make the device opaque in 10,10 40x40.
992 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
993 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
994 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
996 // Begin a layer that preserves opaque.
997 context.setCompositeOperation(CompositeSourceOver);
998 context.beginTransparencyLayer(0.5);
1000 // Begin a layer that does not preserve opaque.
1001 context.setCompositeOperation(CompositeSourceOut);
1002 context.beginTransparencyLayer(0.5);
1004 // This should not destroy the device opaqueness.
1005 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1007 // This should not destroy the device opaqueness either.
1008 context.setFillColor(opaque);
1009 path.moveTo(FloatPoint(10, 10));
1010 path.addLineTo(FloatPoint(40, 40));
1011 context.strokePath(path);
1015 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1016 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1018 // Now begin a layer that does not preserve opaque and draw through it to the device.
1019 context.setCompositeOperation(CompositeSourceOut);
1020 context.beginTransparencyLayer(0.5);
1022 // This should destroy the device opaqueness.
1023 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1026 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1027 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1029 // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
1031 context.setCompositeOperation(CompositeSourceOut);
1032 context.beginTransparencyLayer(0.5);
1034 // This should nuke the device opaqueness.
1035 context.setFillColor(opaque);
1036 path.moveTo(FloatPoint(10, 10));
1037 path.addLineTo(FloatPoint(40, 40));
1038 context.strokePath(path);
1041 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1042 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1045 #define DISPATCH(c1, c2, op, params) do { c1.op(params); c2.op(params); } while (0);
1047 TEST(GraphicsContextTest, RecordingTotalMatrix)
1050 ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
1051 bitmap.eraseColor(0);
1052 SkCanvas canvas(bitmap);
1053 GraphicsContext context(&canvas);
1055 SkCanvas controlCanvas(400, 400);
1056 GraphicsContext controlContext(&controlCanvas);
1058 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1059 DISPATCH(context, controlContext, scale, FloatSize(2, 2));
1060 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1062 controlContext.save();
1063 context.beginRecording(FloatRect(0, 0, 200, 200));
1064 DISPATCH(context, controlContext, translate, FloatSize(10, 10));
1065 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1067 controlContext.save();
1068 context.beginRecording(FloatRect(10, 10, 100, 100));
1069 DISPATCH(context, controlContext, rotate, 45);
1070 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1072 controlContext.restore();
1073 context.endRecording();
1074 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1076 controlContext.restore();
1077 context.endRecording();
1078 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1081 TEST(GraphicsContextTest, DisplayList)
1083 FloatRect rect(0, 0, 1, 1);
1084 RefPtr<DisplayList> dl = adoptRef(new DisplayList(rect));
1086 // picture() returns 0 initially
1087 SkPicture* pic = dl->picture();
1090 // endRecording without a beginRecording does nothing
1092 pic = dl->picture();
1095 // Two beginRecordings in a row generate two canvases.
1096 // Unfortunately the new one could be allocated in the same
1097 // spot as the old one so ref the first one to prolong its life.
1099 SkCanvas* canvas1 = dl->beginRecording(size);
1100 EXPECT_TRUE(canvas1);
1102 SkCanvas* canvas2 = dl->beginRecording(size);
1103 EXPECT_TRUE(canvas2);
1105 EXPECT_NE(canvas1, canvas2);
1106 EXPECT_EQ(1, canvas1->getRefCnt());
1109 EXPECT_TRUE(dl->isRecording());
1111 // picture() returns 0 during recording
1112 pic = dl->picture();
1115 // endRecording finally makes the picture accessible
1117 pic = dl->picture();
1119 EXPECT_EQ(1, pic->getRefCnt());