15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(awalker): clean up the const/non-const reference handling in this test
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <ApplicationServices/ApplicationServices.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_device.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkPixelRef.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace skia {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return true if the canvas is filled to canvas_color, and contains a single
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rectangle filled to rect_color. This function ignores the alpha channel,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// since Windows will sometimes clear the alpha channel when drawing, and we
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will fix that up later in cases it's necessary.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyRect(const PlatformCanvas& canvas,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                uint32_t canvas_color, uint32_t rect_color,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int x, int y, int w, int h) {
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkBaseDevice* device = skia::GetTopDevice(canvas);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap& bitmap = device->accessBitmap(false);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock(bitmap);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For masking out the alpha values.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t alpha_mask = 0xFF << SK_A32_SHIFT;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int cur_y = 0; cur_y < bitmap.height(); cur_y++) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int cur_x = 0; cur_x < bitmap.width(); cur_x++) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (cur_x >= x && cur_x < x + w &&
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cur_y >= y && cur_y < y + h) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Inside the square should be rect_color
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((*bitmap.getAddr32(cur_x, cur_y) | alpha_mask) !=
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (rect_color | alpha_mask))
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Outside the square should be canvas_color
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((*bitmap.getAddr32(cur_x, cur_y) | alpha_mask) !=
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (canvas_color | alpha_mask))
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsOfColor(const SkBitmap& bitmap, int x, int y, uint32_t color) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For masking out the alpha values.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static uint32_t alpha_mask = 0xFF << SK_A32_SHIFT;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (*bitmap.getAddr32(x, y) | alpha_mask) == (color | alpha_mask);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return true if canvas has something that passes for a rounded-corner
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rectangle. Basically, we're just checking to make sure that the pixels in the
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// middle are of rect_color and pixels in the corners are of canvas_color.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyRoundedRect(const PlatformCanvas& canvas,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       uint32_t canvas_color, uint32_t rect_color,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int x, int y, int w, int h) {
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SkBaseDevice* device = skia::GetTopDevice(canvas);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap& bitmap = device->accessBitmap(false);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock(bitmap);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check corner points first. They should be of canvas_color.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x, y, canvas_color)) return false;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x + w, y, canvas_color)) return false;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x, y + h, canvas_color)) return false;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x + w, y, canvas_color)) return false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check middle points. They should be of rect_color.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, (x + w / 2), y, rect_color)) return false;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x, (y + h / 2), rect_color)) return false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, x + w, (y + h / 2), rect_color)) return false;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOfColor(bitmap, (x + w / 2), y + h, rect_color)) return false;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks whether there is a white canvas with a black square at the given
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// location in pixels (not in the canvas coordinate system).
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyBlackRect(const PlatformCanvas& canvas, int x, int y, int w, int h) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VerifyRect(canvas, SK_ColorWHITE, SK_ColorBLACK, x, y, w, h);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that every pixel in the canvas is a single color.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyCanvasColor(const PlatformCanvas& canvas, uint32_t canvas_color) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VerifyRect(canvas, canvas_color, 0, 0, 0, 0, 0);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDC dc = scoped_platform_paint.GetPlatformSurface();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RECT inner_rc;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_rc.left = x;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_rc.top = y;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_rc.right = x + w;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_rc.bottom = y + h;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillRect(dc, &inner_rc, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGContextRef context = scoped_platform_paint.GetPlatformSurface();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGRect inner_rc = CGRectMake(x, y, w, h);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RGBA opaque black
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGColorRef black = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGContextSetFillColorWithColor(context, black);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGColorRelease(black);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGContextFillRect(context, inner_rc);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DrawNativeRect(PlatformCanvas& canvas, int x, int y, int w, int h) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notImplemented();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Clips the contents of the canvas to the given rectangle. This will be
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// intersected with any existing clip.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddClip(PlatformCanvas& canvas, int x, int y, int w, int h) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect rect;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.set(SkIntToScalar(x), SkIntToScalar(y),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           SkIntToScalar(x + w), SkIntToScalar(y + h));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas.clipRect(rect);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LayerSaver {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerSaver(PlatformCanvas& canvas, int x, int y, int w, int h)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : canvas_(canvas),
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        x_(x),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        y_(y),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        w_(w),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        h_(h) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect bounds;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set(SkIntToScalar(x_), SkIntToScalar(y_),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SkIntToScalar(right()), SkIntToScalar(bottom()));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas_.saveLayer(&bounds, NULL);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas.clear(SkColorSetARGB(0, 0, 0, 0));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LayerSaver() {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas_.restore();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x() const { return x_; }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y() const { return y_; }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int w() const { return w_; }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int h() const { return h_; }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the EXCLUSIVE far bounds of the layer.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int right() const { return x_ + w_; }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bottom() const { return y_ + h_; }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformCanvas& canvas_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x_, y_, w_, h_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size used for making layers in many of the below tests.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLayerX = 2;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLayerY = 3;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLayerW = 9;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLayerH = 7;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size used by some tests to draw a rectangle inside the layer.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInnerX = 4;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInnerY = 5;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInnerW = 2;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInnerH = 3;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This just checks that our checking code is working properly, it just uses
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regular skia primitives.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformCanvas, SkLayer) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the canvas initialized to opaque white.
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a layer and fill it completely to make sure that the bounds are
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correct.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->drawColor(SK_ColorBLACK);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kLayerX, kLayerY, kLayerW, kLayerH));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA)  // http://crbug.com/154358
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test native clipping.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformCanvas, ClipRegion) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize a white canvas
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyCanvasColor(*canvas, SK_ColorWHITE));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that initially the canvas has no clip region, by filling it
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with a black rectangle.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: Don't use LayerSaver, since internally it sets a clip region.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DrawNativeRect(*canvas, 0, 0, 16, 16);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyCanvasColor(*canvas, SK_ColorBLACK));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that intersecting disjoint clip rectangles sets an empty clip region
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyCanvasColor(*canvas, SK_ColorWHITE));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, 0, 0, 16, 16);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddClip(*canvas, 2, 3, 4, 5);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddClip(*canvas, 4, 9, 10, 10);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 16, 16);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyCanvasColor(*canvas, SK_ColorWHITE));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(USE_AURA)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the layers get filled properly by native rendering.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformCanvas, FillLayer) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the canvas initialized to opaque white.
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a layer and fill it completely to make sure that the bounds are
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correct.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), 0, 0, 100, 100);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kLayerX, kLayerY, kLayerW, kLayerH));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a layer and fill it partially to make sure the translation is correct.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kInnerX, kInnerY, kInnerW, kInnerH);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a clip on the layer and fill to make sure clip is correct.
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->save();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddClip(*canvas, kInnerX, kInnerY, kInnerW, kInnerH);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kInnerX, kInnerY, kInnerW, kInnerH);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->restore();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a clip and then make the layer to make sure the clip is correct.
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddClip(*canvas, kInnerX, kInnerY, kInnerW, kInnerH);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), 0, 0, 100, 100);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA)  // http://crbug.com/154358
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that translation + make layer works properly.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PlatformCanvas, TranslateLayer) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the canvas initialized to opaque white.
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a layer and fill it completely to make sure that the bounds are
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correct.
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->translate(1, 1);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), 0, 0, 100, 100);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kLayerX + 1, kLayerY + 1,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kLayerW, kLayerH));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Translate then make the layer.
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->translate(1, 1);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kInnerX, kInnerY, kInnerW, kInnerH);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX + 1, kInnerY + 1,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kInnerW, kInnerH));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the layer then translate.
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->translate(1, 1);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, kInnerX, kInnerY, kInnerW, kInnerH);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kInnerX, kInnerY, kInnerW, kInnerH);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX + 1, kInnerY + 1,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kInnerW, kInnerH));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Translate both before and after, and have a clip.
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->translate(1, 1);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->drawColor(SK_ColorWHITE);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->translate(1, 1);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddClip(*canvas, kInnerX + 1, kInnerY + 1, kInnerW - 1, kInnerH - 1);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kLayerX, kLayerY, kLayerW, kLayerH);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyBlackRect(*canvas, kInnerX + 3, kInnerY + 3,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kInnerW - 1, kInnerH - 1));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(dglazkov): Figure out why this fails on Mac (antialiased clipping?),
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modify test and remove this guard.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Translate both before and after, and have a path clip.
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->drawColor(SK_ColorWHITE);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->save();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->translate(1, 1);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerSaver layer(*canvas, kLayerX, kLayerY, kLayerW, kLayerH);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->drawColor(SK_ColorWHITE);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->translate(1, 1);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect rect;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.iset(kInnerX - 1, kInnerY - 1,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              kInnerX + kInnerW, kInnerY + kInnerH);
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const SkScalar kRadius = 2.0;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addRoundRect(rect, kRadius, kRadius);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canvas->clipPath(path);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DrawNativeRect(*canvas, 0, 0, 100, 100);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MakeOpaque(canvas.get(), kLayerX, kLayerY, kLayerW, kLayerH);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->restore();
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(VerifyRoundedRect(*canvas, SK_ColorWHITE, SK_ColorBLACK,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                kInnerX + 1, kInnerY + 1, kInnerW, kInnerH));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // #if !defined(USE_AURA)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(PlatformBitmapTest, PlatformBitmap) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kWidth = 400;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kHeight = 300;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<PlatformBitmap> platform_bitmap(new PlatformBitmap);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(0 == platform_bitmap->GetSurface());
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(platform_bitmap->GetBitmap().empty());
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(platform_bitmap->GetBitmap().isNull());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(platform_bitmap->Allocate(kWidth, kHeight, /*is_opaque=*/false));
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(0 != platform_bitmap->GetSurface());
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(platform_bitmap->GetBitmap().empty());
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(platform_bitmap->GetBitmap().isNull());
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kWidth, platform_bitmap->GetBitmap().width());
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kHeight, platform_bitmap->GetBitmap().height());
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(static_cast<size_t>(platform_bitmap->GetBitmap().width()*4),
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            platform_bitmap->GetBitmap().rowBytes());
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SkBitmap::kARGB_8888_Config,  // Same for all platforms.
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            platform_bitmap->GetBitmap().config());
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(platform_bitmap->GetBitmap().lockPixelsAreWritable());
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(platform_bitmap->GetBitmap().pixelRef()->isLocked());
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, platform_bitmap->GetBitmap().pixelRef()->getRefCnt());
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *(platform_bitmap->GetBitmap().getAddr32(10, 20)) = 0xDEED1020;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *(platform_bitmap->GetBitmap().getAddr32(20, 30)) = 0xDEED2030;
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap sk_bitmap = platform_bitmap->GetBitmap();
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sk_bitmap.lockPixels();
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, platform_bitmap->GetBitmap().pixelRef()->getRefCnt());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, sk_bitmap.pixelRef()->getRefCnt());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED1020, *sk_bitmap.getAddr32(10, 20));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED2030, *sk_bitmap.getAddr32(20, 30));
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *(platform_bitmap->GetBitmap().getAddr32(30, 40)) = 0xDEED3040;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The SkBitmaps derived from a PlatformBitmap must be capable of outliving
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the PlatformBitmap.
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  platform_bitmap.reset();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, sk_bitmap.pixelRef()->getRefCnt());
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED1020, *sk_bitmap.getAddr32(10, 20));
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED2030, *sk_bitmap.getAddr32(20, 30));
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED3040, *sk_bitmap.getAddr32(30, 40));
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sk_bitmap.unlockPixels();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(NULL, sk_bitmap.getPixels());
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sk_bitmap.lockPixels();
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED1020, *sk_bitmap.getAddr32(10, 20));
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED2030, *sk_bitmap.getAddr32(20, 30));
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0xDEED3040, *sk_bitmap.getAddr32(30, 40));
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sk_bitmap.unlockPixels();
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace skia
458