| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 else if (base::HexStringToInt(piece, &hex_value)) | 74 else if (base::HexStringToInt(piece, &hex_value)) |
| 75 path.push_back(PathElement(SkIntToScalar(hex_value))); | 75 path.push_back(PathElement(SkIntToScalar(hex_value))); |
| 76 else | 76 else |
| 77 path.push_back(PathElement(CommandFromString(piece))); | 77 path.push_back(PathElement(CommandFromString(piece))); |
| 78 } | 78 } |
| 79 return path; | 79 return path; |
| 80 } | 80 } |
| 81 | 81 |
| 82 void PaintPath(Canvas* canvas, | 82 void PaintPath(Canvas* canvas, |
| 83 const PathElement* path_elements, | 83 const PathElement* path_elements, |
| 84 size_t dip_size, | 84 int dip_size, |
| 85 SkColor color) { | 85 SkColor color) { |
| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 flips_in_rtl = true; | 286 flips_in_rtl = true; |
| 287 break; | 287 break; |
| 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 gfx::ScopedRTLFlipCanvas scoped_rtl_flip_canvas( | 296 gfx::ScopedRTLFlipCanvas scoped_rtl_flip_canvas(canvas, canvas_size, |
| 297 canvas, static_cast<int>(canvas_size), flips_in_rtl); | 297 flips_in_rtl); |
| 298 | 298 |
| 299 if (dip_size != canvas_size) { | 299 if (dip_size != canvas_size) { |
| 300 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); | 300 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); |
| 301 canvas->sk_canvas()->scale(scale, scale); | 301 canvas->sk_canvas()->scale(scale, scale); |
| 302 } | 302 } |
| 303 | 303 |
| 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(VectorIconId id, |
| 315 size_t dip_size, | 315 int dip_size, |
| 316 SkColor color, | 316 SkColor color, |
| 317 VectorIconId badge_id) | 317 VectorIconId badge_id) |
| 318 : CanvasImageSource( | 318 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 319 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 320 false), | |
| 321 id_(id), | 319 id_(id), |
| 322 color_(color), | 320 color_(color), |
| 323 badge_id_(badge_id) {} | 321 badge_id_(badge_id) {} |
| 324 | 322 |
| 325 VectorIconSource(const std::string& definition, | 323 VectorIconSource(const std::string& definition, |
| 326 size_t dip_size, | 324 int dip_size, |
| 327 SkColor color) | 325 SkColor color) |
| 328 : CanvasImageSource( | 326 : CanvasImageSource(gfx::Size(dip_size, dip_size), false), |
| 329 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 330 false), | |
| 331 id_(VectorIconId::VECTOR_ICON_NONE), | 327 id_(VectorIconId::VECTOR_ICON_NONE), |
| 332 path_(PathFromSource(definition)), | 328 path_(PathFromSource(definition)), |
| 333 color_(color), | 329 color_(color), |
| 334 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} | 330 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} |
| 335 | 331 |
| 336 ~VectorIconSource() override {} | 332 ~VectorIconSource() override {} |
| 337 | 333 |
| 338 // CanvasImageSource: | 334 // CanvasImageSource: |
| 339 bool HasRepresentationAtAllScales() const override { | 335 bool HasRepresentationAtAllScales() const override { |
| 340 return id_ != VectorIconId::VECTOR_ICON_NONE; | 336 return id_ != VectorIconId::VECTOR_ICON_NONE; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 361 | 357 |
| 362 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 358 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
| 363 // more than once. This also guarantees the backing data for the images returned | 359 // more than once. This also guarantees the backing data for the images returned |
| 364 // by CreateVectorIcon will persist in memory until program termination. | 360 // by CreateVectorIcon will persist in memory until program termination. |
| 365 class VectorIconCache { | 361 class VectorIconCache { |
| 366 public: | 362 public: |
| 367 VectorIconCache() {} | 363 VectorIconCache() {} |
| 368 ~VectorIconCache() {} | 364 ~VectorIconCache() {} |
| 369 | 365 |
| 370 ImageSkia GetOrCreateIcon(VectorIconId id, | 366 ImageSkia GetOrCreateIcon(VectorIconId id, |
| 371 size_t dip_size, | 367 int dip_size, |
| 372 SkColor color, | 368 SkColor color, |
| 373 VectorIconId badge_id) { | 369 VectorIconId badge_id) { |
| 374 IconDescription description(id, dip_size, color, badge_id); | 370 IconDescription description(id, dip_size, color, badge_id); |
| 375 auto iter = images_.find(description); | 371 auto iter = images_.find(description); |
| 376 if (iter != images_.end()) | 372 if (iter != images_.end()) |
| 377 return iter->second; | 373 return iter->second; |
| 378 | 374 |
| 379 ImageSkia icon( | 375 ImageSkia icon(new VectorIconSource(id, dip_size, color, badge_id), |
| 380 new VectorIconSource(id, dip_size, color, badge_id), | 376 gfx::Size(dip_size, dip_size)); |
| 381 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 382 images_.insert(std::make_pair(description, icon)); | 377 images_.insert(std::make_pair(description, icon)); |
| 383 return icon; | 378 return icon; |
| 384 } | 379 } |
| 385 | 380 |
| 386 private: | 381 private: |
| 387 struct IconDescription { | 382 struct IconDescription { |
| 388 IconDescription(VectorIconId id, | 383 IconDescription(VectorIconId id, |
| 389 size_t dip_size, | 384 int dip_size, |
| 390 SkColor color, | 385 SkColor color, |
| 391 VectorIconId badge_id) | 386 VectorIconId badge_id) |
| 392 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} | 387 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} |
| 393 | 388 |
| 394 bool operator<(const IconDescription& other) const { | 389 bool operator<(const IconDescription& other) const { |
| 395 return std::tie(id, dip_size, color, badge_id) < | 390 return std::tie(id, dip_size, color, badge_id) < |
| 396 std::tie(other.id, other.dip_size, other.color, other.badge_id); | 391 std::tie(other.id, other.dip_size, other.color, other.badge_id); |
| 397 } | 392 } |
| 398 | 393 |
| 399 VectorIconId id; | 394 VectorIconId id; |
| 400 size_t dip_size; | 395 size_t dip_size; |
| 401 SkColor color; | 396 SkColor color; |
| 402 VectorIconId badge_id; | 397 VectorIconId badge_id; |
| 403 }; | 398 }; |
| 404 | 399 |
| 405 std::map<IconDescription, ImageSkia> images_; | 400 std::map<IconDescription, ImageSkia> images_; |
| 406 | 401 |
| 407 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 402 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); |
| 408 }; | 403 }; |
| 409 | 404 |
| 410 static base::LazyInstance<VectorIconCache> g_icon_cache = | 405 static base::LazyInstance<VectorIconCache> g_icon_cache = |
| 411 LAZY_INSTANCE_INITIALIZER; | 406 LAZY_INSTANCE_INITIALIZER; |
| 412 | 407 |
| 413 } // namespace | 408 } // namespace |
| 414 | 409 |
| 415 void PaintVectorIcon(Canvas* canvas, | 410 void PaintVectorIcon(Canvas* canvas, |
| 416 VectorIconId id, | 411 VectorIconId id, |
| 417 size_t dip_size, | 412 int dip_size, |
| 418 SkColor color) { | 413 SkColor color) { |
| 419 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | 414 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); |
| 420 const PathElement* path = canvas->image_scale() == 1.f | 415 const PathElement* path = canvas->image_scale() == 1.f |
| 421 ? GetPathForVectorIconAt1xScale(id) | 416 ? GetPathForVectorIconAt1xScale(id) |
| 422 : GetPathForVectorIcon(id); | 417 : GetPathForVectorIcon(id); |
| 423 PaintPath(canvas, path, dip_size, color); | 418 PaintPath(canvas, path, dip_size, color); |
| 424 } | 419 } |
| 425 | 420 |
| 426 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { | 421 ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) { |
| 427 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); | 422 const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id); |
| 428 size_t size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg | 423 int size = (one_x_path[0].type == CANVAS_DIMENSIONS) |
| 429 : kReferenceSizeDip; | 424 ? SkScalarTruncToInt(one_x_path[1].arg) |
| 425 : kReferenceSizeDip; |
| 430 return CreateVectorIcon(id, size, color); | 426 return CreateVectorIcon(id, size, color); |
| 431 } | 427 } |
| 432 | 428 |
| 433 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { | 429 ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) { |
| 434 return CreateVectorIconWithBadge(id, dip_size, color, | 430 return CreateVectorIconWithBadge(id, dip_size, color, |
| 435 VectorIconId::VECTOR_ICON_NONE); | 431 VectorIconId::VECTOR_ICON_NONE); |
| 436 } | 432 } |
| 437 | 433 |
| 438 ImageSkia CreateVectorIconWithBadge(VectorIconId id, | 434 ImageSkia CreateVectorIconWithBadge(VectorIconId id, |
| 439 size_t dip_size, | 435 int dip_size, |
| 440 SkColor color, | 436 SkColor color, |
| 441 VectorIconId badge_id) { | 437 VectorIconId badge_id) { |
| 442 return (id == VectorIconId::VECTOR_ICON_NONE) | 438 return (id == VectorIconId::VECTOR_ICON_NONE) |
| 443 ? gfx::ImageSkia() | 439 ? gfx::ImageSkia() |
| 444 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, | 440 : g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, |
| 445 badge_id); | 441 badge_id); |
| 446 } | 442 } |
| 447 | 443 |
| 448 ImageSkia CreateVectorIconFromSource(const std::string& source, | 444 ImageSkia CreateVectorIconFromSource(const std::string& source, |
| 449 size_t dip_size, | 445 int dip_size, |
| 450 SkColor color) { | 446 SkColor color) { |
| 451 return ImageSkia( | 447 return ImageSkia( |
| 452 new VectorIconSource(source, dip_size, color), | 448 new VectorIconSource(source, dip_size, color), |
| 453 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | 449 gfx::Size(dip_size, dip_size)); |
| 454 } | 450 } |
| 455 | 451 |
| 456 } // namespace gfx | 452 } // namespace gfx |
| OLD | NEW |