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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 if (!clip_rect.isEmpty()) | 304 if (!clip_rect.isEmpty()) |
| 305 canvas->sk_canvas()->clipRect(clip_rect); | 305 canvas->sk_canvas()->clipRect(clip_rect); |
| 306 | 306 |
| 307 DCHECK_EQ(paints.size(), paths.size()); | 307 DCHECK_EQ(paints.size(), paths.size()); |
| 308 for (size_t i = 0; i < paths.size(); ++i) | 308 for (size_t i = 0; i < paths.size(); ++i) |
| 309 canvas->DrawPath(paths[i], paints[i]); | 309 canvas->DrawPath(paths[i], paints[i]); |
| 310 } | 310 } |
| 311 | 311 |
| 312 class VectorIconSource : public CanvasImageSource { | 312 class VectorIconSource : public CanvasImageSource { |
| 313 public: | 313 public: |
| 314 VectorIconSource(VectorIconId id, | 314 VectorIconSource(const VectorIcon& icon, |
| 315 int dip_size, | 315 int dip_size, |
| 316 SkColor color, | 316 SkColor color, |
| 317 VectorIconId badge_id) | 317 const VectorIcon& badge_icon) |
| 318 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | |
| 319 color_(color), | |
| 320 icon_(icon), | |
| 321 badge_(badge_icon) {} | |
| 322 | |
| 323 ~VectorIconSource() override {} | |
| 324 | |
| 325 // CanvasImageSource: | |
| 326 bool HasRepresentationAtAllScales() const override { | |
| 327 return !icon_.is_empty(); | |
| 328 } | |
| 329 | |
| 330 void Draw(gfx::Canvas* canvas) override { | |
| 331 PaintVectorIcon(canvas, icon_, size_.width(), color_); | |
| 332 if (!badge_.is_empty()) | |
| 333 PaintVectorIcon(canvas, badge_, size_.width(), color_); | |
| 334 } | |
| 335 | |
| 336 private: | |
| 337 const SkColor color_; | |
| 338 const VectorIcon& icon_; | |
| 339 const VectorIcon& badge_; | |
| 340 | |
| 341 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | |
| 342 }; | |
| 343 | |
| 344 class VectorIconSourceLegacy : public CanvasImageSource { | |
| 345 public: | |
| 346 VectorIconSourceLegacy(VectorIconId id, | |
| 347 int dip_size, | |
| 348 SkColor color, | |
| 349 VectorIconId badge_id) | |
| 318 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | 350 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 319 id_(id), | 351 id_(id), |
| 320 color_(color), | 352 color_(color), |
| 321 badge_id_(badge_id) {} | 353 badge_id_(badge_id) {} |
| 322 | 354 |
| 323 VectorIconSource(const std::string& definition, | 355 VectorIconSourceLegacy(const std::string& definition, |
| 324 int dip_size, | 356 int dip_size, |
| 325 SkColor color) | 357 SkColor color) |
| 326 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), | 358 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 327 id_(VectorIconId::VECTOR_ICON_NONE), | 359 id_(VectorIconId::VECTOR_ICON_NONE), |
| 328 path_(PathFromSource(definition)), | 360 path_(PathFromSource(definition)), |
| 329 color_(color), | 361 color_(color), |
| 330 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} | 362 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} |
| 331 | 363 |
| 332 ~VectorIconSource() override {} | 364 ~VectorIconSourceLegacy() override {} |
| 333 | 365 |
| 334 // CanvasImageSource: | 366 // CanvasImageSource: |
| 335 bool HasRepresentationAtAllScales() const override { | 367 bool HasRepresentationAtAllScales() const override { |
| 336 return id_ != VectorIconId::VECTOR_ICON_NONE; | 368 return id_ != VectorIconId::VECTOR_ICON_NONE; |
|
Evan Stade
2016/08/31 00:47:01
I can't actually remember why this doesn't just al
| |
| 337 } | 369 } |
| 338 | 370 |
| 339 void Draw(gfx::Canvas* canvas) override { | 371 void Draw(gfx::Canvas* canvas) override { |
| 340 if (path_.empty()) { | 372 if (path_.empty()) { |
| 341 PaintVectorIcon(canvas, id_, size_.width(), color_); | 373 PaintVectorIcon(canvas, id_, size_.width(), color_); |
| 342 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) | 374 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) |
| 343 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); | 375 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); |
| 344 } else { | 376 } else { |
| 345 PaintPath(canvas, path_.data(), size_.width(), color_); | 377 PaintPath(canvas, path_.data(), size_.width(), color_); |
| 346 } | 378 } |
| 347 } | 379 } |
| 348 | 380 |
| 349 private: | 381 private: |
| 350 const VectorIconId id_; | 382 const VectorIconId id_; |
| 351 const std::vector<PathElement> path_; | 383 const std::vector<PathElement> path_; |
| 352 const SkColor color_; | 384 const SkColor color_; |
| 353 const VectorIconId badge_id_; | 385 const VectorIconId badge_id_; |
| 354 | 386 |
| 355 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | 387 DISALLOW_COPY_AND_ASSIGN(VectorIconSourceLegacy); |
| 356 }; | 388 }; |
| 357 | 389 |
| 358 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 390 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
| 359 // more than once. This also guarantees the backing data for the images returned | 391 // more than once. This also guarantees the backing data for the images returned |
| 360 // by CreateVectorIcon will persist in memory until program termination. | 392 // by CreateVectorIcon will persist in memory until program termination. |
| 361 class VectorIconCache { | 393 class VectorIconCache { |
| 362 public: | 394 public: |
| 363 VectorIconCache() {} | 395 VectorIconCache() {} |
| 364 ~VectorIconCache() {} | 396 ~VectorIconCache() {} |
| 365 | 397 |
| 398 ImageSkia GetOrCreateIcon(const VectorIcon& icon, | |
| 399 int dip_size, | |
| 400 SkColor color, | |
| 401 const VectorIcon& badge_icon) { | |
| 402 IconDescription description(&icon, dip_size, color, &badge_icon); | |
| 403 auto iter = images_.find(description); | |
| 404 if (iter != images_.end()) | |
| 405 return iter->second; | |
| 406 | |
| 407 ImageSkia icon_image( | |
| 408 new VectorIconSource(icon, dip_size, color, badge_icon), | |
| 409 gfx::Size(dip_size, dip_size)); | |
| 410 images_.insert(std::make_pair(description, icon_image)); | |
| 411 return icon_image; | |
| 412 } | |
| 413 | |
| 414 private: | |
| 415 struct IconDescription { | |
| 416 IconDescription(const VectorIcon* icon, | |
| 417 int dip_size, | |
| 418 SkColor color, | |
| 419 const VectorIcon* badge_icon) | |
| 420 : icon(icon), | |
| 421 dip_size(dip_size), | |
| 422 color(color), | |
| 423 badge_icon(badge_icon) {} | |
| 424 | |
| 425 bool operator<(const IconDescription& other) const { | |
| 426 return std::tie(icon, dip_size, color, badge_icon) < | |
| 427 std::tie(other.icon, other.dip_size, other.color, | |
| 428 other.badge_icon); | |
| 429 } | |
| 430 | |
| 431 const gfx::VectorIcon* icon; | |
| 432 int dip_size; | |
| 433 SkColor color; | |
| 434 const gfx::VectorIcon* badge_icon; | |
| 435 }; | |
| 436 | |
| 437 std::map<IconDescription, ImageSkia> images_; | |
| 438 | |
| 439 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | |
| 440 }; | |
| 441 | |
| 442 static base::LazyInstance<VectorIconCache> g_icon_cache = | |
| 443 LAZY_INSTANCE_INITIALIZER; | |
| 444 | |
| 445 class VectorIconCacheLegacy { | |
| 446 public: | |
| 447 VectorIconCacheLegacy() {} | |
| 448 ~VectorIconCacheLegacy() {} | |
| 449 | |
| 366 ImageSkia GetOrCreateIcon(VectorIconId id, | 450 ImageSkia GetOrCreateIcon(VectorIconId id, |
| 367 int dip_size, | 451 int dip_size, |
| 368 SkColor color, | 452 SkColor color, |
| 369 VectorIconId badge_id) { | 453 VectorIconId badge_id) { |
| 370 IconDescription description(id, dip_size, color, badge_id); | 454 IconDescription description(id, dip_size, color, badge_id); |
| 371 auto iter = images_.find(description); | 455 auto iter = images_.find(description); |
| 372 if (iter != images_.end()) | 456 if (iter != images_.end()) |
| 373 return iter->second; | 457 return iter->second; |
| 374 | 458 |
| 375 ImageSkia icon(new VectorIconSource(id, dip_size, color, badge_id), | 459 ImageSkia icon(new VectorIconSourceLegacy(id, dip_size, color, badge_id), |
| 376 gfx::Size(dip_size, dip_size)); | 460 gfx::Size(dip_size, dip_size)); |
| 377 images_.insert(std::make_pair(description, icon)); | 461 images_.insert(std::make_pair(description, icon)); |
| 378 return icon; | 462 return icon; |
| 379 } | 463 } |
| 380 | 464 |
| 381 private: | 465 private: |
| 382 struct IconDescription { | 466 struct IconDescription { |
| 383 IconDescription(VectorIconId id, | 467 IconDescription(VectorIconId id, |
| 384 int dip_size, | 468 int dip_size, |
| 385 SkColor color, | 469 SkColor color, |
| 386 VectorIconId badge_id) | 470 VectorIconId badge_id) |
| 387 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} | 471 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} |
| 388 | 472 |
| 389 bool operator<(const IconDescription& other) const { | 473 bool operator<(const IconDescription& other) const { |
| 390 return std::tie(id, dip_size, color, badge_id) < | 474 return std::tie(id, dip_size, color, badge_id) < |
| 391 std::tie(other.id, other.dip_size, other.color, other.badge_id); | 475 std::tie(other.id, other.dip_size, other.color, other.badge_id); |
| 392 } | 476 } |
| 393 | 477 |
| 394 VectorIconId id; | 478 VectorIconId id; |
| 395 size_t dip_size; | 479 int dip_size; |
| 396 SkColor color; | 480 SkColor color; |
| 397 VectorIconId badge_id; | 481 VectorIconId badge_id; |
| 398 }; | 482 }; |
| 399 | 483 |
| 400 std::map<IconDescription, ImageSkia> images_; | 484 std::map<IconDescription, ImageSkia> images_; |
| 401 | 485 |
| 402 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 486 DISALLOW_COPY_AND_ASSIGN(VectorIconCacheLegacy); |
| 403 }; | 487 }; |
| 404 | 488 |
| 405 static base::LazyInstance<VectorIconCache> g_icon_cache = | 489 static base::LazyInstance<VectorIconCacheLegacy> g_icon_cache_legacy = |
| 406 LAZY_INSTANCE_INITIALIZER; | 490 LAZY_INSTANCE_INITIALIZER; |
| 407 | 491 |
| 408 } // namespace | 492 } // namespace |
| 409 | 493 |
| 494 const VectorIcon kNoneIcon = {nullptr, nullptr}; | |
|
Evan Stade
2016/08/31 00:47:01
you can just do = {};
but I also like oshima's su
tdanderson
2016/08/31 22:18:20
Done.
| |
| 495 | |
| 410 void PaintVectorIcon(Canvas* canvas, | 496 void PaintVectorIcon(Canvas* canvas, |
| 411 VectorIconId id, | 497 VectorIconId id, |
| 412 int dip_size, | 498 int dip_size, |
| 413 SkColor color) { | 499 SkColor color) { |
| 414 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | 500 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); |
| 415 const PathElement* path = canvas->image_scale() == 1.f | 501 const PathElement* path = canvas->image_scale() == 1.f |
| 416 ? GetPathForVectorIconAt1xScale(id) | 502 ? GetPathForVectorIconAt1xScale(id) |
| 417 : GetPathForVectorIcon(id); | 503 : GetPathForVectorIcon(id); |
| 418 PaintPath(canvas, path, dip_size, color); | 504 PaintPath(canvas, path, dip_size, color); |
| 419 } | 505 } |
| 420 | 506 |
| 507 void PaintVectorIcon(Canvas* canvas, | |
| 508 const VectorIcon& icon, | |
| 509 int dip_size, | |
| 510 SkColor color) { | |
| 511 DCHECK(!icon.is_empty()); | |
| 512 const PathElement* path = | |
| 513 (canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path; | |
| 514 PaintPath(canvas, path, dip_size, color); | |
| 515 } | |
| 516 | |
| 421 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { | 517 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { |
| 422 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); | 518 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); |
| 423 int size = (one_x_path[0].type == CANVAS_DIMENSIONS) | 519 int size = (one_x_path[0].type == CANVAS_DIMENSIONS) |
| 424 ? SkScalarTruncToInt(one_x_path[1].arg) | 520 ? SkScalarTruncToInt(one_x_path[1].arg) |
| 425 : kReferenceSizeDip; | 521 : kReferenceSizeDip; |
| 426 return CreateVectorIcon(id, size, color); | 522 return CreateVectorIcon(id, size, color); |
| 427 } | 523 } |
| 428 | 524 |
| 525 ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) { | |
| 526 const PathElement* one_x_path = icon.path_1x ? icon.path_1x : icon.path; | |
| 527 int size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | |
| 528 : kReferenceSizeDip; | |
| 529 return CreateVectorIcon(icon, size, color); | |
| 530 } | |
| 531 | |
| 429 ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) { | 532 ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) { |
| 430 return CreateVectorIconWithBadge(id, dip_size, color, | 533 return CreateVectorIconWithBadge(id, dip_size, color, |
| 431 VectorIconId::VECTOR_ICON_NONE); | 534 VectorIconId::VECTOR_ICON_NONE); |
| 432 } | 535 } |
| 433 | 536 |
| 537 ImageSkia CreateVectorIcon(const VectorIcon& icon, | |
| 538 int dip_size, | |
| 539 SkColor color) { | |
| 540 return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon); | |
| 541 } | |
| 542 | |
| 434 ImageSkia CreateVectorIconWithBadge(VectorIconId id, | 543 ImageSkia CreateVectorIconWithBadge(VectorIconId id, |
| 435 int dip_size, | 544 int dip_size, |
| 436 SkColor color, | 545 SkColor color, |
| 437 VectorIconId badge_id) { | 546 VectorIconId badge_id) { |
| 438 return (id == VectorIconId::VECTOR_ICON_NONE) | 547 return (id == VectorIconId::VECTOR_ICON_NONE) |
| 439 ? gfx::ImageSkia() | 548 ? gfx::ImageSkia() |
| 440 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, | 549 : g_icon_cache_legacy.Get().GetOrCreateIcon(id, dip_size, color, |
| 441 badge_id); | 550 badge_id); |
| 551 } | |
| 552 | |
| 553 ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon, | |
| 554 int dip_size, | |
| 555 SkColor color, | |
| 556 const VectorIcon& badge_icon) { | |
| 557 return icon.is_empty() ? gfx::ImageSkia() | |
| 558 : g_icon_cache.Get().GetOrCreateIcon( | |
| 559 icon, dip_size, color, badge_icon); | |
| 442 } | 560 } |
| 443 | 561 |
| 444 ImageSkia CreateVectorIconFromSource(const std::string& source, | 562 ImageSkia CreateVectorIconFromSource(const std::string& source, |
| 445 int dip_size, | 563 int dip_size, |
| 446 SkColor color) { | 564 SkColor color) { |
| 447 return ImageSkia( | 565 return ImageSkia(new VectorIconSourceLegacy(source, dip_size, color), |
| 448 new VectorIconSource(source, dip_size, color), | 566 gfx::Size(dip_size, dip_size)); |
| 449 gfx::Size(dip_size, dip_size)); | |
| 450 } | 567 } |
| 451 | 568 |
| 452 } // namespace gfx | 569 } // namespace gfx |
| OLD | NEW |