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" |
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 "cc/paint/paint_canvas.h" | 16 #include "cc/paint/paint_canvas.h" |
17 #include "cc/paint/paint_flags.h" | 17 #include "cc/paint/paint_flags.h" |
18 #include "third_party/skia/include/core/SkPath.h" | 18 #include "third_party/skia/include/core/SkPath.h" |
19 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/image/canvas_image_source.h" | 20 #include "ui/gfx/image/canvas_image_source.h" |
21 #include "ui/gfx/scoped_canvas.h" | 21 #include "ui/gfx/scoped_canvas.h" |
22 #include "ui/gfx/vector_icon_types.h" | 22 #include "ui/gfx/vector_icon_types.h" |
23 #include "ui/gfx/vector_icons_public.h" | |
24 | 23 |
25 namespace gfx { | 24 namespace gfx { |
26 | 25 |
27 namespace { | 26 namespace { |
28 | 27 |
29 // Translates a string such as "MOVE_TO" into a command such as MOVE_TO. | 28 // Translates a string such as "MOVE_TO" into a command such as MOVE_TO. |
30 CommandType CommandFromString(const std::string& source) { | 29 CommandType CommandFromString(const std::string& source) { |
31 #define RETURN_IF_IS(command) \ | 30 #define RETURN_IF_IS(command) \ |
32 if (source == #command) \ | 31 if (source == #command) \ |
33 return command; | 32 return command; |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 public: | 353 public: |
355 VectorIconSource(const VectorIcon& icon, | 354 VectorIconSource(const VectorIcon& icon, |
356 int dip_size, | 355 int dip_size, |
357 SkColor color, | 356 SkColor color, |
358 const VectorIcon& badge_icon) | 357 const VectorIcon& badge_icon) |
359 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | 358 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
360 color_(color), | 359 color_(color), |
361 icon_(icon), | 360 icon_(icon), |
362 badge_(badge_icon) {} | 361 badge_(badge_icon) {} |
363 | 362 |
| 363 VectorIconSource(const std::string& definition, int dip_size, SkColor color) |
| 364 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 365 color_(color), |
| 366 icon_(kNoneIcon), |
| 367 badge_(kNoneIcon), |
| 368 path_(PathFromSource(definition)) {} |
| 369 |
364 ~VectorIconSource() override {} | 370 ~VectorIconSource() override {} |
365 | 371 |
366 // CanvasImageSource: | 372 // CanvasImageSource: |
367 bool HasRepresentationAtAllScales() const override { | 373 bool HasRepresentationAtAllScales() const override { |
368 return !icon_.is_empty(); | 374 return !icon_.is_empty(); |
369 } | 375 } |
370 | 376 |
371 void Draw(gfx::Canvas* canvas) override { | 377 void Draw(gfx::Canvas* canvas) override { |
372 PaintVectorIcon(canvas, icon_, size_.width(), color_); | 378 if (path_.empty()) { |
373 if (!badge_.is_empty()) | 379 PaintVectorIcon(canvas, icon_, size_.width(), color_); |
374 PaintVectorIcon(canvas, badge_, size_.width(), color_); | 380 if (!badge_.is_empty()) |
| 381 PaintVectorIcon(canvas, badge_, size_.width(), color_); |
| 382 } else { |
| 383 PaintPath(canvas, path_.data(), size_.width(), color_); |
| 384 } |
375 } | 385 } |
376 | 386 |
377 private: | 387 private: |
378 const SkColor color_; | 388 const SkColor color_; |
379 const VectorIcon& icon_; | 389 const VectorIcon& icon_; |
380 const VectorIcon& badge_; | 390 const VectorIcon& badge_; |
| 391 const std::vector<PathElement> path_; |
381 | 392 |
382 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | 393 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); |
383 }; | 394 }; |
384 | 395 |
385 class VectorIconSourceLegacy : public CanvasImageSource { | |
386 public: | |
387 VectorIconSourceLegacy(VectorIconId id, | |
388 int dip_size, | |
389 SkColor color, | |
390 VectorIconId badge_id) | |
391 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | |
392 id_(id), | |
393 color_(color), | |
394 badge_id_(badge_id) {} | |
395 | |
396 VectorIconSourceLegacy(const std::string& definition, | |
397 int dip_size, | |
398 SkColor color) | |
399 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | |
400 id_(VectorIconId::VECTOR_ICON_NONE), | |
401 path_(PathFromSource(definition)), | |
402 color_(color), | |
403 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} | |
404 | |
405 ~VectorIconSourceLegacy() override {} | |
406 | |
407 // CanvasImageSource: | |
408 bool HasRepresentationAtAllScales() const override { | |
409 return id_ != VectorIconId::VECTOR_ICON_NONE; | |
410 } | |
411 | |
412 void Draw(gfx::Canvas* canvas) override { | |
413 if (path_.empty()) { | |
414 PaintVectorIcon(canvas, id_, size_.width(), color_); | |
415 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) | |
416 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); | |
417 } else { | |
418 PaintPath(canvas, path_.data(), size_.width(), color_); | |
419 } | |
420 } | |
421 | |
422 private: | |
423 const VectorIconId id_; | |
424 const std::vector<PathElement> path_; | |
425 const SkColor color_; | |
426 const VectorIconId badge_id_; | |
427 | |
428 DISALLOW_COPY_AND_ASSIGN(VectorIconSourceLegacy); | |
429 }; | |
430 | |
431 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 396 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
432 // more than once. This also guarantees the backing data for the images returned | 397 // more than once. This also guarantees the backing data for the images returned |
433 // by CreateVectorIcon will persist in memory until program termination. | 398 // by CreateVectorIcon will persist in memory until program termination. |
434 class VectorIconCache { | 399 class VectorIconCache { |
435 public: | 400 public: |
436 VectorIconCache() {} | 401 VectorIconCache() {} |
437 ~VectorIconCache() {} | 402 ~VectorIconCache() {} |
438 | 403 |
439 ImageSkia GetOrCreateIcon(const VectorIcon& icon, | 404 ImageSkia GetOrCreateIcon(const VectorIcon& icon, |
440 int dip_size, | 405 int dip_size, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 }; | 441 }; |
477 | 442 |
478 std::map<IconDescription, ImageSkia> images_; | 443 std::map<IconDescription, ImageSkia> images_; |
479 | 444 |
480 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 445 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); |
481 }; | 446 }; |
482 | 447 |
483 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache = | 448 static base::LazyInstance<VectorIconCache>::DestructorAtExit g_icon_cache = |
484 LAZY_INSTANCE_INITIALIZER; | 449 LAZY_INSTANCE_INITIALIZER; |
485 | 450 |
486 class VectorIconCacheLegacy { | |
487 public: | |
488 VectorIconCacheLegacy() {} | |
489 ~VectorIconCacheLegacy() {} | |
490 | |
491 ImageSkia GetOrCreateIcon(VectorIconId id, | |
492 int dip_size, | |
493 SkColor color, | |
494 VectorIconId badge_id) { | |
495 IconDescription description(id, dip_size, color, badge_id); | |
496 auto iter = images_.find(description); | |
497 if (iter != images_.end()) | |
498 return iter->second; | |
499 | |
500 ImageSkia icon(new VectorIconSourceLegacy(id, dip_size, color, badge_id), | |
501 gfx::Size(dip_size, dip_size)); | |
502 images_.insert(std::make_pair(description, icon)); | |
503 return icon; | |
504 } | |
505 | |
506 private: | |
507 struct IconDescription { | |
508 IconDescription(VectorIconId id, | |
509 int dip_size, | |
510 SkColor color, | |
511 VectorIconId badge_id) | |
512 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} | |
513 | |
514 bool operator<(const IconDescription& other) const { | |
515 return std::tie(id, dip_size, color, badge_id) < | |
516 std::tie(other.id, other.dip_size, other.color, other.badge_id); | |
517 } | |
518 | |
519 VectorIconId id; | |
520 int dip_size; | |
521 SkColor color; | |
522 VectorIconId badge_id; | |
523 }; | |
524 | |
525 std::map<IconDescription, ImageSkia> images_; | |
526 | |
527 DISALLOW_COPY_AND_ASSIGN(VectorIconCacheLegacy); | |
528 }; | |
529 | |
530 static base::LazyInstance<VectorIconCacheLegacy>::DestructorAtExit | |
531 g_icon_cache_legacy = LAZY_INSTANCE_INITIALIZER; | |
532 | |
533 } // namespace | 451 } // namespace |
534 | 452 |
535 const VectorIcon kNoneIcon = {}; | 453 const VectorIcon kNoneIcon = {}; |
536 | 454 |
537 void PaintVectorIcon(Canvas* canvas, | 455 void PaintVectorIcon(Canvas* canvas, |
538 VectorIconId id, | |
539 int dip_size, | |
540 SkColor color) { | |
541 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | |
542 const PathElement* path = canvas->image_scale() == 1.f | |
543 ? GetPathForVectorIconAt1xScale(id) | |
544 : GetPathForVectorIcon(id); | |
545 PaintPath(canvas, path, dip_size, color); | |
546 } | |
547 | |
548 void PaintVectorIcon(Canvas* canvas, | |
549 const VectorIcon& icon, | 456 const VectorIcon& icon, |
550 int dip_size, | 457 int dip_size, |
551 SkColor color) { | 458 SkColor color) { |
552 DCHECK(!icon.is_empty()); | 459 DCHECK(!icon.is_empty()); |
553 const PathElement* path = (canvas->image_scale() == 1.f && icon.path_1x_) | 460 const PathElement* path = (canvas->image_scale() == 1.f && icon.path_1x_) |
554 ? icon.path_1x_ | 461 ? icon.path_1x_ |
555 : icon.path_; | 462 : icon.path_; |
556 PaintPath(canvas, path, dip_size, color); | 463 PaintPath(canvas, path, dip_size, color); |
557 } | 464 } |
558 | 465 |
559 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { | |
560 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); | |
561 int size = (one_x_path[0].type == CANVAS_DIMENSIONS) | |
562 ? SkScalarTruncToInt(one_x_path[1].arg) | |
563 : kReferenceSizeDip; | |
564 return CreateVectorIcon(id, size, color); | |
565 } | |
566 | |
567 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) { | 466 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) { |
568 const PathElement* one_x_path = icon.path_1x_ ? icon.path_1x_ : icon.path_; | 467 const PathElement* one_x_path = icon.path_1x_ ? icon.path_1x_ : icon.path_; |
569 int size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | 468 int size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg |
570 : kReferenceSizeDip; | 469 : kReferenceSizeDip; |
571 return CreateVectorIcon(icon, size, color); | 470 return CreateVectorIcon(icon, size, color); |
572 } | 471 } |
573 | 472 |
574 ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) { | |
575 return CreateVectorIconWithBadge(id, dip_size, color, | |
576 VectorIconId::VECTOR_ICON_NONE); | |
577 } | |
578 | |
579 ImageSkia CreateVectorIcon(const VectorIcon& icon, | 473 ImageSkia CreateVectorIcon(const VectorIcon& icon, |
580 int dip_size, | 474 int dip_size, |
581 SkColor color) { | 475 SkColor color) { |
582 return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon); | 476 return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon); |
583 } | 477 } |
584 | 478 |
585 ImageSkia CreateVectorIconWithBadge(VectorIconId id, | |
586 int dip_size, | |
587 SkColor color, | |
588 VectorIconId badge_id) { | |
589 return (id == VectorIconId::VECTOR_ICON_NONE) | |
590 ? gfx::ImageSkia() | |
591 : g_icon_cache_legacy.Get().GetOrCreateIcon(id, dip_size, color, | |
592 badge_id); | |
593 } | |
594 | |
595 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon, | 479 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon, |
596 int dip_size, | 480 int dip_size, |
597 SkColor color, | 481 SkColor color, |
598 const VectorIcon& badge_icon) { | 482 const VectorIcon& badge_icon) { |
599 return icon.is_empty() ? gfx::ImageSkia() | 483 return icon.is_empty() ? gfx::ImageSkia() |
600 : g_icon_cache.Get().GetOrCreateIcon( | 484 : g_icon_cache.Get().GetOrCreateIcon( |
601 icon, dip_size, color, badge_icon); | 485 icon, dip_size, color, badge_icon); |
602 } | 486 } |
603 | 487 |
604 ImageSkia CreateVectorIconFromSource(const std::string& source, | 488 ImageSkia CreateVectorIconFromSource(const std::string& source, |
605 int dip_size, | 489 int dip_size, |
606 SkColor color) { | 490 SkColor color) { |
607 return CanvasImageSource::MakeImageSkia<VectorIconSourceLegacy>( | 491 return CanvasImageSource::MakeImageSkia<VectorIconSource>(source, dip_size, |
608 source, dip_size, color); | 492 color); |
609 } | 493 } |
610 | 494 |
611 } // namespace gfx | 495 } // namespace gfx |
OLD | NEW |