Index: base/gfx/vector_canvas_unittest.cc |
=================================================================== |
--- base/gfx/vector_canvas_unittest.cc (revision 5678) |
+++ base/gfx/vector_canvas_unittest.cc (working copy) |
@@ -1,1008 +0,0 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "base/gfx/vector_canvas.h" |
- |
-#include <vector> |
- |
-#include "base/command_line.h" |
-#include "base/file_util.h" |
-#include "base/gfx/gdi_util.h" |
-#include "base/gfx/png_decoder.h" |
-#include "base/gfx/png_encoder.h" |
-#include "base/gfx/size.h" |
-#include "base/path_service.h" |
-#include "base/string_util.h" |
-#include "base/win_util.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-#include "SkDashPathEffect.h" |
- |
-namespace { |
- |
-const wchar_t* const kGenerateSwitch = L"vector-canvas-generate"; |
- |
-// Base class for unit test that uses data. It initializes a directory path |
-// based on the test's name. |
-class DataUnitTest : public testing::Test { |
- public: |
- DataUnitTest(const std::wstring& base_path) : base_path_(base_path) { } |
- |
- protected: |
- // Load the test's data path. |
- virtual void SetUp() { |
- const testing::TestInfo& test_info = |
- *testing::UnitTest::GetInstance()->current_test_info(); |
- PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_); |
- file_util::AppendToPath(&test_dir_, base_path_); |
- file_util::AppendToPath(&test_dir_, L"data"); |
- file_util::AppendToPath(&test_dir_, |
- ASCIIToWide(test_info.test_case_name())); |
- file_util::AppendToPath(&test_dir_, ASCIIToWide(test_info.name())); |
- |
- // Hack for a quick lowercase. We assume all the tests names are ASCII. |
- std::string tmp(WideToASCII(test_dir_)); |
- for (size_t i = 0; i < tmp.size(); ++i) |
- tmp[i] = ToLowerASCII(tmp[i]); |
- test_dir_ = ASCIIToWide(tmp); |
- } |
- |
- // Returns the fully qualified path of directory containing test data files. |
- const std::wstring& test_dir() const { |
- return test_dir_; |
- } |
- |
- // Returns the fully qualified path of a data file. |
- std::wstring test_file(const std::wstring& filename) const { |
- // Hack for a quick lowercase. We assume all the test data file names are |
- // ASCII. |
- std::string tmp(WideToASCII(filename)); |
- for (size_t i = 0; i < tmp.size(); ++i) |
- tmp[i] = ToLowerASCII(tmp[i]); |
- |
- std::wstring path(test_dir()); |
- file_util::AppendToPath(&path, ASCIIToWide(tmp)); |
- return path; |
- } |
- |
- private: |
- // Path where the unit test is coming from: base, net, chrome, etc. |
- std::wstring base_path_; |
- |
- // Path to directory used to contain the test data. |
- std::wstring test_dir_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(DataUnitTest); |
-}; |
- |
-// Lightweight HDC management. |
-class Context { |
- public: |
- Context() : context_(CreateCompatibleDC(NULL)) { |
- EXPECT_TRUE(context_); |
- } |
- ~Context() { |
- DeleteDC(context_); |
- } |
- |
- HDC context() const { return context_; } |
- |
- private: |
- HDC context_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(Context); |
-}; |
- |
-// Lightweight HBITMAP management. |
-class Bitmap { |
- public: |
- Bitmap(const Context& context, int x, int y) { |
- BITMAPINFOHEADER hdr; |
- gfx::CreateBitmapHeader(x, y, &hdr); |
- bitmap_ = CreateDIBSection(context.context(), |
- reinterpret_cast<BITMAPINFO*>(&hdr), 0, |
- &data_, NULL, 0); |
- EXPECT_TRUE(bitmap_); |
- EXPECT_TRUE(SelectObject(context.context(), bitmap_)); |
- } |
- ~Bitmap() { |
- EXPECT_TRUE(DeleteObject(bitmap_)); |
- } |
- |
- private: |
- HBITMAP bitmap_; |
- |
- void* data_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(Bitmap); |
-}; |
- |
-// Lightweight raw-bitmap management. The image, once initialized, is immuable. |
-// It is mainly used for comparison. |
-class Image { |
- public: |
- // Creates the image from the given filename on disk. |
- Image(const std::wstring& filename) : ignore_alpha_(true) { |
- std::string compressed; |
- file_util::ReadFileToString(filename, &compressed); |
- EXPECT_TRUE(compressed.size()); |
- |
- int w; |
- int h; |
- EXPECT_TRUE(PNGDecoder::Decode( |
- reinterpret_cast<const unsigned char*>(compressed.c_str()), |
- compressed.size(), PNGDecoder::FORMAT_BGRA, &data_, &w, &h)); |
- size_.SetSize(w, h); |
- row_length_ = w * sizeof(uint32); |
- } |
- |
- // Loads the image from a canvas. |
- Image(const gfx::PlatformCanvasWin& canvas) : ignore_alpha_(true) { |
- // Use a different way to access the bitmap. The normal way would be to |
- // query the SkBitmap. |
- HDC context = canvas.getTopPlatformDevice().getBitmapDC(); |
- HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP); |
- EXPECT_TRUE(bitmap != NULL); |
- // Initialize the clip region to the entire bitmap. |
- BITMAP bitmap_data; |
- EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data), |
- sizeof(BITMAP)); |
- size_.SetSize(bitmap_data.bmWidth, bitmap_data.bmHeight); |
- row_length_ = bitmap_data.bmWidthBytes; |
- size_t size = row_length_ * size_.height(); |
- data_.resize(size); |
- memcpy(&*data_.begin(), bitmap_data.bmBits, size); |
- } |
- |
- // Loads the image from a canvas. |
- Image(const SkBitmap& bitmap) : ignore_alpha_(true) { |
- SkAutoLockPixels lock(bitmap); |
- size_.SetSize(bitmap.width(), bitmap.height()); |
- row_length_ = static_cast<int>(bitmap.rowBytes()); |
- size_t size = row_length_ * size_.height(); |
- data_.resize(size); |
- memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size); |
- } |
- |
- const gfx::Size& size() const { |
- return size_; |
- } |
- |
- int row_length() const { |
- return row_length_; |
- } |
- |
- // Save the image to a png file. Used to create the initial test files. |
- void SaveToFile(const std::wstring& filename) { |
- std::vector<unsigned char> compressed; |
- ASSERT_TRUE(PNGEncoder::Encode(&*data_.begin(), |
- PNGEncoder::FORMAT_BGRA, |
- size_.width(), |
- size_.height(), |
- row_length_, |
- true, |
- &compressed)); |
- ASSERT_TRUE(compressed.size()); |
- FILE* f = file_util::OpenFile(filename, "wb"); |
- ASSERT_TRUE(f); |
- ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f), |
- compressed.size()); |
- file_util::CloseFile(f); |
- } |
- |
- // Returns the percentage of the image that is different from the other, |
- // between 0 and 100. |
- double PercentageDifferent(const Image& rhs) const { |
- if (size_ != rhs.size_ || row_length_ != rhs.row_length_ || |
- size_.width() == 0 || size_.height() == 0) |
- return 100.; // When of different size or empty, they are 100% different. |
- |
- // Compute pixels different in the overlap |
- int pixels_different = 0; |
- for (int y = 0; y < size_.height(); ++y) { |
- for (int x = 0; x < size_.width(); ++x) { |
- uint32_t lhs_pixel = pixel_at(x, y); |
- uint32_t rhs_pixel = rhs.pixel_at(x, y); |
- if (lhs_pixel != rhs_pixel) |
- ++pixels_different; |
- } |
- } |
- |
- // Like the WebKit ImageDiff tool, we define percentage different in terms |
- // of the size of the 'actual' bitmap. |
- double total_pixels = static_cast<double>(size_.width()) * |
- static_cast<double>(size_.height()); |
- return static_cast<double>(pixels_different) / total_pixels * 100.; |
- } |
- |
- // Returns the 0x0RGB or 0xARGB value of the pixel at the given location, |
- // depending on ignore_alpha_. |
- uint32 pixel_at(int x, int y) const { |
- EXPECT_TRUE(x >= 0 && x < size_.width()); |
- EXPECT_TRUE(y >= 0 && y < size_.height()); |
- const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin()); |
- const uint32* data_row = data + y * row_length_ / sizeof(uint32); |
- if (ignore_alpha_) |
- return data_row[x] & 0xFFFFFF; // Strip out A. |
- else |
- return data_row[x]; |
- } |
- |
- private: |
- // Pixel dimensions of the image. |
- gfx::Size size_; |
- |
- // Length of a line in bytes. |
- int row_length_; |
- |
- // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's |
- // 0xABGR). |
- std::vector<unsigned char> data_; |
- |
- // Flag to signal if the comparison functions should ignore the alpha channel. |
- const bool ignore_alpha_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(Image); |
-}; |
- |
-// Base for tests. Capability to process an image. |
-class ImageTest : public DataUnitTest { |
- public: |
- typedef DataUnitTest parent; |
- |
- // In what state is the test running. |
- enum ProcessAction { |
- GENERATE, |
- COMPARE, |
- NOOP, |
- }; |
- |
- ImageTest(const std::wstring& base_path, ProcessAction default_action) |
- : parent(base_path), |
- action_(default_action) { |
- } |
- |
- protected: |
- virtual void SetUp() { |
- parent::SetUp(); |
- |
- if (action_ == GENERATE) { |
- // Make sure the directory exist. |
- file_util::CreateDirectory(test_dir()); |
- } |
- } |
- |
- // Compares or saves the bitmap currently loaded in the context, depending on |
- // kGenerating value. Returns 0 on success or any positive value between ]0, |
- // 100] on failure. The return value is the percentage of difference between |
- // the image in the file and the image in the canvas. |
- double ProcessCanvas(const gfx::PlatformCanvasWin& canvas, |
- std::wstring filename) const { |
- filename += L".png"; |
- switch (action_) { |
- case GENERATE: |
- SaveImage(canvas, filename); |
- return 0.; |
- case COMPARE: |
- return CompareImage(canvas, filename); |
- case NOOP: |
- return 0; |
- default: |
- // Invalid state, returns that the image is 100 different. |
- return 100.; |
- } |
- } |
- |
- // Compares the bitmap currently loaded in the context with the file. Returns |
- // the percentage of pixel difference between both images, between 0 and 100. |
- double CompareImage(const gfx::PlatformCanvasWin& canvas, |
- const std::wstring& filename) const { |
- Image image1(canvas); |
- Image image2(test_file(filename)); |
- double diff = image1.PercentageDifferent(image2); |
- return diff; |
- } |
- |
- // Saves the bitmap currently loaded in the context into the file. |
- void SaveImage(const gfx::PlatformCanvasWin& canvas, |
- const std::wstring& filename) const { |
- Image(canvas).SaveToFile(test_file(filename)); |
- } |
- |
- ProcessAction action_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(ImageTest); |
-}; |
- |
-// Premultiply the Alpha channel on the R, B and G channels. |
-void Premultiply(SkBitmap bitmap) { |
- SkAutoLockPixels lock(bitmap); |
- for (int x = 0; x < bitmap.width(); ++x) { |
- for (int y = 0; y < bitmap.height(); ++y) { |
- uint32_t* pixel_addr = bitmap.getAddr32(x, y); |
- uint32_t color = *pixel_addr; |
- BYTE alpha = SkColorGetA(color); |
- if (!alpha) { |
- *pixel_addr = 0; |
- } else { |
- BYTE alpha_offset = alpha / 2; |
- *pixel_addr = SkColorSetARGB( |
- SkColorGetA(color), |
- (SkColorGetR(color) * 255 + alpha_offset) / alpha, |
- (SkColorGetG(color) * 255 + alpha_offset) / alpha, |
- (SkColorGetB(color) * 255 + alpha_offset) / alpha); |
- } |
- } |
- } |
-} |
- |
-void LoadPngFileToSkBitmap(const std::wstring& file, SkBitmap* bitmap) { |
- std::string compressed; |
- file_util::ReadFileToString(file, &compressed); |
- EXPECT_TRUE(compressed.size()); |
- // Extra-lame. If you care, fix it. |
- std::vector<unsigned char> data; |
- data.assign(reinterpret_cast<const unsigned char*>(compressed.c_str()), |
- reinterpret_cast<const unsigned char*>(compressed.c_str() + |
- compressed.size())); |
- EXPECT_TRUE(PNGDecoder::Decode(&data, bitmap)); |
- EXPECT_FALSE(bitmap->isOpaque()); |
- Premultiply(*bitmap); |
-} |
- |
-} // namespace |
- |
-// Streams an image. |
-inline std::ostream& operator<<(std::ostream& out, const Image& image) { |
- return out << "Image(" << image.size() << ", " << image.row_length() << ")"; |
-} |
- |
-// Runs simultaneously the same drawing commands on VectorCanvas and |
-// PlatformCanvas and compare the results. |
-class VectorCanvasTest : public ImageTest { |
- public: |
- typedef ImageTest parent; |
- |
- VectorCanvasTest() : parent(L"base", CurrentMode()), compare_canvas_(true) { |
- } |
- |
- protected: |
- virtual void SetUp() { |
- parent::SetUp(); |
- Init(100); |
- number_ = 0; |
- } |
- |
- virtual void TearDown() { |
- delete pcanvas_; |
- pcanvas_ = NULL; |
- |
- delete vcanvas_; |
- vcanvas_ = NULL; |
- |
- delete bitmap_; |
- bitmap_ = NULL; |
- |
- delete context_; |
- context_ = NULL; |
- |
- parent::TearDown(); |
- } |
- |
- void Init(int size) { |
- size_ = size; |
- context_ = new Context(); |
- bitmap_ = new Bitmap(*context_, size_, size_); |
- vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_); |
- pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false); |
- |
- // Clear white. |
- vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode); |
- pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode); |
- } |
- |
- // Compares both canvas and returns the pixel difference in percentage between |
- // both images. 0 on success and ]0, 100] on failure. |
- double ProcessImage(const std::wstring& filename) { |
- std::wstring number(StringPrintf(L"%02d_", number_++)); |
- double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename); |
- double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename); |
- if (!compare_canvas_) |
- return std::max(diff1, diff2); |
- |
- Image image1(*vcanvas_); |
- Image image2(*pcanvas_); |
- double diff = image1.PercentageDifferent(image2); |
- return std::max(std::max(diff1, diff2), diff); |
- } |
- |
- // Returns COMPARE, which is the default. If kGenerateSwitch command |
- // line argument is used to start this process, GENERATE is returned instead. |
- static ProcessAction CurrentMode() { |
- return CommandLine().HasSwitch(kGenerateSwitch) ? GENERATE : COMPARE; |
- } |
- |
- // Length in x and y of the square canvas. |
- int size_; |
- |
- // Current image number in the current test. Used to number of test files. |
- int number_; |
- |
- // A temporary HDC to draw into. |
- Context* context_; |
- |
- // Bitmap created inside context_. |
- Bitmap* bitmap_; |
- |
- // Vector based canvas. |
- gfx::VectorCanvas* vcanvas_; |
- |
- // Pixel based canvas. |
- gfx::PlatformCanvasWin* pcanvas_; |
- |
- // When true (default), vcanvas_ and pcanvas_ contents are compared and |
- // verified to be identical. |
- bool compare_canvas_; |
-}; |
- |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// Actual tests |
- |
-TEST_F(VectorCanvasTest, Uninitialized) { |
- // Do a little mubadumba do get uninitialized stuff. |
- VectorCanvasTest::TearDown(); |
- |
- // The goal is not to verify that have the same uninitialized data. |
- compare_canvas_ = false; |
- |
- context_ = new Context(); |
- bitmap_ = new Bitmap(*context_, size_, size_); |
- vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_); |
- pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false); |
- |
- // VectorCanvas default initialization is black. |
- // PlatformCanvas default initialization is almost white 0x01FFFEFD (invalid |
- // Skia color) in both Debug and Release. See magicTransparencyColor in |
- // platform_device.cc |
- EXPECT_EQ(0., ProcessImage(L"empty")); |
-} |
- |
-TEST_F(VectorCanvasTest, BasicDrawing) { |
- EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.) |
- << L"clean"; |
- EXPECT_EQ(0., ProcessImage(L"clean")); |
- |
- // Clear white. |
- { |
- vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode); |
- pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawARGB")); |
- |
- // Diagonal line top-left to bottom-right. |
- { |
- SkPaint paint; |
- // Default color is black. |
- vcanvas_->drawLine(10, 10, 90, 90, paint); |
- pcanvas_->drawLine(10, 10, 90, 90, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawLine_black")); |
- |
- // Rect. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorGREEN); |
- vcanvas_->drawRectCoords(25, 25, 75, 75, paint); |
- pcanvas_->drawRectCoords(25, 25, 75, 75, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawRect_green")); |
- |
- // A single-point rect doesn't leave any mark. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorBLUE); |
- vcanvas_->drawRectCoords(5, 5, 5, 5, paint); |
- pcanvas_->drawRectCoords(5, 5, 5, 5, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawRect_noop")); |
- |
- // Rect. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorBLUE); |
- vcanvas_->drawRectCoords(75, 50, 80, 55, paint); |
- pcanvas_->drawRectCoords(75, 50, 80, 55, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawRect_noop")); |
- |
- // Empty again |
- { |
- vcanvas_->drawPaint(SkPaint()); |
- pcanvas_->drawPaint(SkPaint()); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawPaint_black")); |
- |
- // Horizontal line left to right. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- vcanvas_->drawLine(10, 20, 90, 20, paint); |
- pcanvas_->drawLine(10, 20, 90, 20, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawLine_left_to_right")); |
- |
- // Vertical line downward. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- vcanvas_->drawLine(30, 10, 30, 90, paint); |
- pcanvas_->drawLine(30, 10, 30, 90, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawLine_red")); |
-} |
- |
-TEST_F(VectorCanvasTest, Circles) { |
- // There is NO WAY to make them agree. At least verify that the output doesn't |
- // change across versions. This test is disabled. See bug 1060231. |
- compare_canvas_ = false; |
- |
- // Stroked Circle. |
- { |
- SkPaint paint; |
- SkPath path; |
- path.addCircle(50, 75, 10); |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(SK_ColorMAGENTA); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"circle_stroke")); |
- |
- // Filled Circle. |
- { |
- SkPaint paint; |
- SkPath path; |
- path.addCircle(50, 25, 10); |
- paint.setStyle(SkPaint::kFill_Style); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"circle_fill")); |
- |
- // Stroked Circle over. |
- { |
- SkPaint paint; |
- SkPath path; |
- path.addCircle(50, 25, 10); |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(SK_ColorBLUE); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"circle_over_strike")); |
- |
- // Stroke and Fill Circle. |
- { |
- SkPaint paint; |
- SkPath path; |
- path.addCircle(12, 50, 10); |
- paint.setStyle(SkPaint::kStrokeAndFill_Style); |
- paint.setColor(SK_ColorRED); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"circle_stroke_and_fill")); |
- |
- // Line + Quad + Cubic. |
- { |
- SkPaint paint; |
- SkPath path; |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(SK_ColorGREEN); |
- path.moveTo(1, 1); |
- path.lineTo(60, 40); |
- path.lineTo(80, 80); |
- path.quadTo(20, 50, 10, 90); |
- path.quadTo(50, 20, 90, 10); |
- path.cubicTo(20, 40, 50, 50, 10, 10); |
- path.cubicTo(30, 20, 50, 50, 90, 10); |
- path.addRect(90, 90, 95, 96); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"mixed_stroke")); |
-} |
- |
-TEST_F(VectorCanvasTest, LineOrientation) { |
- // There is NO WAY to make them agree. At least verify that the output doesn't |
- // change across versions. This test is disabled. See bug 1060231. |
- compare_canvas_ = false; |
- |
- // Horizontal lines. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- // Left to right. |
- vcanvas_->drawLine(10, 20, 90, 20, paint); |
- pcanvas_->drawLine(10, 20, 90, 20, paint); |
- // Right to left. |
- vcanvas_->drawLine(90, 30, 10, 30, paint); |
- pcanvas_->drawLine(90, 30, 10, 30, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"horizontal")); |
- |
- // Vertical lines. |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- // Top down. |
- vcanvas_->drawLine(20, 10, 20, 90, paint); |
- pcanvas_->drawLine(20, 10, 20, 90, paint); |
- // Bottom up. |
- vcanvas_->drawLine(30, 90, 30, 10, paint); |
- pcanvas_->drawLine(30, 90, 30, 10, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"vertical")); |
- |
- // Try again with a 180 degres rotation. |
- vcanvas_->rotate(180); |
- pcanvas_->rotate(180); |
- |
- // Horizontal lines (rotated). |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- vcanvas_->drawLine(-10, -25, -90, -25, paint); |
- pcanvas_->drawLine(-10, -25, -90, -25, paint); |
- vcanvas_->drawLine(-90, -35, -10, -35, paint); |
- pcanvas_->drawLine(-90, -35, -10, -35, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"horizontal_180")); |
- |
- // Vertical lines (rotated). |
- { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- vcanvas_->drawLine(-25, -10, -25, -90, paint); |
- pcanvas_->drawLine(-25, -10, -25, -90, paint); |
- vcanvas_->drawLine(-35, -90, -35, -10, paint); |
- pcanvas_->drawLine(-35, -90, -35, -10, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"vertical_180")); |
-} |
- |
-TEST_F(VectorCanvasTest, PathOrientation) { |
- // There is NO WAY to make them agree. At least verify that the output doesn't |
- // change across versions. This test is disabled. See bug 1060231. |
- compare_canvas_ = false; |
- |
- // Horizontal lines. |
- { |
- SkPaint paint; |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(SK_ColorRED); |
- SkPath path; |
- SkPoint start; |
- start.set(10, 20); |
- SkPoint end; |
- end.set(90, 20); |
- path.moveTo(start); |
- path.lineTo(end); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawPath_ltr")); |
- |
- // Horizontal lines. |
- { |
- SkPaint paint; |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(SK_ColorRED); |
- SkPath path; |
- SkPoint start; |
- start.set(90, 30); |
- SkPoint end; |
- end.set(10, 30); |
- path.moveTo(start); |
- path.lineTo(end); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"drawPath_rtl")); |
-} |
- |
-TEST_F(VectorCanvasTest, DiagonalLines) { |
- SkPaint paint; |
- paint.setColor(SK_ColorRED); |
- |
- vcanvas_->drawLine(10, 10, 90, 90, paint); |
- pcanvas_->drawLine(10, 10, 90, 90, paint); |
- EXPECT_EQ(0., ProcessImage(L"nw-se")); |
- |
- // Starting here, there is NO WAY to make them agree. At least verify that the |
- // output doesn't change across versions. This test is disabled. See bug |
- // 1060231. |
- compare_canvas_ = false; |
- |
- vcanvas_->drawLine(10, 95, 90, 15, paint); |
- pcanvas_->drawLine(10, 95, 90, 15, paint); |
- EXPECT_EQ(0., ProcessImage(L"sw-ne")); |
- |
- vcanvas_->drawLine(90, 10, 10, 90, paint); |
- pcanvas_->drawLine(90, 10, 10, 90, paint); |
- EXPECT_EQ(0., ProcessImage(L"ne-sw")); |
- |
- vcanvas_->drawLine(95, 90, 15, 10, paint); |
- pcanvas_->drawLine(95, 90, 15, 10, paint); |
- EXPECT_EQ(0., ProcessImage(L"se-nw")); |
-} |
- |
-TEST_F(VectorCanvasTest, PathEffects) { |
- { |
- SkPaint paint; |
- SkScalar intervals[] = { 1, 1 }; |
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals), |
- 0); |
- paint.setPathEffect(effect)->unref(); |
- paint.setColor(SK_ColorMAGENTA); |
- paint.setStyle(SkPaint::kStroke_Style); |
- |
- vcanvas_->drawLine(10, 10, 90, 10, paint); |
- pcanvas_->drawLine(10, 10, 90, 10, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"dash_line")); |
- |
- |
- // Starting here, there is NO WAY to make them agree. At least verify that the |
- // output doesn't change across versions. This test is disabled. See bug |
- // 1060231. |
- compare_canvas_ = false; |
- |
- { |
- SkPaint paint; |
- SkScalar intervals[] = { 3, 5 }; |
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals), |
- 0); |
- paint.setPathEffect(effect)->unref(); |
- paint.setColor(SK_ColorMAGENTA); |
- paint.setStyle(SkPaint::kStroke_Style); |
- |
- SkPath path; |
- path.moveTo(10, 15); |
- path.lineTo(90, 15); |
- path.lineTo(90, 90); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"dash_path")); |
- |
- { |
- SkPaint paint; |
- SkScalar intervals[] = { 2, 1 }; |
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals), |
- 0); |
- paint.setPathEffect(effect)->unref(); |
- paint.setColor(SK_ColorMAGENTA); |
- paint.setStyle(SkPaint::kStroke_Style); |
- |
- vcanvas_->drawRectCoords(20, 20, 30, 30, paint); |
- pcanvas_->drawRectCoords(20, 20, 30, 30, paint); |
- } |
- EXPECT_EQ(0., ProcessImage(L"dash_rect")); |
- |
- // This thing looks like it has been drawn by a 3 years old kid. I haven't |
- // filed a bug on this since I guess nobody is expecting this to look nice. |
- { |
- SkPaint paint; |
- SkScalar intervals[] = { 1, 1 }; |
- SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals), |
- 0); |
- paint.setPathEffect(effect)->unref(); |
- paint.setColor(SK_ColorMAGENTA); |
- paint.setStyle(SkPaint::kStroke_Style); |
- |
- SkPath path; |
- path.addCircle(50, 75, 10); |
- vcanvas_->drawPath(path, paint); |
- pcanvas_->drawPath(path, paint); |
- EXPECT_EQ(0., ProcessImage(L"circle")); |
- } |
-} |
- |
-TEST_F(VectorCanvasTest, Bitmaps) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- { |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap); |
- vcanvas_->drawBitmap(bitmap, 13, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 13, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"opaque")); |
- } |
- |
- { |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap); |
- vcanvas_->drawBitmap(bitmap, 5, 15, NULL); |
- pcanvas_->drawBitmap(bitmap, 5, 15, NULL); |
- EXPECT_EQ(0., ProcessImage(L"alpha")); |
- } |
-} |
- |
-TEST_F(VectorCanvasTest, ClippingRect) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- SkRect rect; |
- rect.fLeft = 2; |
- rect.fTop = 2; |
- rect.fRight = 30.5f; |
- rect.fBottom = 30.5f; |
- vcanvas_->clipRect(rect); |
- pcanvas_->clipRect(rect); |
- |
- vcanvas_->drawBitmap(bitmap, 13, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 13, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"rect")); |
-} |
- |
-TEST_F(VectorCanvasTest, ClippingPath) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- SkPath path; |
- path.addCircle(20, 20, 10); |
- vcanvas_->clipPath(path); |
- pcanvas_->clipPath(path); |
- |
- vcanvas_->drawBitmap(bitmap, 14, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 14, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"path")); |
-} |
- |
-TEST_F(VectorCanvasTest, ClippingCombined) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- |
- SkRect rect; |
- rect.fLeft = 2; |
- rect.fTop = 2; |
- rect.fRight = 30.5f; |
- rect.fBottom = 30.5f; |
- vcanvas_->clipRect(rect); |
- pcanvas_->clipRect(rect); |
- SkPath path; |
- path.addCircle(20, 20, 10); |
- vcanvas_->clipPath(path, SkRegion::kUnion_Op); |
- pcanvas_->clipPath(path, SkRegion::kUnion_Op); |
- |
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"combined")); |
-} |
- |
-TEST_F(VectorCanvasTest, ClippingIntersect) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- |
- SkRect rect; |
- rect.fLeft = 2; |
- rect.fTop = 2; |
- rect.fRight = 30.5f; |
- rect.fBottom = 30.5f; |
- vcanvas_->clipRect(rect); |
- pcanvas_->clipRect(rect); |
- SkPath path; |
- path.addCircle(23, 23, 15); |
- vcanvas_->clipPath(path); |
- pcanvas_->clipPath(path); |
- |
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"intersect")); |
-} |
- |
-TEST_F(VectorCanvasTest, ClippingClean) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- { |
- SkRegion old_region(pcanvas_->getTotalClip()); |
- SkRect rect; |
- rect.fLeft = 2; |
- rect.fTop = 2; |
- rect.fRight = 30.5f; |
- rect.fBottom = 30.5f; |
- vcanvas_->clipRect(rect); |
- pcanvas_->clipRect(rect); |
- |
- vcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 15, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"clipped")); |
- vcanvas_->clipRegion(old_region, SkRegion::kReplace_Op); |
- pcanvas_->clipRegion(old_region, SkRegion::kReplace_Op); |
- } |
- { |
- // Verify that the clipping region has been fixed back. |
- vcanvas_->drawBitmap(bitmap, 55, 3, NULL); |
- pcanvas_->drawBitmap(bitmap, 55, 3, NULL); |
- EXPECT_EQ(0., ProcessImage(L"unclipped")); |
- } |
-} |
- |
-TEST_F(VectorCanvasTest, Matrix) { |
- // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests |
- // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't |
- // really care about Windows 2000 pixel colors. |
- if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) |
- return; |
- SkBitmap bitmap; |
- LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap); |
- { |
- vcanvas_->translate(15, 3); |
- pcanvas_->translate(15, 3); |
- vcanvas_->drawBitmap(bitmap, 0, 0, NULL); |
- pcanvas_->drawBitmap(bitmap, 0, 0, NULL); |
- EXPECT_EQ(0., ProcessImage(L"translate1")); |
- } |
- { |
- vcanvas_->translate(-30, -23); |
- pcanvas_->translate(-30, -23); |
- vcanvas_->drawBitmap(bitmap, 0, 0, NULL); |
- pcanvas_->drawBitmap(bitmap, 0, 0, NULL); |
- EXPECT_EQ(0., ProcessImage(L"translate2")); |
- } |
- vcanvas_->resetMatrix(); |
- pcanvas_->resetMatrix(); |
- |
- // For scaling and rotation, they use a different algorithm (nearest |
- // neighborhood vs smoothing). At least verify that the output doesn't change |
- // across versions. |
- compare_canvas_ = false; |
- |
- { |
- vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5)); |
- pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5)); |
- vcanvas_->drawBitmap(bitmap, 1, 1, NULL); |
- pcanvas_->drawBitmap(bitmap, 1, 1, NULL); |
- EXPECT_EQ(0., ProcessImage(L"scale")); |
- } |
- vcanvas_->resetMatrix(); |
- pcanvas_->resetMatrix(); |
- |
- { |
- vcanvas_->rotate(67); |
- pcanvas_->rotate(67); |
- vcanvas_->drawBitmap(bitmap, 20, -50, NULL); |
- pcanvas_->drawBitmap(bitmap, 20, -50, NULL); |
- EXPECT_EQ(0., ProcessImage(L"rotate")); |
- } |
-} |
- |