Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / GraphicsContextTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 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.
23  */
24
25 #include "config.h"
26
27 #include "platform/graphics/GraphicsContext.h"
28
29 #include "platform/graphics/BitmapImage.h"
30 #include "platform/graphics/DisplayList.h"
31 #include "platform/graphics/ImageBuffer.h"
32 #include "platform/graphics/skia/NativeImageSkia.h"
33 #include "third_party/skia/include/core/SkBitmap.h"
34 #include "third_party/skia/include/core/SkCanvas.h"
35 #include "third_party/skia/include/core/SkPicture.h"
36 #include <gtest/gtest.h>
37
38 using namespace blink;
39
40 namespace {
41
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());
47
48 #define EXPECT_PIXELS_MATCH(bitmap, opaqueRect) \
49 { \
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); \
55         } \
56 }
57
58 #define EXPECT_PIXELS_MATCH_EXACT(bitmap, opaqueRect) \
59 { \
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); \
66         } \
67 }
68
69 TEST(GraphicsContextTest, trackOpaqueTest)
70 {
71     SkBitmap bitmap;
72     bitmap.allocN32Pixels(400, 400);
73     bitmap.eraseColor(0);
74     SkCanvas canvas(bitmap);
75
76     GraphicsContext context(&canvas);
77     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
78
79     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
80     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
81
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());
85
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());
89
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());
93
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());
97
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());
101
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());
105
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());
109
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());
113
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());
117
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());
121
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());
125 }
126
127 TEST(GraphicsContextTest, trackOpaqueClipTest)
128 {
129     SkBitmap bitmap;
130     bitmap.allocN32Pixels(400, 400);
131     SkCanvas canvas(bitmap);
132
133     GraphicsContext context(&canvas);
134     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
135
136     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
137     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
138
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());
142
143     context.clearRect(FloatRect(10, 10, 90, 90));
144     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
145
146     context.save();
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());
151     context.restore();
152
153     context.clearRect(FloatRect(10, 10, 90, 90));
154     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
155
156     context.save();
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());
161
162     context.clearRect(FloatRect(10, 10, 90, 90));
163     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
164
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());
170     context.restore();
171
172     context.clearRect(FloatRect(10, 10, 90, 90));
173     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
174
175     // The transform and the clip need to interact correctly (transform first)
176     context.save();
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());
182     context.restore();
183
184     context.clearRect(FloatRect(10, 10, 90, 90));
185     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
186
187     // The transform and the clip need to interact correctly (clip first)
188     context.save();
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());
194     context.restore();
195
196     context.clearRect(FloatRect(10, 10, 90, 90));
197     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
198
199     Path path;
200     path.moveTo(FloatPoint(0, 0));
201     path.addLineTo(FloatPoint(100, 0));
202
203     // Non-rectangular clips just cause the paint to be considered non-opaque.
204     context.save();
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());
209     context.restore();
210
211     // Another non-rectangular clip.
212     context.save();
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());
218     context.restore();
219 }
220
221 TEST(GraphicsContextTest, trackImageMask)
222 {
223     SkBitmap bitmap;
224     bitmap.allocN32Pixels(400, 400);
225     bitmap.eraseColor(0);
226     SkCanvas canvas(bitmap);
227
228     GraphicsContext context(&canvas);
229     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
230
231     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
232     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
233
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.
237
238     context.setCompositeOperation(CompositeSourceOver);
239     context.beginTransparencyLayer(1);
240     context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
241
242     context.setCompositeOperation(CompositeDestinationIn);
243     context.beginTransparencyLayer(1);
244
245     OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
246     EXPECT_FALSE(!alphaImage);
247     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
248
249     context.setCompositeOperation(CompositeSourceOver);
250     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
251
252     context.endLayer();
253     context.endLayer();
254
255     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
256     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
257 }
258
259 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
260 {
261     SkBitmap bitmap;
262     bitmap.allocN32Pixels(400, 400);
263     bitmap.eraseColor(0);
264     SkCanvas canvas(bitmap);
265
266     GraphicsContext context(&canvas);
267     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
268
269     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
270     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
271
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.
275
276     context.setCompositeOperation(CompositeSourceOver);
277     context.beginTransparencyLayer(1);
278     context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
279
280     context.setCompositeOperation(CompositeDestinationIn);
281     context.beginTransparencyLayer(1);
282
283     OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
284     EXPECT_FALSE(!alphaImage);
285     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
286
287     context.setCompositeOperation(CompositeSourceOver);
288     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
289
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);
292
293     context.endLayer();
294     context.endLayer();
295
296     EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
297     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
298 }
299
300 TEST(GraphicsContextTest, trackOpaqueJoinTest)
301 {
302     SkBitmap bitmap;
303     bitmap.allocN32Pixels(400, 400);
304     SkCanvas canvas(bitmap);
305
306     GraphicsContext context(&canvas);
307     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
308
309     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
310     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
311
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());
315
316     // Doesn't join
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());
320
321     // Does join
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());
325
326     // Doesn't join
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());
330
331     // Does join
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());
335
336     // Doesn't join
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());
340
341     // Does join
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());
345
346     // Doesn't join
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());
350
351     // Does join
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());
355 }
356
357 TEST(GraphicsContextTest, trackOpaqueLineTest)
358 {
359     SkBitmap bitmap;
360     bitmap.allocN32Pixels(200, 200);
361     bitmap.eraseColor(0);
362     SkCanvas canvas(bitmap);
363
364     GraphicsContext context(&canvas);
365     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
366
367     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
368     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
369
370     context.setShouldAntialias(false);
371     context.setMiterLimit(0);
372     context.setStrokeThickness(4);
373     context.setLineCap(SquareCap);
374     context.setStrokeStyle(SolidStroke);
375     context.setCompositeOperation(CompositeSourceOver);
376
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());
380
381     context.setCompositeOperation(CompositeSourceIn);
382
383     context.save();
384     context.setStrokeColor(alpha);
385     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
386     context.restore();
387     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
388     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
389
390     context.save();
391     context.setStrokeColor(opaque);
392     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
393     context.restore();
394     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
395     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
396
397     context.save();
398     context.setStrokeColor(alpha);
399     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
400     context.restore();
401     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
402     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
403
404     context.save();
405     context.setStrokeColor(alpha);
406     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
407     context.restore();
408     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
409     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
410
411     context.setShouldAntialias(true);
412     context.setCompositeOperation(CompositeSourceOver);
413
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());
417
418     context.setCompositeOperation(CompositeSourceIn);
419
420     context.save();
421     context.setStrokeColor(alpha);
422     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
423     context.restore();
424     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
425     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
426
427     context.setShouldAntialias(false);
428     context.save();
429     context.setStrokeColor(opaque);
430     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
431     context.restore();
432     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
433     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
434
435     context.setShouldAntialias(true);
436     context.save();
437     context.setStrokeColor(opaque);
438     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
439     context.restore();
440     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
441     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
442
443     context.save();
444     context.setStrokeColor(alpha);
445     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
446     context.restore();
447     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
448     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
449 }
450
451 TEST(GraphicsContextTest, trackOpaquePathTest)
452 {
453     SkBitmap bitmap;
454     bitmap.allocN32Pixels(200, 200);
455     SkCanvas canvas(bitmap);
456
457     GraphicsContext context(&canvas);
458     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
459
460     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
461     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
462
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());
466
467     context.setShouldAntialias(false);
468     context.setMiterLimit(1);
469     context.setStrokeThickness(5);
470     context.setLineCap(SquareCap);
471     context.setStrokeStyle(SolidStroke);
472     context.setCompositeOperation(CompositeSourceIn);
473
474     Path path;
475
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());
482     path.clear();
483
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());
490     path.clear();
491
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());
498     path.clear();
499
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());
506     path.clear();
507 }
508
509 TEST(GraphicsContextTest, trackOpaqueImageTest)
510 {
511     SkBitmap bitmap;
512     bitmap.allocN32Pixels(200, 200);
513     SkCanvas canvas(bitmap);
514
515     GraphicsContext context(&canvas);
516     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
517
518     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
519     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
520
521     SkBitmap opaqueBitmap;
522     opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
523
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());
529
530     SkBitmap alphaBitmap;
531     alphaBitmap.allocN32Pixels(10, 10);
532
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());
538
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());
542
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());
549
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());
556
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());
563
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());
567
568     context.save();
569     context.setAlphaAsFloat(0.5);
570     context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
571     context.restore();
572     EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
573     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
574
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());
578
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());
582
583     context.save();
584     context.setAlphaAsFloat(0.5);
585     context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
586     context.restore();
587     EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
588     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
589 }
590
591 TEST(GraphicsContextTest, trackOpaqueOvalTest)
592 {
593     SkBitmap bitmap;
594     bitmap.allocN32Pixels(200, 200);
595     bitmap.eraseColor(0);
596     SkCanvas canvas(bitmap);
597
598     GraphicsContext context(&canvas);
599     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
600
601     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
602     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
603
604     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
605     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
606
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());
611
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());
615
616     context.setCompositeOperation(CompositeSourceIn);
617
618     context.setShouldAntialias(false);
619
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());
625
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());
631
632     context.setShouldAntialias(true);
633
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());
639
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());
645 }
646
647 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
648 {
649     SkBitmap bitmap;
650     bitmap.allocN32Pixels(200, 200);
651     SkCanvas canvas(bitmap);
652
653     GraphicsContext context(&canvas);
654     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
655
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);
659
660     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
661     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
662
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());
666
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());
670
671     context.setCompositeOperation(CompositeSourceIn);
672     context.setShouldAntialias(false);
673
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());
677
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());
681
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());
685
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());
689 }
690
691 TEST(GraphicsContextTest, trackOpaqueTextTest)
692 {
693     int width = 200, height = 200;
694     SkBitmap bitmap;
695     bitmap.allocN32Pixels(width, height);
696     bitmap.eraseColor(0);
697     SkCanvas canvas(bitmap);
698     SkRect textRect = SkRect::MakeWH(width, height);
699
700     GraphicsContext context(&canvas);
701     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
702
703     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
704     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
705
706     SkPaint opaquePaint;
707     opaquePaint.setColor(opaque.rgb());
708     opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
709     SkPaint alphaPaint;
710     alphaPaint.setColor(alpha.rgb());
711     alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
712
713     SkPoint point = SkPoint::Make(0, 0);
714
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());
718
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());
722
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());
726
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());
730
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());
734 }
735
736 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
737 {
738     SkBitmap bitmap;
739     bitmap.allocN32Pixels(200, 200);
740     bitmap.eraseColor(0);
741     SkCanvas canvas(bitmap);
742
743     GraphicsContext context(&canvas);
744     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
745
746     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
747
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;
753
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;
759
760     SkPaint paint;
761     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
762
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());
766
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());
770
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());
774
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());
778
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());
782
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());
786 }
787
788 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
789 {
790     SkBitmap bitmap;
791     bitmap.allocN32Pixels(200, 200);
792     bitmap.eraseColor(0);
793     SkCanvas canvas(bitmap);
794
795     GraphicsContext context(&canvas);
796     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
797
798     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
799
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;
805
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;
811
812     SkPaint paint;
813     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
814
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());
818
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());
822
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());
826
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());
830
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());
834
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());
838 }
839
840 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
841 {
842     SkBitmap bitmap;
843     bitmap.allocN32Pixels(200, 200);
844     bitmap.eraseColor(0);
845     SkCanvas canvas(bitmap);
846
847     GraphicsContext context(&canvas);
848     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
849
850     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
851
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;
857
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;
863
864     SkPaint paint;
865     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
866
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());
870
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());
874
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());
878
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());
882
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());
886 }
887
888 TEST(GraphicsContextTest, contextTransparencyLayerTest)
889 {
890     SkBitmap bitmap;
891     bitmap.allocN32Pixels(400, 400);
892     bitmap.eraseColor(0);
893     SkCanvas canvas(bitmap);
894
895     GraphicsContext context(&canvas);
896     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
897
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());
902
903     context.clearRect(FloatRect(20, 20, 10, 10));
904     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
905
906     context.beginTransparencyLayer(0.5);
907     context.save();
908     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
909     context.restore();
910     context.endLayer();
911     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
912
913     context.clearRect(FloatRect(20, 20, 10, 10));
914     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
915
916     context.beginTransparencyLayer(0.5);
917     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
918     context.endLayer();
919     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
920 }
921
922 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
923 {
924     SkBitmap bitmap;
925     bitmap.allocN32Pixels(400, 400);
926     bitmap.eraseColor(0);
927     SkCanvas canvas(bitmap);
928
929     GraphicsContext context(&canvas);
930     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
931
932     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
933     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
934
935     Path path;
936     context.setShouldAntialias(false);
937     context.setMiterLimit(1);
938     context.setStrokeThickness(5);
939     context.setLineCap(SquareCap);
940     context.setStrokeStyle(SolidStroke);
941
942     // Make skia unable to compute fast bounds for our paths.
943     DashArray dashArray;
944     dashArray.append(1);
945     dashArray.append(0);
946     context.setLineDash(dashArray, 0);
947
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());
952
953     // Clip to the left edge of the opaque area.
954     context.clip(IntRect(10, 10, 10, 40));
955
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);
962
963     EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
964     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
965 }
966
967 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
968 {
969     SkBitmap bitmap;
970     bitmap.allocN32Pixels(400, 400);
971     bitmap.eraseColor(0);
972     SkCanvas canvas(bitmap);
973
974     GraphicsContext context(&canvas);
975     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
976
977     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
978     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
979
980     Path path;
981     context.setShouldAntialias(false);
982     context.setMiterLimit(1);
983     context.setStrokeThickness(5);
984     context.setLineCap(SquareCap);
985     context.setStrokeStyle(SolidStroke);
986
987     // Make skia unable to compute fast bounds for our paths.
988     DashArray dashArray;
989     dashArray.append(1);
990     dashArray.append(0);
991     context.setLineDash(dashArray, 0);
992
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());
997
998     // Begin a layer that preserves opaque.
999     context.setCompositeOperation(CompositeSourceOver);
1000     context.beginTransparencyLayer(0.5);
1001
1002     // Begin a layer that does not preserve opaque.
1003     context.setCompositeOperation(CompositeSourceOut);
1004     context.beginTransparencyLayer(0.5);
1005
1006     // This should not destroy the device opaqueness.
1007     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1008
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);
1014
1015     context.endLayer();
1016     context.endLayer();
1017     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1018     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1019
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);
1023
1024     // This should destroy the device opaqueness.
1025     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1026
1027     context.endLayer();
1028     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1029     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1030
1031     // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
1032
1033     context.setCompositeOperation(CompositeSourceOut);
1034     context.beginTransparencyLayer(0.5);
1035
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);
1041
1042     context.endLayer();
1043     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1044     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1045 }
1046
1047 TEST(GraphicsContextTest, OpaqueRegionForLayerWithNonRectDeviceClip)
1048 {
1049     SkBitmap bitmap;
1050     bitmap.allocN32Pixels(100, 100);
1051     bitmap.eraseColor(0);
1052     SkCanvas canvas(bitmap);
1053
1054     GraphicsContext context(&canvas);
1055     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1056     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1057
1058     context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1059
1060     context.setCompositeOperation(CompositeSourceOver);
1061     context.beginTransparencyLayer(0.5);
1062     context.endLayer();
1063     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1064
1065     Path path;
1066     path.moveTo(FloatPoint(0, 0));
1067     path.addLineTo(FloatPoint(50, 50));
1068
1069     // For opaque preserving mode and deviceClip is not rect
1070     // we will not alter opaque rect.
1071     context.clipPath(path, RULE_EVENODD);
1072
1073     context.setCompositeOperation(CompositeSourceOver);
1074     context.beginTransparencyLayer(0.5);
1075     context.endLayer();
1076     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1077
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);
1082
1083     context.endLayer();
1084     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1085 }
1086
1087 TEST(GraphicsContextTest, OpaqueRegionForLayerWithRectDeviceClip)
1088 {
1089     SkBitmap bitmap;
1090     bitmap.allocN32Pixels(100, 100);
1091     bitmap.eraseColor(0);
1092     SkCanvas canvas(bitmap);
1093
1094     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
1095
1096     GraphicsContext context(&canvas);
1097     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
1098
1099     context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
1100     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
1101
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);
1106     context.endLayer();
1107     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1108     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1109
1110     context.clip(FloatRect(0, 0, 50, 50));
1111     context.fillRect(FloatRect(20, 20, 100, 100), opaque, CompositeSourceOver);
1112
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);
1117     context.endLayer();
1118     EXPECT_EQ_RECT(IntRect(20, 20, 30, 30), context.opaqueRegion().asRect());
1119     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
1120 }
1121
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);
1124
1125 TEST(GraphicsContextTest, RecordingTotalMatrix)
1126 {
1127     SkBitmap bitmap;
1128     bitmap.allocN32Pixels(400, 400);
1129     bitmap.eraseColor(0);
1130     SkCanvas canvas(bitmap);
1131     GraphicsContext context(&canvas);
1132
1133     SkCanvas controlCanvas(400, 400);
1134     GraphicsContext controlContext(&controlCanvas);
1135
1136     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1137     DISPATCH2(context, controlContext, scale, 2, 2);
1138     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1139
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());
1144
1145     controlContext.save();
1146     context.beginRecording(FloatRect(10, 10, 100, 100));
1147     DISPATCH1(context, controlContext, rotate, 45);
1148     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1149
1150     controlContext.restore();
1151     context.endRecording();
1152     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1153
1154     controlContext.restore();
1155     context.endRecording();
1156     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1157 }
1158
1159 TEST(GraphicsContextTest, RecordingCanvas)
1160 {
1161     SkBitmap bitmap;
1162     bitmap.allocN32Pixels(1, 1);
1163     bitmap.eraseColor(0);
1164     SkCanvas canvas(bitmap);
1165     GraphicsContext context(&canvas);
1166
1167     FloatRect rect(0, 0, 1, 1);
1168
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);
1178
1179     EXPECT_NE(canvas1, canvas2);
1180     EXPECT_EQ(1, canvas1->getRefCnt());
1181
1182     // endRecording finally makes the picture accessible
1183     RefPtr<DisplayList> dl = context.endRecording();
1184     SkPicture* pic = dl->picture();
1185     EXPECT_TRUE(pic);
1186     EXPECT_EQ(1, pic->getRefCnt());
1187
1188     context.endRecording();
1189 }
1190
1191 } // namespace