| Index: Source/platform/graphics/GraphicsContextTest.cpp
|
| diff --git a/Source/platform/graphics/GraphicsContextTest.cpp b/Source/platform/graphics/GraphicsContextTest.cpp
|
| index fe8b95e939a8b6b9ff9302c82b5914cec334658a..a911387f56d01d41d30778e7d6e521ed747147d2 100644
|
| --- a/Source/platform/graphics/GraphicsContextTest.cpp
|
| +++ b/Source/platform/graphics/GraphicsContextTest.cpp
|
| @@ -66,6 +66,17 @@ namespace {
|
| } \
|
| }
|
|
|
| +#define EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, color) \
|
| +{ \
|
| + SkAutoLockPixels locker(bitmap); \
|
| + for (int y = rect.y(); y < rect.maxY(); ++y) { \
|
| + for (int x = rect.x(); x < rect.maxX(); ++x) { \
|
| + RGBA32 pixel = *bitmap.getAddr32(x, y); \
|
| + EXPECT_EQ(color, pixel); \
|
| + } \
|
| + } \
|
| +}
|
| +
|
| TEST(GraphicsContextTest, trackOpaqueTest)
|
| {
|
| SkBitmap bitmap;
|
| @@ -1214,4 +1225,156 @@ TEST(GraphicsContextTest, RecordingCanvas)
|
| context.endRecording();
|
| }
|
|
|
| +TEST(GraphicsContextTest, BeginLayerDontAffectCanvasState)
|
| +{
|
| + SkBitmap bitmap;
|
| + bitmap.allocN32Pixels(1, 1);
|
| + bitmap.eraseColor(0);
|
| + SkCanvas canvas(bitmap);
|
| + GraphicsContext context(&canvas);
|
| +
|
| + IntRect rect(0, 0, 1, 1);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::transparent);
|
| + context.fillRect(rect, Color::gray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray);
|
| +
|
| + // Translate out of bound not to draw.
|
| + context.translate(1, 0);
|
| + context.fillRect(rect, Color::darkGray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray);
|
| + EXPECT_EQ(SK_Scalar1, context.getTotalMatrix().getTranslateX());
|
| +
|
| + context.beginLayer(1, CompositeSourceOver);
|
| + context.translate(-1, 0);
|
| + EXPECT_EQ(0, context.getTotalMatrix().getTranslateX());
|
| + context.fillRect(rect, Color::darkGray);
|
| + context.endLayer();
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::darkGray);
|
| +
|
| + // GraphicsContext::endLayer() must preserve current states.
|
| + EXPECT_EQ(0, context.getTotalMatrix().getTranslateX());
|
| +
|
| + context.fillRect(rect, Color::lightGray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::lightGray);
|
| +}
|
| +
|
| +// Although this test looks like duplicated to BeginLayerPreserveCanvasState,
|
| +// this is needed because GraphicsContext keeps a composite operator in SkPaint
|
| +// while setting a transform to SkCanvas directly.
|
| +TEST(GraphicsContextTest, BeginLayerDontAffectPaintState)
|
| +{
|
| + SkBitmap bitmap;
|
| + bitmap.allocN32Pixels(1, 1);
|
| + bitmap.eraseColor(0);
|
| + SkCanvas canvas(bitmap);
|
| + GraphicsContext context(&canvas);
|
| +
|
| + IntRect rect(0, 0, 1, 1);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::transparent);
|
| + EXPECT_EQ(CompositeSourceOver, context.compositeOperation());
|
| + context.fillRect(rect, Color::gray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray);
|
| +
|
| + // Set CompositeDestinationIn not to draw.
|
| + context.setCompositeOperation(CompositeDestinationIn);
|
| + context.fillRect(rect, Color::darkGray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::gray);
|
| + EXPECT_EQ(CompositeDestinationIn, context.compositeOperation());
|
| +
|
| + context.beginLayer(1, CompositeSourceIn);
|
| + EXPECT_EQ(CompositeDestinationIn, context.compositeOperation());
|
| + context.setCompositeOperation(CompositeSourceOver);
|
| + EXPECT_EQ(CompositeSourceOver, context.compositeOperation());
|
| + context.fillRect(rect, Color::darkGray);
|
| + context.endLayer();
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::darkGray);
|
| +
|
| + // GraphicsContext::endLayer() must preserve current states.
|
| + EXPECT_EQ(CompositeSourceOver, context.compositeOperation());
|
| +
|
| + context.fillRect(rect, Color::lightGray);
|
| + EXPECT_PIXELS_MATCH_COLOR(bitmap, rect, Color::lightGray);
|
| +}
|
| +
|
| +// Cannot reuse SkClipStack::Element::operator==() because it checks save count.
|
| +bool equal(const SkClipStack::Element* a, const SkClipStack::Element* b)
|
| +{
|
| + if (a->getOp() != b->getOp() || a->getType() != b->getType() || a->isAA() != b->isAA()) {
|
| + return false;
|
| + }
|
| + switch (a->getType()) {
|
| + case SkClipStack::Element::kPath_Type:
|
| + return a->getPath() == b->getPath();
|
| + case SkClipStack::Element::kRRect_Type:
|
| + return a->getRRect() == b->getRRect();
|
| + case SkClipStack::Element::kRect_Type:
|
| + return a->getRect() == b->getRect();
|
| + case SkClipStack::Element::kEmpty_Type:
|
| + return true;
|
| + default:
|
| + ASSERT_NOT_REACHED();
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +// Cannot reuse SkClipStack::operator==() because it checks save count.
|
| +bool equal(const SkClipStack* a, const SkClipStack* b)
|
| +{
|
| + SkClipStack::B2TIter aIter(*a);
|
| + SkClipStack::B2TIter bIter(*b);
|
| + const SkClipStack::Element* aElement = aIter.next();
|
| + const SkClipStack::Element* bElement = bIter.next();
|
| +
|
| + while (aElement && bElement) {
|
| + if (!equal(aElement, bElement)) {
|
| + return false;
|
| + }
|
| + aElement = aIter.next();
|
| + bElement = bIter.next();
|
| + }
|
| + return !aElement && !bElement;
|
| +}
|
| +
|
| +TEST(GraphicsContextTest, BeginLayerDontAffectClipState)
|
| +{
|
| + SkBitmap bitmap;
|
| + bitmap.allocN32Pixels(10, 10);
|
| + bitmap.eraseColor(0);
|
| + SkCanvas canvas(bitmap);
|
| + GraphicsContext context(&canvas);
|
| + // Reference to compare clip stack. It's needed because SkCanvas::saveLayer() can perform an additional clip op.
|
| + SkBitmap bitmapRef;
|
| + bitmapRef.allocN32Pixels(10, 10);
|
| + bitmapRef.eraseColor(0);
|
| + SkCanvas canvasRef(bitmapRef);
|
| + GraphicsContext contextRef(&canvasRef);
|
| +
|
| + context.clip(IntRect(1, 1, 9, 9));
|
| + contextRef.clip(IntRect(1, 1, 9, 9));
|
| + context.save();
|
| + context.clip(IntRect(0, 0, 7, 7));
|
| + context.translate(1, 1);
|
| + context.clip(IntRect(0, 0, 7, 7));
|
| + contextRef.save();
|
| + contextRef.clip(IntRect(0, 0, 7, 7));
|
| + contextRef.translate(1, 1);
|
| + contextRef.clip(IntRect(0, 0, 7, 7));
|
| + EXPECT_TRUE(equal(canvasRef.getClipStack(), canvas.getClipStack()));
|
| +
|
| + RoundedRect roundedClipRect(IntRect(20, 20, 70, 70), RoundedRect::Radii(IntSize(2, 3), IntSize(2, 3), IntSize(2, 3), IntSize(2, 3)));
|
| + context.beginLayer(1, CompositeSourceOver);
|
| + context.scale(0.1, 0.1);
|
| + context.clipRoundedRect(roundedClipRect);
|
| + context.clipOut(IntRect(40, 40, 10, 10));
|
| + context.endLayer();
|
| + contextRef.scale(0.1, 0.1);
|
| + contextRef.clipRoundedRect(roundedClipRect);
|
| + contextRef.clipOut(IntRect(40, 40, 10, 10));
|
| +
|
| + // GraphicsContext::endLayer() must preserve clip state.
|
| + EXPECT_TRUE(equal(canvasRef.getClipStack(), canvas.getClipStack()));
|
| + context.restore();
|
| + contextRef.restore();
|
| +}
|
| +
|
| } // namespace
|
|
|