chromeos: bluetooth: add BluetoothInputClient
[chromium-blink-merge.git] / skia / ext / vector_canvas_unittest.cc
blobe4c748694f9f07d85a7e22e4216ca9462d4d2e74
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "build/build_config.h"
7 #if !defined(OS_WIN)
8 #include <unistd.h>
9 #endif
11 #include "base/command_line.h"
12 #include "base/file_util.h"
13 #include "base/path_service.h"
14 #include "base/string_util.h"
15 #include "base/stringprintf.h"
16 #include "base/utf_string_conversions.h"
17 #include "skia/ext/vector_canvas.h"
18 #include "skia/ext/vector_platform_device_emf_win.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/skia/include/effects/SkDashPathEffect.h"
21 #include "ui/gfx/codec/png_codec.h"
22 #include "ui/gfx/size.h"
24 namespace skia {
26 namespace {
28 const char kGenerateSwitch[] = "vector-canvas-generate";
30 // Lightweight HDC management.
31 class Context {
32 public:
33 Context() : context_(CreateCompatibleDC(NULL)) {
34 EXPECT_TRUE(context_);
36 ~Context() {
37 DeleteDC(context_);
40 HDC context() const { return context_; }
42 private:
43 HDC context_;
45 DISALLOW_COPY_AND_ASSIGN(Context);
48 // Lightweight HBITMAP management.
49 class Bitmap {
50 public:
51 Bitmap(const Context& context, int x, int y) {
52 BITMAPINFOHEADER hdr;
53 hdr.biSize = sizeof(BITMAPINFOHEADER);
54 hdr.biWidth = x;
55 hdr.biHeight = -y; // Minus means top-down bitmap.
56 hdr.biPlanes = 1;
57 hdr.biBitCount = 32;
58 hdr.biCompression = BI_RGB; // No compression.
59 hdr.biSizeImage = 0;
60 hdr.biXPelsPerMeter = 1;
61 hdr.biYPelsPerMeter = 1;
62 hdr.biClrUsed = 0;
63 hdr.biClrImportant = 0;
64 bitmap_ = CreateDIBSection(context.context(),
65 reinterpret_cast<BITMAPINFO*>(&hdr), 0,
66 &data_, NULL, 0);
67 EXPECT_TRUE(bitmap_);
68 EXPECT_TRUE(SelectObject(context.context(), bitmap_));
70 ~Bitmap() {
71 EXPECT_TRUE(DeleteObject(bitmap_));
74 private:
75 HBITMAP bitmap_;
77 void* data_;
79 DISALLOW_COPY_AND_ASSIGN(Bitmap);
82 // Lightweight raw-bitmap management. The image, once initialized, is immuable.
83 // It is mainly used for comparison.
84 class Image {
85 public:
86 // Creates the image from the given filename on disk.
87 explicit Image(const FilePath& filename) : ignore_alpha_(true) {
88 std::string compressed;
89 file_util::ReadFileToString(filename, &compressed);
90 EXPECT_TRUE(compressed.size());
92 SkBitmap bitmap;
93 EXPECT_TRUE(gfx::PNGCodec::Decode(
94 reinterpret_cast<const unsigned char*>(compressed.data()),
95 compressed.size(), &bitmap));
96 SetSkBitmap(bitmap);
99 // Loads the image from a canvas.
100 Image(skia::PlatformCanvas& canvas) : ignore_alpha_(true) {
101 // Use a different way to access the bitmap. The normal way would be to
102 // query the SkBitmap.
103 skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
104 HDC context = scoped_platform_paint.GetPlatformSurface();
105 HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP);
106 EXPECT_TRUE(bitmap != NULL);
107 // Initialize the clip region to the entire bitmap.
108 BITMAP bitmap_data;
109 EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data), sizeof(BITMAP));
110 width_ = bitmap_data.bmWidth;
111 height_ = bitmap_data.bmHeight;
112 row_length_ = bitmap_data.bmWidthBytes;
113 size_t size = row_length_ * height_;
114 data_.resize(size);
115 memcpy(&*data_.begin(), bitmap_data.bmBits, size);
118 // Loads the image from a canvas.
119 Image(const SkBitmap& bitmap) : ignore_alpha_(true) {
120 SetSkBitmap(bitmap);
123 int width() const { return width_; }
124 int height() const { return height_; }
125 int row_length() const { return row_length_; }
127 // Save the image to a png file. Used to create the initial test files.
128 void SaveToFile(const FilePath& filename) {
129 std::vector<unsigned char> compressed;
130 ASSERT_TRUE(gfx::PNGCodec::Encode(&*data_.begin(),
131 gfx::PNGCodec::FORMAT_BGRA,
132 gfx::Size(width_, height_),
133 row_length_,
134 true,
135 std::vector<gfx::PNGCodec::Comment>(),
136 &compressed));
137 ASSERT_TRUE(compressed.size());
138 FILE* f = file_util::OpenFile(filename, "wb");
139 ASSERT_TRUE(f);
140 ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f),
141 compressed.size());
142 file_util::CloseFile(f);
145 // Returns the percentage of the image that is different from the other,
146 // between 0 and 100.
147 double PercentageDifferent(const Image& rhs) const {
148 if (width_ != rhs.width_ ||
149 height_ != rhs.height_ ||
150 row_length_ != rhs.row_length_ ||
151 width_ == 0 ||
152 height_ == 0) {
153 return 100.; // When of different size or empty, they are 100% different.
155 // Compute pixels different in the overlap
156 int pixels_different = 0;
157 for (int y = 0; y < height_; ++y) {
158 for (int x = 0; x < width_; ++x) {
159 uint32_t lhs_pixel = pixel_at(x, y);
160 uint32_t rhs_pixel = rhs.pixel_at(x, y);
161 if (lhs_pixel != rhs_pixel)
162 ++pixels_different;
166 // Like the WebKit ImageDiff tool, we define percentage different in terms
167 // of the size of the 'actual' bitmap.
168 double total_pixels = static_cast<double>(width_) *
169 static_cast<double>(height_);
170 return static_cast<double>(pixels_different) / total_pixels * 100.;
173 // Returns the 0x0RGB or 0xARGB value of the pixel at the given location,
174 // depending on ignore_alpha_.
175 uint32 pixel_at(int x, int y) const {
176 EXPECT_TRUE(x >= 0 && x < width_);
177 EXPECT_TRUE(y >= 0 && y < height_);
178 const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin());
179 const uint32* data_row = data + y * row_length_ / sizeof(uint32);
180 if (ignore_alpha_)
181 return data_row[x] & 0xFFFFFF; // Strip out A.
182 else
183 return data_row[x];
186 protected:
187 void SetSkBitmap(const SkBitmap& bitmap) {
188 SkAutoLockPixels lock(bitmap);
189 width_ = bitmap.width();
190 height_ = bitmap.height();
191 row_length_ = static_cast<int>(bitmap.rowBytes());
192 size_t size = row_length_ * height_;
193 data_.resize(size);
194 memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size);
197 private:
198 // Pixel dimensions of the image.
199 int width_;
200 int height_;
202 // Length of a line in bytes.
203 int row_length_;
205 // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's
206 // 0xABGR).
207 std::vector<unsigned char> data_;
209 // Flag to signal if the comparison functions should ignore the alpha channel.
210 const bool ignore_alpha_;
212 DISALLOW_COPY_AND_ASSIGN(Image);
215 // Base for tests. Capability to process an image.
216 class ImageTest : public testing::Test {
217 public:
218 // In what state is the test running.
219 enum ProcessAction {
220 GENERATE,
221 COMPARE,
222 NOOP,
225 ImageTest(ProcessAction default_action)
226 : action_(default_action) {
229 protected:
230 virtual void SetUp() {
231 const testing::TestInfo& test_info =
232 *testing::UnitTest::GetInstance()->current_test_info();
233 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_);
234 test_dir_ = test_dir_.AppendASCII("skia").
235 AppendASCII("ext").
236 AppendASCII("data").
237 AppendASCII(test_info.test_case_name()).
238 AppendASCII(test_info.name());
240 // Hack for a quick lowercase. We assume all the tests names are ASCII.
241 FilePath::StringType tmp(test_dir_.value());
242 for (size_t i = 0; i < tmp.size(); ++i)
243 tmp[i] = base::ToLowerASCII(tmp[i]);
244 test_dir_ = FilePath(tmp);
246 if (action_ == GENERATE) {
247 // Make sure the directory exist.
248 file_util::CreateDirectory(test_dir_);
252 // Returns the fully qualified path of a data file.
253 FilePath test_file(const FilePath::StringType& filename) const {
254 // Hack for a quick lowercase. We assume all the test data file names are
255 // ASCII.
256 #if defined(OS_WIN)
257 std::string tmp = WideToASCII(filename);
258 #else
259 std::string tmp(filename);
260 #endif
261 for (size_t i = 0; i < tmp.size(); ++i)
262 tmp[i] = base::ToLowerASCII(tmp[i]);
264 return test_dir_.AppendASCII(tmp);
267 // Compares or saves the bitmap currently loaded in the context, depending on
268 // kGenerating value. Returns 0 on success or any positive value between ]0,
269 // 100] on failure. The return value is the percentage of difference between
270 // the image in the file and the image in the canvas.
271 double ProcessCanvas(skia::PlatformCanvas& canvas,
272 FilePath::StringType filename) const {
273 filename = filename + FILE_PATH_LITERAL(".png");
274 switch (action_) {
275 case GENERATE:
276 SaveImage(canvas, filename);
277 return 0.;
278 case COMPARE:
279 return CompareImage(canvas, filename);
280 case NOOP:
281 return 0;
282 default:
283 // Invalid state, returns that the image is 100 different.
284 return 100.;
288 // Compares the bitmap currently loaded in the context with the file. Returns
289 // the percentage of pixel difference between both images, between 0 and 100.
290 double CompareImage(skia::PlatformCanvas& canvas,
291 const FilePath::StringType& filename) const {
292 Image image1(canvas);
293 Image image2(test_file(filename));
294 double diff = image1.PercentageDifferent(image2);
295 return diff;
298 // Saves the bitmap currently loaded in the context into the file.
299 void SaveImage(skia::PlatformCanvas& canvas,
300 const FilePath::StringType& filename) const {
301 Image(canvas).SaveToFile(test_file(filename));
304 ProcessAction action_;
306 // Path to directory used to contain the test data.
307 FilePath test_dir_;
309 DISALLOW_COPY_AND_ASSIGN(ImageTest);
312 // Premultiply the Alpha channel on the R, B and G channels.
313 void Premultiply(SkBitmap bitmap) {
314 SkAutoLockPixels lock(bitmap);
315 for (int x = 0; x < bitmap.width(); ++x) {
316 for (int y = 0; y < bitmap.height(); ++y) {
317 uint32_t* pixel_addr = bitmap.getAddr32(x, y);
318 uint32_t color = *pixel_addr;
319 BYTE alpha = SkColorGetA(color);
320 if (!alpha) {
321 *pixel_addr = 0;
322 } else {
323 BYTE alpha_offset = alpha / 2;
324 *pixel_addr = SkColorSetARGB(
325 SkColorGetA(color),
326 (SkColorGetR(color) * 255 + alpha_offset) / alpha,
327 (SkColorGetG(color) * 255 + alpha_offset) / alpha,
328 (SkColorGetB(color) * 255 + alpha_offset) / alpha);
334 void LoadPngFileToSkBitmap(const FilePath& filename,
335 SkBitmap* bitmap,
336 bool is_opaque) {
337 std::string compressed;
338 file_util::ReadFileToString(filename, &compressed);
339 ASSERT_TRUE(compressed.size());
341 ASSERT_TRUE(gfx::PNGCodec::Decode(
342 reinterpret_cast<const unsigned char*>(compressed.data()),
343 compressed.size(), bitmap));
345 EXPECT_EQ(is_opaque, bitmap->isOpaque());
346 Premultiply(*bitmap);
349 } // namespace
351 // Streams an image.
352 inline std::ostream& operator<<(std::ostream& out, const Image& image) {
353 return out << "Image(" << image.width() << ", "
354 << image.height() << ", " << image.row_length() << ")";
357 // Runs simultaneously the same drawing commands on VectorCanvas and
358 // PlatformCanvas and compare the results.
359 class VectorCanvasTest : public ImageTest {
360 public:
361 typedef ImageTest parent;
363 VectorCanvasTest() : parent(CurrentMode()), compare_canvas_(true) {
366 protected:
367 virtual void SetUp() {
368 parent::SetUp();
369 Init(100);
370 number_ = 0;
373 virtual void TearDown() {
374 delete pcanvas_;
375 pcanvas_ = NULL;
377 delete vcanvas_;
378 vcanvas_ = NULL;
380 delete bitmap_;
381 bitmap_ = NULL;
383 delete context_;
384 context_ = NULL;
386 parent::TearDown();
389 void Init(int size) {
390 size_ = size;
391 context_ = new Context();
392 bitmap_ = new Bitmap(*context_, size_, size_);
393 vcanvas_ = new VectorCanvas(VectorPlatformDeviceEmf::CreateDevice(
394 size_, size_, true, context_->context()));
395 pcanvas_ = new PlatformCanvas(size_, size_, false);
397 // Clear white.
398 vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
399 pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
402 // Compares both canvas and returns the pixel difference in percentage between
403 // both images. 0 on success and ]0, 100] on failure.
404 double ProcessImage(const FilePath::StringType& filename) {
405 std::wstring number(base::StringPrintf(L"%02d_", number_++));
406 double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename);
407 double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename);
408 if (!compare_canvas_)
409 return std::max(diff1, diff2);
411 Image image1(*vcanvas_);
412 Image image2(*pcanvas_);
413 double diff = image1.PercentageDifferent(image2);
414 return std::max(std::max(diff1, diff2), diff);
417 // Returns COMPARE, which is the default. If kGenerateSwitch command
418 // line argument is used to start this process, GENERATE is returned instead.
419 static ProcessAction CurrentMode() {
420 return CommandLine::ForCurrentProcess()->HasSwitch(kGenerateSwitch) ?
421 GENERATE : COMPARE;
424 // Length in x and y of the square canvas.
425 int size_;
427 // Current image number in the current test. Used to number of test files.
428 int number_;
430 // A temporary HDC to draw into.
431 Context* context_;
433 // Bitmap created inside context_.
434 Bitmap* bitmap_;
436 // Vector based canvas.
437 VectorCanvas* vcanvas_;
439 // Pixel based canvas.
440 PlatformCanvas* pcanvas_;
442 // When true (default), vcanvas_ and pcanvas_ contents are compared and
443 // verified to be identical.
444 bool compare_canvas_;
448 ////////////////////////////////////////////////////////////////////////////////
449 // Actual tests
451 TEST_F(VectorCanvasTest, Uninitialized) {
452 // Do a little mubadumba do get uninitialized stuff.
453 VectorCanvasTest::TearDown();
455 // The goal is not to verify that have the same uninitialized data.
456 compare_canvas_ = false;
458 context_ = new Context();
459 bitmap_ = new Bitmap(*context_, size_, size_);
460 vcanvas_ = new VectorCanvas(VectorPlatformDeviceEmf::CreateDevice(
461 size_, size_, true, context_->context()));
462 pcanvas_ = new PlatformCanvas(size_, size_, false);
464 // VectorCanvas default initialization is black.
465 // PlatformCanvas default initialization is almost white 0x01FFFEFD (invalid
466 // Skia color) in both Debug and Release. See magicTransparencyColor in
467 // platform_device.cc
468 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("empty")));
471 TEST_F(VectorCanvasTest, BasicDrawing) {
472 EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.)
473 << L"clean";
474 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clean")));
476 // Clear white.
478 vcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
479 pcanvas_->drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
481 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawARGB")));
483 // Diagonal line top-left to bottom-right.
485 SkPaint paint;
486 // Default color is black.
487 vcanvas_->drawLine(10, 10, 90, 90, paint);
488 pcanvas_->drawLine(10, 10, 90, 90, paint);
490 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_black")));
492 // Rect.
494 SkPaint paint;
495 paint.setColor(SK_ColorGREEN);
496 vcanvas_->drawRectCoords(25, 25, 75, 75, paint);
497 pcanvas_->drawRectCoords(25, 25, 75, 75, paint);
499 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_green")));
501 // A single-point rect doesn't leave any mark.
503 SkPaint paint;
504 paint.setColor(SK_ColorBLUE);
505 vcanvas_->drawRectCoords(5, 5, 5, 5, paint);
506 pcanvas_->drawRectCoords(5, 5, 5, 5, paint);
508 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop")));
510 // Rect.
512 SkPaint paint;
513 paint.setColor(SK_ColorBLUE);
514 vcanvas_->drawRectCoords(75, 50, 80, 55, paint);
515 pcanvas_->drawRectCoords(75, 50, 80, 55, paint);
517 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawRect_noop")));
519 // Empty again
521 vcanvas_->drawPaint(SkPaint());
522 pcanvas_->drawPaint(SkPaint());
524 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPaint_black")));
526 // Horizontal line left to right.
528 SkPaint paint;
529 paint.setColor(SK_ColorRED);
530 vcanvas_->drawLine(10, 20, 90, 20, paint);
531 pcanvas_->drawLine(10, 20, 90, 20, paint);
533 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_left_to_right")));
535 // Vertical line downward.
537 SkPaint paint;
538 paint.setColor(SK_ColorRED);
539 vcanvas_->drawLine(30, 10, 30, 90, paint);
540 pcanvas_->drawLine(30, 10, 30, 90, paint);
542 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawLine_red")));
545 TEST_F(VectorCanvasTest, Circles) {
546 // There is NO WAY to make them agree. At least verify that the output doesn't
547 // change across versions. This test is disabled. See bug 1060231.
548 compare_canvas_ = false;
550 // Stroked Circle.
552 SkPaint paint;
553 SkPath path;
554 path.addCircle(50, 75, 10);
555 paint.setStyle(SkPaint::kStroke_Style);
556 paint.setColor(SK_ColorMAGENTA);
557 vcanvas_->drawPath(path, paint);
558 pcanvas_->drawPath(path, paint);
560 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke")));
562 // Filled Circle.
564 SkPaint paint;
565 SkPath path;
566 path.addCircle(50, 25, 10);
567 paint.setStyle(SkPaint::kFill_Style);
568 vcanvas_->drawPath(path, paint);
569 pcanvas_->drawPath(path, paint);
571 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_fill")));
573 // Stroked Circle over.
575 SkPaint paint;
576 SkPath path;
577 path.addCircle(50, 25, 10);
578 paint.setStyle(SkPaint::kStroke_Style);
579 paint.setColor(SK_ColorBLUE);
580 vcanvas_->drawPath(path, paint);
581 pcanvas_->drawPath(path, paint);
583 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_over_strike")));
585 // Stroke and Fill Circle.
587 SkPaint paint;
588 SkPath path;
589 path.addCircle(12, 50, 10);
590 paint.setStyle(SkPaint::kStrokeAndFill_Style);
591 paint.setColor(SK_ColorRED);
592 vcanvas_->drawPath(path, paint);
593 pcanvas_->drawPath(path, paint);
595 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle_stroke_and_fill")));
597 // Line + Quad + Cubic.
599 SkPaint paint;
600 SkPath path;
601 paint.setStyle(SkPaint::kStroke_Style);
602 paint.setColor(SK_ColorGREEN);
603 path.moveTo(1, 1);
604 path.lineTo(60, 40);
605 path.lineTo(80, 80);
606 path.quadTo(20, 50, 10, 90);
607 path.quadTo(50, 20, 90, 10);
608 path.cubicTo(20, 40, 50, 50, 10, 10);
609 path.cubicTo(30, 20, 50, 50, 90, 10);
610 path.addRect(90, 90, 95, 96);
611 vcanvas_->drawPath(path, paint);
612 pcanvas_->drawPath(path, paint);
614 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("mixed_stroke")));
617 TEST_F(VectorCanvasTest, LineOrientation) {
618 // There is NO WAY to make them agree. At least verify that the output doesn't
619 // change across versions. This test is disabled. See bug 1060231.
620 compare_canvas_ = false;
622 // Horizontal lines.
624 SkPaint paint;
625 paint.setColor(SK_ColorRED);
626 // Left to right.
627 vcanvas_->drawLine(10, 20, 90, 20, paint);
628 pcanvas_->drawLine(10, 20, 90, 20, paint);
629 // Right to left.
630 vcanvas_->drawLine(90, 30, 10, 30, paint);
631 pcanvas_->drawLine(90, 30, 10, 30, paint);
633 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal")));
635 // Vertical lines.
637 SkPaint paint;
638 paint.setColor(SK_ColorRED);
639 // Top down.
640 vcanvas_->drawLine(20, 10, 20, 90, paint);
641 pcanvas_->drawLine(20, 10, 20, 90, paint);
642 // Bottom up.
643 vcanvas_->drawLine(30, 90, 30, 10, paint);
644 pcanvas_->drawLine(30, 90, 30, 10, paint);
646 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical")));
648 // Try again with a 180 degres rotation.
649 vcanvas_->rotate(180);
650 pcanvas_->rotate(180);
652 // Horizontal lines (rotated).
654 SkPaint paint;
655 paint.setColor(SK_ColorRED);
656 vcanvas_->drawLine(-10, -25, -90, -25, paint);
657 pcanvas_->drawLine(-10, -25, -90, -25, paint);
658 vcanvas_->drawLine(-90, -35, -10, -35, paint);
659 pcanvas_->drawLine(-90, -35, -10, -35, paint);
661 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("horizontal_180")));
663 // Vertical lines (rotated).
665 SkPaint paint;
666 paint.setColor(SK_ColorRED);
667 vcanvas_->drawLine(-25, -10, -25, -90, paint);
668 pcanvas_->drawLine(-25, -10, -25, -90, paint);
669 vcanvas_->drawLine(-35, -90, -35, -10, paint);
670 pcanvas_->drawLine(-35, -90, -35, -10, paint);
672 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("vertical_180")));
675 TEST_F(VectorCanvasTest, PathOrientation) {
676 // There is NO WAY to make them agree. At least verify that the output doesn't
677 // change across versions. This test is disabled. See bug 1060231.
678 compare_canvas_ = false;
680 // Horizontal lines.
682 SkPaint paint;
683 paint.setStyle(SkPaint::kStroke_Style);
684 paint.setColor(SK_ColorRED);
685 SkPath path;
686 SkPoint start;
687 start.set(10, 20);
688 SkPoint end;
689 end.set(90, 20);
690 path.moveTo(start);
691 path.lineTo(end);
692 vcanvas_->drawPath(path, paint);
693 pcanvas_->drawPath(path, paint);
695 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_ltr")));
697 // Horizontal lines.
699 SkPaint paint;
700 paint.setStyle(SkPaint::kStroke_Style);
701 paint.setColor(SK_ColorRED);
702 SkPath path;
703 SkPoint start;
704 start.set(90, 30);
705 SkPoint end;
706 end.set(10, 30);
707 path.moveTo(start);
708 path.lineTo(end);
709 vcanvas_->drawPath(path, paint);
710 pcanvas_->drawPath(path, paint);
712 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("drawPath_rtl")));
715 TEST_F(VectorCanvasTest, DiagonalLines) {
716 SkPaint paint;
717 paint.setColor(SK_ColorRED);
719 vcanvas_->drawLine(10, 10, 90, 90, paint);
720 pcanvas_->drawLine(10, 10, 90, 90, paint);
721 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("nw-se")));
723 // Starting here, there is NO WAY to make them agree. At least verify that the
724 // output doesn't change across versions. This test is disabled. See bug
725 // 1060231.
726 compare_canvas_ = false;
728 vcanvas_->drawLine(10, 95, 90, 15, paint);
729 pcanvas_->drawLine(10, 95, 90, 15, paint);
730 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("sw-ne")));
732 vcanvas_->drawLine(90, 10, 10, 90, paint);
733 pcanvas_->drawLine(90, 10, 10, 90, paint);
734 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("ne-sw")));
736 vcanvas_->drawLine(95, 90, 15, 10, paint);
737 pcanvas_->drawLine(95, 90, 15, 10, paint);
738 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("se-nw")));
741 TEST_F(VectorCanvasTest, PathEffects) {
743 SkPaint paint;
744 SkScalar intervals[] = { 1, 1 };
745 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
747 paint.setPathEffect(effect)->unref();
748 paint.setColor(SK_ColorMAGENTA);
749 paint.setStyle(SkPaint::kStroke_Style);
751 vcanvas_->drawLine(10, 10, 90, 10, paint);
752 pcanvas_->drawLine(10, 10, 90, 10, paint);
754 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_line")));
757 // Starting here, there is NO WAY to make them agree. At least verify that the
758 // output doesn't change across versions. This test is disabled. See bug
759 // 1060231.
760 compare_canvas_ = false;
763 SkPaint paint;
764 SkScalar intervals[] = { 3, 5 };
765 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
767 paint.setPathEffect(effect)->unref();
768 paint.setColor(SK_ColorMAGENTA);
769 paint.setStyle(SkPaint::kStroke_Style);
771 SkPath path;
772 path.moveTo(10, 15);
773 path.lineTo(90, 15);
774 path.lineTo(90, 90);
775 vcanvas_->drawPath(path, paint);
776 pcanvas_->drawPath(path, paint);
778 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_path")));
781 SkPaint paint;
782 SkScalar intervals[] = { 2, 1 };
783 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
785 paint.setPathEffect(effect)->unref();
786 paint.setColor(SK_ColorMAGENTA);
787 paint.setStyle(SkPaint::kStroke_Style);
789 vcanvas_->drawRectCoords(20, 20, 30, 30, paint);
790 pcanvas_->drawRectCoords(20, 20, 30, 30, paint);
792 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("dash_rect")));
794 // This thing looks like it has been drawn by a 3 years old kid. I haven't
795 // filed a bug on this since I guess nobody is expecting this to look nice.
797 SkPaint paint;
798 SkScalar intervals[] = { 1, 1 };
799 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
801 paint.setPathEffect(effect)->unref();
802 paint.setColor(SK_ColorMAGENTA);
803 paint.setStyle(SkPaint::kStroke_Style);
805 SkPath path;
806 path.addCircle(50, 75, 10);
807 vcanvas_->drawPath(path, paint);
808 pcanvas_->drawPath(path, paint);
809 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("circle")));
813 TEST_F(VectorCanvasTest, Bitmaps) {
815 SkBitmap bitmap;
816 LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap, true);
817 vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
818 pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
819 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("opaque")));
823 SkBitmap bitmap;
824 LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap, false);
825 vcanvas_->drawBitmap(bitmap, 5, 15, NULL);
826 pcanvas_->drawBitmap(bitmap, 5, 15, NULL);
827 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("alpha")));
831 TEST_F(VectorCanvasTest, ClippingRect) {
832 SkBitmap bitmap;
833 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
834 true);
835 SkRect rect;
836 rect.fLeft = 2;
837 rect.fTop = 2;
838 rect.fRight = 30.5f;
839 rect.fBottom = 30.5f;
840 vcanvas_->clipRect(rect);
841 pcanvas_->clipRect(rect);
843 vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
844 pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
845 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rect")));
848 TEST_F(VectorCanvasTest, ClippingPath) {
849 SkBitmap bitmap;
850 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
851 true);
852 SkPath path;
853 path.addCircle(20, 20, 10);
854 vcanvas_->clipPath(path);
855 pcanvas_->clipPath(path);
857 vcanvas_->drawBitmap(bitmap, 14, 3, NULL);
858 pcanvas_->drawBitmap(bitmap, 14, 3, NULL);
859 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("path")));
862 TEST_F(VectorCanvasTest, ClippingCombined) {
863 SkBitmap bitmap;
864 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
865 true);
867 SkRect rect;
868 rect.fLeft = 2;
869 rect.fTop = 2;
870 rect.fRight = 30.5f;
871 rect.fBottom = 30.5f;
872 vcanvas_->clipRect(rect);
873 pcanvas_->clipRect(rect);
874 SkPath path;
875 path.addCircle(20, 20, 10);
876 vcanvas_->clipPath(path, SkRegion::kUnion_Op);
877 pcanvas_->clipPath(path, SkRegion::kUnion_Op);
879 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
880 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
881 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("combined")));
884 TEST_F(VectorCanvasTest, ClippingIntersect) {
885 SkBitmap bitmap;
886 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
887 true);
889 SkRect rect;
890 rect.fLeft = 2;
891 rect.fTop = 2;
892 rect.fRight = 30.5f;
893 rect.fBottom = 30.5f;
894 vcanvas_->clipRect(rect);
895 pcanvas_->clipRect(rect);
896 SkPath path;
897 path.addCircle(23, 23, 15);
898 vcanvas_->clipPath(path);
899 pcanvas_->clipPath(path);
901 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
902 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
903 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("intersect")));
906 TEST_F(VectorCanvasTest, ClippingClean) {
907 SkBitmap bitmap;
908 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
909 true);
911 SkRegion old_region(pcanvas_->getTotalClip());
912 SkRect rect;
913 rect.fLeft = 2;
914 rect.fTop = 2;
915 rect.fRight = 30.5f;
916 rect.fBottom = 30.5f;
917 vcanvas_->clipRect(rect);
918 pcanvas_->clipRect(rect);
920 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
921 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
922 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("clipped")));
923 vcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
924 pcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
927 // Verify that the clipping region has been fixed back.
928 vcanvas_->drawBitmap(bitmap, 55, 3, NULL);
929 pcanvas_->drawBitmap(bitmap, 55, 3, NULL);
930 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("unclipped")));
934 // See http://crbug.com/26938
935 TEST_F(VectorCanvasTest, DISABLED_Matrix) {
936 SkBitmap bitmap;
937 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap,
938 true);
940 vcanvas_->translate(15, 3);
941 pcanvas_->translate(15, 3);
942 vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
943 pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
944 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate1")));
947 vcanvas_->translate(-30, -23);
948 pcanvas_->translate(-30, -23);
949 vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
950 pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
951 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("translate2")));
953 vcanvas_->resetMatrix();
954 pcanvas_->resetMatrix();
956 // For scaling and rotation, they use a different algorithm (nearest
957 // neighborhood vs smoothing). At least verify that the output doesn't change
958 // across versions.
959 compare_canvas_ = false;
962 vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
963 pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
964 vcanvas_->drawBitmap(bitmap, 1, 1, NULL);
965 pcanvas_->drawBitmap(bitmap, 1, 1, NULL);
966 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("scale")));
968 vcanvas_->resetMatrix();
969 pcanvas_->resetMatrix();
972 vcanvas_->rotate(67);
973 pcanvas_->rotate(67);
974 vcanvas_->drawBitmap(bitmap, 20, -50, NULL);
975 pcanvas_->drawBitmap(bitmap, 20, -50, NULL);
976 EXPECT_EQ(0., ProcessImage(FILE_PATH_LITERAL("rotate")));
980 } // namespace skia