| 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 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 else | 61 else |
| 62 path.push_back(PathElement(CommandFromString(piece))); | 62 path.push_back(PathElement(CommandFromString(piece))); |
| 63 } | 63 } |
| 64 return path; | 64 return path; |
| 65 } | 65 } |
| 66 | 66 |
| 67 void PaintPath(Canvas* canvas, | 67 void PaintPath(Canvas* canvas, |
| 68 const PathElement* path_elements, | 68 const PathElement* path_elements, |
| 69 size_t dip_size, | 69 size_t dip_size, |
| 70 SkColor color) { | 70 SkColor color) { |
| 71 canvas->Save(); |
| 71 SkPath path; | 72 SkPath path; |
| 72 path.setFillType(SkPath::kEvenOdd_FillType); | 73 path.setFillType(SkPath::kEvenOdd_FillType); |
| 73 | 74 |
| 74 size_t canvas_size = kReferenceSizeDip; | 75 size_t canvas_size = kReferenceSizeDip; |
| 75 std::vector<SkPath> paths; | 76 std::vector<SkPath> paths; |
| 76 std::vector<SkPaint> paints; | 77 std::vector<SkPaint> paints; |
| 77 SkRect clip_rect = SkRect::MakeEmpty(); | 78 SkRect clip_rect = SkRect::MakeEmpty(); |
| 78 | 79 |
| 79 for (size_t i = 0; path_elements[i].type != END; i++) { | 80 for (size_t i = 0; path_elements[i].type != END; i++) { |
| 80 if (paths.empty() || path_elements[i].type == NEW_PATH) { | 81 if (paths.empty() || path_elements[i].type == NEW_PATH) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); | 232 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size); |
| 232 canvas->sk_canvas()->scale(scale, scale); | 233 canvas->sk_canvas()->scale(scale, scale); |
| 233 } | 234 } |
| 234 | 235 |
| 235 if (!clip_rect.isEmpty()) | 236 if (!clip_rect.isEmpty()) |
| 236 canvas->sk_canvas()->clipRect(clip_rect); | 237 canvas->sk_canvas()->clipRect(clip_rect); |
| 237 | 238 |
| 238 DCHECK_EQ(paints.size(), paths.size()); | 239 DCHECK_EQ(paints.size(), paths.size()); |
| 239 for (size_t i = 0; i < paths.size(); ++i) | 240 for (size_t i = 0; i < paths.size(); ++i) |
| 240 canvas->DrawPath(paths[i], paints[i]); | 241 canvas->DrawPath(paths[i], paints[i]); |
| 242 canvas->Restore(); |
| 241 } | 243 } |
| 242 | 244 |
| 243 class VectorIconSource : public CanvasImageSource { | 245 class VectorIconSource : public CanvasImageSource { |
| 244 public: | 246 public: |
| 245 VectorIconSource(VectorIconId id, size_t dip_size, SkColor color) | 247 VectorIconSource(VectorIconId id, |
| 248 size_t dip_size, |
| 249 SkColor color, |
| 250 VectorIconId badge_id) |
| 246 : CanvasImageSource( | 251 : CanvasImageSource( |
| 247 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | 252 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), |
| 248 false), | 253 false), |
| 249 id_(id), | 254 id_(id), |
| 250 color_(color) {} | 255 color_(color), |
| 256 badge_id_(badge_id) {} |
| 251 | 257 |
| 252 VectorIconSource(const std::string& definition, | 258 VectorIconSource(const std::string& definition, |
| 253 size_t dip_size, | 259 size_t dip_size, |
| 254 SkColor color) | 260 SkColor color) |
| 255 : CanvasImageSource( | 261 : CanvasImageSource( |
| 256 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | 262 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), |
| 257 false), | 263 false), |
| 258 id_(VectorIconId::VECTOR_ICON_NONE), | 264 id_(VectorIconId::VECTOR_ICON_NONE), |
| 259 path_(PathFromSource(definition)), | 265 path_(PathFromSource(definition)), |
| 260 color_(color) {} | 266 color_(color), |
| 267 badge_id_(VectorIconId::VECTOR_ICON_NONE) {} |
| 261 | 268 |
| 262 ~VectorIconSource() override {} | 269 ~VectorIconSource() override {} |
| 263 | 270 |
| 264 // CanvasImageSource: | 271 // CanvasImageSource: |
| 265 void Draw(gfx::Canvas* canvas) override { | 272 void Draw(gfx::Canvas* canvas) override { |
| 266 if (path_.empty()) | 273 if (path_.empty()) { |
| 267 PaintVectorIcon(canvas, id_, size_.width(), color_); | 274 PaintVectorIcon(canvas, id_, size_.width(), color_); |
| 268 else | 275 if (badge_id_ != VectorIconId::VECTOR_ICON_NONE) |
| 276 PaintVectorIcon(canvas, badge_id_, size_.width(), color_); |
| 277 } else { |
| 269 PaintPath(canvas, path_.data(), size_.width(), color_); | 278 PaintPath(canvas, path_.data(), size_.width(), color_); |
| 279 } |
| 270 } | 280 } |
| 271 | 281 |
| 272 private: | 282 private: |
| 273 const VectorIconId id_; | 283 const VectorIconId id_; |
| 274 const std::vector<PathElement> path_; | 284 const std::vector<PathElement> path_; |
| 275 const SkColor color_; | 285 const SkColor color_; |
| 286 const VectorIconId badge_id_; |
| 276 | 287 |
| 277 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | 288 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); |
| 278 }; | 289 }; |
| 279 | 290 |
| 280 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | 291 // This class caches vector icons (as ImageSkia) so they don't have to be drawn |
| 281 // more than once. This also guarantees the backing data for the images returned | 292 // more than once. This also guarantees the backing data for the images returned |
| 282 // by CreateVectorIcon will persist in memory until program termination. | 293 // by CreateVectorIcon will persist in memory until program termination. |
| 283 class VectorIconCache { | 294 class VectorIconCache { |
| 284 public: | 295 public: |
| 285 VectorIconCache() {} | 296 VectorIconCache() {} |
| 286 ~VectorIconCache() {} | 297 ~VectorIconCache() {} |
| 287 | 298 |
| 288 ImageSkia GetOrCreateIcon(VectorIconId id, size_t dip_size, SkColor color) { | 299 ImageSkia GetOrCreateIcon(VectorIconId id, |
| 289 IconDescription description(id, dip_size, color); | 300 size_t dip_size, |
| 301 SkColor color, |
| 302 VectorIconId badge_id) { |
| 303 IconDescription description(id, dip_size, color, badge_id); |
| 290 auto iter = images_.find(description); | 304 auto iter = images_.find(description); |
| 291 if (iter != images_.end()) | 305 if (iter != images_.end()) |
| 292 return iter->second; | 306 return iter->second; |
| 293 | 307 |
| 294 ImageSkia icon( | 308 ImageSkia icon( |
| 295 new VectorIconSource(id, dip_size, color), | 309 new VectorIconSource(id, dip_size, color, badge_id), |
| 296 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | 310 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); |
| 297 images_.insert(std::make_pair(description, icon)); | 311 images_.insert(std::make_pair(description, icon)); |
| 298 return icon; | 312 return icon; |
| 299 } | 313 } |
| 300 | 314 |
| 301 private: | 315 private: |
| 302 struct IconDescription { | 316 struct IconDescription { |
| 303 IconDescription(VectorIconId id, size_t dip_size, SkColor color) | 317 IconDescription(VectorIconId id, |
| 304 : id(id), dip_size(dip_size), color(color) {} | 318 size_t dip_size, |
| 319 SkColor color, |
| 320 VectorIconId badge_id) |
| 321 : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {} |
| 305 | 322 |
| 306 bool operator<(const IconDescription& other) const { | 323 bool operator<(const IconDescription& other) const { |
| 307 if (id != other.id) | 324 if (id != other.id) |
| 308 return id < other.id; | 325 return id < other.id; |
| 309 if (dip_size != other.dip_size) | 326 if (dip_size != other.dip_size) |
| 310 return dip_size < other.dip_size; | 327 return dip_size < other.dip_size; |
| 311 return color < other.color; | 328 if (color != other.color) |
| 329 return color < other.color; |
| 330 return badge_id < other.badge_id; |
| 312 } | 331 } |
| 313 | 332 |
| 314 VectorIconId id; | 333 VectorIconId id; |
| 315 size_t dip_size; | 334 size_t dip_size; |
| 316 SkColor color; | 335 SkColor color; |
| 336 VectorIconId badge_id; |
| 317 }; | 337 }; |
| 318 | 338 |
| 319 std::map<IconDescription, ImageSkia> images_; | 339 std::map<IconDescription, ImageSkia> images_; |
| 320 | 340 |
| 321 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | 341 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); |
| 322 }; | 342 }; |
| 323 | 343 |
| 324 static base::LazyInstance<VectorIconCache> g_icon_cache = | 344 static base::LazyInstance<VectorIconCache> g_icon_cache = |
| 325 LAZY_INSTANCE_INITIALIZER; | 345 LAZY_INSTANCE_INITIALIZER; |
| 326 | 346 |
| 327 } // namespace | 347 } // namespace |
| 328 | 348 |
| 329 void PaintVectorIcon(Canvas* canvas, | 349 void PaintVectorIcon(Canvas* canvas, |
| 330 VectorIconId id, | 350 VectorIconId id, |
| 331 size_t dip_size, | 351 size_t dip_size, |
| 332 SkColor color) { | 352 SkColor color) { |
| 333 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | 353 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); |
| 334 const PathElement* path = canvas->image_scale() == 1.f | 354 const PathElement* path = canvas->image_scale() == 1.f |
| 335 ? GetPathForVectorIconAt1xScale(id) | 355 ? GetPathForVectorIconAt1xScale(id) |
| 336 : GetPathForVectorIcon(id); | 356 : GetPathForVectorIcon(id); |
| 337 PaintPath(canvas, path, dip_size, color); | 357 PaintPath(canvas, path, dip_size, color); |
| 338 } | 358 } |
| 339 | 359 |
| 340 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { | 360 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { |
| 341 return g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color); | 361 return CreateVectorIconWithBadge(id, dip_size, color, |
| 362 VectorIconId::VECTOR_ICON_NONE); |
| 363 } |
| 364 |
| 365 ImageSkia CreateVectorIconWithBadge(VectorIconId id, |
| 366 size_t dip_size, |
| 367 SkColor color, |
| 368 VectorIconId badge_id) { |
| 369 return g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, badge_id); |
| 342 } | 370 } |
| 343 | 371 |
| 344 ImageSkia CreateVectorIconFromSource(const std::string& source, | 372 ImageSkia CreateVectorIconFromSource(const std::string& source, |
| 345 size_t dip_size, | 373 size_t dip_size, |
| 346 SkColor color) { | 374 SkColor color) { |
| 347 return ImageSkia( | 375 return ImageSkia( |
| 348 new VectorIconSource(source, dip_size, color), | 376 new VectorIconSource(source, dip_size, color), |
| 349 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | 377 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); |
| 350 } | 378 } |
| 351 | 379 |
| 352 } // namespace gfx | 380 } // namespace gfx |
| OLD | NEW |