Home | History | Annotate | Download | only in tests
      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 "SkCanvas.h"
     30 #include "platform/graphics/BitmapImage.h"
     31 #include "platform/graphics/DisplayList.h"
     32 #include "platform/graphics/ImageBuffer.h"
     33 #include "platform/graphics/skia/NativeImageSkia.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 uses 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 uses 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 would 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_SkAlphaType);
    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::create(opaqueBitmap));
    534     EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
    535 
    536     SkBitmap alphaBitmap;
    537     alphaBitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0, kPremul_SkAlphaType);
    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_SkAlphaType);
    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_SkAlphaType);
    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_SkAlphaType);
    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_SkAlphaType);
    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_SkAlphaType);
    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_SkAlphaType);
    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), &paint);
    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), &paint);
    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), &paint);
    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), &paint);
    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), &paint);
    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 only 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 the 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 should 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
   1124