| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "skia/ext/vector_canvas.h" | 5 #include "skia/ext/vector_canvas.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/gfx/gdi_util.h" | 11 #include "base/gfx/gdi_util.h" |
| 12 #include "base/gfx/png_decoder.h" | 12 #include "base/gfx/png_decoder.h" |
| 13 #include "base/gfx/png_encoder.h" | 13 #include "base/gfx/png_encoder.h" |
| 14 #include "base/gfx/size.h" | 14 #include "base/gfx/size.h" |
| 15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/win_util.h" | 17 #include "base/win_util.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 19 |
| 20 #include "SkDashPathEffect.h" | 20 #include "SkDashPathEffect.h" |
| 21 | 21 |
| 22 namespace skia { | 22 namespace skia { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 const wchar_t* const kGenerateSwitch = L"vector-canvas-generate"; | 26 const wchar_t* const kGenerateSwitch = L"vector-canvas-generate"; |
| 27 | 27 |
| 28 // Base class for unit test that uses data. It initializes a directory path | |
| 29 // based on the test's name. | |
| 30 class DataUnitTest : public testing::Test { | |
| 31 public: | |
| 32 DataUnitTest(const std::wstring& base_path) : base_path_(base_path) { } | |
| 33 | |
| 34 protected: | |
| 35 // Load the test's data path. | |
| 36 virtual void SetUp() { | |
| 37 const testing::TestInfo& test_info = | |
| 38 *testing::UnitTest::GetInstance()->current_test_info(); | |
| 39 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_); | |
| 40 file_util::AppendToPath(&test_dir_, base_path_); | |
| 41 file_util::AppendToPath(&test_dir_, L"data"); | |
| 42 file_util::AppendToPath(&test_dir_, | |
| 43 ASCIIToWide(test_info.test_case_name())); | |
| 44 file_util::AppendToPath(&test_dir_, ASCIIToWide(test_info.name())); | |
| 45 | |
| 46 // Hack for a quick lowercase. We assume all the tests names are ASCII. | |
| 47 std::string tmp(WideToASCII(test_dir_)); | |
| 48 for (size_t i = 0; i < tmp.size(); ++i) | |
| 49 tmp[i] = ToLowerASCII(tmp[i]); | |
| 50 test_dir_ = ASCIIToWide(tmp); | |
| 51 } | |
| 52 | |
| 53 // Returns the fully qualified path of directory containing test data files. | |
| 54 const std::wstring& test_dir() const { | |
| 55 return test_dir_; | |
| 56 } | |
| 57 | |
| 58 // Returns the fully qualified path of a data file. | |
| 59 std::wstring test_file(const std::wstring& filename) const { | |
| 60 // Hack for a quick lowercase. We assume all the test data file names are | |
| 61 // ASCII. | |
| 62 std::string tmp(WideToASCII(filename)); | |
| 63 for (size_t i = 0; i < tmp.size(); ++i) | |
| 64 tmp[i] = ToLowerASCII(tmp[i]); | |
| 65 | |
| 66 std::wstring path(test_dir()); | |
| 67 file_util::AppendToPath(&path, ASCIIToWide(tmp)); | |
| 68 return path; | |
| 69 } | |
| 70 | |
| 71 private: | |
| 72 // Path where the unit test is coming from: base, net, chrome, etc. | |
| 73 std::wstring base_path_; | |
| 74 | |
| 75 // Path to directory used to contain the test data. | |
| 76 std::wstring test_dir_; | |
| 77 | |
| 78 DISALLOW_EVIL_CONSTRUCTORS(DataUnitTest); | |
| 79 }; | |
| 80 | |
| 81 // Lightweight HDC management. | 28 // Lightweight HDC management. |
| 82 class Context { | 29 class Context { |
| 83 public: | 30 public: |
| 84 Context() : context_(CreateCompatibleDC(NULL)) { | 31 Context() : context_(CreateCompatibleDC(NULL)) { |
| 85 EXPECT_TRUE(context_); | 32 EXPECT_TRUE(context_); |
| 86 } | 33 } |
| 87 ~Context() { | 34 ~Context() { |
| 88 DeleteDC(context_); | 35 DeleteDC(context_); |
| 89 } | 36 } |
| 90 | 37 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 // 0xABGR). | 189 // 0xABGR). |
| 243 std::vector<unsigned char> data_; | 190 std::vector<unsigned char> data_; |
| 244 | 191 |
| 245 // Flag to signal if the comparison functions should ignore the alpha channel. | 192 // Flag to signal if the comparison functions should ignore the alpha channel. |
| 246 const bool ignore_alpha_; | 193 const bool ignore_alpha_; |
| 247 | 194 |
| 248 DISALLOW_EVIL_CONSTRUCTORS(Image); | 195 DISALLOW_EVIL_CONSTRUCTORS(Image); |
| 249 }; | 196 }; |
| 250 | 197 |
| 251 // Base for tests. Capability to process an image. | 198 // Base for tests. Capability to process an image. |
| 252 class ImageTest : public DataUnitTest { | 199 class ImageTest : public testing::Test { |
| 253 public: | 200 public: |
| 254 typedef DataUnitTest parent; | |
| 255 | |
| 256 // In what state is the test running. | 201 // In what state is the test running. |
| 257 enum ProcessAction { | 202 enum ProcessAction { |
| 258 GENERATE, | 203 GENERATE, |
| 259 COMPARE, | 204 COMPARE, |
| 260 NOOP, | 205 NOOP, |
| 261 }; | 206 }; |
| 262 | 207 |
| 263 ImageTest(const std::wstring& base_path, ProcessAction default_action) | 208 ImageTest(ProcessAction default_action) |
| 264 : parent(base_path), | 209 : action_(default_action) { |
| 265 action_(default_action) { | |
| 266 } | 210 } |
| 267 | 211 |
| 268 protected: | 212 protected: |
| 269 virtual void SetUp() { | 213 virtual void SetUp() { |
| 270 parent::SetUp(); | 214 const testing::TestInfo& test_info = |
| 215 *testing::UnitTest::GetInstance()->current_test_info(); |
| 216 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir_); |
| 217 file_util::AppendToPath(&test_dir_, L"skia"); |
| 218 file_util::AppendToPath(&test_dir_, L"ext"); |
| 219 file_util::AppendToPath(&test_dir_, L"data"); |
| 220 file_util::AppendToPath(&test_dir_, |
| 221 ASCIIToWide(test_info.test_case_name())); |
| 222 file_util::AppendToPath(&test_dir_, ASCIIToWide(test_info.name())); |
| 223 |
| 224 // Hack for a quick lowercase. We assume all the tests names are ASCII. |
| 225 std::string tmp(WideToASCII(test_dir_)); |
| 226 for (size_t i = 0; i < tmp.size(); ++i) |
| 227 tmp[i] = ToLowerASCII(tmp[i]); |
| 228 test_dir_ = ASCIIToWide(tmp); |
| 271 | 229 |
| 272 if (action_ == GENERATE) { | 230 if (action_ == GENERATE) { |
| 273 // Make sure the directory exist. | 231 // Make sure the directory exist. |
| 274 file_util::CreateDirectory(test_dir()); | 232 file_util::CreateDirectory(test_dir_); |
| 275 } | 233 } |
| 276 } | 234 } |
| 277 | 235 |
| 236 // Returns the fully qualified path of a data file. |
| 237 std::wstring test_file(const std::wstring& filename) const { |
| 238 // Hack for a quick lowercase. We assume all the test data file names are |
| 239 // ASCII. |
| 240 std::string tmp(WideToASCII(filename)); |
| 241 for (size_t i = 0; i < tmp.size(); ++i) |
| 242 tmp[i] = ToLowerASCII(tmp[i]); |
| 243 |
| 244 std::wstring path(test_dir_); |
| 245 file_util::AppendToPath(&path, ASCIIToWide(tmp)); |
| 246 return path; |
| 247 } |
| 248 |
| 278 // Compares or saves the bitmap currently loaded in the context, depending on | 249 // Compares or saves the bitmap currently loaded in the context, depending on |
| 279 // kGenerating value. Returns 0 on success or any positive value between ]0, | 250 // kGenerating value. Returns 0 on success or any positive value between ]0, |
| 280 // 100] on failure. The return value is the percentage of difference between | 251 // 100] on failure. The return value is the percentage of difference between |
| 281 // the image in the file and the image in the canvas. | 252 // the image in the file and the image in the canvas. |
| 282 double ProcessCanvas(const skia::PlatformCanvasWin& canvas, | 253 double ProcessCanvas(const skia::PlatformCanvasWin& canvas, |
| 283 std::wstring filename) const { | 254 std::wstring filename) const { |
| 284 filename += L".png"; | 255 filename += L".png"; |
| 285 switch (action_) { | 256 switch (action_) { |
| 286 case GENERATE: | 257 case GENERATE: |
| 287 SaveImage(canvas, filename); | 258 SaveImage(canvas, filename); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 307 } | 278 } |
| 308 | 279 |
| 309 // Saves the bitmap currently loaded in the context into the file. | 280 // Saves the bitmap currently loaded in the context into the file. |
| 310 void SaveImage(const skia::PlatformCanvasWin& canvas, | 281 void SaveImage(const skia::PlatformCanvasWin& canvas, |
| 311 const std::wstring& filename) const { | 282 const std::wstring& filename) const { |
| 312 Image(canvas).SaveToFile(test_file(filename)); | 283 Image(canvas).SaveToFile(test_file(filename)); |
| 313 } | 284 } |
| 314 | 285 |
| 315 ProcessAction action_; | 286 ProcessAction action_; |
| 316 | 287 |
| 288 // Path to directory used to contain the test data. |
| 289 std::wstring test_dir_; |
| 290 |
| 317 DISALLOW_EVIL_CONSTRUCTORS(ImageTest); | 291 DISALLOW_EVIL_CONSTRUCTORS(ImageTest); |
| 318 }; | 292 }; |
| 319 | 293 |
| 320 // Premultiply the Alpha channel on the R, B and G channels. | 294 // Premultiply the Alpha channel on the R, B and G channels. |
| 321 void Premultiply(SkBitmap bitmap) { | 295 void Premultiply(SkBitmap bitmap) { |
| 322 SkAutoLockPixels lock(bitmap); | 296 SkAutoLockPixels lock(bitmap); |
| 323 for (int x = 0; x < bitmap.width(); ++x) { | 297 for (int x = 0; x < bitmap.width(); ++x) { |
| 324 for (int y = 0; y < bitmap.height(); ++y) { | 298 for (int y = 0; y < bitmap.height(); ++y) { |
| 325 uint32_t* pixel_addr = bitmap.getAddr32(x, y); | 299 uint32_t* pixel_addr = bitmap.getAddr32(x, y); |
| 326 uint32_t color = *pixel_addr; | 300 uint32_t color = *pixel_addr; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 return out << "Image(" << image.size().width() << ", " | 334 return out << "Image(" << image.size().width() << ", " |
| 361 << image.size().height() << ", " << image.row_length() << ")"; | 335 << image.size().height() << ", " << image.row_length() << ")"; |
| 362 } | 336 } |
| 363 | 337 |
| 364 // Runs simultaneously the same drawing commands on VectorCanvas and | 338 // Runs simultaneously the same drawing commands on VectorCanvas and |
| 365 // PlatformCanvas and compare the results. | 339 // PlatformCanvas and compare the results. |
| 366 class VectorCanvasTest : public ImageTest { | 340 class VectorCanvasTest : public ImageTest { |
| 367 public: | 341 public: |
| 368 typedef ImageTest parent; | 342 typedef ImageTest parent; |
| 369 | 343 |
| 370 VectorCanvasTest() : parent(L"base", CurrentMode()), compare_canvas_(true) { | 344 VectorCanvasTest() : parent(CurrentMode()), compare_canvas_(true) { |
| 371 } | 345 } |
| 372 | 346 |
| 373 protected: | 347 protected: |
| 374 virtual void SetUp() { | 348 virtual void SetUp() { |
| 375 parent::SetUp(); | 349 parent::SetUp(); |
| 376 Init(100); | 350 Init(100); |
| 377 number_ = 0; | 351 number_ = 0; |
| 378 } | 352 } |
| 379 | 353 |
| 380 virtual void TearDown() { | 354 virtual void TearDown() { |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 { | 977 { |
| 1004 vcanvas_->rotate(67); | 978 vcanvas_->rotate(67); |
| 1005 pcanvas_->rotate(67); | 979 pcanvas_->rotate(67); |
| 1006 vcanvas_->drawBitmap(bitmap, 20, -50, NULL); | 980 vcanvas_->drawBitmap(bitmap, 20, -50, NULL); |
| 1007 pcanvas_->drawBitmap(bitmap, 20, -50, NULL); | 981 pcanvas_->drawBitmap(bitmap, 20, -50, NULL); |
| 1008 EXPECT_EQ(0., ProcessImage(L"rotate")); | 982 EXPECT_EQ(0., ProcessImage(L"rotate")); |
| 1009 } | 983 } |
| 1010 } | 984 } |
| 1011 | 985 |
| 1012 } // namespace skia | 986 } // namespace skia |
| OLD | NEW |