Upstream version 7.36.149.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 WebCore;
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     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
73     bitmap.eraseColor(0);
74     SkCanvas canvas(bitmap);
75
76     GraphicsContext context(&canvas);
77     context.setTrackOpaqueRegion(true);
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     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
131     SkCanvas canvas(bitmap);
132
133     GraphicsContext context(&canvas);
134     context.setTrackOpaqueRegion(true);
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     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
225     bitmap.eraseColor(0);
226     SkCanvas canvas(bitmap);
227
228     GraphicsContext context(&canvas);
229     context.setTrackOpaqueRegion(true);
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     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
247
248     context.setCompositeOperation(CompositeSourceOver);
249     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
250
251     context.endLayer();
252     context.endLayer();
253
254     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
255     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
256 }
257
258 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
259 {
260     SkBitmap bitmap;
261     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
262     bitmap.eraseColor(0);
263     SkCanvas canvas(bitmap);
264
265     GraphicsContext context(&canvas);
266     context.setTrackOpaqueRegion(true);
267
268     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
269     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
270
271     // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
272     // out a transparency layer below that is filled with the mask color. In the end this should
273     // not be marked opaque.
274
275     context.setCompositeOperation(CompositeSourceOver);
276     context.beginTransparencyLayer(1);
277     context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
278
279     context.setCompositeOperation(CompositeDestinationIn);
280     context.beginTransparencyLayer(1);
281
282     OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
283     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
284
285     context.setCompositeOperation(CompositeSourceOver);
286     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
287
288     // We can't have an opaque mask actually, but we can pretend here like it would look if we did.
289     context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver);
290
291     context.endLayer();
292     context.endLayer();
293
294     EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
295     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
296 }
297
298 TEST(GraphicsContextTest, trackOpaqueJoinTest)
299 {
300     SkBitmap bitmap;
301     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
302     SkCanvas canvas(bitmap);
303
304     GraphicsContext context(&canvas);
305     context.setTrackOpaqueRegion(true);
306
307     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
308     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
309
310     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
311     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
312     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
313
314     // Doesn't join
315     context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver);
316     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
317     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
318
319     // Does join
320     context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver);
321     EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
322     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
323
324     // Doesn't join
325     context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver);
326     EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
327     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
328
329     // Does join
330     context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver);
331     EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
332     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
333
334     // Doesn't join
335     context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver);
336     EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
337     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
338
339     // Does join
340     context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver);
341     EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
342     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
343
344     // Doesn't join
345     context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver);
346     EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
347     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
348
349     // Does join
350     context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver);
351     EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect());
352     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
353 }
354
355 TEST(GraphicsContextTest, trackOpaqueLineTest)
356 {
357     SkBitmap bitmap;
358     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
359     bitmap.eraseColor(0);
360     SkCanvas canvas(bitmap);
361
362     GraphicsContext context(&canvas);
363     context.setTrackOpaqueRegion(true);
364
365     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
366     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
367
368     context.setShouldAntialias(false);
369     context.setMiterLimit(0);
370     context.setStrokeThickness(4);
371     context.setLineCap(SquareCap);
372     context.setStrokeStyle(SolidStroke);
373     context.setCompositeOperation(CompositeSourceOver);
374
375     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
376     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
377     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
378
379     context.setCompositeOperation(CompositeSourceIn);
380
381     context.save();
382     context.setStrokeColor(alpha);
383     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
384     context.restore();
385     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
386     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
387
388     context.save();
389     context.setStrokeColor(opaque);
390     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
391     context.restore();
392     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
393     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
394
395     context.save();
396     context.setStrokeColor(alpha);
397     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
398     context.restore();
399     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
400     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
401
402     context.save();
403     context.setStrokeColor(alpha);
404     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
405     context.restore();
406     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
407     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
408
409     context.setShouldAntialias(true);
410     context.setCompositeOperation(CompositeSourceOver);
411
412     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
413     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
414     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
415
416     context.setCompositeOperation(CompositeSourceIn);
417
418     context.save();
419     context.setStrokeColor(alpha);
420     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
421     context.restore();
422     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
423     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
424
425     context.setShouldAntialias(false);
426     context.save();
427     context.setStrokeColor(opaque);
428     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
429     context.restore();
430     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
431     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
432
433     context.setShouldAntialias(true);
434     context.save();
435     context.setStrokeColor(opaque);
436     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
437     context.restore();
438     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
439     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
440
441     context.save();
442     context.setStrokeColor(alpha);
443     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
444     context.restore();
445     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
446     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
447 }
448
449 TEST(GraphicsContextTest, trackOpaquePathTest)
450 {
451     SkBitmap bitmap;
452     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
453     SkCanvas canvas(bitmap);
454
455     GraphicsContext context(&canvas);
456     context.setTrackOpaqueRegion(true);
457
458     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
459     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
460
461     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
462     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
463     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
464
465     context.setShouldAntialias(false);
466     context.setMiterLimit(1);
467     context.setStrokeThickness(5);
468     context.setLineCap(SquareCap);
469     context.setStrokeStyle(SolidStroke);
470     context.setCompositeOperation(CompositeSourceIn);
471
472     Path path;
473
474     context.setFillColor(alpha);
475     path.moveTo(FloatPoint(0, 0));
476     path.addLineTo(FloatPoint(100, 0));
477     context.fillPath(path);
478     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
479     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
480     path.clear();
481
482     context.setFillColor(opaque);
483     path.moveTo(FloatPoint(0, 10));
484     path.addLineTo(FloatPoint(100, 13));
485     context.fillPath(path);
486     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
487     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
488     path.clear();
489
490     context.setFillColor(alpha);
491     path.moveTo(FloatPoint(0, 10));
492     path.addLineTo(FloatPoint(100, 13));
493     context.fillPath(path);
494     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
495     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
496     path.clear();
497
498     context.setFillColor(alpha);
499     path.moveTo(FloatPoint(0, 14));
500     path.addLineTo(FloatPoint(100, 10));
501     context.fillPath(path);
502     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
503     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
504     path.clear();
505 }
506
507 TEST(GraphicsContextTest, trackOpaqueImageTest)
508 {
509     SkBitmap bitmap;
510     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
511     SkCanvas canvas(bitmap);
512
513     GraphicsContext context(&canvas);
514     context.setTrackOpaqueRegion(true);
515
516     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
517     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
518
519     SkBitmap opaqueBitmap;
520     ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
521
522     for (int y = 0; y < opaqueBitmap.height(); ++y)
523         for (int x = 0; x < opaqueBitmap.width(); ++x)
524             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
525     RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::create(opaqueBitmap));
526     EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
527
528     SkBitmap alphaBitmap;
529     ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
530
531     for (int y = 0; y < alphaBitmap.height(); ++y)
532         for (int x = 0; x < alphaBitmap.width(); ++x)
533             *alphaBitmap.getAddr32(x, y) = 0x00000000;
534     RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create(alphaBitmap));
535     EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque());
536
537     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
538     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
539     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
540
541     context.drawImage(opaqueImage.get(), IntPoint(0, 0));
542     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
543     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
544     context.drawImage(alphaImage.get(), IntPoint(0, 0));
545     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
546     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
547
548     context.drawImage(opaqueImage.get(), IntPoint(5, 5));
549     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
550     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
551     context.drawImage(alphaImage.get(), IntPoint(5, 5));
552     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
553     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
554
555     context.drawImage(opaqueImage.get(), IntPoint(10, 10));
556     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
557     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
558     context.drawImage(alphaImage.get(), IntPoint(10, 10));
559     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
560     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
561
562     context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn);
563     EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect());
564     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
565
566     context.save();
567     context.setAlphaAsFloat(0.5);
568     context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
569     context.restore();
570     EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
571     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
572
573     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
574     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
575     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
576
577     context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn);
578     EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect());
579     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
580
581     context.save();
582     context.setAlphaAsFloat(0.5);
583     context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
584     context.restore();
585     EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
586     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
587 }
588
589 TEST(GraphicsContextTest, trackOpaqueOvalTest)
590 {
591     SkBitmap bitmap;
592     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
593     bitmap.eraseColor(0);
594     SkCanvas canvas(bitmap);
595
596     GraphicsContext context(&canvas);
597     context.setTrackOpaqueRegion(true);
598
599     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
600     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
601
602     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
603     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
604
605     context.fillEllipse(FloatRect(10, 10, 90, 90));
606     context.strokeEllipse(FloatRect(10, 10, 90, 90));
607     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
608     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
609
610     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
611     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
612     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
613
614     context.setCompositeOperation(CompositeSourceIn);
615
616     context.setShouldAntialias(false);
617
618     context.setFillColor(opaque);
619     context.fillEllipse(FloatRect(10, 10, 50, 30));
620     context.strokeEllipse(FloatRect(10, 10, 50, 30));
621     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
622     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
623
624     context.setFillColor(alpha);
625     context.fillEllipse(FloatRect(10, 10, 30, 50));
626     context.strokeEllipse(FloatRect(10, 10, 30, 50));
627     EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
628     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
629
630     context.setShouldAntialias(true);
631
632     context.setFillColor(opaque);
633     context.fillEllipse(FloatRect(10, 10, 50, 30));
634     context.strokeEllipse(FloatRect(10, 10, 50, 30));
635     EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect());
636     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
637
638     context.setFillColor(alpha);
639     context.fillEllipse(FloatRect(20, 10, 30, 50));
640     context.strokeEllipse(FloatRect(20, 10, 30, 50));
641     EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect());
642     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
643 }
644
645 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
646 {
647     SkBitmap bitmap;
648     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
649     SkCanvas canvas(bitmap);
650
651     GraphicsContext context(&canvas);
652     context.setTrackOpaqueRegion(true);
653
654     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
655     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
656     IntSize radii(10, 10);
657
658     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
659     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
660
661     context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii, opaque);
662     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
663     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
664
665     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
666     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
667     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
668
669     context.setCompositeOperation(CompositeSourceIn);
670     context.setShouldAntialias(false);
671
672     context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii, opaque);
673     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
674     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
675
676     context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii, alpha);
677     EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
678     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
679
680     context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii, alpha);
681     EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
682     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
683
684     context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii, opaque);
685     EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
686     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
687 }
688
689 TEST(GraphicsContextTest, trackOpaqueTextTest)
690 {
691     int width = 200, height = 200;
692     SkBitmap bitmap;
693     ASSERT_TRUE(bitmap.allocN32Pixels(width, height));
694     bitmap.eraseColor(0);
695     SkCanvas canvas(bitmap);
696     SkRect textRect = SkRect::MakeWH(width, height);
697
698     GraphicsContext context(&canvas);
699     context.setTrackOpaqueRegion(true);
700
701     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
702     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
703
704     SkPaint opaquePaint;
705     opaquePaint.setColor(opaque.rgb());
706     opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
707     SkPaint alphaPaint;
708     alphaPaint.setColor(alpha.rgb());
709     alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
710
711     SkPoint point = SkPoint::Make(0, 0);
712
713     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
714     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
715     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
716
717     context.drawPosText("A", 1, &point, textRect, opaquePaint);
718     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
719     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
720
721     context.drawPosText("A", 1, &point, textRect, alphaPaint);
722     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
723     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
724
725     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
726     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
727     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
728
729     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
730     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
731     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
732 }
733
734 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
735 {
736     SkBitmap bitmap;
737     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
738     bitmap.eraseColor(0);
739     SkCanvas canvas(bitmap);
740
741     GraphicsContext context(&canvas);
742     context.setTrackOpaqueRegion(true);
743
744     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
745
746     SkBitmap opaqueBitmap;
747     ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
748     for (int y = 0; y < opaqueBitmap.height(); ++y)
749         for (int x = 0; x < opaqueBitmap.width(); ++x)
750             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
751
752     SkBitmap alphaBitmap;
753     ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
754     for (int y = 0; y < alphaBitmap.height(); ++y)
755         for (int x = 0; x < alphaBitmap.width(); ++x)
756             *alphaBitmap.getAddr32(x, y) = 0x00000000;
757
758     SkPaint paint;
759     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
760
761     context.writePixels(opaqueBitmap, 50, 50);
762     EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect());
763     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
764
765     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
766     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
767     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
768
769     context.writePixels(alphaBitmap, 10, 0);
770     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
771     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
772
773     context.writePixels(alphaBitmap, 10, 1);
774     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
775     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
776
777     context.writePixels(alphaBitmap, 0, 10);
778     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
779     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
780
781     context.writePixels(alphaBitmap, 1, 10);
782     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
783     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
784 }
785
786 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
787 {
788     SkBitmap bitmap;
789     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
790     bitmap.eraseColor(0);
791     SkCanvas canvas(bitmap);
792
793     GraphicsContext context(&canvas);
794     context.setTrackOpaqueRegion(true);
795
796     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
797
798     SkBitmap opaqueBitmap;
799     ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
800     for (int y = 0; y < opaqueBitmap.height(); ++y)
801         for (int x = 0; x < opaqueBitmap.width(); ++x)
802             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
803
804     SkBitmap alphaBitmap;
805     ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
806     for (int y = 0; y < alphaBitmap.height(); ++y)
807         for (int x = 0; x < alphaBitmap.width(); ++x)
808             *alphaBitmap.getAddr32(x, y) = 0x00000000;
809
810     SkPaint paint;
811     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
812
813     context.drawBitmap(opaqueBitmap, 10, 10, &paint);
814     EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect());
815     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
816
817     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
818     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
819     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
820
821     context.drawBitmap(alphaBitmap, 10, 0, &paint);
822     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
823     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
824
825     context.drawBitmap(alphaBitmap, 10, 1, &paint);
826     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
827     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
828
829     context.drawBitmap(alphaBitmap, 0, 10, &paint);
830     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
831     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
832
833     context.drawBitmap(alphaBitmap, 1, 10, &paint);
834     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
835     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
836 }
837
838 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
839 {
840     SkBitmap bitmap;
841     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
842     bitmap.eraseColor(0);
843     SkCanvas canvas(bitmap);
844
845     GraphicsContext context(&canvas);
846     context.setTrackOpaqueRegion(true);
847
848     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
849
850     SkBitmap opaqueBitmap;
851     ASSERT_TRUE(opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */));
852     for (int y = 0; y < opaqueBitmap.height(); ++y)
853         for (int x = 0; x < opaqueBitmap.width(); ++x)
854             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
855
856     SkBitmap alphaBitmap;
857     ASSERT_TRUE(alphaBitmap.allocN32Pixels(10, 10));
858     for (int y = 0; y < alphaBitmap.height(); ++y)
859         for (int x = 0; x < alphaBitmap.width(); ++x)
860             *alphaBitmap.getAddr32(x, y) = 0x00000000;
861
862     SkPaint paint;
863     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
864
865     context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &paint);
866     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
867     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
868
869     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &paint);
870     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
871     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
872
873     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &paint);
874     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
875     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
876
877     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &paint);
878     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
879     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
880
881     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &paint);
882     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
883     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
884 }
885
886 TEST(GraphicsContextTest, contextTransparencyLayerTest)
887 {
888     SkBitmap bitmap;
889     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
890     bitmap.eraseColor(0);
891     SkCanvas canvas(bitmap);
892
893     GraphicsContext context(&canvas);
894     context.setTrackOpaqueRegion(true);
895
896     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
897     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
898     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
899     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
900
901     context.clearRect(FloatRect(20, 20, 10, 10));
902     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
903
904     context.beginTransparencyLayer(0.5);
905     context.save();
906     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
907     context.restore();
908     context.endLayer();
909     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
910
911     context.clearRect(FloatRect(20, 20, 10, 10));
912     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
913
914     context.beginTransparencyLayer(0.5);
915     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
916     context.endLayer();
917     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
918 }
919
920 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
921 {
922     SkBitmap bitmap;
923     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
924     bitmap.eraseColor(0);
925     SkCanvas canvas(bitmap);
926
927     GraphicsContext context(&canvas);
928     context.setTrackOpaqueRegion(true);
929
930     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
931     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
932
933     Path path;
934     context.setShouldAntialias(false);
935     context.setMiterLimit(1);
936     context.setStrokeThickness(5);
937     context.setLineCap(SquareCap);
938     context.setStrokeStyle(SolidStroke);
939
940     // Make skia unable to compute fast bounds for our paths.
941     DashArray dashArray;
942     dashArray.append(1);
943     dashArray.append(0);
944     context.setLineDash(dashArray, 0);
945
946     // Make the device opaque in 10,10 40x40.
947     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
948     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
949     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
950
951     // Clip to the left edge of the opaque area.
952     context.clip(IntRect(10, 10, 10, 40));
953
954     // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
955     context.setCompositeOperation(CompositeSourceOut);
956     context.setFillColor(alpha);
957     path.moveTo(FloatPoint(10, 10));
958     path.addLineTo(FloatPoint(40, 40));
959     context.strokePath(path);
960
961     EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
962     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
963 }
964
965 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
966 {
967     SkBitmap bitmap;
968     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
969     bitmap.eraseColor(0);
970     SkCanvas canvas(bitmap);
971
972     GraphicsContext context(&canvas);
973     context.setTrackOpaqueRegion(true);
974
975     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
976     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
977
978     Path path;
979     context.setShouldAntialias(false);
980     context.setMiterLimit(1);
981     context.setStrokeThickness(5);
982     context.setLineCap(SquareCap);
983     context.setStrokeStyle(SolidStroke);
984
985     // Make skia unable to compute fast bounds for our paths.
986     DashArray dashArray;
987     dashArray.append(1);
988     dashArray.append(0);
989     context.setLineDash(dashArray, 0);
990
991     // Make the device opaque in 10,10 40x40.
992     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
993     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
994     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
995
996     // Begin a layer that preserves opaque.
997     context.setCompositeOperation(CompositeSourceOver);
998     context.beginTransparencyLayer(0.5);
999
1000     // Begin a layer that does not preserve opaque.
1001     context.setCompositeOperation(CompositeSourceOut);
1002     context.beginTransparencyLayer(0.5);
1003
1004     // This should not destroy the device opaqueness.
1005     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1006
1007     // This should not destroy the device opaqueness either.
1008     context.setFillColor(opaque);
1009     path.moveTo(FloatPoint(10, 10));
1010     path.addLineTo(FloatPoint(40, 40));
1011     context.strokePath(path);
1012
1013     context.endLayer();
1014     context.endLayer();
1015     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
1016     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1017
1018     // Now begin a layer that does not preserve opaque and draw through it to the device.
1019     context.setCompositeOperation(CompositeSourceOut);
1020     context.beginTransparencyLayer(0.5);
1021
1022     // This should destroy the device opaqueness.
1023     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
1024
1025     context.endLayer();
1026     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1027     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1028
1029     // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
1030
1031     context.setCompositeOperation(CompositeSourceOut);
1032     context.beginTransparencyLayer(0.5);
1033
1034     // This should nuke the device opaqueness.
1035     context.setFillColor(opaque);
1036     path.moveTo(FloatPoint(10, 10));
1037     path.addLineTo(FloatPoint(40, 40));
1038     context.strokePath(path);
1039
1040     context.endLayer();
1041     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
1042     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
1043 }
1044
1045 #define DISPATCH(c1, c2, op, params) do { c1.op(params); c2.op(params); } while (0);
1046
1047 TEST(GraphicsContextTest, RecordingTotalMatrix)
1048 {
1049     SkBitmap bitmap;
1050     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
1051     bitmap.eraseColor(0);
1052     SkCanvas canvas(bitmap);
1053     GraphicsContext context(&canvas);
1054
1055     SkCanvas controlCanvas(400, 400);
1056     GraphicsContext controlContext(&controlCanvas);
1057
1058     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1059     DISPATCH(context, controlContext, scale, FloatSize(2, 2));
1060     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1061
1062     controlContext.save();
1063     context.beginRecording(FloatRect(0, 0, 200, 200));
1064     DISPATCH(context, controlContext, translate, FloatSize(10, 10));
1065     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1066
1067     controlContext.save();
1068     context.beginRecording(FloatRect(10, 10, 100, 100));
1069     DISPATCH(context, controlContext, rotate, 45);
1070     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1071
1072     controlContext.restore();
1073     context.endRecording();
1074     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1075
1076     controlContext.restore();
1077     context.endRecording();
1078     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
1079 }
1080
1081 TEST(GraphicsContextTest, DisplayList)
1082 {
1083     FloatRect rect(0, 0, 1, 1);
1084     RefPtr<DisplayList> dl = adoptRef(new DisplayList(rect));
1085
1086     // picture() returns 0 initially
1087     SkPicture* pic = dl->picture();
1088     EXPECT_FALSE(pic);
1089
1090     // endRecording without a beginRecording does nothing
1091     dl->endRecording();
1092     pic = dl->picture();
1093     EXPECT_FALSE(pic);
1094
1095     // Two beginRecordings in a row generate two canvases.
1096     // Unfortunately the new one could be allocated in the same
1097     // spot as the old one so ref the first one to prolong its life.
1098     IntSize size(1, 1);
1099     SkCanvas* canvas1 = dl->beginRecording(size);
1100     EXPECT_TRUE(canvas1);
1101     canvas1->ref();
1102     SkCanvas* canvas2 = dl->beginRecording(size);
1103     EXPECT_TRUE(canvas2);
1104
1105     EXPECT_NE(canvas1, canvas2);
1106     EXPECT_EQ(1, canvas1->getRefCnt());
1107     canvas1->unref();
1108
1109     EXPECT_TRUE(dl->isRecording());
1110
1111     // picture() returns 0 during recording
1112     pic = dl->picture();
1113     EXPECT_FALSE(pic);
1114
1115     // endRecording finally makes the picture accessible
1116     dl->endRecording();
1117     pic = dl->picture();
1118     EXPECT_TRUE(pic);
1119     EXPECT_EQ(1, pic->getRefCnt());
1120 }
1121
1122 } // namespace