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 |