Home | History | Annotate | Download | only in graphics
      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 DISPATCH1(c1, c2, op, param1) do { c1.op(param1); c2.op(param1); } while (0);
   1046 #define DISPATCH2(c1, c2, op, param1, param2) do { c1.op(param1, param2); c2.op(param1, param2); } while (0);
   1047 
   1048 TEST(GraphicsContextTest, RecordingTotalMatrix)
   1049 {
   1050     SkBitmap bitmap;
   1051     ASSERT_TRUE(bitmap.allocN32Pixels(400, 400));
   1052     bitmap.eraseColor(0);
   1053     SkCanvas canvas(bitmap);
   1054     GraphicsContext context(&canvas);
   1055 
   1056     SkCanvas controlCanvas(400, 400);
   1057     GraphicsContext controlContext(&controlCanvas);
   1058 
   1059     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1060     DISPATCH2(context, controlContext, scale, 2, 2);
   1061     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1062 
   1063     controlContext.save();
   1064     context.beginRecording(FloatRect(0, 0, 200, 200));
   1065     DISPATCH2(context, controlContext, translate, 10, 10);
   1066     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1067 
   1068     controlContext.save();
   1069     context.beginRecording(FloatRect(10, 10, 100, 100));
   1070     DISPATCH1(context, controlContext, rotate, 45);
   1071     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1072 
   1073     controlContext.restore();
   1074     context.endRecording();
   1075     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1076 
   1077     controlContext.restore();
   1078     context.endRecording();
   1079     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1080 }
   1081 
   1082 TEST(GraphicsContextTest, DisplayList)
   1083 {
   1084     FloatRect rect(0, 0, 1, 1);
   1085     RefPtr<DisplayList> dl = adoptRef(new DisplayList(rect));
   1086 
   1087     // picture() returns 0 initially
   1088     SkPicture* pic = dl->picture();
   1089     EXPECT_FALSE(pic);
   1090 
   1091     // endRecording without a beginRecording does nothing
   1092     dl->endRecording();
   1093     pic = dl->picture();
   1094     EXPECT_FALSE(pic);
   1095 
   1096     // Two beginRecordings in a row generate two canvases.
   1097     // Unfortunately the new one could be allocated in the same
   1098     // spot as the old one so ref the first one to prolong its life.
   1099     IntSize size(1, 1);
   1100     SkCanvas* canvas1 = dl->beginRecording(size);
   1101     EXPECT_TRUE(canvas1);
   1102     canvas1->ref();
   1103     SkCanvas* canvas2 = dl->beginRecording(size);
   1104     EXPECT_TRUE(canvas2);
   1105 
   1106     EXPECT_NE(canvas1, canvas2);
   1107     EXPECT_EQ(1, canvas1->getRefCnt());
   1108     canvas1->unref();
   1109 
   1110     EXPECT_TRUE(dl->isRecording());
   1111 
   1112     // picture() returns 0 during recording
   1113     pic = dl->picture();
   1114     EXPECT_FALSE(pic);
   1115 
   1116     // endRecording finally makes the picture accessible
   1117     dl->endRecording();
   1118     pic = dl->picture();
   1119     EXPECT_TRUE(pic);
   1120     EXPECT_EQ(1, pic->getRefCnt());
   1121 }
   1122 
   1123 } // namespace
   1124