OLD | NEW |
| (Empty) |
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 AN
Y | |
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 AN
Y | |
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 O
N | |
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 "core/platform/graphics/GraphicsContext.h" | |
28 | |
29 #include "SkCanvas.h" | |
30 #include "core/platform/graphics/BitmapImage.h" | |
31 #include "core/platform/graphics/ImageBuffer.h" | |
32 #include "core/platform/graphics/skia/NativeImageSkia.h" | |
33 #include "platform/graphics/DisplayList.h" | |
34 #include "third_party/skia/include/core/SkBitmapDevice.h" | |
35 #include <gtest/gtest.h> | |
36 | |
37 using namespace WebCore; | |
38 | |
39 namespace { | |
40 | |
41 #define EXPECT_EQ_RECT(a, b) \ | |
42 EXPECT_EQ(a.x(), b.x()); \ | |
43 EXPECT_EQ(a.y(), b.y()); \ | |
44 EXPECT_EQ(a.width(), b.width()); \ | |
45 EXPECT_EQ(a.height(), b.height()); | |
46 | |
47 #define EXPECT_PIXELS_MATCH(bitmap, opaqueRect) \ | |
48 { \ | |
49 SkAutoLockPixels locker(bitmap); \ | |
50 for (int y = opaqueRect.y(); y < opaqueRect.maxY(); ++y) \ | |
51 for (int x = opaqueRect.x(); x < opaqueRect.maxX(); ++x) { \ | |
52 int alpha = *bitmap.getAddr32(x, y) >> 24; \ | |
53 EXPECT_EQ(255, alpha); \ | |
54 } \ | |
55 } | |
56 | |
57 #define EXPECT_PIXELS_MATCH_EXACT(bitmap, opaqueRect) \ | |
58 { \ | |
59 SkAutoLockPixels locker(bitmap); \ | |
60 for (int y = 0; y < bitmap.height(); ++y) \ | |
61 for (int x = 0; x < bitmap.width(); ++x) { \ | |
62 int alpha = *bitmap.getAddr32(x, y) >> 24; \ | |
63 bool opaque = opaqueRect.contains(x, y); \ | |
64 EXPECT_EQ(opaque, alpha == 255); \ | |
65 } \ | |
66 } | |
67 | |
68 TEST(GraphicsContextTest, trackOpaqueTest) | |
69 { | |
70 SkBitmap bitmap; | |
71 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
72 bitmap.allocPixels(); | |
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 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
131 bitmap.allocPixels(); | |
132 SkCanvas canvas(bitmap); | |
133 | |
134 GraphicsContext context(&canvas); | |
135 context.setTrackOpaqueRegion(true); | |
136 | |
137 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
138 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
139 | |
140 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
141 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
142 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
143 | |
144 context.clearRect(FloatRect(10, 10, 90, 90)); | |
145 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
146 | |
147 context.save(); | |
148 context.clip(FloatRect(0, 0, 10, 10)); | |
149 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
150 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
151 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
152 context.restore(); | |
153 | |
154 context.clearRect(FloatRect(10, 10, 90, 90)); | |
155 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
156 | |
157 context.save(); | |
158 context.clip(FloatRect(20, 20, 10, 10)); | |
159 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
160 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
161 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
162 | |
163 context.clearRect(FloatRect(10, 10, 90, 90)); | |
164 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
165 | |
166 // The intersection of the two clips becomes empty. | |
167 context.clip(FloatRect(30, 20, 10, 10)); | |
168 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
169 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
170 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
171 context.restore(); | |
172 | |
173 context.clearRect(FloatRect(10, 10, 90, 90)); | |
174 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
175 | |
176 // The transform and the clip need to interact correctly (transform first) | |
177 context.save(); | |
178 context.translate(10, 10); | |
179 context.clip(FloatRect(20, 20, 10, 10)); | |
180 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
181 EXPECT_EQ_RECT(IntRect(30, 30, 10, 10), context.opaqueRegion().asRect()); | |
182 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
183 context.restore(); | |
184 | |
185 context.clearRect(FloatRect(10, 10, 90, 90)); | |
186 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
187 | |
188 // The transform and the clip need to interact correctly (clip first) | |
189 context.save(); | |
190 context.clip(FloatRect(20, 20, 10, 10)); | |
191 context.translate(10, 10); | |
192 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
193 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
194 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
195 context.restore(); | |
196 | |
197 context.clearRect(FloatRect(10, 10, 90, 90)); | |
198 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
199 | |
200 Path path; | |
201 path.moveTo(FloatPoint(0, 0)); | |
202 path.addLineTo(FloatPoint(100, 0)); | |
203 | |
204 // Non-rectangular clips just cause the paint to be considered non-opaque. | |
205 context.save(); | |
206 context.clipPath(path, RULE_EVENODD); | |
207 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
208 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
209 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
210 context.restore(); | |
211 | |
212 // Another non-rectangular clip. | |
213 context.save(); | |
214 context.clip(IntRect(30, 30, 20, 20)); | |
215 context.clipOut(IntRect(30, 30, 10, 10)); | |
216 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
217 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
218 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
219 context.restore(); | |
220 } | |
221 | |
222 TEST(GraphicsContextTest, trackImageMask) | |
223 { | |
224 SkBitmap bitmap; | |
225 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
226 bitmap.allocPixels(); | |
227 bitmap.eraseColor(0); | |
228 SkCanvas canvas(bitmap); | |
229 | |
230 GraphicsContext context(&canvas); | |
231 context.setTrackOpaqueRegion(true); | |
232 | |
233 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
234 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
235 | |
236 // Image masks are done by drawing a bitmap into a transparency layer that u
ses DstIn to mask | |
237 // out a transparency layer below that is filled with the mask color. In the
end this should | |
238 // not be marked opaque. | |
239 | |
240 context.setCompositeOperation(CompositeSourceOver); | |
241 context.beginTransparencyLayer(1); | |
242 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver); | |
243 | |
244 context.setCompositeOperation(CompositeDestinationIn); | |
245 context.beginTransparencyLayer(1); | |
246 | |
247 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100)); | |
248 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha); | |
249 | |
250 context.setCompositeOperation(CompositeSourceOver); | |
251 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10)); | |
252 | |
253 context.endLayer(); | |
254 context.endLayer(); | |
255 | |
256 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
257 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
258 } | |
259 | |
260 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect) | |
261 { | |
262 SkBitmap bitmap; | |
263 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
264 bitmap.allocPixels(); | |
265 bitmap.eraseColor(0); | |
266 SkCanvas canvas(bitmap); | |
267 | |
268 GraphicsContext context(&canvas); | |
269 context.setTrackOpaqueRegion(true); | |
270 | |
271 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
272 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
273 | |
274 // Image masks are done by drawing a bitmap into a transparency layer that u
ses DstIn to mask | |
275 // out a transparency layer below that is filled with the mask color. In the
end this should | |
276 // not be marked opaque. | |
277 | |
278 context.setCompositeOperation(CompositeSourceOver); | |
279 context.beginTransparencyLayer(1); | |
280 context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver); | |
281 | |
282 context.setCompositeOperation(CompositeDestinationIn); | |
283 context.beginTransparencyLayer(1); | |
284 | |
285 OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100)); | |
286 alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha); | |
287 | |
288 context.setCompositeOperation(CompositeSourceOver); | |
289 context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10)); | |
290 | |
291 // We can't have an opaque mask actually, but we can pretend here like it wo
uld look if we did. | |
292 context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver); | |
293 | |
294 context.endLayer(); | |
295 context.endLayer(); | |
296 | |
297 EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect()); | |
298 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
299 } | |
300 | |
301 TEST(GraphicsContextTest, trackOpaqueJoinTest) | |
302 { | |
303 SkBitmap bitmap; | |
304 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
305 bitmap.allocPixels(); | |
306 SkCanvas canvas(bitmap); | |
307 | |
308 GraphicsContext context(&canvas); | |
309 context.setTrackOpaqueRegion(true); | |
310 | |
311 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
312 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
313 | |
314 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
315 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
316 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
317 | |
318 // Doesn't join | |
319 context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver); | |
320 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
321 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
322 | |
323 // Does join | |
324 context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver); | |
325 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect()); | |
326 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
327 | |
328 // Doesn't join | |
329 context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver); | |
330 EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect()); | |
331 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
332 | |
333 // Does join | |
334 context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver); | |
335 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect()); | |
336 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
337 | |
338 // Doesn't join | |
339 context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver); | |
340 EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect()); | |
341 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
342 | |
343 // Does join | |
344 context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver); | |
345 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect()); | |
346 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
347 | |
348 // Doesn't join | |
349 context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver); | |
350 EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect()); | |
351 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
352 | |
353 // Does join | |
354 context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver); | |
355 EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect()); | |
356 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
357 } | |
358 | |
359 TEST(GraphicsContextTest, trackOpaqueLineTest) | |
360 { | |
361 SkBitmap bitmap; | |
362 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
363 bitmap.allocPixels(); | |
364 bitmap.eraseColor(0); | |
365 SkCanvas canvas(bitmap); | |
366 | |
367 GraphicsContext context(&canvas); | |
368 context.setTrackOpaqueRegion(true); | |
369 | |
370 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
371 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
372 | |
373 context.setShouldAntialias(false); | |
374 context.setMiterLimit(0); | |
375 context.setStrokeThickness(4); | |
376 context.setLineCap(SquareCap); | |
377 context.setStrokeStyle(SolidStroke); | |
378 context.setCompositeOperation(CompositeSourceOver); | |
379 | |
380 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
381 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
382 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
383 | |
384 context.setCompositeOperation(CompositeSourceIn); | |
385 | |
386 context.save(); | |
387 context.setStrokeColor(alpha); | |
388 context.drawLine(IntPoint(0, 0), IntPoint(100, 0)); | |
389 context.restore(); | |
390 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
391 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
392 | |
393 context.save(); | |
394 context.setStrokeColor(opaque); | |
395 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
396 context.restore(); | |
397 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
398 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
399 | |
400 context.save(); | |
401 context.setStrokeColor(alpha); | |
402 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
403 context.restore(); | |
404 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
405 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
406 | |
407 context.save(); | |
408 context.setStrokeColor(alpha); | |
409 context.drawLine(IntPoint(0, 11), IntPoint(100, 11)); | |
410 context.restore(); | |
411 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
412 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
413 | |
414 context.setShouldAntialias(true); | |
415 context.setCompositeOperation(CompositeSourceOver); | |
416 | |
417 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
418 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
419 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
420 | |
421 context.setCompositeOperation(CompositeSourceIn); | |
422 | |
423 context.save(); | |
424 context.setStrokeColor(alpha); | |
425 context.drawLine(IntPoint(0, 0), IntPoint(100, 0)); | |
426 context.restore(); | |
427 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
428 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
429 | |
430 context.setShouldAntialias(false); | |
431 context.save(); | |
432 context.setStrokeColor(opaque); | |
433 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
434 context.restore(); | |
435 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
436 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
437 | |
438 context.setShouldAntialias(true); | |
439 context.save(); | |
440 context.setStrokeColor(opaque); | |
441 context.drawLine(IntPoint(0, 10), IntPoint(100, 10)); | |
442 context.restore(); | |
443 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
444 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
445 | |
446 context.save(); | |
447 context.setStrokeColor(alpha); | |
448 context.drawLine(IntPoint(0, 11), IntPoint(100, 11)); | |
449 context.restore(); | |
450 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
451 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
452 } | |
453 | |
454 TEST(GraphicsContextTest, trackOpaquePathTest) | |
455 { | |
456 SkBitmap bitmap; | |
457 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
458 bitmap.allocPixels(); | |
459 SkCanvas canvas(bitmap); | |
460 | |
461 GraphicsContext context(&canvas); | |
462 context.setTrackOpaqueRegion(true); | |
463 | |
464 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
465 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
466 | |
467 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
468 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
469 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
470 | |
471 context.setShouldAntialias(false); | |
472 context.setMiterLimit(1); | |
473 context.setStrokeThickness(5); | |
474 context.setLineCap(SquareCap); | |
475 context.setStrokeStyle(SolidStroke); | |
476 context.setCompositeOperation(CompositeSourceIn); | |
477 | |
478 Path path; | |
479 | |
480 context.setFillColor(alpha); | |
481 path.moveTo(FloatPoint(0, 0)); | |
482 path.addLineTo(FloatPoint(100, 0)); | |
483 context.fillPath(path); | |
484 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
485 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
486 path.clear(); | |
487 | |
488 context.setFillColor(opaque); | |
489 path.moveTo(FloatPoint(0, 10)); | |
490 path.addLineTo(FloatPoint(100, 13)); | |
491 context.fillPath(path); | |
492 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
493 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
494 path.clear(); | |
495 | |
496 context.setFillColor(alpha); | |
497 path.moveTo(FloatPoint(0, 10)); | |
498 path.addLineTo(FloatPoint(100, 13)); | |
499 context.fillPath(path); | |
500 EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect()); | |
501 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
502 path.clear(); | |
503 | |
504 context.setFillColor(alpha); | |
505 path.moveTo(FloatPoint(0, 14)); | |
506 path.addLineTo(FloatPoint(100, 10)); | |
507 context.fillPath(path); | |
508 EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect()); | |
509 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
510 path.clear(); | |
511 } | |
512 | |
513 TEST(GraphicsContextTest, trackOpaqueImageTest) | |
514 { | |
515 SkBitmap bitmap; | |
516 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
517 bitmap.allocPixels(); | |
518 SkCanvas canvas(bitmap); | |
519 | |
520 GraphicsContext context(&canvas); | |
521 context.setTrackOpaqueRegion(true); | |
522 | |
523 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
524 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
525 | |
526 SkBitmap opaqueBitmap; | |
527 opaqueBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kOpaque_SkAlp
haType); | |
528 opaqueBitmap.allocPixels(); | |
529 | |
530 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
531 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
532 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
533 RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::creat
e(opaqueBitmap)); | |
534 EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque()); | |
535 | |
536 SkBitmap alphaBitmap; | |
537 alphaBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kPremul_SkAlph
aType); | |
538 alphaBitmap.allocPixels(); | |
539 | |
540 for (int y = 0; y < alphaBitmap.height(); ++y) | |
541 for (int x = 0; x < alphaBitmap.width(); ++x) | |
542 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
543 RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create
(alphaBitmap)); | |
544 EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque()); | |
545 | |
546 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
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(0, 0)); | |
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(0, 0)); | |
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(5, 5)); | |
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(5, 5)); | |
561 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
562 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
563 | |
564 context.drawImage(opaqueImage.get(), IntPoint(10, 10)); | |
565 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
566 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
567 context.drawImage(alphaImage.get(), IntPoint(10, 10)); | |
568 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
569 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
570 | |
571 context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn); | |
572 EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect()); | |
573 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
574 | |
575 context.save(); | |
576 context.setAlpha(0.5); | |
577 context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn); | |
578 context.restore(); | |
579 EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect()); | |
580 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
581 | |
582 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
583 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
584 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
585 | |
586 context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn); | |
587 EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect()); | |
588 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
589 | |
590 context.save(); | |
591 context.setAlpha(0.5); | |
592 context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn); | |
593 context.restore(); | |
594 EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect()); | |
595 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
596 } | |
597 | |
598 TEST(GraphicsContextTest, trackOpaqueOvalTest) | |
599 { | |
600 SkBitmap bitmap; | |
601 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
602 bitmap.allocPixels(); | |
603 bitmap.eraseColor(0); | |
604 SkCanvas canvas(bitmap); | |
605 | |
606 GraphicsContext context(&canvas); | |
607 context.setTrackOpaqueRegion(true); | |
608 | |
609 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
610 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
611 | |
612 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
613 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
614 | |
615 context.drawEllipse(IntRect(10, 10, 90, 90)); | |
616 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
617 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
618 | |
619 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
620 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
621 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
622 | |
623 context.setCompositeOperation(CompositeSourceIn); | |
624 | |
625 context.setShouldAntialias(false); | |
626 | |
627 context.setFillColor(opaque); | |
628 context.drawEllipse(IntRect(10, 10, 50, 30)); | |
629 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
630 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
631 | |
632 context.setFillColor(alpha); | |
633 context.drawEllipse(IntRect(10, 10, 30, 50)); | |
634 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect()); | |
635 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
636 | |
637 context.setShouldAntialias(true); | |
638 | |
639 context.setFillColor(opaque); | |
640 context.drawEllipse(IntRect(10, 10, 50, 30)); | |
641 EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect()); | |
642 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
643 | |
644 context.setFillColor(alpha); | |
645 context.drawEllipse(IntRect(20, 10, 30, 50)); | |
646 EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect()); | |
647 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
648 } | |
649 | |
650 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest) | |
651 { | |
652 SkBitmap bitmap; | |
653 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
654 bitmap.allocPixels(); | |
655 bitmap.eraseColor(0); | |
656 SkCanvas canvas(bitmap); | |
657 | |
658 GraphicsContext context(&canvas); | |
659 context.setTrackOpaqueRegion(true); | |
660 | |
661 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
662 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
663 IntSize radii(10, 10); | |
664 | |
665 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
666 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
667 | |
668 context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii,
opaque); | |
669 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
670 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
671 | |
672 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
673 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
674 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
675 | |
676 context.setCompositeOperation(CompositeSourceIn); | |
677 context.setShouldAntialias(false); | |
678 | |
679 context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii,
opaque); | |
680 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
681 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
682 | |
683 context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii,
alpha); | |
684 EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect()); | |
685 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
686 | |
687 context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii,
alpha); | |
688 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect()); | |
689 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
690 | |
691 context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii,
opaque); | |
692 EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect()); | |
693 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
694 } | |
695 | |
696 TEST(GraphicsContextTest, trackOpaqueTextTest) | |
697 { | |
698 int width = 200, height = 200; | |
699 SkBitmap bitmap; | |
700 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | |
701 bitmap.allocPixels(); | |
702 bitmap.eraseColor(0); | |
703 SkCanvas canvas(bitmap); | |
704 SkRect textRect = SkRect::MakeWH(width, height); | |
705 | |
706 GraphicsContext context(&canvas); | |
707 context.setTrackOpaqueRegion(true); | |
708 | |
709 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
710 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
711 | |
712 SkPaint opaquePaint; | |
713 opaquePaint.setColor(opaque.rgb()); | |
714 opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
715 SkPaint alphaPaint; | |
716 alphaPaint.setColor(alpha.rgb()); | |
717 alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
718 | |
719 SkPoint point = SkPoint::Make(0, 0); | |
720 SkScalar pointX = 0; | |
721 SkPath path; | |
722 path.moveTo(SkPoint::Make(0, 0)); | |
723 path.lineTo(SkPoint::Make(100, 0)); | |
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.drawPosText("A", 1, &point, textRect, opaquePaint); | |
730 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
731 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
732 | |
733 context.drawPosText("A", 1, &point, textRect, alphaPaint); | |
734 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
735 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
736 | |
737 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver); | |
738 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
739 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
740 | |
741 context.drawPosTextH("A", 1, &pointX, 0, textRect, opaquePaint); | |
742 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
743 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
744 | |
745 context.drawPosTextH("A", 1, &pointX, 0, textRect, alphaPaint); | |
746 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
747 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
748 | |
749 context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver); | |
750 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
751 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
752 | |
753 context.drawTextOnPath("A", 1, path, textRect, 0, opaquePaint); | |
754 EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect()); | |
755 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
756 | |
757 context.drawTextOnPath("A", 1, path, textRect, 0, alphaPaint); | |
758 EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect()); | |
759 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
760 } | |
761 | |
762 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest) | |
763 { | |
764 SkBitmap bitmap; | |
765 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
766 bitmap.allocPixels(); | |
767 bitmap.eraseColor(0); | |
768 SkCanvas canvas(bitmap); | |
769 | |
770 GraphicsContext context(&canvas); | |
771 context.setTrackOpaqueRegion(true); | |
772 | |
773 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
774 | |
775 SkBitmap opaqueBitmap; | |
776 opaqueBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kOpaque_SkAlp
haType); | |
777 opaqueBitmap.allocPixels(); | |
778 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
779 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
780 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
781 | |
782 SkBitmap alphaBitmap; | |
783 alphaBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kPremul_SkAlph
aType); | |
784 alphaBitmap.allocPixels(); | |
785 for (int y = 0; y < alphaBitmap.height(); ++y) | |
786 for (int x = 0; x < alphaBitmap.width(); ++x) | |
787 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
788 | |
789 SkPaint paint; | |
790 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
791 | |
792 context.writePixels(opaqueBitmap, 50, 50); | |
793 EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect()); | |
794 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
795 | |
796 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
797 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
798 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
799 | |
800 context.writePixels(alphaBitmap, 10, 0); | |
801 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
802 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
803 | |
804 context.writePixels(alphaBitmap, 10, 1); | |
805 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
806 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
807 | |
808 context.writePixels(alphaBitmap, 0, 10); | |
809 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
810 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
811 | |
812 context.writePixels(alphaBitmap, 1, 10); | |
813 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
814 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
815 } | |
816 | |
817 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest) | |
818 { | |
819 SkBitmap bitmap; | |
820 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
821 bitmap.allocPixels(); | |
822 bitmap.eraseColor(0); | |
823 SkCanvas canvas(bitmap); | |
824 | |
825 GraphicsContext context(&canvas); | |
826 context.setTrackOpaqueRegion(true); | |
827 | |
828 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
829 | |
830 SkBitmap opaqueBitmap; | |
831 opaqueBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kOpaque_SkAlp
haType); | |
832 opaqueBitmap.allocPixels(); | |
833 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
834 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
835 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
836 | |
837 SkBitmap alphaBitmap; | |
838 alphaBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kPremul_SkAlph
aType); | |
839 alphaBitmap.allocPixels(); | |
840 for (int y = 0; y < alphaBitmap.height(); ++y) | |
841 for (int x = 0; x < alphaBitmap.width(); ++x) | |
842 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
843 | |
844 SkPaint paint; | |
845 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
846 | |
847 context.drawBitmap(opaqueBitmap, 10, 10, &paint); | |
848 EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect()); | |
849 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
850 | |
851 context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver); | |
852 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
853 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
854 | |
855 context.drawBitmap(alphaBitmap, 10, 0, &paint); | |
856 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
857 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
858 | |
859 context.drawBitmap(alphaBitmap, 10, 1, &paint); | |
860 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
861 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
862 | |
863 context.drawBitmap(alphaBitmap, 0, 10, &paint); | |
864 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
865 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
866 | |
867 context.drawBitmap(alphaBitmap, 1, 10, &paint); | |
868 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
869 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
870 } | |
871 | |
872 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest) | |
873 { | |
874 SkBitmap bitmap; | |
875 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); | |
876 bitmap.allocPixels(); | |
877 bitmap.eraseColor(0); | |
878 SkCanvas canvas(bitmap); | |
879 | |
880 GraphicsContext context(&canvas); | |
881 context.setTrackOpaqueRegion(true); | |
882 | |
883 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
884 | |
885 SkBitmap opaqueBitmap; | |
886 opaqueBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kOpaque_SkAlp
haType); | |
887 opaqueBitmap.allocPixels(); | |
888 for (int y = 0; y < opaqueBitmap.height(); ++y) | |
889 for (int x = 0; x < opaqueBitmap.width(); ++x) | |
890 *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF; | |
891 | |
892 SkBitmap alphaBitmap; | |
893 alphaBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kPremul_SkAlph
aType); | |
894 alphaBitmap.allocPixels(); | |
895 for (int y = 0; y < alphaBitmap.height(); ++y) | |
896 for (int x = 0; x < alphaBitmap.width(); ++x) | |
897 *alphaBitmap.getAddr32(x, y) = 0x00000000; | |
898 | |
899 SkPaint paint; | |
900 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
901 | |
902 context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &p
aint); | |
903 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
904 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
905 | |
906 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &pai
nt); | |
907 EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect()); | |
908 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
909 | |
910 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &pai
nt); | |
911 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
912 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
913 | |
914 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &pai
nt); | |
915 EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect()); | |
916 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
917 | |
918 context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &pai
nt); | |
919 EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect()); | |
920 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
921 } | |
922 | |
923 TEST(GraphicsContextTest, contextTransparencyLayerTest) | |
924 { | |
925 SkBitmap bitmap; | |
926 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
927 bitmap.allocPixels(); | |
928 bitmap.eraseColor(0); | |
929 SkCanvas canvas(bitmap); | |
930 | |
931 GraphicsContext context(&canvas); | |
932 context.setTrackOpaqueRegion(true); | |
933 | |
934 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
935 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
936 EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect()); | |
937 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
938 | |
939 context.clearRect(FloatRect(20, 20, 10, 10)); | |
940 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
941 | |
942 context.beginTransparencyLayer(0.5); | |
943 context.save(); | |
944 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
945 context.restore(); | |
946 context.endLayer(); | |
947 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
948 | |
949 context.clearRect(FloatRect(20, 20, 10, 10)); | |
950 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
951 | |
952 context.beginTransparencyLayer(0.5); | |
953 context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver); | |
954 context.endLayer(); | |
955 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
956 } | |
957 | |
958 TEST(GraphicsContextTest, UnboundedDrawsAreClipped) | |
959 { | |
960 SkBitmap bitmap; | |
961 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
962 bitmap.allocPixels(); | |
963 bitmap.eraseColor(0); | |
964 SkCanvas canvas(bitmap); | |
965 | |
966 GraphicsContext context(&canvas); | |
967 context.setTrackOpaqueRegion(true); | |
968 | |
969 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
970 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
971 | |
972 Path path; | |
973 context.setShouldAntialias(false); | |
974 context.setMiterLimit(1); | |
975 context.setStrokeThickness(5); | |
976 context.setLineCap(SquareCap); | |
977 context.setStrokeStyle(SolidStroke); | |
978 | |
979 // Make skia unable to compute fast bounds for our paths. | |
980 DashArray dashArray; | |
981 dashArray.append(1); | |
982 dashArray.append(0); | |
983 context.setLineDash(dashArray, 0); | |
984 | |
985 // Make the device opaque in 10,10 40x40. | |
986 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
987 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
988 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
989 | |
990 // Clip to the left edge of the opaque area. | |
991 context.clip(IntRect(10, 10, 10, 40)); | |
992 | |
993 // Draw a path that gets clipped. This should destroy the opaque area but on
ly inside the clip. | |
994 context.setCompositeOperation(CompositeSourceOut); | |
995 context.setFillColor(alpha); | |
996 path.moveTo(FloatPoint(10, 10)); | |
997 path.addLineTo(FloatPoint(40, 40)); | |
998 context.strokePath(path); | |
999 | |
1000 EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect()); | |
1001 EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect()); | |
1002 } | |
1003 | |
1004 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer) | |
1005 { | |
1006 SkBitmap bitmap; | |
1007 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
1008 bitmap.allocPixels(); | |
1009 bitmap.eraseColor(0); | |
1010 SkCanvas canvas(bitmap); | |
1011 | |
1012 GraphicsContext context(&canvas); | |
1013 context.setTrackOpaqueRegion(true); | |
1014 | |
1015 Color opaque(1.0f, 0.0f, 0.0f, 1.0f); | |
1016 Color alpha(0.0f, 0.0f, 0.0f, 0.0f); | |
1017 | |
1018 Path path; | |
1019 context.setShouldAntialias(false); | |
1020 context.setMiterLimit(1); | |
1021 context.setStrokeThickness(5); | |
1022 context.setLineCap(SquareCap); | |
1023 context.setStrokeStyle(SolidStroke); | |
1024 | |
1025 // Make skia unable to compute fast bounds for our paths. | |
1026 DashArray dashArray; | |
1027 dashArray.append(1); | |
1028 dashArray.append(0); | |
1029 context.setLineDash(dashArray, 0); | |
1030 | |
1031 // Make the device opaque in 10,10 40x40. | |
1032 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1033 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
1034 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1035 | |
1036 // Begin a layer that preserves opaque. | |
1037 context.setCompositeOperation(CompositeSourceOver); | |
1038 context.beginTransparencyLayer(0.5); | |
1039 | |
1040 // Begin a layer that does not preserve opaque. | |
1041 context.setCompositeOperation(CompositeSourceOut); | |
1042 context.beginTransparencyLayer(0.5); | |
1043 | |
1044 // This should not destroy the device opaqueness. | |
1045 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1046 | |
1047 // This should not destroy the device opaqueness either. | |
1048 context.setFillColor(opaque); | |
1049 path.moveTo(FloatPoint(10, 10)); | |
1050 path.addLineTo(FloatPoint(40, 40)); | |
1051 context.strokePath(path); | |
1052 | |
1053 context.endLayer(); | |
1054 context.endLayer(); | |
1055 EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect()); | |
1056 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1057 | |
1058 // Now begin a layer that does not preserve opaque and draw through it to th
e device. | |
1059 context.setCompositeOperation(CompositeSourceOut); | |
1060 context.beginTransparencyLayer(0.5); | |
1061 | |
1062 // This should destroy the device opaqueness. | |
1063 context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver); | |
1064 | |
1065 context.endLayer(); | |
1066 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
1067 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1068 | |
1069 // Now we draw with a path for which it cannot compute fast bounds. This sho
uld destroy the entire opaque region. | |
1070 | |
1071 context.setCompositeOperation(CompositeSourceOut); | |
1072 context.beginTransparencyLayer(0.5); | |
1073 | |
1074 // This should nuke the device opaqueness. | |
1075 context.setFillColor(opaque); | |
1076 path.moveTo(FloatPoint(10, 10)); | |
1077 path.addLineTo(FloatPoint(40, 40)); | |
1078 context.strokePath(path); | |
1079 | |
1080 context.endLayer(); | |
1081 EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect()); | |
1082 EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect()); | |
1083 } | |
1084 | |
1085 #define DISPATCH(c1, c2, op, params) do { c1.op(params); c2.op(params); } while
(0); | |
1086 | |
1087 TEST(GraphicsContextTest, RecordingTotalMatrix) | |
1088 { | |
1089 SkBitmap bitmap; | |
1090 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400); | |
1091 bitmap.allocPixels(); | |
1092 bitmap.eraseColor(0); | |
1093 SkCanvas canvas(bitmap); | |
1094 GraphicsContext context(&canvas); | |
1095 | |
1096 SkBitmapDevice controlDevice(SkBitmap::kNo_Config, 400, 400); | |
1097 SkCanvas controlCanvas(&controlDevice); | |
1098 GraphicsContext controlContext(&controlCanvas); | |
1099 | |
1100 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1101 DISPATCH(context, controlContext, scale, FloatSize(2, 2)); | |
1102 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1103 | |
1104 controlContext.save(); | |
1105 context.beginRecording(FloatRect(0, 0, 200, 200)); | |
1106 DISPATCH(context, controlContext, translate, FloatSize(10, 10)); | |
1107 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1108 | |
1109 controlContext.save(); | |
1110 context.beginRecording(FloatRect(10, 10, 100, 100)); | |
1111 DISPATCH(context, controlContext, rotate, 45); | |
1112 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1113 | |
1114 controlContext.restore(); | |
1115 context.endRecording(); | |
1116 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1117 | |
1118 controlContext.restore(); | |
1119 context.endRecording(); | |
1120 EXPECT_EQ(context.getCTM(), controlContext.getCTM()); | |
1121 } | |
1122 | |
1123 } // namespace | |
OLD | NEW |