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)#include "build/build_config.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/vector_canvas.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/vector_platform_device_emf_win.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkDashPathEffect.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace skia {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGenerateSwitch[] = "vector-canvas-generate";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lightweight HDC management.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Context {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Context() : context_(CreateCompatibleDC(NULL)) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(context_);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Context() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteDC(context_);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDC context() const { return context_; }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDC context_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Context);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lightweight HBITMAP management.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Bitmap {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Bitmap(const Context& context, int x, int y) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BITMAPINFOHEADER hdr;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biSize = sizeof(BITMAPINFOHEADER);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biWidth = x;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biHeight = -y;  // Minus means top-down bitmap.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biPlanes = 1;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biBitCount = 32;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biCompression = BI_RGB;  // No compression.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biSizeImage = 0;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biXPelsPerMeter = 1;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biYPelsPerMeter = 1;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biClrUsed = 0;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hdr.biClrImportant = 0;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_ = CreateDIBSection(context.context(),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               reinterpret_cast<BITMAPINFO*>(&hdr), 0,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &data_, NULL, 0);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(bitmap_);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(SelectObject(context.context(), bitmap_));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Bitmap() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(DeleteObject(bitmap_));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HBITMAP bitmap_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* data_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Bitmap);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lightweight raw-bitmap management. The image, once initialized, is immuable.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is mainly used for comparison.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Image {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the image from the given filename on disk.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit Image(const base::FilePath& filename) : ignore_alpha_(true) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string compressed;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_util::ReadFileToString(filename, &compressed);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(compressed.size());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap bitmap;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(gfx::PNGCodec::Decode(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<const unsigned char*>(compressed.data()),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        compressed.size(), &bitmap));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSkBitmap(bitmap);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads the image from a canvas.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Image(skia::PlatformCanvas& canvas) : ignore_alpha_(true) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use a different way to access the bitmap. The normal way would be to
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // query the SkBitmap.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HDC context = scoped_platform_paint.GetPlatformSurface();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(bitmap != NULL);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Initialize the clip region to the entire bitmap.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BITMAP bitmap_data;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data), sizeof(BITMAP));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width_ = bitmap_data.bmWidth;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = bitmap_data.bmHeight;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row_length_ = bitmap_data.bmWidthBytes;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size = row_length_ * height_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.resize(size);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&*data_.begin(), bitmap_data.bmBits, size);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads the image from a canvas.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Image(const SkBitmap& bitmap) : ignore_alpha_(true) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetSkBitmap(bitmap);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width() const { return width_; }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height() const { return height_; }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int row_length() const { return row_length_; }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the image to a png file. Used to create the initial test files.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SaveToFile(const base::FilePath& filename) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<unsigned char> compressed;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(gfx::PNGCodec::Encode(&*data_.begin(),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      gfx::PNGCodec::FORMAT_BGRA,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      gfx::Size(width_, height_),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      row_length_,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      true,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::vector<gfx::PNGCodec::Comment>(),
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &compressed));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(compressed.size());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* f = file_util::OpenFile(filename, "wb");
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(f);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              compressed.size());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_util::CloseFile(f);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the percentage of the image that is different from the other,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // between 0 and 100.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double PercentageDifferent(const Image& rhs) const {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (width_ != rhs.width_ ||
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        height_ != rhs.height_ ||
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        row_length_ != rhs.row_length_ ||
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        width_ == 0 ||
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        height_ == 0) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 100.;  // When of different size or empty, they are 100% different.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Compute pixels different in the overlap
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pixels_different = 0;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int y = 0; y < height_; ++y) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int x = 0; x < width_; ++x) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t lhs_pixel = pixel_at(x, y);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t rhs_pixel = rhs.pixel_at(x, y);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (lhs_pixel != rhs_pixel)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++pixels_different;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Like the WebKit ImageDiff tool, we define percentage different in terms
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of the size of the 'actual' bitmap.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double total_pixels = static_cast<double>(width_) *
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          static_cast<double>(height_);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<double>(pixels_different) / total_pixels * 100.;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the 0x0RGB or 0xARGB value of the pixel at the given location,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // depending on ignore_alpha_.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 pixel_at(int x, int y) const {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(x >= 0 && x < width_);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(y >= 0 && y < height_);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint32* data_row = data + y * row_length_ / sizeof(uint32);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ignore_alpha_)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return data_row[x] & 0xFFFFFF;  // Strip out A.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return data_row[x];
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetSkBitmap(const SkBitmap& bitmap) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkAutoLockPixels lock(bitmap);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width_ = bitmap.width();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = bitmap.height();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row_length_ = static_cast<int>(bitmap.rowBytes());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size = row_length_ * height_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_.resize(size);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pixel dimensions of the image.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Length of a line in bytes.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int row_length_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0xABGR).
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> data_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flag to signal if the comparison functions should ignore the alpha channel.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool ignore_alpha_;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Image);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base for tests. Capability to process an image.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageTest : public testing::Test {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In what state is the test running.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ProcessAction {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GENERATE,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPARE,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOOP,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageTest(ProcessAction default_action)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : action_(default_action) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const testing::TestInfo& test_info =
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *testing::UnitTest::GetInstance()->current_test_info();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_dir_ = test_dir_.AppendASCII("skia").
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          AppendASCII("ext").
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          AppendASCII("data").
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          AppendASCII(test_info.test_case_name()).
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          AppendASCII(test_info.name());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Hack for a quick lowercase. We assume all the tests names are ASCII.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath::StringType tmp(test_dir_.value());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < tmp.size(); ++i)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tmp[i] = base::ToLowerASCII(tmp[i]);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_dir_ = base::FilePath(tmp);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (action_ == GENERATE) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Make sure the directory exist.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_util::CreateDirectory(test_dir_);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the fully qualified path of a data file.
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_file(const base::FilePath::StringType& filename) const {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Hack for a quick lowercase. We assume all the test data file names are
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ASCII.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string tmp = WideToASCII(filename);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string tmp(filename);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < tmp.size(); ++i)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tmp[i] = base::ToLowerASCII(tmp[i]);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_dir_.AppendASCII(tmp);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compares or saves the bitmap currently loaded in the context, depending on
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kGenerating value. Returns 0 on success or any positive value between ]0,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 100] on failure. The return value is the percentage of difference between
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the image in the file and the image in the canvas.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double ProcessCanvas(skia::PlatformCanvas& canvas,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       base::FilePath::StringType filename) const {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filename = filename + FILE_PATH_LITERAL(".png");
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (action_) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case GENERATE:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SaveImage(canvas, filename);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0.;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case COMPARE:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return CompareImage(canvas, filename);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case NOOP:
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Invalid state, returns that the image is 100 different.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 100.;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compares the bitmap currently loaded in the context with the file. Returns
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the percentage of pixel difference between both images, between 0 and 100.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double CompareImage(skia::PlatformCanvas& canvas,
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      const base::FilePath::StringType& filename) const {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Image image1(canvas);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Image image2(test_file(filename));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double diff = image1.PercentageDifferent(image2);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return diff;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Saves the bitmap currently loaded in the context into the file.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SaveImage(skia::PlatformCanvas& canvas,
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 const base::FilePath::StringType& filename) const {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Image(canvas).SaveToFile(test_file(filename));
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessAction action_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Path to directory used to contain the test data.
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_dir_;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageTest);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Premultiply the Alpha channel on the R, B and G channels.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Premultiply(SkBitmap bitmap) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock(bitmap);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int x = 0; x < bitmap.width(); ++x) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int y = 0; y < bitmap.height(); ++y) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32_t* pixel_addr = bitmap.getAddr32(x, y);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32_t color = *pixel_addr;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BYTE alpha = SkColorGetA(color);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!alpha) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *pixel_addr = 0;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BYTE alpha_offset = alpha / 2;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *pixel_addr = SkColorSetARGB(
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SkColorGetA(color),
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (SkColorGetR(color) * 255 + alpha_offset) / alpha,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (SkColorGetG(color) * 255 + alpha_offset) / alpha,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (SkColorGetB(color) * 255 + alpha_offset) / alpha);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoadPngFileToSkBitmap(const base::FilePath& filename,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SkBitmap* bitmap,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool is_opaque) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string compressed;
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_util::ReadFileToString(base::MakeAbsoluteFilePath(filename),
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              &compressed);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(compressed.size());
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(gfx::PNGCodec::Decode(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const unsigned char*>(compressed.data()),
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      compressed.size(), bitmap));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(is_opaque, bitmap->isOpaque());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Premultiply(*bitmap);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Streams an image.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& out, const Image& image) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out << "Image(" << image.width() << ", "
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << image.height() << ", " << image.row_length() << ")";
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Runs simultaneously the same drawing commands on VectorCanvas and
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PlatformCanvas and compare the results.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VectorCanvasTest : public ImageTest {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ImageTest parent;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VectorCanvasTest() : parent(CurrentMode()), compare_canvas_(true) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parent::SetUp();
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Init(100);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    number_ = 0;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete pcanvas_;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_ = NULL;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete vcanvas_;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_ = NULL;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete bitmap_;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_ = NULL;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete context_;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_ = NULL;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parent::TearDown();
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(int size) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_ = size;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_ = new Context();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_ = new Bitmap(*context_, size_, size_);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vcanvas_ = new VectorCanvas(
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        VectorPlatformDeviceEmf::CreateDevice(
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            size_, size_, true, context_->context()));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pcanvas_ = CreatePlatformCanvas(size_, size_, false);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear white.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compares both canvas and returns the pixel difference in percentage between
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // both images. 0 on success and ]0, 100] on failure.
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double ProcessImage(const base::FilePath::StringType& filename) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring number(base::StringPrintf(L"%02d_", number_++));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!compare_canvas_)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::max(diff1, diff2);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Image image1(*vcanvas_);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Image image2(*pcanvas_);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double diff = image1.PercentageDifferent(image2);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::max(std::max(diff1, diff2), diff);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns COMPARE, which is the default. If kGenerateSwitch command
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // line argument is used to start this process, GENERATE is returned instead.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProcessAction CurrentMode() {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CommandLine::ForCurrentProcess()->HasSwitch(kGenerateSwitch) ?
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GENERATE : COMPARE;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Length in x and y of the square canvas.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size_;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Current image number in the current test. Used to number of test files.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int number_;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A temporary HDC to draw into.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Context* context_;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bitmap created inside context_.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Bitmap* bitmap_;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vector based canvas.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VectorCanvas* vcanvas_;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pixel based canvas.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformCanvas* pcanvas_;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When true (default), vcanvas_ and pcanvas_ contents are compared and
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // verified to be identical.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool compare_canvas_;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Actual tests
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA)  // http://crbug.com/154358
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, BasicDrawing) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << L"clean";
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clean")));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear white.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawARGB")));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Diagonal line top-left to bottom-right.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Default color is black.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(10, 10, 90, 90, paint);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(10, 10, 90, 90, paint);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_black")));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rect.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorGREEN);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawRectCoords(25, 25, 75, 75, paint);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawRectCoords(25, 25, 75, 75, paint);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_green")));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A single-point rect doesn't leave any mark.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorBLUE);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawRectCoords(5, 5, 5, 5, paint);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawRectCoords(5, 5, 5, 5, paint);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop")));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rect.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorBLUE);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawRectCoords(75, 50, 80, 55, paint);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawRectCoords(75, 50, 80, 55, paint);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop")));
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty again
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPaint(SkPaint());
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPaint(SkPaint());
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPaint_black")));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal line left to right.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(10, 20, 90, 20, paint);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(10, 20, 90, 20, paint);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_left_to_right")));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vertical line downward.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(30, 10, 30, 90, paint);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(30, 10, 30, 90, paint);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_red")));
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, Circles) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is NO WAY to make them agree. At least verify that the output doesn't
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change across versions. This test is disabled. See bug 1060231.
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stroked Circle.
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addCircle(50, 75, 10);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorMAGENTA);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke")));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filled Circle.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addCircle(50, 25, 10);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_fill")));
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stroked Circle over.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addCircle(50, 25, 10);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorBLUE);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_over_strike")));
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stroke and Fill Circle.
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addCircle(12, 50, 10);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStrokeAndFill_Style);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke_and_fill")));
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Line + Quad + Cubic.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorGREEN);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(1, 1);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(60, 40);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(80, 80);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.quadTo(20, 50, 10, 90);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.quadTo(50, 20, 90, 10);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.cubicTo(20, 40, 50, 50, 10, 10);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.cubicTo(30, 20, 50, 50, 90, 10);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addRect(90, 90, 95, 96);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("mixed_stroke")));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, LineOrientation) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is NO WAY to make them agree. At least verify that the output doesn't
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change across versions. This test is disabled. See bug 1060231.
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal lines.
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Left to right.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(10, 20, 90, 20, paint);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(10, 20, 90, 20, paint);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Right to left.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(90, 30, 10, 30, paint);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(90, 30, 10, 30, paint);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal")));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vertical lines.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Top down.
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(20, 10, 20, 90, paint);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(20, 10, 20, 90, paint);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Bottom up.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(30, 90, 30, 10, paint);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(30, 90, 30, 10, paint);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical")));
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try again with a 180 degres rotation.
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->rotate(180);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->rotate(180);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal lines (rotated).
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(-10, -25, -90, -25, paint);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(-10, -25, -90, -25, paint);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(-90, -35, -10, -35, paint);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(-90, -35, -10, -35, paint);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal_180")));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vertical lines (rotated).
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(-25, -10, -25, -90, paint);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(-25, -10, -25, -90, paint);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(-35, -90, -35, -10, paint);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(-35, -90, -35, -10, paint);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical_180")));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, PathOrientation) {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is NO WAY to make them agree. At least verify that the output doesn't
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change across versions. This test is disabled. See bug 1060231.
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal lines.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPoint start;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start.set(10, 20);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPoint end;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end.set(90, 20);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(start);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(end);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_ltr")));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Horizontal lines.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorRED);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPoint start;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start.set(90, 30);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPoint end;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end.set(10, 30);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(start);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(end);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_rtl")));
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, DiagonalLines) {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorRED);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawLine(10, 10, 90, 90, paint);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawLine(10, 10, 90, 90, paint);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("nw-se")));
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starting here, there is NO WAY to make them agree. At least verify that the
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output doesn't change across versions. This test is disabled. See bug
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1060231.
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawLine(10, 95, 90, 15, paint);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawLine(10, 95, 90, 15, paint);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("sw-ne")));
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawLine(90, 10, 10, 90, paint);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawLine(90, 10, 10, 90, paint);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("ne-sw")));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawLine(95, 90, 15, 10, paint);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawLine(95, 90, 15, 10, paint);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("se-nw")));
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_PathEffects DISABLED_PathEffects
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_PathEffects PathEffects
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, MAYBE_PathEffects) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar intervals[] = { 1, 1 };
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkPathEffect> effect = skia::AdoptRef(
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new SkDashPathEffect(intervals, arraysize(intervals), 0));
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setPathEffect(effect.get());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorMAGENTA);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawLine(10, 10, 90, 10, paint);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawLine(10, 10, 90, 10, paint);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_line")));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starting here, there is NO WAY to make them agree. At least verify that the
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output doesn't change across versions. This test is disabled. See bug
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1060231.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar intervals[] = { 3, 5 };
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkPathEffect> effect = skia::AdoptRef(
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new SkDashPathEffect(intervals, arraysize(intervals), 0));
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setPathEffect(effect.get());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorMAGENTA);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(10, 15);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(90, 15);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(90, 90);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_path")));
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar intervals[] = { 2, 1 };
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkPathEffect> effect = skia::AdoptRef(
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new SkDashPathEffect(intervals, arraysize(intervals), 0));
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setPathEffect(effect.get());
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorMAGENTA);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawRectCoords(20, 20, 30, 30, paint);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawRectCoords(20, 20, 30, 30, paint);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_rect")));
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This thing looks like it has been drawn by a 3 years old kid. I haven't
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // filed a bug on this since I guess nobody is expecting this to look nice.
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar intervals[] = { 1, 1 };
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkPathEffect> effect = skia::AdoptRef(
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new SkDashPathEffect(intervals, arraysize(intervals), 0));
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setPathEffect(effect.get());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorMAGENTA);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.addCircle(50, 75, 10);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawPath(path, paint);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawPath(path, paint);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle")));
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, Bitmaps) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap bitmap;
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap, true);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("opaque")));
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkBitmap bitmap;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap, false);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 5, 15, NULL);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 5, 15, NULL);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("alpha")));
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, ClippingRect) {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect rect;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fLeft = 2;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fTop = 2;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fRight = 30.5f;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fBottom = 30.5f;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipRect(rect);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipRect(rect);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rect")));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, ClippingPath) {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.addCircle(20, 20, 10);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipPath(path);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipPath(path);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawBitmap(bitmap, 14, 3, NULL);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawBitmap(bitmap, 14, 3, NULL);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("path")));
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, ClippingCombined) {
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect rect;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fLeft = 2;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fTop = 2;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fRight = 30.5f;
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fBottom = 30.5f;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipRect(rect);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipRect(rect);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.addCircle(20, 20, 10);
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipPath(path, SkRegion::kUnion_Op);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipPath(path, SkRegion::kUnion_Op);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("combined")));
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, ClippingIntersect) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect rect;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fLeft = 2;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fTop = 2;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fRight = 30.5f;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect.fBottom = 30.5f;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipRect(rect);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipRect(rect);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.addCircle(23, 23, 15);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->clipPath(path);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->clipPath(path);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("intersect")));
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, ClippingClean) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkAutoCanvasRestore acrv(vcanvas_, true);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkAutoCanvasRestore acrp(pcanvas_, true);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect rect;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.fLeft = 2;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.fTop = 2;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.fRight = 30.5f;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.fBottom = 30.5f;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->clipRect(rect);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->clipRect(rect);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clipped")));
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the clipping region has been fixed back.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 55, 3, NULL);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 55, 3, NULL);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("unclipped")));
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/26938
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VectorCanvasTest, DISABLED_Matrix) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        true);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->translate(15, 3);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->translate(15, 3);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate1")));
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->translate(-30, -23);
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->translate(-30, -23);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate2")));
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->resetMatrix();
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->resetMatrix();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For scaling and rotation, they use a different algorithm (nearest
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // neighborhood vs smoothing). At least verify that the output doesn't change
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // across versions.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compare_canvas_ = false;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 1, 1, NULL);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 1, 1, NULL);
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("scale")));
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vcanvas_->resetMatrix();
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pcanvas_->resetMatrix();
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->rotate(67);
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->rotate(67);
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vcanvas_->drawBitmap(bitmap, 20, -50, NULL);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pcanvas_->drawBitmap(bitmap, 20, -50, NULL);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rotate")));
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(USE_AURA)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace skia
971