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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 else if (base::HexStringToInt(piece, &hex_value)) | 73 else if (base::HexStringToInt(piece, &hex_value)) |
| 74 path.push_back(PathElement(SkIntToScalar(hex_value))); | 74 path.push_back(PathElement(SkIntToScalar(hex_value))); |
| 75 else | 75 else |
| 76 path.push_back(PathElement(CommandFromString(piece))); | 76 path.push_back(PathElement(CommandFromString(piece))); |
| 77 } | 77 } |
| 78 return path; | 78 return path; |
| 79 } | 79 } |
| 80 | 80 |
| 81 void PaintPath(Canvas* canvas, | 81 void PaintPath(Canvas* canvas, |
| 82 const PathElement* path_elements, | 82 const PathElement* path_elements, |
| 83 size_t dip_size, | 83 int dip_size, |
| 84 SkColor color) { | 84 SkColor color) { |
| 85 canvas->Save(); | 85 canvas->Save(); |
| 86 SkPath path; | 86 SkPath path; |
| 87 path.setFillType(SkPath::kEvenOdd_FillType); | 87 path.setFillType(SkPath::kEvenOdd_FillType); |
| 88 | 88 |
| 89 size_t canvas_size = kReferenceSizeDip; | 89 int canvas_size = kReferenceSizeDip; |
| 90 std::vector<SkPath> paths; | 90 std::vector<SkPath> paths; |
| 91 std::vector<SkPaint> paints; | 91 std::vector<SkPaint> paints; |
| 92 SkRect clip_rect = SkRect::MakeEmpty(); | 92 SkRect clip_rect = SkRect::MakeEmpty(); |
| 93 bool flips_in_rtl = false; | 93 bool flips_in_rtl = false; |
| 94 | 94 |
| 95 for (size_t i = 0; path_elements[i].type != END; i++) { | 95 for (size_t i = 0; path_elements[i].type != END; i++) { |
| 96 if (paths.empty() || path_elements[i].type == NEW_PATH) { | 96 if (paths.empty() || path_elements[i].type == NEW_PATH) { |
| 97 paths.push_back(SkPath()); | 97 paths.push_back(SkPath()); |
| 98 paths.back().setFillType(SkPath::kEvenOdd_FillType); | 98 paths.back().setFillType(SkPath::kEvenOdd_FillType); |
| 99 | 99 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 } | 288 } |
| 289 | 289 |
| 290 case END: | 290 case END: |
| 291 NOTREACHED(); | 291 NOTREACHED(); |
| 292 break; | 292 break; |
| 293 } | 293 } |
| 294 } | 294 } |
| 295 | 295 |
| 296 if (flips_in_rtl && base::i18n::IsRTL()) { | 296 if (flips_in_rtl && base::i18n::IsRTL()) { |
| 297 canvas->Scale(-1, 1); | 297 canvas->Scale(-1, 1); |
| 298 canvas->Translate(gfx::Vector2d(-static_cast<int>(canvas_size), 0)); | 298 canvas->Translate(gfx::Vector2d(-canvas_size, 0)); |
|
Evan Stade
2016/08/18 23:25:37
I don't think this cast is an indication that a ne
Peter Kasting
2016/08/18 23:35:13
Well, a negative canvas size doesn't make sense in
Evan Stade
2016/08/19 04:21:49
I didn't know the style guide said that and I stil
| |
| 299 } | 299 } |
| 300 | 300 |
| 301 if (dip_size != canvas_size) { | 301 if (dip_size != canvas_size) { |
| 302 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); | 302 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); |
| 303 canvas->sk_canvas()->scale(scale, scale); | 303 canvas->sk_canvas()->scale(scale, scale); |
| 304 } | 304 } |
| 305 | 305 |
| 306 if (!clip_rect.isEmpty()) | 306 if (!clip_rect.isEmpty()) |
| 307 canvas->sk_canvas()->clipRect(clip_rect); | 307 canvas->sk_canvas()->clipRect(clip_rect); |
| 308 | 308 |
| 309 DCHECK_EQ(paints.size(), paths.size()); | 309 DCHECK_EQ(paints.size(), paths.size()); |
| 310 for (size_t i = 0; i < paths.size(); ++i) | 310 for (size_t i = 0; i < paths.size(); ++i) |
| 311 canvas->DrawPath(paths[i], paints[i]); | 311 canvas->DrawPath(paths[i], paints[i]); |
| 312 canvas->Restore(); | 312 canvas->Restore(); |
| 313 } | 313 } |
| 314 | 314 |
| 315 class VectorIconSource : public CanvasImageSource { | 315 class VectorIconSource : public CanvasImageSource { |
| 316 public: | 316 public: |
| 317 VectorIconSource(VectorIconId id, | 317 VectorIconSource(VectorIconId id, |
| 318 size_t dip_size, | 318 int dip_size, |
| 319 SkColor color, | 319 SkColor color, |
| 320 VectorIconId badge_id) | 320 VectorIconId badge_id) |
| 321 : CanvasImageSource( | 321 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 322 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 323 false), | |
| 324 id_(id), | 322 id_(id), |
| 325 color_(color), | 323 color_(color), |
| 326 badge_id_(badge_id) {} | 324 badge_id_(badge_id) {} |
| 327 | 325 |
| 328 VectorIconSource(const std::string& definition, | 326 VectorIconSource(const std::string& definition, |
| 329 size_t dip_size, | 327 int dip_size, |
| 330 SkColor color) | 328 SkColor color) |
| 331 : CanvasImageSource( | 329 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 332 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 333 false), | |
| 334 id_(VectorIconId::VECTOR_ICON_NONE), | 330 id_(VectorIconId::VECTOR_ICON_NONE), |
| 335 path_(PathFromSource(definition)), | 331 path_(PathFromSource(definition)), |
| 336 color_(color), | 332 color_(color), |
| 337 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} | 333 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} |
| 338 | 334 |
| 339 ~VectorIconSource() override {} | 335 ~VectorIconSource() override {} |
| 340 | 336 |
| 341 // CanvasImageSource: | 337 // CanvasImageSource: |
| 342 bool HasRepresentationAtAllScales() const override { | 338 bool HasRepresentationAtAllScales() const override { |
| 343 return id_ != VectorIconId::VECTOR_ICON_NONE; | 339 return id_ != VectorIconId::VECTOR_ICON_NONE; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 364 | 360 |
| 365 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 361 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
| 366 // more than once. This also guarantees the backing data for the images returned | 362 // more than once. This also guarantees the backing data for the images returned |
| 367 // by CreateVectorIcon will persist in memory until program termination. | 363 // by CreateVectorIcon will persist in memory until program termination. |
| 368 class VectorIconCache { | 364 class VectorIconCache { |
| 369 public: | 365 public: |
| 370 VectorIconCache() {} | 366 VectorIconCache() {} |
| 371 ~VectorIconCache() {} | 367 ~VectorIconCache() {} |
| 372 | 368 |
| 373 ImageSkia GetOrCreateIcon(VectorIconId id, | 369 ImageSkia GetOrCreateIcon(VectorIconId id, |
| 374 size_t dip_size, | 370 int dip_size, |
| 375 SkColor color, | 371 SkColor color, |
| 376 VectorIconId badge_id) { | 372 VectorIconId badge_id) { |
| 377 IconDescription description(id, dip_size, color, badge_id); | 373 IconDescription description(id, dip_size, color, badge_id); |
| 378 auto iter = images_.find(description); | 374 auto iter = images_.find(description); |
| 379 if (iter != images_.end()) | 375 if (iter != images_.end()) |
| 380 return iter->second; | 376 return iter->second; |
| 381 | 377 |
| 382 ImageSkia icon( | 378 ImageSkia icon(new VectorIconSource(id, dip_size, color, badge_id), |
| 383 new VectorIconSource(id, dip_size, color, badge_id), | 379 gfx::Size(dip_size, dip_size)); |
| 384 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 385 images_.insert(std::make_pair(description, icon)); | 380 images_.insert(std::make_pair(description, icon)); |
| 386 return icon; | 381 return icon; |
| 387 } | 382 } |
| 388 | 383 |
| 389 private: | 384 private: |
| 390 struct IconDescription { | 385 struct IconDescription { |
| 391 IconDescription(VectorIconId id, | 386 IconDescription(VectorIconId id, |
| 392 size_t dip_size, | 387 int dip_size, |
| 393 SkColor color, | 388 SkColor color, |
| 394 VectorIconId badge_id) | 389 VectorIconId badge_id) |
| 395 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} | 390 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} |
| 396 | 391 |
| 397 bool operator<(const IconDescription& other) const { | 392 bool operator<(const IconDescription& other) const { |
| 398 return std::tie(id, dip_size, color, badge_id) < | 393 return std::tie(id, dip_size, color, badge_id) < |
| 399 std::tie(other.id, other.dip_size, other.color, other.badge_id); | 394 std::tie(other.id, other.dip_size, other.color, other.badge_id); |
| 400 } | 395 } |
| 401 | 396 |
| 402 VectorIconId id; | 397 VectorIconId id; |
| 403 size_t dip_size; | 398 size_t dip_size; |
| 404 SkColor color; | 399 SkColor color; |
| 405 VectorIconId badge_id; | 400 VectorIconId badge_id; |
| 406 }; | 401 }; |
| 407 | 402 |
| 408 std::map<IconDescription, ImageSkia> images_; | 403 std::map<IconDescription, ImageSkia> images_; |
| 409 | 404 |
| 410 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 405 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); |
| 411 }; | 406 }; |
| 412 | 407 |
| 413 static base::LazyInstance<VectorIconCache> g_icon_cache = | 408 static base::LazyInstance<VectorIconCache> g_icon_cache = |
| 414 LAZY_INSTANCE_INITIALIZER; | 409 LAZY_INSTANCE_INITIALIZER; |
| 415 | 410 |
| 416 } // namespace | 411 } // namespace |
| 417 | 412 |
| 418 void PaintVectorIcon(Canvas* canvas, | 413 void PaintVectorIcon(Canvas* canvas, |
| 419 VectorIconId id, | 414 VectorIconId id, |
| 420 size_t dip_size, | 415 int dip_size, |
| 421 SkColor color) { | 416 SkColor color) { |
| 422 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | 417 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); |
| 423 const PathElement* path = canvas->image_scale() == 1.f | 418 const PathElement* path = canvas->image_scale() == 1.f |
| 424 ? GetPathForVectorIconAt1xScale(id) | 419 ? GetPathForVectorIconAt1xScale(id) |
| 425 : GetPathForVectorIcon(id); | 420 : GetPathForVectorIcon(id); |
| 426 PaintPath(canvas, path, dip_size, color); | 421 PaintPath(canvas, path, dip_size, color); |
| 427 } | 422 } |
| 428 | 423 |
| 429 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { | 424 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { |
| 430 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); | 425 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); |
| 431 size_t size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | 426 int size = (one_x_path[0].type == CANVAS_DIMENSIONS) |
| 432 : kReferenceSizeDip; | 427 ? SkScalarTruncToInt(one_x_path[1].arg) |
| 428 : kReferenceSizeDip; | |
| 433 return CreateVectorIcon(id, size, color); | 429 return CreateVectorIcon(id, size, color); |
| 434 } | 430 } |
| 435 | 431 |
| 436 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { | 432 ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) { |
| 437 return CreateVectorIconWithBadge(id, dip_size, color, | 433 return CreateVectorIconWithBadge(id, dip_size, color, |
| 438 VectorIconId::VECTOR_ICON_NONE); | 434 VectorIconId::VECTOR_ICON_NONE); |
| 439 } | 435 } |
| 440 | 436 |
| 441 ImageSkia CreateVectorIconWithBadge(VectorIconId id, | 437 ImageSkia CreateVectorIconWithBadge(VectorIconId id, |
| 442 size_t dip_size, | 438 int dip_size, |
| 443 SkColor color, | 439 SkColor color, |
| 444 VectorIconId badge_id) { | 440 VectorIconId badge_id) { |
| 445 return (id == VectorIconId::VECTOR_ICON_NONE) | 441 return (id == VectorIconId::VECTOR_ICON_NONE) |
| 446 ? gfx::ImageSkia() | 442 ? gfx::ImageSkia() |
| 447 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, | 443 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, |
| 448 badge_id); | 444 badge_id); |
| 449 } | 445 } |
| 450 | 446 |
| 451 ImageSkia CreateVectorIconFromSource(const std::string& source, | 447 ImageSkia CreateVectorIconFromSource(const std::string& source, |
| 452 size_t dip_size, | 448 int dip_size, |
| 453 SkColor color) { | 449 SkColor color) { |
| 454 return ImageSkia( | 450 return ImageSkia( |
| 455 new VectorIconSource(source, dip_size, color), | 451 new VectorIconSource(source, dip_size, color), |
| 456 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | 452 gfx::Size(dip_size, dip_size)); |
| 457 } | 453 } |
| 458 | 454 |
| 459 } // namespace gfx | 455 } // namespace gfx |
| OLD | NEW |