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

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

Issue 2892563004: Use animated vector icon for app menu notification animation. (Closed)
Patch Set: one more f Created 3 years, 6 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
« no previous file with comments | « ui/gfx/paint_vector_icon.h ('k') | ui/views/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
31 struct CompareIconDescription {
32 bool operator()(const IconDescription& a, const IconDescription& b) const {
33 const VectorIcon* a_icon = &a.icon;
34 const VectorIcon* b_icon = &b.icon;
35 const VectorIcon* a_badge = &a.badge_icon;
36 const VectorIcon* b_badge = &b.badge_icon;
37 return std::tie(a_icon, a.dip_size, a.color, a.elapsed_time, a_badge) <
38 std::tie(b_icon, b.dip_size, b.color, b.elapsed_time, b_badge);
39 }
40 };
41
30 // Helper that simplifies iterating over a sequence of PathElements. 42 // Helper that simplifies iterating over a sequence of PathElements.
31 class PathParser { 43 class PathParser {
32 public: 44 public:
33 PathParser(const PathElement* path_elements) 45 PathParser(const PathElement* path_elements)
34 : path_elements_(path_elements) {} 46 : path_elements_(path_elements) {}
35 ~PathParser() {} 47 ~PathParser() {}
36 48
37 void Advance() { command_index_ += GetArgumentCount() + 1; } 49 void Advance() { command_index_ += GetArgumentCount() + 1; }
38 50
39 CommandType CurrentCommand() const { 51 CommandType CurrentCommand() const {
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!clip_rect.isEmpty()) 442 if (!clip_rect.isEmpty())
431 canvas->sk_canvas()->clipRect(clip_rect); 443 canvas->sk_canvas()->clipRect(clip_rect);
432 444
433 DCHECK_EQ(flags_array.size(), paths.size()); 445 DCHECK_EQ(flags_array.size(), paths.size());
434 for (size_t i = 0; i < paths.size(); ++i) 446 for (size_t i = 0; i < paths.size(); ++i)
435 canvas->DrawPath(paths[i], flags_array[i]); 447 canvas->DrawPath(paths[i], flags_array[i]);
436 } 448 }
437 449
438 class VectorIconSource : public CanvasImageSource { 450 class VectorIconSource : public CanvasImageSource {
439 public: 451 public:
440 VectorIconSource(const VectorIcon& icon, 452 explicit VectorIconSource(const IconDescription& data)
441 int dip_size, 453 : CanvasImageSource(Size(data.dip_size, data.dip_size), false),
442 SkColor color, 454 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 455
449 VectorIconSource(const std::string& definition, int dip_size, SkColor color) 456 VectorIconSource(const std::string& definition, int dip_size, SkColor color)
450 : CanvasImageSource(Size(dip_size, dip_size), false), 457 : CanvasImageSource(Size(dip_size, dip_size), false),
451 color_(color), 458 data_(kNoneIcon, dip_size, color, base::TimeDelta(), kNoneIcon),
452 icon_(kNoneIcon),
453 badge_(kNoneIcon),
454 path_(PathFromSource(definition)) {} 459 path_(PathFromSource(definition)) {}
455 460
456 ~VectorIconSource() override {} 461 ~VectorIconSource() override {}
457 462
458 // CanvasImageSource: 463 // CanvasImageSource:
459 bool HasRepresentationAtAllScales() const override { 464 bool HasRepresentationAtAllScales() const override {
460 return !icon_.is_empty(); 465 return !data_.icon.is_empty();
461 } 466 }
462 467
463 void Draw(Canvas* canvas) override { 468 void Draw(Canvas* canvas) override {
464 if (path_.empty()) { 469 if (path_.empty()) {
465 PaintVectorIcon(canvas, icon_, size_.width(), color_); 470 PaintVectorIcon(canvas, data_.icon, size_.width(), data_.color,
466 if (!badge_.is_empty()) 471 data_.elapsed_time);
467 PaintVectorIcon(canvas, badge_, size_.width(), color_); 472 if (!data_.badge_icon.is_empty())
473 PaintVectorIcon(canvas, data_.badge_icon, size_.width(), data_.color);
468 } else { 474 } else {
469 PaintPath(canvas, path_.data(), size_.width(), color_, base::TimeDelta()); 475 PaintPath(canvas, path_.data(), size_.width(), data_.color,
476 base::TimeDelta());
470 } 477 }
471 } 478 }
472 479
473 private: 480 private:
474 const SkColor color_; 481 const IconDescription data_;
475 const VectorIcon& icon_;
476 const VectorIcon& badge_;
477 const std::vector<PathElement> path_; 482 const std::vector<PathElement> path_;
478 483
479 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); 484 DISALLOW_COPY_AND_ASSIGN(VectorIconSource);
480 }; 485 };
481 486
482 // This class caches vector icons (as ImageSkia) so they don't have to be drawn 487 // 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 488 // more than once. This also guarantees the backing data for the images returned
484 // by CreateVectorIcon will persist in memory until program termination. 489 // by CreateVectorIcon will persist in memory until program termination.
485 class VectorIconCache { 490 class VectorIconCache {
486 public: 491 public:
487 VectorIconCache() {} 492 VectorIconCache() {}
488 ~VectorIconCache() {} 493 ~VectorIconCache() {}
489 494
490 ImageSkia GetOrCreateIcon(const VectorIcon& icon, 495 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); 496 auto iter = images_.find(description);
496 if (iter != images_.end()) 497 if (iter != images_.end())
497 return iter->second; 498 return iter->second;
498 499
499 ImageSkia icon_image( 500 ImageSkia icon_image(new VectorIconSource(description),
500 new VectorIconSource(icon, dip_size, color, badge_icon), 501 Size(description.dip_size, description.dip_size));
501 Size(dip_size, dip_size));
502 images_.insert(std::make_pair(description, icon_image)); 502 images_.insert(std::make_pair(description, icon_image));
503 return icon_image; 503 return icon_image;
504 } 504 }
505 505
506 private: 506 private:
507 struct IconDescription { 507 std::map<IconDescription, ImageSkia, CompareIconDescription> images_;
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_;
530 508
531 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); 509 DISALLOW_COPY_AND_ASSIGN(VectorIconCache);
532 }; 510 };
533 511
534 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache = 512 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache =
535 LAZY_INSTANCE_INITIALIZER; 513 LAZY_INSTANCE_INITIALIZER;
536 514
537 } // namespace 515 } // namespace
538 516
517 IconDescription::IconDescription(const IconDescription& other) = default;
518
519 IconDescription::IconDescription(const VectorIcon& icon,
520 int dip_size,
521 SkColor color,
522 const base::TimeDelta& elapsed_time,
523 const VectorIcon& badge_icon)
524 : icon(icon),
525 dip_size(dip_size),
526 color(color),
527 elapsed_time(elapsed_time),
528 badge_icon(badge_icon) {
529 if (dip_size == 0)
530 this->dip_size = GetDefaultSizeOfVectorIcon(icon);
531 }
532
533 IconDescription::~IconDescription() {}
534
539 const VectorIcon kNoneIcon = {}; 535 const VectorIcon kNoneIcon = {};
540 536
541 void PaintVectorIcon(Canvas* canvas, 537 void PaintVectorIcon(Canvas* canvas,
542 const VectorIcon& icon, 538 const VectorIcon& icon,
543 SkColor color, 539 SkColor color,
544 const base::TimeDelta& elapsed_time) { 540 const base::TimeDelta& elapsed_time) {
545 PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color, 541 PaintVectorIcon(canvas, icon, GetDefaultSizeOfVectorIcon(icon), color,
546 elapsed_time); 542 elapsed_time);
547 } 543 }
548 544
549 void PaintVectorIcon(Canvas* canvas, 545 void PaintVectorIcon(Canvas* canvas,
550 const VectorIcon& icon, 546 const VectorIcon& icon,
551 int dip_size, 547 int dip_size,
552 SkColor color, 548 SkColor color,
553 const base::TimeDelta& elapsed_time) { 549 const base::TimeDelta& elapsed_time) {
554 DCHECK(!icon.is_empty()); 550 DCHECK(!icon.is_empty());
555 const PathElement* path = 551 const PathElement* path =
556 (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path; 552 (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path;
557 PaintPath(canvas, path, dip_size, color, elapsed_time); 553 PaintPath(canvas, path, dip_size, color, elapsed_time);
558 } 554 }
559 555
556 ImageSkia CreateVectorIcon(const IconDescription& params) {
557 if (params.icon.is_empty())
558 return gfx::ImageSkia();
559
560 return g_icon_cache.Get().GetOrCreateIcon(params);
561 }
562
560 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) { 563 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) {
561 return CreateVectorIcon(icon, GetDefaultSizeOfVectorIcon(icon), color); 564 return CreateVectorIcon(icon, GetDefaultSizeOfVectorIcon(icon), color);
562 } 565 }
563 566
564 ImageSkia CreateVectorIcon(const VectorIcon& icon, 567 ImageSkia CreateVectorIcon(const VectorIcon& icon,
565 int dip_size, 568 int dip_size,
566 SkColor color) { 569 SkColor color) {
567 return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon); 570 return CreateVectorIcon(
571 IconDescription(icon, dip_size, color, base::TimeDelta(), kNoneIcon));
568 } 572 }
569 573
570 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon, 574 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon,
571 int dip_size, 575 int dip_size,
572 SkColor color, 576 SkColor color,
573 const VectorIcon& badge_icon) { 577 const VectorIcon& badge_icon) {
574 return icon.is_empty() ? ImageSkia() 578 return CreateVectorIcon(
575 : g_icon_cache.Get().GetOrCreateIcon( 579 IconDescription(icon, dip_size, color, base::TimeDelta(), badge_icon));
576 icon, dip_size, color, badge_icon);
577 } 580 }
578 581
579 ImageSkia CreateVectorIconFromSource(const std::string& source, 582 ImageSkia CreateVectorIconFromSource(const std::string& source,
580 int dip_size, 583 int dip_size,
581 SkColor color) { 584 SkColor color) {
582 return CanvasImageSource::MakeImageSkia<VectorIconSource>(source, dip_size, 585 return CanvasImageSource::MakeImageSkia<VectorIconSource>(source, dip_size,
583 color); 586 color);
584 } 587 }
585 588
586 int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) { 589 int GetDefaultSizeOfVectorIcon(const VectorIcon& icon) {
(...skipping 11 matching lines...) Expand all
598 601
599 auto end_time = base::TimeDelta::FromMillisecondsD(parser.GetArgument(0)) + 602 auto end_time = base::TimeDelta::FromMillisecondsD(parser.GetArgument(0)) +
600 base::TimeDelta::FromMillisecondsD(parser.GetArgument(1)); 603 base::TimeDelta::FromMillisecondsD(parser.GetArgument(1));
601 if (end_time > last_motion) 604 if (end_time > last_motion)
602 last_motion = end_time; 605 last_motion = end_time;
603 } 606 }
604 return last_motion; 607 return last_motion;
605 } 608 }
606 609
607 } // namespace gfx 610 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/paint_vector_icon.h ('k') | ui/views/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698