OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 { \ | 59 { \ |
60 SkAutoLockPixels locker(bitmap); \ | 60 SkAutoLockPixels locker(bitmap); \ |
61 for (int y = 0; y < bitmap.height(); ++y) \ | 61 for (int y = 0; y < bitmap.height(); ++y) \ |
62 for (int x = 0; x < bitmap.width(); ++x) { \ | 62 for (int x = 0; x < bitmap.width(); ++x) { \ |
63 int alpha = *bitmap.getAddr32(x, y) >> 24; \ | 63 int alpha = *bitmap.getAddr32(x, y) >> 24; \ |
64 bool opaque = opaqueRect.contains(x, y); \ | 64 bool opaque = opaqueRect.contains(x, y); \ |
65 EXPECT_EQ(opaque, alpha == 255); \ | 65 EXPECT_EQ(opaque, alpha == 255); \ |
66 } \ | 66 } \ |
67 } | 67 } |
68 | 68 |
| 69 #define EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, color) \ |
| 70 { \ |
| 71 SkAutoLockPixels locker(bitmap); \ |
| 72 for (int y = rect.y(); y < rect.maxY(); ++y) { \ |
| 73 for (int x = rect.x(); x < rect.maxX(); ++x) { \ |
| 74 RGBA32 pixel = *bitmap.getAddr32(x, y); \ |
| 75 EXPECT_EQ(color, pixel); \ |
| 76 } \ |
| 77 } \ |
| 78 } |
| 79 |
69 TEST(GraphicsContextTest, trackOpaqueTest) | 80 TEST(GraphicsContextTest, trackOpaqueTest) |
70 { | 81 { |
71 SkBitmap bitmap; | 82 SkBitmap bitmap; |
72 bitmap.allocN32Pixels(400, 400); | 83 bitmap.allocN32Pixels(400, 400); |
73 bitmap.eraseColor(0); | 84 bitmap.eraseColor(0); |
74 SkCanvas canvas(bitmap); | 85 SkCanvas canvas(bitmap); |
75 | 86 |
76 GraphicsContext context(&canvas); | 87 GraphicsContext context(&canvas); |
77 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque); | 88 context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque); |
78 | 89 |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 | 1218 |
1208 // endRecording finally makes the picture accessible | 1219 // endRecording finally makes the picture accessible |
1209 RefPtr<DisplayList> dl = context.endRecording(); | 1220 RefPtr<DisplayList> dl = context.endRecording(); |
1210 SkPicture* pic = dl->picture(); | 1221 SkPicture* pic = dl->picture(); |
1211 EXPECT_TRUE(pic); | 1222 EXPECT_TRUE(pic); |
1212 EXPECT_EQ(1, pic->getRefCnt()); | 1223 EXPECT_EQ(1, pic->getRefCnt()); |
1213 | 1224 |
1214 context.endRecording(); | 1225 context.endRecording(); |
1215 } | 1226 } |
1216 | 1227 |
| 1228 TEST(GraphicsContextTest, BeginLayerDontAffectCanvasState) |
| 1229 { |
| 1230 SkBitmap bitmap; |
| 1231 bitmap.allocN32Pixels(1, 1); |
| 1232 bitmap.eraseColor(0); |
| 1233 SkCanvas canvas(bitmap); |
| 1234 GraphicsContext context(&canvas); |
| 1235 |
| 1236 IntRect rect(0, 0, 1, 1); |
| 1237 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::transparent); |
| 1238 context.fillRect(rect, Color::gray); |
| 1239 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray); |
| 1240 |
| 1241 // Translate out of bound not to draw. |
| 1242 context.translate(1, 0); |
| 1243 context.fillRect(rect, Color::darkGray); |
| 1244 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray); |
| 1245 EXPECT_EQ(SK_Scalar1, context.getTotalMatrix().getTranslateX()); |
| 1246 |
| 1247 context.beginLayer(1, CompositeSourceOver); |
| 1248 context.translate(-1, 0); |
| 1249 EXPECT_EQ(0, context.getTotalMatrix().getTranslateX()); |
| 1250 context.fillRect(rect, Color::darkGray); |
| 1251 context.endLayer(); |
| 1252 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::darkGray); |
| 1253 |
| 1254 // GraphicsContext::endLayer() must preserve current states. |
| 1255 EXPECT_EQ(0, context.getTotalMatrix().getTranslateX()); |
| 1256 |
| 1257 context.fillRect(rect, Color::lightGray); |
| 1258 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::lightGray); |
| 1259 } |
| 1260 |
| 1261 // Although this test looks like duplicated to BeginLayerPreserveCanvasState, |
| 1262 // this is needed because GraphicsContext keeps a composite operator in SkPaint |
| 1263 // while setting a transform to SkCanvas directly. |
| 1264 TEST(GraphicsContextTest, BeginLayerDontAffectPaintState) |
| 1265 { |
| 1266 SkBitmap bitmap; |
| 1267 bitmap.allocN32Pixels(1, 1); |
| 1268 bitmap.eraseColor(0); |
| 1269 SkCanvas canvas(bitmap); |
| 1270 GraphicsContext context(&canvas); |
| 1271 |
| 1272 IntRect rect(0, 0, 1, 1); |
| 1273 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::transparent); |
| 1274 EXPECT_EQ(CompositeSourceOver, context.compositeOperation()); |
| 1275 context.fillRect(rect, Color::gray); |
| 1276 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray); |
| 1277 |
| 1278 // Set CompositeDestinationIn not to draw. |
| 1279 context.setCompositeOperation(CompositeDestinationIn); |
| 1280 context.fillRect(rect, Color::darkGray); |
| 1281 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray); |
| 1282 EXPECT_EQ(CompositeDestinationIn, context.compositeOperation()); |
| 1283 |
| 1284 context.beginLayer(1, CompositeSourceIn); |
| 1285 EXPECT_EQ(CompositeDestinationIn, context.compositeOperation()); |
| 1286 context.setCompositeOperation(CompositeSourceOver); |
| 1287 EXPECT_EQ(CompositeSourceOver, context.compositeOperation()); |
| 1288 context.fillRect(rect, Color::darkGray); |
| 1289 context.endLayer(); |
| 1290 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::darkGray); |
| 1291 |
| 1292 // GraphicsContext::endLayer() must preserve current states. |
| 1293 EXPECT_EQ(CompositeSourceOver, context.compositeOperation()); |
| 1294 |
| 1295 context.fillRect(rect, Color::lightGray); |
| 1296 EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::lightGray); |
| 1297 } |
| 1298 |
| 1299 // Cannot reuse SkClipStack::Element::operator==() because it checks save count. |
| 1300 bool equal(const SkClipStack::Element* a, const SkClipStack::Element* b) |
| 1301 { |
| 1302 if (a->getOp() != b->getOp() || a->getType() != b->getType() || a->isAA() !=
b->isAA()) { |
| 1303 return false; |
| 1304 } |
| 1305 switch (a->getType()) { |
| 1306 case SkClipStack::Element::kPath_Type: |
| 1307 return a->getPath() == b->getPath(); |
| 1308 case SkClipStack::Element::kRRect_Type: |
| 1309 return a->getRRect() == b->getRRect(); |
| 1310 case SkClipStack::Element::kRect_Type: |
| 1311 return a->getRect() == b->getRect(); |
| 1312 case SkClipStack::Element::kEmpty_Type: |
| 1313 return true; |
| 1314 default: |
| 1315 ASSERT_NOT_REACHED(); |
| 1316 return false; |
| 1317 } |
| 1318 } |
| 1319 |
| 1320 // Cannot reuse SkClipStack::operator==() because it checks save count. |
| 1321 bool equal(const SkClipStack* a, const SkClipStack* b) |
| 1322 { |
| 1323 SkClipStack::B2TIter aIter(*a); |
| 1324 SkClipStack::B2TIter bIter(*b); |
| 1325 const SkClipStack::Element* aElement = aIter.next(); |
| 1326 const SkClipStack::Element* bElement = bIter.next(); |
| 1327 |
| 1328 while (aElement && bElement) { |
| 1329 if (!equal(aElement, bElement)) { |
| 1330 return false; |
| 1331 } |
| 1332 aElement = aIter.next(); |
| 1333 bElement = bIter.next(); |
| 1334 } |
| 1335 return !aElement && !bElement; |
| 1336 } |
| 1337 |
| 1338 TEST(GraphicsContextTest, BeginLayerDontAffectClipState) |
| 1339 { |
| 1340 SkBitmap bitmap; |
| 1341 bitmap.allocN32Pixels(10, 10); |
| 1342 bitmap.eraseColor(0); |
| 1343 SkCanvas canvas(bitmap); |
| 1344 GraphicsContext context(&canvas); |
| 1345 // Reference to compare clip stack. It's needed because SkCanvas::saveLayer(
) can perform an additional clip op. |
| 1346 SkBitmap bitmapRef; |
| 1347 bitmapRef.allocN32Pixels(10, 10); |
| 1348 bitmapRef.eraseColor(0); |
| 1349 SkCanvas canvasRef(bitmapRef); |
| 1350 GraphicsContext contextRef(&canvasRef); |
| 1351 |
| 1352 context.clip(IntRect(1, 1, 9, 9)); |
| 1353 contextRef.clip(IntRect(1, 1, 9, 9)); |
| 1354 context.save(); |
| 1355 context.clip(IntRect(0, 0, 7, 7)); |
| 1356 context.translate(1, 1); |
| 1357 context.clip(IntRect(0, 0, 7, 7)); |
| 1358 contextRef.save(); |
| 1359 contextRef.clip(IntRect(0, 0, 7, 7)); |
| 1360 contextRef.translate(1, 1); |
| 1361 contextRef.clip(IntRect(0, 0, 7, 7)); |
| 1362 EXPECT_TRUE(equal(canvasRef.getClipStack(), canvas.getClipStack())); |
| 1363 |
| 1364 RoundedRect roundedClipRect(IntRect(20, 20, 70, 70), RoundedRect::Radii(IntS
ize(2, 3), IntSize(2, 3), IntSize(2, 3), IntSize(2, 3))); |
| 1365 context.beginLayer(1, CompositeSourceOver); |
| 1366 context.scale(0.1, 0.1); |
| 1367 context.clipRoundedRect(roundedClipRect); |
| 1368 context.clipOut(IntRect(40, 40, 10, 10)); |
| 1369 context.endLayer(); |
| 1370 contextRef.scale(0.1, 0.1); |
| 1371 contextRef.clipRoundedRect(roundedClipRect); |
| 1372 contextRef.clipOut(IntRect(40, 40, 10, 10)); |
| 1373 |
| 1374 // GraphicsContext::endLayer() must preserve clip state. |
| 1375 EXPECT_TRUE(equal(canvasRef.getClipStack(), canvas.getClipStack())); |
| 1376 context.restore(); |
| 1377 contextRef.restore(); |
| 1378 } |
| 1379 |
1217 } // namespace | 1380 } // namespace |
OLD | NEW |