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

Side by Side Diff: ui/gfx/paint_vector_icon.cc

Issue 2892563004: Use animated vector icon for app menu notification animation. (Closed)
Patch Set: git add Created 3 years, 7 months 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
OLDNEW
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"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
16 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
17 #include "cc/paint/paint_canvas.h" 17 #include "cc/paint/paint_canvas.h"
18 #include "cc/paint/paint_flags.h" 18 #include "cc/paint/paint_flags.h"
19 #include "third_party/skia/include/core/SkPath.h" 19 #include "third_party/skia/include/core/SkPath.h"
20 #include "ui/gfx/animation/tween.h" 20 #include "ui/gfx/animation/tween.h"
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/color_palette.h"
22 #include "ui/gfx/image/canvas_image_source.h" 23 #include "ui/gfx/image/canvas_image_source.h"
23 #include "ui/gfx/scoped_canvas.h" 24 #include "ui/gfx/scoped_canvas.h"
24 #include "ui/gfx/vector_icon_types.h" 25 #include "ui/gfx/vector_icon_types.h"
25 26
26 namespace gfx { 27 namespace gfx {
27 28
28 namespace { 29 namespace {
29 30
30 // Helper that simplifies iterating over a sequence of PathElements. 31 // Helper that simplifies iterating over a sequence of PathElements.
31 class PathParser { 32 class PathParser {
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!clip_rect.isEmpty()) 431 if (!clip_rect.isEmpty())
431 canvas->sk_canvas()->clipRect(clip_rect); 432 canvas->sk_canvas()->clipRect(clip_rect);
432 433
433 DCHECK_EQ(flags_array.size(), paths.size()); 434 DCHECK_EQ(flags_array.size(), paths.size());
434 for (size_t i = 0; i < paths.size(); ++i) 435 for (size_t i = 0; i < paths.size(); ++i)
435 canvas->DrawPath(paths[i], flags_array[i]); 436 canvas->DrawPath(paths[i], flags_array[i]);
436 } 437 }
437 438
438 class VectorIconSource : public CanvasImageSource { 439 class VectorIconSource : public CanvasImageSource {
439 public: 440 public:
440 VectorIconSource(const VectorIcon& icon, 441 explicit VectorIconSource(const IconDescription& data)
441 int dip_size, 442 : CanvasImageSource(Size(data.dip_size, data.dip_size), false),
442 SkColor color, 443 data_(data) {}
443 const VectorIcon& badge_icon)
444 : CanvasImageSource(Size(dip_size, dip_size), false),
445 color_(color),
446 icon_(icon),
447 badge_(badge_icon) {}
448 444
449 VectorIconSource(const std::string& definition, int dip_size, SkColor color) 445 VectorIconSource(const std::string& definition, int dip_size, SkColor color)
450 : CanvasImageSource(Size(dip_size, dip_size), false), 446 : CanvasImageSource(Size(dip_size, dip_size), false),
451 color_(color), 447 data_(kNoneIcon, dip_size, color, base::TimeDelta(), kNoneIcon),
452 icon_(kNoneIcon),
453 badge_(kNoneIcon),
454 path_(PathFromSource(definition)) {} 448 path_(PathFromSource(definition)) {}
455 449
456 ~VectorIconSource() override {} 450 ~VectorIconSource() override {}
457 451
458 // CanvasImageSource: 452 // CanvasImageSource:
459 bool HasRepresentationAtAllScales() const override { 453 bool HasRepresentationAtAllScales() const override {
460 return !icon_.is_empty(); 454 return !data_.icon.is_empty();
461 } 455 }
462 456
463 void Draw(Canvas* canvas) override { 457 void Draw(Canvas* canvas) override {
464 if (path_.empty()) { 458 if (path_.empty()) {
465 PaintVectorIcon(canvas, icon_, size_.width(), color_); 459 PaintVectorIcon(canvas, data_.icon, size_.width(), data_.color,
466 if (!badge_.is_empty()) 460 data_.elapsed_time);
467 PaintVectorIcon(canvas, badge_, size_.width(), color_); 461 if (!data_.badge_icon.is_empty())
462 PaintVectorIcon(canvas, data_.badge_icon, size_.width(), data_.color);
468 } else { 463 } else {
469 PaintPath(canvas, path_.data(), size_.width(), color_, base::TimeDelta()); 464 PaintPath(canvas, path_.data(), size_.width(), data_.color,
465 base::TimeDelta());
470 } 466 }
471 } 467 }
472 468
473 private: 469 private:
474 const SkColor color_; 470 const IconDescription data_;
475 const VectorIcon& icon_;
476 const VectorIcon& badge_;
477 const std::vector<PathElement> path_; 471 const std::vector<PathElement> path_;
478 472
479 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); 473 DISALLOW_COPY_AND_ASSIGN(VectorIconSource);
480 }; 474 };
481 475
482 // This class caches vector icons (as ImageSkia) so they don't have to be drawn 476 // This class caches vector icons (as ImageSkia) so they don't have to be drawn
483 // more than once. This also guarantees the backing data for the images returned 477 // more than once. This also guarantees the backing data for the images returned
484 // by CreateVectorIcon will persist in memory until program termination. 478 // by CreateVectorIcon will persist in memory until program termination.
485 class VectorIconCache { 479 class VectorIconCache {
486 public: 480 public:
487 VectorIconCache() {} 481 VectorIconCache() {}
488 ~VectorIconCache() {} 482 ~VectorIconCache() {}
489 483
490 ImageSkia GetOrCreateIcon(const VectorIcon& icon, 484 ImageSkia GetOrCreateIcon(const IconDescription& description) {
491 int dip_size,
492 SkColor color,
493 const VectorIcon& badge_icon) {
494 IconDescription description(&icon, dip_size, color, &badge_icon);
495 auto iter = images_.find(description); 485 auto iter = images_.find(description);
496 if (iter != images_.end()) 486 if (iter != images_.end())
497 return iter->second; 487 return iter->second;
498 488
499 ImageSkia icon_image( 489 ImageSkia icon_image(new VectorIconSource(description),
500 new VectorIconSource(icon, dip_size, color, badge_icon), 490 Size(description.dip_size, description.dip_size));
501 Size(dip_size, dip_size));
502 images_.insert(std::make_pair(description, icon_image)); 491 images_.insert(std::make_pair(description, icon_image));
503 return icon_image; 492 return icon_image;
504 } 493 }
505 494
506 private: 495 private:
507 struct IconDescription {
508 IconDescription(const VectorIcon* icon,
509 int dip_size,
510 SkColor color,
511 const VectorIcon* badge_icon)
512 : icon(icon),
513 dip_size(dip_size),
514 color(color),
515 badge_icon(badge_icon) {}
516
517 bool operator<(const IconDescription& other) const {
518 return std::tie(icon, dip_size, color, badge_icon) <
519 std::tie(other.icon, other.dip_size, other.color,
520 other.badge_icon);
521 }
522
523 const VectorIcon* icon;
524 int dip_size;
525 SkColor color;
526 const VectorIcon* badge_icon;
527 };
528
529 std::map<IconDescription, ImageSkia> images_; 496 std::map<IconDescription, ImageSkia> images_;
530 497
531 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); 498 DISALLOW_COPY_AND_ASSIGN(VectorIconCache);
532 }; 499 };
533 500
534 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache = 501 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache =
535 LAZY_INSTANCE_INITIALIZER; 502 LAZY_INSTANCE_INITIALIZER;
536 503
537 } // namespace 504 } // namespace
538 505
506 IconDescription::IconDescription(const IconDescription& other) = default;
507
508 IconDescription::IconDescription(const VectorIcon& icon,
509 int dip_size,
510 SkColor color,
511 const base::TimeDelta& elapsed_time,
512 const VectorIcon& badge_icon)
513 : icon(icon),
514 dip_size(dip_size),
515 color(color),
516 elapsed_time(elapsed_time),
517 badge_icon(badge_icon) {
518 if (dip_size == 0)
519 this->dip_size = GetDefaultSizeOfVectorIcon(icon);
520 }
521
522 IconDescription::~IconDescription() {}
523
524 bool IconDescription::operator<(const IconDescription& other) const {
525 const VectorIcon* this_icon = &icon;
526 const VectorIcon* other_icon = &other.icon;
527 const VectorIcon* this_badge = &badge_icon;
528 const VectorIcon* other_badge = &other.badge_icon;
529 return std::tie(this_icon, dip_size, color, elapsed_time, this_badge) <
530 std::tie(other_icon, other.dip_size, other.color, other.elapsed_time,
sadrul 2017/05/24 17:35:13 This is .. comparing pointers?
Evan Stade 2017/05/24 17:47:53 yes. This is not new. Our code is already doing th
531 other_badge);
532 }
533
539 const VectorIcon kNoneIcon = {}; 534 const VectorIcon kNoneIcon = {};
540 535
541 void PaintVectorIcon(Canvas* canvas, 536 void PaintVectorIcon(Canvas* canvas,
542 const VectorIcon& icon, 537 const VectorIcon& icon,
543 SkColor color, 538 SkColor color,
544 const base::TimeDelta& elapsed_time) { 539 const base::TimeDelta& elapsed_time) {
545 PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color, 540 PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color,
546 elapsed_time); 541 elapsed_time);
547 } 542 }
548 543
549 void PaintVectorIcon(Canvas* canvas, 544 void PaintVectorIcon(Canvas* canvas,
550 const VectorIcon& icon, 545 const VectorIcon& icon,
551 int dip_size, 546 int dip_size,
552 SkColor color, 547 SkColor color,
553 const base::TimeDelta& elapsed_time) { 548 const base::TimeDelta& elapsed_time) {
554 DCHECK(!icon.is_empty()); 549 DCHECK(!icon.is_empty());
555 const PathElement* path = 550 const PathElement* path =
556 (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path; 551 (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path;
557 PaintPath(canvas, path, dip_size, color, elapsed_time); 552 PaintPath(canvas, path, dip_size, color, elapsed_time);
558 } 553 }
559 554
555 ImageSkia CreateVectorIcon(const IconDescription& params) {
556 if (params.icon.is_empty())
557 return gfx::ImageSkia();
558
559 return g_icon_cache.Get().GetOrCreateIcon(params);
560 }
561
560 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) { 562 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) {
561 return CreateVectorIcon(icon, GetDefaultSizeOfVectorIcon(icon), color); 563 return CreateVectorIcon(icon, GetDefaultSizeOfVectorIcon(icon), color);
562 } 564 }
563 565
564 ImageSkia CreateVectorIcon(const VectorIcon& icon, 566 ImageSkia CreateVectorIcon(const VectorIcon& icon,
565 int dip_size, 567 int dip_size,
566 SkColor color) { 568 SkColor color) {
567 return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon); 569 return CreateVectorIcon(
570 IconDescription(icon, dip_size, color, base::TimeDelta(), kNoneIcon));
568 } 571 }
569 572
570 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon, 573 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon,
571 int dip_size, 574 int dip_size,
572 SkColor color, 575 SkColor color,
573 const VectorIcon& badge_icon) { 576 const VectorIcon& badge_icon) {
574 return icon.is_empty() ? ImageSkia() 577 return CreateVectorIcon(
575 : g_icon_cache.Get().GetOrCreateIcon( 578 IconDescription(icon, dip_size, color, base::TimeDelta(), badge_icon));
576 icon, dip_size, color, badge_icon);
577 } 579 }
578 580
579 ImageSkia CreateVectorIconFromSource(const std::string& source, 581 ImageSkia CreateVectorIconFromSource(const std::string& source,
580 int dip_size, 582 int dip_size,
581 SkColor color) { 583 SkColor color) {
582 return CanvasImageSource::MakeImageSkia<VectorIconSource>(source, dip_size, 584 return CanvasImageSource::MakeImageSkia<VectorIconSource>(source, dip_size,
583 color); 585 color);
584 } 586 }
585 587
586 int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) { 588 int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) {
(...skipping 11 matching lines...) Expand all
598 600
599 auto end_time = base::TimeDelta::FromMillisecondsD(parser.GetArgument(0)) + 601 auto end_time = base::TimeDelta::FromMillisecondsD(parser.GetArgument(0)) +
600 base::TimeDelta::FromMillisecondsD(parser.GetArgument(1)); 602 base::TimeDelta::FromMillisecondsD(parser.GetArgument(1));
601 if (end_time > last_motion) 603 if (end_time > last_motion)
602 last_motion = end_time; 604 last_motion = end_time;
603 } 605 }
604 return last_motion; 606 return last_motion;
605 } 607 }
606 608
607 } // namespace gfx 609 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698