| 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> g_icon_cache = | 448 static base::LazyInstance<VectorIconCache> 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> g_icon_cache_legacy = | |
| 531 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 |