Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(781)

Side by Side Diff: webkit/port/platform/graphics/skia/public/VectorCanvas_unittest.cpp

Issue 11568: Move skia extensions from the port to skia/ext. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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.
4
5 #include "VectorCanvas.h"
6
7 #include <vector>
8
9 #include "base/command_line.h"
10 #include "base/file_util.h"
11 #include "base/gfx/gdi_util.h"
12 #include "base/gfx/png_decoder.h"
13 #include "base/gfx/png_encoder.h"
14 #include "base/gfx/size.h"
15 #include "base/path_service.h"
16 #include "base/string_util.h"
17 #include "base/win_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 #include "SkDashPathEffect.h"
21
22 namespace {
23
24 const wchar_t* const kGenerateSwitch = L"vector-canvas-generate";
25
26 // Base class for unit test that uses data. It initializes a directory path
27 // based on the test's name.
28 class DataUnitTest : public testing::Test {
29 public:
30 DataUnitTest(const std::wstring& base_path) : base_path_(base_path) { }
31
32 protected:
33 // Load the test's data path.
34 virtual void SetUp() {
35 const testing::TestInfo& test_info =
36 *testing::UnitTest::GetInstance()->current_test_info();
37 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_);
38 file_util::AppendToPath(&test_dir_, base_path_);
39 file_util::AppendToPath(&test_dir_, L"data");
40 file_util::AppendToPath(&test_dir_,
41 ASCIIToWide(test_info.test_case_name()));
42 file_util::AppendToPath(&test_dir_, ASCIIToWide(test_info.name()));
43
44 // Hack for a quick lowercase. We assume all the tests names are ASCII.
45 std::string tmp(WideToASCII(test_dir_));
46 for (size_t i = 0; i < tmp.size(); ++i)
47 tmp[i] = ToLowerASCII(tmp[i]);
48 test_dir_ = ASCIIToWide(tmp);
49 }
50
51 // Returns the fully qualified path of directory containing test data files.
52 const std::wstring& test_dir() const {
53 return test_dir_;
54 }
55
56 // Returns the fully qualified path of a data file.
57 std::wstring test_file(const std::wstring& filename) const {
58 // Hack for a quick lowercase. We assume all the test data file names are
59 // ASCII.
60 std::string tmp(WideToASCII(filename));
61 for (size_t i = 0; i < tmp.size(); ++i)
62 tmp[i] = ToLowerASCII(tmp[i]);
63
64 std::wstring path(test_dir());
65 file_util::AppendToPath(&path, ASCIIToWide(tmp));
66 return path;
67 }
68
69 private:
70 // Path where the unit test is coming from: base, net, chrome, etc.
71 std::wstring base_path_;
72
73 // Path to directory used to contain the test data.
74 std::wstring test_dir_;
75
76 DISALLOW_EVIL_CONSTRUCTORS(DataUnitTest);
77 };
78
79 // Lightweight HDC management.
80 class Context {
81 public:
82 Context() : context_(CreateCompatibleDC(NULL)) {
83 EXPECT_TRUE(context_);
84 }
85 ~Context() {
86 DeleteDC(context_);
87 }
88
89 HDC context() const { return context_; }
90
91 private:
92 HDC context_;
93
94 DISALLOW_EVIL_CONSTRUCTORS(Context);
95 };
96
97 // Lightweight HBITMAP management.
98 class Bitmap {
99 public:
100 Bitmap(const Context& context, int x, int y) {
101 BITMAPINFOHEADER hdr;
102 gfx::CreateBitmapHeader(x, y, &hdr);
103 bitmap_ = CreateDIBSection(context.context(),
104 reinterpret_cast<BITMAPINFO*>(&hdr), 0,
105 &data_, NULL, 0);
106 EXPECT_TRUE(bitmap_);
107 EXPECT_TRUE(SelectObject(context.context(), bitmap_));
108 }
109 ~Bitmap() {
110 EXPECT_TRUE(DeleteObject(bitmap_));
111 }
112
113 private:
114 HBITMAP bitmap_;
115
116 void* data_;
117
118 DISALLOW_EVIL_CONSTRUCTORS(Bitmap);
119 };
120
121 // Lightweight raw-bitmap management. The image, once initialized, is immuable.
122 // It is mainly used for comparison.
123 class Image {
124 public:
125 // Creates the image from the given filename on disk.
126 Image(const std::wstring& filename) : ignore_alpha_(true) {
127 std::string compressed;
128 file_util::ReadFileToString(filename, &compressed);
129 EXPECT_TRUE(compressed.size());
130
131 int w;
132 int h;
133 EXPECT_TRUE(PNGDecoder::Decode(
134 reinterpret_cast<const unsigned char*>(compressed.c_str()),
135 compressed.size(), PNGDecoder::FORMAT_BGRA, &data_, &w, &h));
136 size_.SetSize(w, h);
137 row_length_ = w * sizeof(uint32);
138 }
139
140 // Loads the image from a canvas.
141 Image(const gfx::PlatformCanvasWin& canvas) : ignore_alpha_(true) {
142 // Use a different way to access the bitmap. The normal way would be to
143 // query the SkBitmap.
144 HDC context = canvas.getTopPlatformDevice().getBitmapDC();
145 HGDIOBJ bitmap = GetCurrentObject(context, OBJ_BITMAP);
146 EXPECT_TRUE(bitmap != NULL);
147 // Initialize the clip region to the entire bitmap.
148 BITMAP bitmap_data;
149 EXPECT_EQ(GetObject(bitmap, sizeof(BITMAP), &bitmap_data),
150 sizeof(BITMAP));
151 size_.SetSize(bitmap_data.bmWidth, bitmap_data.bmHeight);
152 row_length_ = bitmap_data.bmWidthBytes;
153 size_t size = row_length_ * size_.height();
154 data_.resize(size);
155 memcpy(&*data_.begin(), bitmap_data.bmBits, size);
156 }
157
158 // Loads the image from a canvas.
159 Image(const SkBitmap& bitmap) : ignore_alpha_(true) {
160 SkAutoLockPixels lock(bitmap);
161 size_.SetSize(bitmap.width(), bitmap.height());
162 row_length_ = static_cast<int>(bitmap.rowBytes());
163 size_t size = row_length_ * size_.height();
164 data_.resize(size);
165 memcpy(&*data_.begin(), bitmap.getAddr(0, 0), size);
166 }
167
168 const gfx::Size& size() const {
169 return size_;
170 }
171
172 int row_length() const {
173 return row_length_;
174 }
175
176 // Save the image to a png file. Used to create the initial test files.
177 void SaveToFile(const std::wstring& filename) {
178 std::vector<unsigned char> compressed;
179 ASSERT_TRUE(PNGEncoder::Encode(&*data_.begin(),
180 PNGEncoder::FORMAT_BGRA,
181 size_.width(),
182 size_.height(),
183 row_length_,
184 true,
185 &compressed));
186 ASSERT_TRUE(compressed.size());
187 FILE* f = file_util::OpenFile(filename, "wb");
188 ASSERT_TRUE(f);
189 ASSERT_EQ(fwrite(&*compressed.begin(), 1, compressed.size(), f),
190 compressed.size());
191 file_util::CloseFile(f);
192 }
193
194 // Returns the percentage of the image that is different from the other,
195 // between 0 and 100.
196 double PercentageDifferent(const Image& rhs) const {
197 if (size_ != rhs.size_ || row_length_ != rhs.row_length_ ||
198 size_.width() == 0 || size_.height() == 0)
199 return 100.; // When of different size or empty, they are 100% different.
200
201 // Compute pixels different in the overlap
202 int pixels_different = 0;
203 for (int y = 0; y < size_.height(); ++y) {
204 for (int x = 0; x < size_.width(); ++x) {
205 uint32_t lhs_pixel = pixel_at(x, y);
206 uint32_t rhs_pixel = rhs.pixel_at(x, y);
207 if (lhs_pixel != rhs_pixel)
208 ++pixels_different;
209 }
210 }
211
212 // Like the WebKit ImageDiff tool, we define percentage different in terms
213 // of the size of the 'actual' bitmap.
214 double total_pixels = static_cast<double>(size_.width()) *
215 static_cast<double>(size_.height());
216 return static_cast<double>(pixels_different) / total_pixels * 100.;
217 }
218
219 // Returns the 0x0RGB or 0xARGB value of the pixel at the given location,
220 // depending on ignore_alpha_.
221 uint32 pixel_at(int x, int y) const {
222 EXPECT_TRUE(x >= 0 && x < size_.width());
223 EXPECT_TRUE(y >= 0 && y < size_.height());
224 const uint32* data = reinterpret_cast<const uint32*>(&*data_.begin());
225 const uint32* data_row = data + y * row_length_ / sizeof(uint32);
226 if (ignore_alpha_)
227 return data_row[x] & 0xFFFFFF; // Strip out A.
228 else
229 return data_row[x];
230 }
231
232 private:
233 // Pixel dimensions of the image.
234 gfx::Size size_;
235
236 // Length of a line in bytes.
237 int row_length_;
238
239 // Actual bitmap data in arrays of RGBAs (so when loaded as uint32, it's
240 // 0xABGR).
241 std::vector<unsigned char> data_;
242
243 // Flag to signal if the comparison functions should ignore the alpha channel.
244 const bool ignore_alpha_;
245
246 DISALLOW_EVIL_CONSTRUCTORS(Image);
247 };
248
249 // Base for tests. Capability to process an image.
250 class ImageTest : public DataUnitTest {
251 public:
252 typedef DataUnitTest parent;
253
254 // In what state is the test running.
255 enum ProcessAction {
256 GENERATE,
257 COMPARE,
258 NOOP,
259 };
260
261 ImageTest(const std::wstring& base_path, ProcessAction default_action)
262 : parent(base_path),
263 action_(default_action) {
264 }
265
266 protected:
267 virtual void SetUp() {
268 parent::SetUp();
269
270 if (action_ == GENERATE) {
271 // Make sure the directory exist.
272 file_util::CreateDirectory(test_dir());
273 }
274 }
275
276 // Compares or saves the bitmap currently loaded in the context, depending on
277 // kGenerating value. Returns 0 on success or any positive value between ]0,
278 // 100] on failure. The return value is the percentage of difference between
279 // the image in the file and the image in the canvas.
280 double ProcessCanvas(const gfx::PlatformCanvasWin& canvas,
281 std::wstring filename) const {
282 filename += L".png";
283 switch (action_) {
284 case GENERATE:
285 SaveImage(canvas, filename);
286 return 0.;
287 case COMPARE:
288 return CompareImage(canvas, filename);
289 case NOOP:
290 return 0;
291 default:
292 // Invalid state, returns that the image is 100 different.
293 return 100.;
294 }
295 }
296
297 // Compares the bitmap currently loaded in the context with the file. Returns
298 // the percentage of pixel difference between both images, between 0 and 100.
299 double CompareImage(const gfx::PlatformCanvasWin& canvas,
300 const std::wstring& filename) const {
301 Image image1(canvas);
302 Image image2(test_file(filename));
303 double diff = image1.PercentageDifferent(image2);
304 return diff;
305 }
306
307 // Saves the bitmap currently loaded in the context into the file.
308 void SaveImage(const gfx::PlatformCanvasWin& canvas,
309 const std::wstring& filename) const {
310 Image(canvas).SaveToFile(test_file(filename));
311 }
312
313 ProcessAction action_;
314
315 DISALLOW_EVIL_CONSTRUCTORS(ImageTest);
316 };
317
318 // Premultiply the Alpha channel on the R, B and G channels.
319 void Premultiply(SkBitmap bitmap) {
320 SkAutoLockPixels lock(bitmap);
321 for (int x = 0; x < bitmap.width(); ++x) {
322 for (int y = 0; y < bitmap.height(); ++y) {
323 uint32_t* pixel_addr = bitmap.getAddr32(x, y);
324 uint32_t color = *pixel_addr;
325 BYTE alpha = SkColorGetA(color);
326 if (!alpha) {
327 *pixel_addr = 0;
328 } else {
329 BYTE alpha_offset = alpha / 2;
330 *pixel_addr = SkColorSetARGB(
331 SkColorGetA(color),
332 (SkColorGetR(color) * 255 + alpha_offset) / alpha,
333 (SkColorGetG(color) * 255 + alpha_offset) / alpha,
334 (SkColorGetB(color) * 255 + alpha_offset) / alpha);
335 }
336 }
337 }
338 }
339
340 void LoadPngFileToSkBitmap(const std::wstring& file, SkBitmap* bitmap) {
341 std::string compressed;
342 file_util::ReadFileToString(file, &compressed);
343 EXPECT_TRUE(compressed.size());
344 // Extra-lame. If you care, fix it.
345 std::vector<unsigned char> data;
346 data.assign(reinterpret_cast<const unsigned char*>(compressed.c_str()),
347 reinterpret_cast<const unsigned char*>(compressed.c_str() +
348 compressed.size()));
349 EXPECT_TRUE(PNGDecoder::Decode(&data, bitmap));
350 EXPECT_FALSE(bitmap->isOpaque());
351 Premultiply(*bitmap);
352 }
353
354 } // namespace
355
356 // Streams an image.
357 inline std::ostream& operator<<(std::ostream& out, const Image& image) {
358 return out << "Image(" << image.size().width() << ", "
359 << image.size().height() << ", " << image.row_length() << ")";
360 }
361
362 // Runs simultaneously the same drawing commands on VectorCanvas and
363 // PlatformCanvas and compare the results.
364 class VectorCanvasTest : public ImageTest {
365 public:
366 typedef ImageTest parent;
367
368 VectorCanvasTest() : parent(L"base", CurrentMode()), compare_canvas_(true) {
369 }
370
371 protected:
372 virtual void SetUp() {
373 parent::SetUp();
374 Init(100);
375 number_ = 0;
376 }
377
378 virtual void TearDown() {
379 delete pcanvas_;
380 pcanvas_ = NULL;
381
382 delete vcanvas_;
383 vcanvas_ = NULL;
384
385 delete bitmap_;
386 bitmap_ = NULL;
387
388 delete context_;
389 context_ = NULL;
390
391 parent::TearDown();
392 }
393
394 void Init(int size) {
395 size_ = size;
396 context_ = new Context();
397 bitmap_ = new Bitmap(*context_, size_, size_);
398 vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_);
399 pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false);
400
401 // Clear white.
402 vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
403 pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
404 }
405
406 // Compares both canvas and returns the pixel difference in percentage between
407 // both images. 0 on success and ]0, 100] on failure.
408 double ProcessImage(const std::wstring& filename) {
409 std::wstring number(StringPrintf(L"%02d_", number_++));
410 double diff1 = parent::ProcessCanvas(*vcanvas_, number + L"vc_" + filename);
411 double diff2 = parent::ProcessCanvas(*pcanvas_, number + L"pc_" + filename);
412 if (!compare_canvas_)
413 return std::max(diff1, diff2);
414
415 Image image1(*vcanvas_);
416 Image image2(*pcanvas_);
417 double diff = image1.PercentageDifferent(image2);
418 return std::max(std::max(diff1, diff2), diff);
419 }
420
421 // Returns COMPARE, which is the default. If kGenerateSwitch command
422 // line argument is used to start this process, GENERATE is returned instead.
423 static ProcessAction CurrentMode() {
424 return CommandLine().HasSwitch(kGenerateSwitch) ? GENERATE : COMPARE;
425 }
426
427 // Length in x and y of the square canvas.
428 int size_;
429
430 // Current image number in the current test. Used to number of test files.
431 int number_;
432
433 // A temporary HDC to draw into.
434 Context* context_;
435
436 // Bitmap created inside context_.
437 Bitmap* bitmap_;
438
439 // Vector based canvas.
440 gfx::VectorCanvas* vcanvas_;
441
442 // Pixel based canvas.
443 gfx::PlatformCanvasWin* pcanvas_;
444
445 // When true (default), vcanvas_ and pcanvas_ contents are compared and
446 // verified to be identical.
447 bool compare_canvas_;
448 };
449
450
451 ////////////////////////////////////////////////////////////////////////////////
452 // Actual tests
453
454 TEST_F(VectorCanvasTest, Uninitialized) {
455 // Do a little mubadumba do get uninitialized stuff.
456 VectorCanvasTest::TearDown();
457
458 // The goal is not to verify that have the same uninitialized data.
459 compare_canvas_ = false;
460
461 context_ = new Context();
462 bitmap_ = new Bitmap(*context_, size_, size_);
463 vcanvas_ = new gfx::VectorCanvas(context_->context(), size_, size_);
464 pcanvas_ = new gfx::PlatformCanvasWin(size_, size_, false);
465
466 // VectorCanvas default initialization is black.
467 // PlatformCanvas default initialization is almost white 0x01FFFEFD (invalid
468 // Skia color) in both Debug and Release. See magicTransparencyColor in
469 // platform_device.cc
470 EXPECT_EQ(0., ProcessImage(L"empty"));
471 }
472
473 TEST_F(VectorCanvasTest, BasicDrawing) {
474 EXPECT_EQ(Image(*vcanvas_).PercentageDifferent(Image(*pcanvas_)), 0.)
475 << L"clean";
476 EXPECT_EQ(0., ProcessImage(L"clean"));
477
478 // Clear white.
479 {
480 vcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
481 pcanvas_->drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
482 }
483 EXPECT_EQ(0., ProcessImage(L"drawARGB"));
484
485 // Diagonal line top-left to bottom-right.
486 {
487 SkPaint paint;
488 // Default color is black.
489 vcanvas_->drawLine(10, 10, 90, 90, paint);
490 pcanvas_->drawLine(10, 10, 90, 90, paint);
491 }
492 EXPECT_EQ(0., ProcessImage(L"drawLine_black"));
493
494 // Rect.
495 {
496 SkPaint paint;
497 paint.setColor(SK_ColorGREEN);
498 vcanvas_->drawRectCoords(25, 25, 75, 75, paint);
499 pcanvas_->drawRectCoords(25, 25, 75, 75, paint);
500 }
501 EXPECT_EQ(0., ProcessImage(L"drawRect_green"));
502
503 // A single-point rect doesn't leave any mark.
504 {
505 SkPaint paint;
506 paint.setColor(SK_ColorBLUE);
507 vcanvas_->drawRectCoords(5, 5, 5, 5, paint);
508 pcanvas_->drawRectCoords(5, 5, 5, 5, paint);
509 }
510 EXPECT_EQ(0., ProcessImage(L"drawRect_noop"));
511
512 // Rect.
513 {
514 SkPaint paint;
515 paint.setColor(SK_ColorBLUE);
516 vcanvas_->drawRectCoords(75, 50, 80, 55, paint);
517 pcanvas_->drawRectCoords(75, 50, 80, 55, paint);
518 }
519 EXPECT_EQ(0., ProcessImage(L"drawRect_noop"));
520
521 // Empty again
522 {
523 vcanvas_->drawPaint(SkPaint());
524 pcanvas_->drawPaint(SkPaint());
525 }
526 EXPECT_EQ(0., ProcessImage(L"drawPaint_black"));
527
528 // Horizontal line left to right.
529 {
530 SkPaint paint;
531 paint.setColor(SK_ColorRED);
532 vcanvas_->drawLine(10, 20, 90, 20, paint);
533 pcanvas_->drawLine(10, 20, 90, 20, paint);
534 }
535 EXPECT_EQ(0., ProcessImage(L"drawLine_left_to_right"));
536
537 // Vertical line downward.
538 {
539 SkPaint paint;
540 paint.setColor(SK_ColorRED);
541 vcanvas_->drawLine(30, 10, 30, 90, paint);
542 pcanvas_->drawLine(30, 10, 30, 90, paint);
543 }
544 EXPECT_EQ(0., ProcessImage(L"drawLine_red"));
545 }
546
547 TEST_F(VectorCanvasTest, Circles) {
548 // There is NO WAY to make them agree. At least verify that the output doesn't
549 // change across versions. This test is disabled. See bug 1060231.
550 compare_canvas_ = false;
551
552 // Stroked Circle.
553 {
554 SkPaint paint;
555 SkPath path;
556 path.addCircle(50, 75, 10);
557 paint.setStyle(SkPaint::kStroke_Style);
558 paint.setColor(SK_ColorMAGENTA);
559 vcanvas_->drawPath(path, paint);
560 pcanvas_->drawPath(path, paint);
561 }
562 EXPECT_EQ(0., ProcessImage(L"circle_stroke"));
563
564 // Filled Circle.
565 {
566 SkPaint paint;
567 SkPath path;
568 path.addCircle(50, 25, 10);
569 paint.setStyle(SkPaint::kFill_Style);
570 vcanvas_->drawPath(path, paint);
571 pcanvas_->drawPath(path, paint);
572 }
573 EXPECT_EQ(0., ProcessImage(L"circle_fill"));
574
575 // Stroked Circle over.
576 {
577 SkPaint paint;
578 SkPath path;
579 path.addCircle(50, 25, 10);
580 paint.setStyle(SkPaint::kStroke_Style);
581 paint.setColor(SK_ColorBLUE);
582 vcanvas_->drawPath(path, paint);
583 pcanvas_->drawPath(path, paint);
584 }
585 EXPECT_EQ(0., ProcessImage(L"circle_over_strike"));
586
587 // Stroke and Fill Circle.
588 {
589 SkPaint paint;
590 SkPath path;
591 path.addCircle(12, 50, 10);
592 paint.setStyle(SkPaint::kStrokeAndFill_Style);
593 paint.setColor(SK_ColorRED);
594 vcanvas_->drawPath(path, paint);
595 pcanvas_->drawPath(path, paint);
596 }
597 EXPECT_EQ(0., ProcessImage(L"circle_stroke_and_fill"));
598
599 // Line + Quad + Cubic.
600 {
601 SkPaint paint;
602 SkPath path;
603 paint.setStyle(SkPaint::kStroke_Style);
604 paint.setColor(SK_ColorGREEN);
605 path.moveTo(1, 1);
606 path.lineTo(60, 40);
607 path.lineTo(80, 80);
608 path.quadTo(20, 50, 10, 90);
609 path.quadTo(50, 20, 90, 10);
610 path.cubicTo(20, 40, 50, 50, 10, 10);
611 path.cubicTo(30, 20, 50, 50, 90, 10);
612 path.addRect(90, 90, 95, 96);
613 vcanvas_->drawPath(path, paint);
614 pcanvas_->drawPath(path, paint);
615 }
616 EXPECT_EQ(0., ProcessImage(L"mixed_stroke"));
617 }
618
619 TEST_F(VectorCanvasTest, LineOrientation) {
620 // There is NO WAY to make them agree. At least verify that the output doesn't
621 // change across versions. This test is disabled. See bug 1060231.
622 compare_canvas_ = false;
623
624 // Horizontal lines.
625 {
626 SkPaint paint;
627 paint.setColor(SK_ColorRED);
628 // Left to right.
629 vcanvas_->drawLine(10, 20, 90, 20, paint);
630 pcanvas_->drawLine(10, 20, 90, 20, paint);
631 // Right to left.
632 vcanvas_->drawLine(90, 30, 10, 30, paint);
633 pcanvas_->drawLine(90, 30, 10, 30, paint);
634 }
635 EXPECT_EQ(0., ProcessImage(L"horizontal"));
636
637 // Vertical lines.
638 {
639 SkPaint paint;
640 paint.setColor(SK_ColorRED);
641 // Top down.
642 vcanvas_->drawLine(20, 10, 20, 90, paint);
643 pcanvas_->drawLine(20, 10, 20, 90, paint);
644 // Bottom up.
645 vcanvas_->drawLine(30, 90, 30, 10, paint);
646 pcanvas_->drawLine(30, 90, 30, 10, paint);
647 }
648 EXPECT_EQ(0., ProcessImage(L"vertical"));
649
650 // Try again with a 180 degres rotation.
651 vcanvas_->rotate(180);
652 pcanvas_->rotate(180);
653
654 // Horizontal lines (rotated).
655 {
656 SkPaint paint;
657 paint.setColor(SK_ColorRED);
658 vcanvas_->drawLine(-10, -25, -90, -25, paint);
659 pcanvas_->drawLine(-10, -25, -90, -25, paint);
660 vcanvas_->drawLine(-90, -35, -10, -35, paint);
661 pcanvas_->drawLine(-90, -35, -10, -35, paint);
662 }
663 EXPECT_EQ(0., ProcessImage(L"horizontal_180"));
664
665 // Vertical lines (rotated).
666 {
667 SkPaint paint;
668 paint.setColor(SK_ColorRED);
669 vcanvas_->drawLine(-25, -10, -25, -90, paint);
670 pcanvas_->drawLine(-25, -10, -25, -90, paint);
671 vcanvas_->drawLine(-35, -90, -35, -10, paint);
672 pcanvas_->drawLine(-35, -90, -35, -10, paint);
673 }
674 EXPECT_EQ(0., ProcessImage(L"vertical_180"));
675 }
676
677 TEST_F(VectorCanvasTest, PathOrientation) {
678 // There is NO WAY to make them agree. At least verify that the output doesn't
679 // change across versions. This test is disabled. See bug 1060231.
680 compare_canvas_ = false;
681
682 // Horizontal lines.
683 {
684 SkPaint paint;
685 paint.setStyle(SkPaint::kStroke_Style);
686 paint.setColor(SK_ColorRED);
687 SkPath path;
688 SkPoint start;
689 start.set(10, 20);
690 SkPoint end;
691 end.set(90, 20);
692 path.moveTo(start);
693 path.lineTo(end);
694 vcanvas_->drawPath(path, paint);
695 pcanvas_->drawPath(path, paint);
696 }
697 EXPECT_EQ(0., ProcessImage(L"drawPath_ltr"));
698
699 // Horizontal lines.
700 {
701 SkPaint paint;
702 paint.setStyle(SkPaint::kStroke_Style);
703 paint.setColor(SK_ColorRED);
704 SkPath path;
705 SkPoint start;
706 start.set(90, 30);
707 SkPoint end;
708 end.set(10, 30);
709 path.moveTo(start);
710 path.lineTo(end);
711 vcanvas_->drawPath(path, paint);
712 pcanvas_->drawPath(path, paint);
713 }
714 EXPECT_EQ(0., ProcessImage(L"drawPath_rtl"));
715 }
716
717 TEST_F(VectorCanvasTest, DiagonalLines) {
718 SkPaint paint;
719 paint.setColor(SK_ColorRED);
720
721 vcanvas_->drawLine(10, 10, 90, 90, paint);
722 pcanvas_->drawLine(10, 10, 90, 90, paint);
723 EXPECT_EQ(0., ProcessImage(L"nw-se"));
724
725 // Starting here, there is NO WAY to make them agree. At least verify that the
726 // output doesn't change across versions. This test is disabled. See bug
727 // 1060231.
728 compare_canvas_ = false;
729
730 vcanvas_->drawLine(10, 95, 90, 15, paint);
731 pcanvas_->drawLine(10, 95, 90, 15, paint);
732 EXPECT_EQ(0., ProcessImage(L"sw-ne"));
733
734 vcanvas_->drawLine(90, 10, 10, 90, paint);
735 pcanvas_->drawLine(90, 10, 10, 90, paint);
736 EXPECT_EQ(0., ProcessImage(L"ne-sw"));
737
738 vcanvas_->drawLine(95, 90, 15, 10, paint);
739 pcanvas_->drawLine(95, 90, 15, 10, paint);
740 EXPECT_EQ(0., ProcessImage(L"se-nw"));
741 }
742
743 TEST_F(VectorCanvasTest, PathEffects) {
744 {
745 SkPaint paint;
746 SkScalar intervals[] = { 1, 1 };
747 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
748 0);
749 paint.setPathEffect(effect)->unref();
750 paint.setColor(SK_ColorMAGENTA);
751 paint.setStyle(SkPaint::kStroke_Style);
752
753 vcanvas_->drawLine(10, 10, 90, 10, paint);
754 pcanvas_->drawLine(10, 10, 90, 10, paint);
755 }
756 EXPECT_EQ(0., ProcessImage(L"dash_line"));
757
758
759 // Starting here, there is NO WAY to make them agree. At least verify that the
760 // output doesn't change across versions. This test is disabled. See bug
761 // 1060231.
762 compare_canvas_ = false;
763
764 {
765 SkPaint paint;
766 SkScalar intervals[] = { 3, 5 };
767 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
768 0);
769 paint.setPathEffect(effect)->unref();
770 paint.setColor(SK_ColorMAGENTA);
771 paint.setStyle(SkPaint::kStroke_Style);
772
773 SkPath path;
774 path.moveTo(10, 15);
775 path.lineTo(90, 15);
776 path.lineTo(90, 90);
777 vcanvas_->drawPath(path, paint);
778 pcanvas_->drawPath(path, paint);
779 }
780 EXPECT_EQ(0., ProcessImage(L"dash_path"));
781
782 {
783 SkPaint paint;
784 SkScalar intervals[] = { 2, 1 };
785 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
786 0);
787 paint.setPathEffect(effect)->unref();
788 paint.setColor(SK_ColorMAGENTA);
789 paint.setStyle(SkPaint::kStroke_Style);
790
791 vcanvas_->drawRectCoords(20, 20, 30, 30, paint);
792 pcanvas_->drawRectCoords(20, 20, 30, 30, paint);
793 }
794 EXPECT_EQ(0., ProcessImage(L"dash_rect"));
795
796 // This thing looks like it has been drawn by a 3 years old kid. I haven't
797 // filed a bug on this since I guess nobody is expecting this to look nice.
798 {
799 SkPaint paint;
800 SkScalar intervals[] = { 1, 1 };
801 SkPathEffect* effect = new SkDashPathEffect(intervals, arraysize(intervals),
802 0);
803 paint.setPathEffect(effect)->unref();
804 paint.setColor(SK_ColorMAGENTA);
805 paint.setStyle(SkPaint::kStroke_Style);
806
807 SkPath path;
808 path.addCircle(50, 75, 10);
809 vcanvas_->drawPath(path, paint);
810 pcanvas_->drawPath(path, paint);
811 EXPECT_EQ(0., ProcessImage(L"circle"));
812 }
813 }
814
815 TEST_F(VectorCanvasTest, Bitmaps) {
816 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
817 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
818 // really care about Windows 2000 pixel colors.
819 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
820 return;
821 {
822 SkBitmap bitmap;
823 LoadPngFileToSkBitmap(test_file(L"bitmap_opaque.png"), &bitmap);
824 vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
825 pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
826 EXPECT_EQ(0., ProcessImage(L"opaque"));
827 }
828
829 {
830 SkBitmap bitmap;
831 LoadPngFileToSkBitmap(test_file(L"bitmap_alpha.png"), &bitmap);
832 vcanvas_->drawBitmap(bitmap, 5, 15, NULL);
833 pcanvas_->drawBitmap(bitmap, 5, 15, NULL);
834 EXPECT_EQ(0., ProcessImage(L"alpha"));
835 }
836 }
837
838 TEST_F(VectorCanvasTest, ClippingRect) {
839 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
840 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
841 // really care about Windows 2000 pixel colors.
842 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
843 return;
844 SkBitmap bitmap;
845 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
846 SkRect rect;
847 rect.fLeft = 2;
848 rect.fTop = 2;
849 rect.fRight = 30.5f;
850 rect.fBottom = 30.5f;
851 vcanvas_->clipRect(rect);
852 pcanvas_->clipRect(rect);
853
854 vcanvas_->drawBitmap(bitmap, 13, 3, NULL);
855 pcanvas_->drawBitmap(bitmap, 13, 3, NULL);
856 EXPECT_EQ(0., ProcessImage(L"rect"));
857 }
858
859 TEST_F(VectorCanvasTest, ClippingPath) {
860 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
861 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
862 // really care about Windows 2000 pixel colors.
863 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
864 return;
865 SkBitmap bitmap;
866 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
867 SkPath path;
868 path.addCircle(20, 20, 10);
869 vcanvas_->clipPath(path);
870 pcanvas_->clipPath(path);
871
872 vcanvas_->drawBitmap(bitmap, 14, 3, NULL);
873 pcanvas_->drawBitmap(bitmap, 14, 3, NULL);
874 EXPECT_EQ(0., ProcessImage(L"path"));
875 }
876
877 TEST_F(VectorCanvasTest, ClippingCombined) {
878 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
879 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
880 // really care about Windows 2000 pixel colors.
881 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
882 return;
883 SkBitmap bitmap;
884 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
885
886 SkRect rect;
887 rect.fLeft = 2;
888 rect.fTop = 2;
889 rect.fRight = 30.5f;
890 rect.fBottom = 30.5f;
891 vcanvas_->clipRect(rect);
892 pcanvas_->clipRect(rect);
893 SkPath path;
894 path.addCircle(20, 20, 10);
895 vcanvas_->clipPath(path, SkRegion::kUnion_Op);
896 pcanvas_->clipPath(path, SkRegion::kUnion_Op);
897
898 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
899 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
900 EXPECT_EQ(0., ProcessImage(L"combined"));
901 }
902
903 TEST_F(VectorCanvasTest, ClippingIntersect) {
904 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
905 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
906 // really care about Windows 2000 pixel colors.
907 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
908 return;
909 SkBitmap bitmap;
910 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
911
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);
919 SkPath path;
920 path.addCircle(23, 23, 15);
921 vcanvas_->clipPath(path);
922 pcanvas_->clipPath(path);
923
924 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
925 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
926 EXPECT_EQ(0., ProcessImage(L"intersect"));
927 }
928
929 TEST_F(VectorCanvasTest, ClippingClean) {
930 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
931 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
932 // really care about Windows 2000 pixel colors.
933 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
934 return;
935 SkBitmap bitmap;
936 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
937 {
938 SkRegion old_region(pcanvas_->getTotalClip());
939 SkRect rect;
940 rect.fLeft = 2;
941 rect.fTop = 2;
942 rect.fRight = 30.5f;
943 rect.fBottom = 30.5f;
944 vcanvas_->clipRect(rect);
945 pcanvas_->clipRect(rect);
946
947 vcanvas_->drawBitmap(bitmap, 15, 3, NULL);
948 pcanvas_->drawBitmap(bitmap, 15, 3, NULL);
949 EXPECT_EQ(0., ProcessImage(L"clipped"));
950 vcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
951 pcanvas_->clipRegion(old_region, SkRegion::kReplace_Op);
952 }
953 {
954 // Verify that the clipping region has been fixed back.
955 vcanvas_->drawBitmap(bitmap, 55, 3, NULL);
956 pcanvas_->drawBitmap(bitmap, 55, 3, NULL);
957 EXPECT_EQ(0., ProcessImage(L"unclipped"));
958 }
959 }
960
961 TEST_F(VectorCanvasTest, Matrix) {
962 // ICM is enabled on VectorCanvas only on Windows 2000 so bitmap-based tests
963 // can't compare the pixels between PlatformCanvas and VectorCanvas. We don't
964 // really care about Windows 2000 pixel colors.
965 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000)
966 return;
967 SkBitmap bitmap;
968 LoadPngFileToSkBitmap(test_file(L"..\\bitmaps\\bitmap_opaque.png"), &bitmap);
969 {
970 vcanvas_->translate(15, 3);
971 pcanvas_->translate(15, 3);
972 vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
973 pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
974 EXPECT_EQ(0., ProcessImage(L"translate1"));
975 }
976 {
977 vcanvas_->translate(-30, -23);
978 pcanvas_->translate(-30, -23);
979 vcanvas_->drawBitmap(bitmap, 0, 0, NULL);
980 pcanvas_->drawBitmap(bitmap, 0, 0, NULL);
981 EXPECT_EQ(0., ProcessImage(L"translate2"));
982 }
983 vcanvas_->resetMatrix();
984 pcanvas_->resetMatrix();
985
986 // For scaling and rotation, they use a different algorithm (nearest
987 // neighborhood vs smoothing). At least verify that the output doesn't change
988 // across versions.
989 compare_canvas_ = false;
990
991 {
992 vcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
993 pcanvas_->scale(SkDoubleToScalar(1.9), SkDoubleToScalar(1.5));
994 vcanvas_->drawBitmap(bitmap, 1, 1, NULL);
995 pcanvas_->drawBitmap(bitmap, 1, 1, NULL);
996 EXPECT_EQ(0., ProcessImage(L"scale"));
997 }
998 vcanvas_->resetMatrix();
999 pcanvas_->resetMatrix();
1000
1001 {
1002 vcanvas_->rotate(67);
1003 pcanvas_->rotate(67);
1004 vcanvas_->drawBitmap(bitmap, 20, -50, NULL);
1005 pcanvas_->drawBitmap(bitmap, 20, -50, NULL);
1006 EXPECT_EQ(0., ProcessImage(L"rotate"));
1007 }
1008 }
1009
OLDNEW
« no previous file with comments | « webkit/port/platform/graphics/skia/public/VectorCanvas.cpp ('k') | webkit/tools/test_shell/test_shell_tests.vcproj » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698