Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "ui/gfx/paint_vector_icon.h" | 5 #include "ui/gfx/paint_vector_icon.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <tuple> | 8 #include <tuple> |
| 9 | 9 |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 public: | 313 public: |
| 314 VectorIconSource(VectorIconId id, | 314 VectorIconSource(VectorIconId id, |
| 315 size_t dip_size, | 315 size_t dip_size, |
| 316 SkColor color, | 316 SkColor color, |
| 317 VectorIconId badge_id) | 317 VectorIconId badge_id) |
| 318 : CanvasImageSource( | 318 : CanvasImageSource( |
| 319 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | 319 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), |
| 320 false), | 320 false), |
| 321 id_(id), | 321 id_(id), |
| 322 color_(color), | 322 color_(color), |
| 323 badge_id_(badge_id) {} | 323 badge_id_(badge_id), |
| 324 icon_(nullptr), | |
| 325 badge_(nullptr) {} | |
| 324 | 326 |
| 325 VectorIconSource(const std::string& definition, | 327 VectorIconSource(const std::string& definition, |
| 326 size_t dip_size, | 328 size_t dip_size, |
| 327 SkColor color) | 329 SkColor color) |
| 328 : CanvasImageSource( | 330 : CanvasImageSource( |
| 329 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | 331 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), |
| 330 false), | 332 false), |
| 331 id_(VectorIconId::VECTOR_ICON_NONE), | 333 id_(VectorIconId::VECTOR_ICON_NONE), |
| 332 path_(PathFromSource(definition)), | 334 path_(PathFromSource(definition)), |
| 333 color_(color), | 335 color_(color), |
| 334 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} | 336 badge_id_(VectorIconId::VECTOR_ICON_NONE), |
| 337 icon_(nullptr), | |
| 338 badge_(nullptr) {} | |
| 339 | |
| 340 VectorIconSource(const VectorIcon* icon, | |
| 341 size_t dip_size, | |
| 342 SkColor color, | |
| 343 const VectorIcon* badge_icon) | |
| 344 : CanvasImageSource( | |
| 345 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 346 false), | |
| 347 id_(VectorIconId::VECTOR_ICON_NONE), | |
| 348 color_(color), | |
| 349 badge_id_(VectorIconId::VECTOR_ICON_NONE), | |
| 350 icon_(icon), | |
| 351 badge_(badge_icon) {} | |
| 335 | 352 |
| 336 ~VectorIconSource() override {} | 353 ~VectorIconSource() override {} |
| 337 | 354 |
| 338 // CanvasImageSource: | 355 // CanvasImageSource: |
| 339 bool HasRepresentationAtAllScales() const override { | 356 bool HasRepresentationAtAllScales() const override { |
| 357 if (icon_) | |
| 358 return icon_; | |
| 340 return id_ != VectorIconId::VECTOR_ICON_NONE; | 359 return id_ != VectorIconId::VECTOR_ICON_NONE; |
| 341 } | 360 } |
| 342 | 361 |
| 343 void Draw(gfx::Canvas* canvas) override { | 362 void Draw(gfx::Canvas* canvas) override { |
| 363 if (icon_) { | |
| 364 PaintVectorIcon(canvas, icon_, size_.width(), color_); | |
| 365 if (badge_) | |
| 366 PaintVectorIcon(canvas, badge_, size_.width(), color_); | |
| 367 return; | |
| 368 } | |
| 369 | |
| 344 if (path_.empty()) { | 370 if (path_.empty()) { |
| 345 PaintVectorIcon(canvas, id_, size_.width(), color_); | 371 PaintVectorIcon(canvas, id_, size_.width(), color_); |
| 346 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) | 372 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) |
| 347 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); | 373 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); |
| 348 } else { | 374 } else { |
| 349 PaintPath(canvas, path_.data(), size_.width(), color_); | 375 PaintPath(canvas, path_.data(), size_.width(), color_); |
| 350 } | 376 } |
| 351 } | 377 } |
| 352 | 378 |
| 353 private: | 379 private: |
| 354 const VectorIconId id_; | 380 const VectorIconId id_; |
| 355 const std::vector<PathElement> path_; | 381 const std::vector<PathElement> path_; |
| 356 const SkColor color_; | 382 const SkColor color_; |
| 357 const VectorIconId badge_id_; | 383 const VectorIconId badge_id_; |
| 358 | 384 |
| 385 const VectorIcon* icon_; | |
| 386 const VectorIcon* badge_; | |
| 387 | |
| 359 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | 388 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); |
| 360 }; | 389 }; |
| 361 | 390 |
| 362 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 391 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
| 363 // more than once. This also guarantees the backing data for the images returned | 392 // more than once. This also guarantees the backing data for the images returned |
| 364 // by CreateVectorIcon will persist in memory until program termination. | 393 // by CreateVectorIcon will persist in memory until program termination. |
| 365 class VectorIconCache { | 394 class VectorIconCache { |
| 366 public: | 395 public: |
| 367 VectorIconCache() {} | 396 VectorIconCache() {} |
| 368 ~VectorIconCache() {} | 397 ~VectorIconCache() {} |
| 369 | 398 |
| 399 ImageSkia GetOrCreateIcon(const VectorIcon* icon, | |
| 400 size_t dip_size, | |
| 401 SkColor color, | |
| 402 const VectorIcon* badge_icon) { | |
| 403 IconDescription description(icon, dip_size, color, badge_icon); | |
| 404 auto iter = images_.find(description); | |
| 405 if (iter != images_.end()) | |
| 406 return iter->second; | |
| 407 | |
| 408 ImageSkia icon_image( | |
| 409 new VectorIconSource(icon, dip_size, color, badge_icon), | |
| 410 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 411 images_.insert(std::make_pair(description, icon_image)); | |
| 412 return icon_image; | |
| 413 } | |
| 414 | |
| 415 private: | |
| 416 struct IconDescription { | |
| 417 IconDescription(const VectorIcon* icon, | |
| 418 size_t dip_size, | |
| 419 SkColor color, | |
| 420 const VectorIcon* badge_icon) | |
| 421 : icon(icon), | |
| 422 dip_size(dip_size), | |
| 423 color(color), | |
| 424 badge_icon(badge_icon) {} | |
| 425 | |
| 426 bool operator<(const IconDescription& other) const { | |
| 427 return std::tie(icon, dip_size, color, badge_icon) < | |
| 428 std::tie(other.icon, other.dip_size, other.color, | |
| 429 other.badge_icon); | |
| 430 } | |
| 431 | |
| 432 const gfx::VectorIcon* icon; | |
| 433 size_t dip_size; | |
| 434 SkColor color; | |
| 435 const gfx::VectorIcon* badge_icon; | |
| 436 }; | |
| 437 | |
| 438 std::map<IconDescription, ImageSkia> images_; | |
| 439 | |
| 440 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | |
| 441 }; | |
| 442 | |
| 443 static base::LazyInstance<VectorIconCache> g_icon_cache = | |
| 444 LAZY_INSTANCE_INITIALIZER; | |
| 445 | |
| 446 class VectorIconCacheLegacy { | |
| 447 public: | |
| 448 VectorIconCacheLegacy() {} | |
| 449 ~VectorIconCacheLegacy() {} | |
| 450 | |
| 370 ImageSkia GetOrCreateIcon(VectorIconId id, | 451 ImageSkia GetOrCreateIcon(VectorIconId id, |
| 371 size_t dip_size, | 452 size_t dip_size, |
| 372 SkColor color, | 453 SkColor color, |
| 373 VectorIconId badge_id) { | 454 VectorIconId badge_id) { |
| 374 IconDescription description(id, dip_size, color, badge_id); | 455 IconDescription description(id, dip_size, color, badge_id); |
| 375 auto iter = images_.find(description); | 456 auto iter = images_.find(description); |
| 376 if (iter != images_.end()) | 457 if (iter != images_.end()) |
| 377 return iter->second; | 458 return iter->second; |
| 378 | 459 |
| 379 ImageSkia icon( | 460 ImageSkia icon( |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 397 } | 478 } |
| 398 | 479 |
| 399 VectorIconId id; | 480 VectorIconId id; |
| 400 size_t dip_size; | 481 size_t dip_size; |
| 401 SkColor color; | 482 SkColor color; |
| 402 VectorIconId badge_id; | 483 VectorIconId badge_id; |
| 403 }; | 484 }; |
| 404 | 485 |
| 405 std::map<IconDescription, ImageSkia> images_; | 486 std::map<IconDescription, ImageSkia> images_; |
| 406 | 487 |
| 407 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 488 DISALLOW_COPY_AND_ASSIGN(VectorIconCacheLegacy); |
| 408 }; | 489 }; |
| 409 | 490 |
| 410 static base::LazyInstance<VectorIconCache> g_icon_cache = | 491 static base::LazyInstance<VectorIconCacheLegacy> g_icon_cache_legacy = |
| 411 LAZY_INSTANCE_INITIALIZER; | 492 LAZY_INSTANCE_INITIALIZER; |
| 412 | 493 |
| 413 } // namespace | 494 } // namespace |
| 414 | 495 |
| 415 void PaintVectorIcon(Canvas* canvas, | 496 void PaintVectorIcon(Canvas* canvas, |
| 416 VectorIconId id, | 497 VectorIconId id, |
| 417 size_t dip_size, | 498 size_t dip_size, |
| 418 SkColor color) { | 499 SkColor color) { |
| 419 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | 500 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); |
| 420 const PathElement* path = canvas->image_scale() == 1.f | 501 const PathElement* path = canvas->image_scale() == 1.f |
| 421 ? GetPathForVectorIconAt1xScale(id) | 502 ? GetPathForVectorIconAt1xScale(id) |
| 422 : GetPathForVectorIcon(id); | 503 : GetPathForVectorIcon(id); |
| 423 PaintPath(canvas, path, dip_size, color); | 504 PaintPath(canvas, path, dip_size, color); |
| 424 } | 505 } |
| 425 | 506 |
| 507 void PaintVectorIcon(Canvas* canvas, | |
| 508 const VectorIcon* icon, | |
| 509 size_t dip_size, | |
| 510 SkColor color) { | |
| 511 DCHECK(icon); | |
| 512 const PathElement* path = (canvas->image_scale() == 1.f && icon->path_1x) | |
| 513 ? icon->path_1x | |
| 514 : icon->path; | |
| 515 PaintPath(canvas, path, dip_size, color); | |
| 516 } | |
| 517 | |
| 426 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { | 518 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { |
| 427 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); | 519 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); |
| 428 size_t size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | 520 size_t size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg |
| 429 : kReferenceSizeDip; | 521 : kReferenceSizeDip; |
| 430 return CreateVectorIcon(id, size, color); | 522 return CreateVectorIcon(id, size, color); |
| 431 } | 523 } |
| 432 | 524 |
| 525 ImageSkia CreateVectorIcon(const VectorIcon* icon, SkColor color) { | |
| 526 const PathElement* one_x_path = icon->path_1x ? icon->path_1x : icon->path; | |
| 527 size_t size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | |
| 528 : kReferenceSizeDip; | |
|
tdanderson
2016/08/19 21:23:35
Alternatively, we could do this work upfront and a
sadrul
2016/08/22 15:14:05
Yeah, that sounds like a good option. (may be a ba
tdanderson
2016/08/25 21:54:32
Will keep in mind as part of follow-up.
| |
| 529 return CreateVectorIcon(icon, size, color); | |
| 530 } | |
| 531 | |
| 433 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { | 532 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { |
| 434 return CreateVectorIconWithBadge(id, dip_size, color, | 533 return CreateVectorIconWithBadge(id, dip_size, color, |
| 435 VectorIconId::VECTOR_ICON_NONE); | 534 VectorIconId::VECTOR_ICON_NONE); |
| 436 } | 535 } |
| 437 | 536 |
| 537 ImageSkia CreateVectorIcon(const VectorIcon* icon, | |
| 538 size_t dip_size, | |
| 539 SkColor color) { | |
| 540 return CreateVectorIconWithBadge(icon, dip_size, color, nullptr); | |
| 541 } | |
| 542 | |
| 438 ImageSkia CreateVectorIconWithBadge(VectorIconId id, | 543 ImageSkia CreateVectorIconWithBadge(VectorIconId id, |
| 439 size_t dip_size, | 544 size_t dip_size, |
| 440 SkColor color, | 545 SkColor color, |
| 441 VectorIconId badge_id) { | 546 VectorIconId badge_id) { |
| 442 return (id == VectorIconId::VECTOR_ICON_NONE) | 547 return (id == VectorIconId::VECTOR_ICON_NONE) |
| 443 ? gfx::ImageSkia() | 548 ? gfx::ImageSkia() |
| 444 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, | 549 : g_icon_cache_legacy.Get().GetOrCreateIcon(id, dip_size, color, |
| 445 badge_id); | 550 badge_id); |
| 551 } | |
| 552 | |
| 553 ImageSkia CreateVectorIconWithBadge(const VectorIcon* icon, | |
| 554 size_t dip_size, | |
| 555 SkColor color, | |
| 556 const VectorIcon* badge_icon) { | |
| 557 if (!icon) | |
| 558 return gfx::ImageSkia(); | |
| 559 return g_icon_cache.Get().GetOrCreateIcon(icon, dip_size, color, badge_icon); | |
| 446 } | 560 } |
| 447 | 561 |
| 448 ImageSkia CreateVectorIconFromSource(const std::string& source, | 562 ImageSkia CreateVectorIconFromSource(const std::string& source, |
|
tdanderson
2016/08/19 21:23:35
As a side note, vector_example (in views_examples)
| |
| 449 size_t dip_size, | 563 size_t dip_size, |
| 450 SkColor color) { | 564 SkColor color) { |
| 451 return ImageSkia( | 565 return ImageSkia( |
| 452 new VectorIconSource(source, dip_size, color), | 566 new VectorIconSource(source, dip_size, color), |
| 453 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | 567 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); |
| 454 } | 568 } |
| 455 | 569 |
| 456 } // namespace gfx | 570 } // namespace gfx |
| OLD | NEW |