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 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/strings/string_split.h" | |
| 10 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
| 11 #include "ui/gfx/image/canvas_image_source.h" | 13 #include "ui/gfx/image/canvas_image_source.h" |
| 12 #include "ui/gfx/vector_icon_types.h" | 14 #include "ui/gfx/vector_icon_types.h" |
| 13 #include "ui/gfx/vector_icons2.h" | 15 #include "ui/gfx/vector_icons2.h" |
| 14 | 16 |
| 15 namespace gfx { | 17 namespace gfx { |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 class VectorIconSource : public CanvasImageSource { | 21 CommandType CommandFromString(const std::string& source) { |
| 20 public: | 22 #define RETURN_IF_IS(command) \ |
| 21 VectorIconSource(VectorIconId id, size_t dip_size, SkColor color) | 23 if (source == #command) \ |
| 22 : CanvasImageSource( | 24 return command; |
| 23 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 24 false), | |
| 25 id_(id), | |
| 26 color_(color) {} | |
| 27 | 25 |
| 28 ~VectorIconSource() override {} | 26 RETURN_IF_IS(MOVE_TO); |
| 27 RETURN_IF_IS(R_MOVE_TO); | |
| 28 RETURN_IF_IS(R_LINE_TO); | |
| 29 RETURN_IF_IS(H_LINE_TO); | |
| 30 RETURN_IF_IS(R_H_LINE_TO); | |
| 31 RETURN_IF_IS(V_LINE_TO); | |
| 32 RETURN_IF_IS(R_V_LINE_TO); | |
| 33 RETURN_IF_IS(CUBIC_TO); | |
| 34 RETURN_IF_IS(R_CUBIC_TO); | |
| 35 RETURN_IF_IS(CIRCLE); | |
| 36 RETURN_IF_IS(CLOSE); | |
| 37 RETURN_IF_IS(END); | |
| 38 #undef RETURN_IF_IS | |
| 29 | 39 |
| 30 // CanvasImageSource: | 40 NOTREACHED(); |
| 31 void Draw(gfx::Canvas* canvas) override { | 41 return CLOSE; |
| 32 PaintVectorIcon(canvas, id_, size_.width(), color_); | 42 } |
| 43 | |
| 44 std::vector<PathElement> PathFromSource(const std::string& source) { | |
| 45 std::vector<PathElement> path; | |
| 46 std::vector<std::string> pieces = base::SplitString( | |
| 47 source, "\n ,f", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
| 48 for (const auto& piece : pieces) { | |
| 49 double value; | |
| 50 if (base::StringToDouble(piece, &value)) | |
| 51 path.push_back(PathElement(SkDoubleToScalar(value))); | |
| 52 else | |
| 53 path.push_back(PathElement(CommandFromString(piece))); | |
| 33 } | 54 } |
| 55 return path; | |
| 56 } | |
| 34 | 57 |
| 35 private: | 58 void PaintPath(Canvas* canvas, |
| 36 const VectorIconId id_; | 59 const PathElement* path_elements, |
| 37 const SkColor color_; | 60 size_t dip_size, |
| 38 | 61 SkColor color) { |
| 39 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | |
| 40 }; | |
| 41 | |
| 42 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | |
| 43 // more than once. This also guarantees the backing data for the images returned | |
| 44 // by CreateVectorIcon will persist in memory until program termination. | |
| 45 class VectorIconCache { | |
| 46 public: | |
| 47 VectorIconCache() {} | |
| 48 ~VectorIconCache() {} | |
| 49 | |
| 50 ImageSkia GetOrCreateIcon(VectorIconId id, size_t dip_size, SkColor color) { | |
| 51 IconDescription description(id, dip_size, color); | |
| 52 auto iter = images_.find(description); | |
| 53 if (iter != images_.end()) | |
| 54 return iter->second; | |
| 55 | |
| 56 ImageSkia icon( | |
| 57 new VectorIconSource(id, dip_size, color), | |
| 58 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 59 images_.insert(std::make_pair(description, icon)); | |
| 60 return icon; | |
| 61 } | |
| 62 | |
| 63 private: | |
| 64 struct IconDescription { | |
| 65 IconDescription(VectorIconId id, size_t dip_size, SkColor color) | |
| 66 : id(id), dip_size(dip_size), color(color) {} | |
| 67 | |
| 68 bool operator<(const IconDescription& other) const { | |
| 69 if (id != other.id) | |
| 70 return id < other.id; | |
| 71 if (dip_size != other.dip_size) | |
| 72 return dip_size < other.dip_size; | |
| 73 return color < other.color; | |
| 74 } | |
| 75 | |
| 76 VectorIconId id; | |
| 77 size_t dip_size; | |
| 78 SkColor color; | |
| 79 }; | |
| 80 | |
| 81 std::map<IconDescription, ImageSkia> images_; | |
| 82 | |
| 83 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | |
| 84 }; | |
| 85 | |
| 86 static base::LazyInstance<VectorIconCache> g_icon_cache = | |
| 87 LAZY_INSTANCE_INITIALIZER; | |
| 88 | |
| 89 } // namespace | |
| 90 | |
| 91 void PaintVectorIcon(Canvas* canvas, | |
| 92 VectorIconId id, | |
| 93 size_t dip_size, | |
| 94 SkColor color) { | |
| 95 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | |
| 96 const PathElement* path_elements = GetPathForVectorIcon(id); | |
| 97 SkPath path; | 62 SkPath path; |
| 98 path.setFillType(SkPath::kEvenOdd_FillType); | 63 path.setFillType(SkPath::kEvenOdd_FillType); |
| 99 if (dip_size != kReferenceSizeDip) { | 64 if (dip_size != kReferenceSizeDip) { |
| 100 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(kReferenceSizeDip); | 65 SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(kReferenceSizeDip); |
| 101 canvas->sk_canvas()->scale(scale, scale); | 66 canvas->sk_canvas()->scale(scale, scale); |
| 102 } | 67 } |
| 103 | 68 |
| 104 for (size_t i = 0; path_elements[i].type != END; i++) { | 69 for (size_t i = 0; path_elements[i].type != END; i++) { |
| 105 switch (path_elements[i].type) { | 70 switch (path_elements[i].type) { |
| 106 case MOVE_TO: { | 71 case MOVE_TO: { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } | 165 } |
| 201 } | 166 } |
| 202 | 167 |
| 203 SkPaint paint; | 168 SkPaint paint; |
| 204 paint.setStyle(SkPaint::kFill_Style); | 169 paint.setStyle(SkPaint::kFill_Style); |
| 205 paint.setAntiAlias(true); | 170 paint.setAntiAlias(true); |
| 206 paint.setColor(color); | 171 paint.setColor(color); |
| 207 canvas->DrawPath(path, paint); | 172 canvas->DrawPath(path, paint); |
| 208 } | 173 } |
| 209 | 174 |
| 175 class VectorIconSource : public CanvasImageSource { | |
|
Evan Stade
2015/07/31 18:59:59
changes to this class: addition of second construc
| |
| 176 public: | |
| 177 VectorIconSource(VectorIconId id, size_t dip_size, SkColor color) | |
| 178 : CanvasImageSource( | |
| 179 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 180 false), | |
| 181 id_(id), | |
| 182 color_(color) {} | |
| 183 | |
| 184 VectorIconSource(const std::string& definition, | |
| 185 size_t dip_size, | |
| 186 SkColor color) | |
| 187 : CanvasImageSource( | |
| 188 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), | |
| 189 false), | |
| 190 id_(VectorIconId::VECTOR_ICON_NONE), | |
| 191 path_(PathFromSource(definition)), | |
| 192 color_(color) {} | |
| 193 | |
| 194 ~VectorIconSource() override {} | |
| 195 | |
| 196 // CanvasImageSource: | |
| 197 void Draw(gfx::Canvas* canvas) override { | |
| 198 if (path_.empty()) | |
| 199 PaintVectorIcon(canvas, id_, size_.width(), color_); | |
| 200 else | |
| 201 PaintPath(canvas, path_.data(), size_.width(), color_); | |
| 202 } | |
| 203 | |
| 204 private: | |
| 205 const VectorIconId id_; | |
| 206 const std::vector<PathElement> path_; | |
| 207 const SkColor color_; | |
| 208 | |
| 209 DISALLOW_COPY_AND_ASSIGN(VectorIconSource); | |
| 210 }; | |
| 211 | |
| 212 // This class caches vector icons (as ImageSkia) so they don't have to be drawn | |
| 213 // more than once. This also guarantees the backing data for the images returned | |
| 214 // by CreateVectorIcon will persist in memory until program termination. | |
| 215 class VectorIconCache { | |
|
Evan Stade
2015/07/31 18:59:59
no change to this class (just moved within file)
| |
| 216 public: | |
| 217 VectorIconCache() {} | |
| 218 ~VectorIconCache() {} | |
| 219 | |
| 220 ImageSkia GetOrCreateIcon(VectorIconId id, size_t dip_size, SkColor color) { | |
| 221 IconDescription description(id, dip_size, color); | |
| 222 auto iter = images_.find(description); | |
| 223 if (iter != images_.end()) | |
| 224 return iter->second; | |
| 225 | |
| 226 ImageSkia icon( | |
| 227 new VectorIconSource(id, dip_size, color), | |
| 228 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 229 images_.insert(std::make_pair(description, icon)); | |
| 230 return icon; | |
| 231 } | |
| 232 | |
| 233 private: | |
| 234 struct IconDescription { | |
| 235 IconDescription(VectorIconId id, size_t dip_size, SkColor color) | |
| 236 : id(id), dip_size(dip_size), color(color) {} | |
| 237 | |
| 238 bool operator<(const IconDescription& other) const { | |
| 239 if (id != other.id) | |
| 240 return id < other.id; | |
| 241 if (dip_size != other.dip_size) | |
| 242 return dip_size < other.dip_size; | |
| 243 return color < other.color; | |
| 244 } | |
| 245 | |
| 246 VectorIconId id; | |
| 247 size_t dip_size; | |
| 248 SkColor color; | |
| 249 }; | |
| 250 | |
| 251 std::map<IconDescription, ImageSkia> images_; | |
| 252 | |
| 253 DISALLOW_COPY_AND_ASSIGN(VectorIconCache); | |
| 254 }; | |
| 255 | |
| 256 static base::LazyInstance<VectorIconCache> g_icon_cache = | |
| 257 LAZY_INSTANCE_INITIALIZER; | |
| 258 | |
| 259 } // namespace | |
| 260 | |
| 261 void PaintVectorIcon(Canvas* canvas, | |
| 262 VectorIconId id, | |
| 263 size_t dip_size, | |
| 264 SkColor color) { | |
| 265 DCHECK(VectorIconId::VECTOR_ICON_NONE != id); | |
| 266 PaintPath(canvas, GetPathForVectorIcon(id), dip_size, color); | |
| 267 } | |
| 268 | |
| 210 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { | 269 ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) { |
| 211 return g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color); | 270 return g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color); |
| 212 } | 271 } |
| 213 | 272 |
| 273 ImageSkia CreateVectorIconFromSource(const std::string& source, | |
| 274 size_t dip_size, | |
| 275 SkColor color) { | |
| 276 return ImageSkia( | |
| 277 new VectorIconSource(source, dip_size, color), | |
| 278 gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size))); | |
| 279 } | |
| 280 | |
| 214 } // namespace gfx | 281 } // namespace gfx |
| OLD | NEW |