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, trackDisplayListRecording)
224 bitmap.allocN32Pixels(100, 100);
225 SkCanvas canvas(bitmap);
227 GraphicsContext context(&canvas);
228 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
230 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
232 context.fillRect(FloatRect(0, 0, 50, 50), opaque, CompositeSourceOver);
233 EXPECT_EQ_RECT(IntRect(0, 0, 50, 50), context.opaqueRegion().asRect());
234 FloatRect bounds(0, 0, 100, 100);
235 context.beginRecording(bounds);
236 context.fillRect(FloatRect(0, 0, 100, 100), opaque, CompositeSourceOver);
237 RefPtr<DisplayList> displayList = context.endRecording();
239 // Make sure the opaque region was unaffected by the rect drawn during DisplayList recording.
240 EXPECT_EQ_RECT(IntRect(0, 0, 50, 50), context.opaqueRegion().asRect());
242 // Make sure the opaque region *is* affected (reset) by drawing the DisplayList itself.
243 context.drawDisplayList(displayList.get());
244 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
247 TEST(GraphicsContextTest, trackImageMask)
250 bitmap.allocN32Pixels(400, 400);
251 bitmap.eraseColor(0);
252 SkCanvas canvas(bitmap);
254 GraphicsContext context(&canvas);
255 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
257 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
258 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
260 // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
261 // out a transparency layer below that is filled with the mask color. In the end this should
262 // not be marked opaque.
264 context.setCompositeOperation(CompositeSourceOver);
265 context.beginTransparencyLayer(1);
266 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
268 context.setCompositeOperation(CompositeDestinationIn);
269 context.beginTransparencyLayer(1);
271 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
272 EXPECT_FALSE(!alphaImage);
273 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
275 context.setCompositeOperation(CompositeSourceOver);
276 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
281 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
282 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
285 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
288 bitmap.allocN32Pixels(400, 400);
289 bitmap.eraseColor(0);
290 SkCanvas canvas(bitmap);
292 GraphicsContext context(&canvas);
293 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
295 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
296 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
298 // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
299 // out a transparency layer below that is filled with the mask color. In the end this should
300 // not be marked opaque.
302 context.setCompositeOperation(CompositeSourceOver);
303 context.beginTransparencyLayer(1);
304 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
306 context.setCompositeOperation(CompositeDestinationIn);
307 context.beginTransparencyLayer(1);
309 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
310 EXPECT_FALSE(!alphaImage);
311 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
313 context.setCompositeOperation(CompositeSourceOver);
314 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
316 // We can't have an opaque mask actually, but we can pretend here like it would look if we did.
317 context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver);
322 EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
323 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
326 TEST(GraphicsContextTest, trackOpaqueJoinTest)
329 bitmap.allocN32Pixels(400, 400);
330 SkCanvas canvas(bitmap);
332 GraphicsContext context(&canvas);
333 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
335 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
336 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
338 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
339 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
340 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
343 context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver);
344 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
345 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
348 context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver);
349 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
350 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
353 context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver);
354 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
355 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
358 context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver);
359 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
360 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
363 context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver);
364 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
365 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
368 context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver);
369 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
370 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
373 context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver);
374 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
375 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
378 context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver);
379 EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect());
380 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
383 TEST(GraphicsContextTest, trackOpaqueLineTest)
386 bitmap.allocN32Pixels(200, 200);
387 bitmap.eraseColor(0);
388 SkCanvas canvas(bitmap);
390 GraphicsContext context(&canvas);
391 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
393 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
394 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
396 context.setShouldAntialias(false);
397 context.setMiterLimit(0);
398 context.setStrokeThickness(4);
399 context.setLineCap(SquareCap);
400 context.setStrokeStyle(SolidStroke);
401 context.setCompositeOperation(CompositeSourceOver);
403 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
404 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
405 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
407 context.setCompositeOperation(CompositeSourceIn);
410 context.setStrokeColor(alpha);
411 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
413 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
414 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
417 context.setStrokeColor(opaque);
418 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
420 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
421 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
424 context.setStrokeColor(alpha);
425 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
427 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
428 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
431 context.setStrokeColor(alpha);
432 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
434 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
435 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
437 context.setShouldAntialias(true);
438 context.setCompositeOperation(CompositeSourceOver);
440 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
441 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
442 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
444 context.setCompositeOperation(CompositeSourceIn);
447 context.setStrokeColor(alpha);
448 context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
450 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
451 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
453 context.setShouldAntialias(false);
455 context.setStrokeColor(opaque);
456 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
458 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
459 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
461 context.setShouldAntialias(true);
463 context.setStrokeColor(opaque);
464 context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
466 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
467 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
470 context.setStrokeColor(alpha);
471 context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
473 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
474 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
477 TEST(GraphicsContextTest, trackOpaquePathTest)
480 bitmap.allocN32Pixels(200, 200);
481 SkCanvas canvas(bitmap);
483 GraphicsContext context(&canvas);
484 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
486 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
487 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
489 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
490 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
491 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
493 context.setShouldAntialias(false);
494 context.setMiterLimit(1);
495 context.setStrokeThickness(5);
496 context.setLineCap(SquareCap);
497 context.setStrokeStyle(SolidStroke);
498 context.setCompositeOperation(CompositeSourceIn);
502 context.setFillColor(alpha);
503 path.moveTo(FloatPoint(0, 0));
504 path.addLineTo(FloatPoint(100, 0));
505 context.fillPath(path);
506 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
507 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
510 context.setFillColor(opaque);
511 path.moveTo(FloatPoint(0, 10));
512 path.addLineTo(FloatPoint(100, 13));
513 context.fillPath(path);
514 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
515 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
518 context.setFillColor(alpha);
519 path.moveTo(FloatPoint(0, 10));
520 path.addLineTo(FloatPoint(100, 13));
521 context.fillPath(path);
522 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
523 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
526 context.setFillColor(alpha);
527 path.moveTo(FloatPoint(0, 14));
528 path.addLineTo(FloatPoint(100, 10));
529 context.fillPath(path);
530 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
531 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
535 TEST(GraphicsContextTest, trackOpaqueImageTest)
538 bitmap.allocN32Pixels(200, 200);
539 SkCanvas canvas(bitmap);
541 GraphicsContext context(&canvas);
542 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
544 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
545 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
547 SkBitmap opaqueBitmap;
548 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
550 for (int y = 0; y < opaqueBitmap.height(); ++y)
551 for (int x = 0; x < opaqueBitmap.width(); ++x)
552 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
553 RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::create(opaqueBitmap));
554 EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
556 SkBitmap alphaBitmap;
557 alphaBitmap.allocN32Pixels(10, 10);
559 for (int y = 0; y < alphaBitmap.height(); ++y)
560 for (int x = 0; x < alphaBitmap.width(); ++x)
561 *alphaBitmap.getAddr32(x, y) = 0x00000000;
562 RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create(alphaBitmap));
563 EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque());
565 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
566 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
567 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
569 context.drawImage(opaqueImage.get(), IntPoint(0, 0));
570 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
571 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
572 context.drawImage(alphaImage.get(), IntPoint(0, 0));
573 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
574 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
576 context.drawImage(opaqueImage.get(), IntPoint(5, 5));
577 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
578 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
579 context.drawImage(alphaImage.get(), IntPoint(5, 5));
580 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
581 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
583 context.drawImage(opaqueImage.get(), IntPoint(10, 10));
584 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
585 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
586 context.drawImage(alphaImage.get(), IntPoint(10, 10));
587 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
588 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
590 context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn);
591 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect());
592 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
595 context.setAlphaAsFloat(0.5);
596 context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
598 EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
599 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
601 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
602 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
603 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
605 context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn);
606 EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect());
607 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
610 context.setAlphaAsFloat(0.5);
611 context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
613 EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
614 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
617 TEST(GraphicsContextTest, trackOpaqueOvalTest)
620 bitmap.allocN32Pixels(200, 200);
621 bitmap.eraseColor(0);
622 SkCanvas canvas(bitmap);
624 GraphicsContext context(&canvas);
625 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
627 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
628 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
630 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
631 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
633 context.fillEllipse(FloatRect(10, 10, 90, 90));
634 context.strokeEllipse(FloatRect(10, 10, 90, 90));
635 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
636 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
638 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
639 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
640 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
642 context.setCompositeOperation(CompositeSourceIn);
644 context.setShouldAntialias(false);
646 context.setFillColor(opaque);
647 context.fillEllipse(FloatRect(10, 10, 50, 30));
648 context.strokeEllipse(FloatRect(10, 10, 50, 30));
649 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
650 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
652 context.setFillColor(alpha);
653 context.fillEllipse(FloatRect(10, 10, 30, 50));
654 context.strokeEllipse(FloatRect(10, 10, 30, 50));
655 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
656 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
658 context.setShouldAntialias(true);
660 context.setFillColor(opaque);
661 context.fillEllipse(FloatRect(10, 10, 50, 30));
662 context.strokeEllipse(FloatRect(10, 10, 50, 30));
663 EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect());
664 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
666 context.setFillColor(alpha);
667 context.fillEllipse(FloatRect(20, 10, 30, 50));
668 context.strokeEllipse(FloatRect(20, 10, 30, 50));
669 EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect());
670 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
673 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
676 bitmap.allocN32Pixels(200, 200);
677 SkCanvas canvas(bitmap);
679 GraphicsContext context(&canvas);
680 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
682 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
683 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
684 IntSize radii(10, 10);
686 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
687 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
689 context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii, opaque);
690 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
691 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
693 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
694 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
695 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
697 context.setCompositeOperation(CompositeSourceIn);
698 context.setShouldAntialias(false);
700 context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii, opaque);
701 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
702 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
704 context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii, alpha);
705 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
706 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
708 context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii, alpha);
709 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
710 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
712 context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii, opaque);
713 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
714 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
717 TEST(GraphicsContextTest, trackOpaqueTextTest)
719 int width = 200, height = 200;
721 bitmap.allocN32Pixels(width, height);
722 bitmap.eraseColor(0);
723 SkCanvas canvas(bitmap);
724 SkRect textRect = SkRect::MakeWH(width, height);
726 GraphicsContext context(&canvas);
727 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
729 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
730 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
733 opaquePaint.setColor(opaque.rgb());
734 opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
736 alphaPaint.setColor(alpha.rgb());
737 alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
739 SkPoint point = SkPoint::Make(0, 0);
741 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
742 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
743 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
745 context.drawPosText("A", 1, &point, textRect, opaquePaint);
746 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
747 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
749 context.drawPosText("A", 1, &point, textRect, alphaPaint);
750 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
751 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
753 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
754 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
755 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
757 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
758 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
759 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
762 static inline void writePixels(GraphicsContext* context, const SkBitmap& bm, int x, int y)
764 SkAutoLockPixels locker(bm);
765 context->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y);
768 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
771 bitmap.allocN32Pixels(200, 200);
772 bitmap.eraseColor(0);
773 SkCanvas canvas(bitmap);
775 GraphicsContext context(&canvas);
776 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
778 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
780 SkBitmap opaqueBitmap;
781 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
782 for (int y = 0; y < opaqueBitmap.height(); ++y)
783 for (int x = 0; x < opaqueBitmap.width(); ++x)
784 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
786 SkBitmap alphaBitmap;
787 alphaBitmap.allocN32Pixels(10, 10);
788 for (int y = 0; y < alphaBitmap.height(); ++y)
789 for (int x = 0; x < alphaBitmap.width(); ++x)
790 *alphaBitmap.getAddr32(x, y) = 0x00000000;
793 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
795 writePixels(&context, opaqueBitmap, 50, 50);
796 EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect());
797 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
799 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
800 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
801 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
803 writePixels(&context, alphaBitmap, 10, 0);
804 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
805 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
807 writePixels(&context, alphaBitmap, 10, 1);
808 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
809 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
811 writePixels(&context, alphaBitmap, 0, 10);
812 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
813 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
815 writePixels(&context, alphaBitmap, 1, 10);
816 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
817 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
820 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
823 bitmap.allocN32Pixels(200, 200);
824 bitmap.eraseColor(0);
825 SkCanvas canvas(bitmap);
827 GraphicsContext context(&canvas);
828 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
830 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
832 SkBitmap opaqueBitmap;
833 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
834 for (int y = 0; y < opaqueBitmap.height(); ++y)
835 for (int x = 0; x < opaqueBitmap.width(); ++x)
836 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
838 SkBitmap alphaBitmap;
839 alphaBitmap.allocN32Pixels(10, 10);
840 for (int y = 0; y < alphaBitmap.height(); ++y)
841 for (int x = 0; x < alphaBitmap.width(); ++x)
842 *alphaBitmap.getAddr32(x, y) = 0x00000000;
845 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
847 context.drawBitmap(opaqueBitmap, 10, 10, &paint);
848 EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect());
849 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
851 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
852 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
853 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
855 context.drawBitmap(alphaBitmap, 10, 0, &paint);
856 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
857 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
859 context.drawBitmap(alphaBitmap, 10, 1, &paint);
860 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
861 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
863 context.drawBitmap(alphaBitmap, 0, 10, &paint);
864 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
865 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
867 context.drawBitmap(alphaBitmap, 1, 10, &paint);
868 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
869 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
872 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
875 bitmap.allocN32Pixels(200, 200);
876 bitmap.eraseColor(0);
877 SkCanvas canvas(bitmap);
879 GraphicsContext context(&canvas);
880 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
882 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
884 SkBitmap opaqueBitmap;
885 opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
886 for (int y = 0; y < opaqueBitmap.height(); ++y)
887 for (int x = 0; x < opaqueBitmap.width(); ++x)
888 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
890 SkBitmap alphaBitmap;
891 alphaBitmap.allocN32Pixels(10, 10);
892 for (int y = 0; y < alphaBitmap.height(); ++y)
893 for (int x = 0; x < alphaBitmap.width(); ++x)
894 *alphaBitmap.getAddr32(x, y) = 0x00000000;
897 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
899 context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &paint);
900 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
901 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
903 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &paint);
904 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
905 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
907 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &paint);
908 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
909 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
911 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &paint);
912 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
913 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
915 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &paint);
916 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
917 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
920 TEST(GraphicsContextTest, contextTransparencyLayerTest)
923 bitmap.allocN32Pixels(400, 400);
924 bitmap.eraseColor(0);
925 SkCanvas canvas(bitmap);
927 GraphicsContext context(&canvas);
928 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
930 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
931 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
932 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
933 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
935 context.clearRect(FloatRect(20, 20, 10, 10));
936 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
938 context.beginTransparencyLayer(0.5);
940 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
943 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
945 context.clearRect(FloatRect(20, 20, 10, 10));
946 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
948 context.beginTransparencyLayer(0.5);
949 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
951 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
954 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
957 bitmap.allocN32Pixels(400, 400);
958 bitmap.eraseColor(0);
959 SkCanvas canvas(bitmap);
961 GraphicsContext context(&canvas);
962 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
964 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
965 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
968 context.setShouldAntialias(false);
969 context.setMiterLimit(1);
970 context.setStrokeThickness(5);
971 context.setLineCap(SquareCap);
972 context.setStrokeStyle(SolidStroke);
974 // Make skia unable to compute fast bounds for our paths.
978 context.setLineDash(dashArray, 0);
980 // Make the device opaque in 10,10 40x40.
981 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
982 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
983 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
985 // Clip to the left edge of the opaque area.
986 context.clip(IntRect(10, 10, 10, 40));
988 // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
989 context.setCompositeOperation(CompositeSourceOut);
990 context.setFillColor(alpha);
991 path.moveTo(FloatPoint(10, 10));
992 path.addLineTo(FloatPoint(40, 40));
993 context.strokePath(path);
995 EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
996 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
999 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
1002 bitmap.allocN32Pixels(400, 400);
1003 bitmap.eraseColor(0);
1004 SkCanvas canvas(bitmap);
1006 GraphicsContext context(&canvas);
1007 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1009 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1010 Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
1013 context.setShouldAntialias(false);
1014 context.setMiterLimit(1);
1015 context.setStrokeThickness(5);
1016 context.setLineCap(SquareCap);
1017 context.setStrokeStyle(SolidStroke);
1019 // Make skia unable to compute fast bounds for our paths.
1020 DashArray dashArray;
1021 dashArray.append(1);
1022 dashArray.append(0);
1023 context.setLineDash(dashArray, 0);
1025 // Make the device opaque in 10,10 40x40.
1026 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1027 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1028 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1030 // Begin a layer that preserves opaque.
1031 context.setCompositeOperation(CompositeSourceOver);
1032 context.beginTransparencyLayer(0.5);
1034 // Begin a layer that does not preserve opaque.
1035 context.setCompositeOperation(CompositeSourceOut);
1036 context.beginTransparencyLayer(0.5);
1038 // This should not destroy the device opaqueness.
1039 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1041 // This should not destroy the device opaqueness either.
1042 context.setFillColor(opaque);
1043 path.moveTo(FloatPoint(10, 10));
1044 path.addLineTo(FloatPoint(40, 40));
1045 context.strokePath(path);
1049 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1050 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1052 // Now begin a layer that does not preserve opaque and draw through it to the device.
1053 context.setCompositeOperation(CompositeSourceOut);
1054 context.beginTransparencyLayer(0.5);
1056 // This should destroy the device opaqueness.
1057 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1060 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1061 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1063 // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
1065 context.setCompositeOperation(CompositeSourceOut);
1066 context.beginTransparencyLayer(0.5);
1068 // This should nuke the device opaqueness.
1069 context.setFillColor(opaque);
1070 path.moveTo(FloatPoint(10, 10));
1071 path.addLineTo(FloatPoint(40, 40));
1072 context.strokePath(path);
1075 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1076 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1079 TEST(GraphicsContextTest, OpaqueRegionForLayerWithNonRectDeviceClip)
1082 bitmap.allocN32Pixels(100, 100);
1083 bitmap.eraseColor(0);
1084 SkCanvas canvas(bitmap);
1086 GraphicsContext context(&canvas);
1087 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1088 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1090 context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1092 context.setCompositeOperation(CompositeSourceOver);
1093 context.beginTransparencyLayer(0.5);
1095 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1098 path.moveTo(FloatPoint(0, 0));
1099 path.addLineTo(FloatPoint(50, 50));
1101 // For opaque preserving mode and deviceClip is not rect
1102 // we will not alter opaque rect.
1103 context.clipPath(path, RULE_EVENODD);
1105 context.setCompositeOperation(CompositeSourceOver);
1106 context.beginTransparencyLayer(0.5);
1108 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1110 // For non-opaque preserving mode and deviceClip is not rect
1111 // we will mark opaque rect as empty.
1112 context.setCompositeOperation(CompositeSourceOut);
1113 context.beginTransparencyLayer(0.5);
1116 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1119 TEST(GraphicsContextTest, OpaqueRegionForLayerWithRectDeviceClip)
1122 bitmap.allocN32Pixels(100, 100);
1123 bitmap.eraseColor(0);
1124 SkCanvas canvas(bitmap);
1126 Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1128 GraphicsContext context(&canvas);
1129 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1131 context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1132 EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1134 // For non-opaque preserving mode and deviceClip is rect
1135 // we will mark device clip rect as non opaque.
1136 context.setCompositeOperation(CompositeSourceOut);
1137 context.beginTransparencyLayer(0.5);
1139 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1140 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1142 context.clip(FloatRect(0, 0, 50, 50));
1143 context.fillRect(FloatRect(20, 20, 100, 100), opaque, CompositeSourceOver);
1145 // For opaque preserving mode and deviceClip is rect
1146 // we will intersect device clip rect with src opaque rect.
1147 context.setCompositeOperation(CompositeSourceOver);
1148 context.beginTransparencyLayer(0.5);
1150 EXPECT_EQ_RECT(IntRect(20, 20, 30, 30), context.opaqueRegion().asRect());
1151 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1154 #define DISPATCH1(c1, c2, op, param1) do { c1.op(param1); c2.op(param1); } while (0);
1155 #define DISPATCH2(c1, c2, op, param1, param2) do { c1.op(param1, param2); c2.op(param1, param2); } while (0);
1157 TEST(GraphicsContextTest, RecordingTotalMatrix)
1160 bitmap.allocN32Pixels(400, 400);
1161 bitmap.eraseColor(0);
1162 SkCanvas canvas(bitmap);
1163 GraphicsContext context(&canvas);
1165 SkCanvas controlCanvas(400, 400);
1166 GraphicsContext controlContext(&controlCanvas);
1168 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1169 DISPATCH2(context, controlContext, scale, 2, 2);
1170 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1172 controlContext.save();
1173 context.beginRecording(FloatRect(0, 0, 200, 200));
1174 DISPATCH2(context, controlContext, translate, 10, 10);
1175 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1177 controlContext.save();
1178 context.beginRecording(FloatRect(10, 10, 100, 100));
1179 DISPATCH1(context, controlContext, rotate, 45);
1180 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1182 controlContext.restore();
1183 context.endRecording();
1184 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1186 controlContext.restore();
1187 context.endRecording();
1188 EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1191 TEST(GraphicsContextTest, RecordingCanvas)
1194 bitmap.allocN32Pixels(1, 1);
1195 bitmap.eraseColor(0);
1196 SkCanvas canvas(bitmap);
1197 GraphicsContext context(&canvas);
1199 FloatRect rect(0, 0, 1, 1);
1201 // Two beginRecordings in a row generate two canvases.
1202 // Unfortunately the new one could be allocated in the same
1203 // spot as the old one so ref the first one to prolong its life.
1204 context.beginRecording(rect);
1205 SkCanvas* canvas1 = context.canvas();
1206 EXPECT_TRUE(canvas1);
1207 context.beginRecording(rect);
1208 SkCanvas* canvas2 = context.canvas();
1209 EXPECT_TRUE(canvas2);
1211 EXPECT_NE(canvas1, canvas2);
1212 EXPECT_EQ(1, canvas1->getRefCnt());
1214 // endRecording finally makes the picture accessible
1215 RefPtr<DisplayList> dl = context.endRecording();
1216 SkPicture* pic = dl->picture().get();
1218 EXPECT_EQ(1, pic->getRefCnt());
1220 context.endRecording();