OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/image/image.h" | 5 #include "ui/gfx/image/image.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "third_party/skia/include/core/SkBitmap.h" | 11 #include "third_party/skia/include/core/SkBitmap.h" |
| 12 #include "ui/gfx/image/image_skia.h" |
12 #include "ui/gfx/size.h" | 13 #include "ui/gfx/size.h" |
13 | 14 |
14 #if defined(TOOLKIT_GTK) | 15 #if defined(TOOLKIT_GTK) |
15 #include <gdk-pixbuf/gdk-pixbuf.h> | 16 #include <gdk-pixbuf/gdk-pixbuf.h> |
16 #include <gdk/gdk.h> | 17 #include <gdk/gdk.h> |
17 #include <glib-object.h> | 18 #include <glib-object.h> |
18 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
19 #include "ui/gfx/gtk_util.h" | 20 #include "ui/gfx/gtk_util.h" |
20 #include "ui/gfx/image/cairo_cached_surface.h" | 21 #include "ui/gfx/image/cairo_cached_surface.h" |
21 #elif defined(OS_MACOSX) | 22 #elif defined(OS_MACOSX) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 #endif | 90 #endif |
90 | 91 |
91 Image::RepresentationType type() const { return type_; } | 92 Image::RepresentationType type() const { return type_; } |
92 | 93 |
93 private: | 94 private: |
94 Image::RepresentationType type_; | 95 Image::RepresentationType type_; |
95 }; | 96 }; |
96 | 97 |
97 class ImageRepSkia : public ImageRep { | 98 class ImageRepSkia : public ImageRep { |
98 public: | 99 public: |
99 explicit ImageRepSkia(const SkBitmap* bitmap) | 100 explicit ImageRepSkia(ImageSkia* image) |
100 : ImageRep(Image::kImageRepSkia) { | |
101 CHECK(bitmap); | |
102 // TODO(rohitrao): Add a CHECK to ensure that !bitmap->isNull(). | |
103 bitmaps_.push_back(bitmap); | |
104 } | |
105 | |
106 explicit ImageRepSkia(const std::vector<const SkBitmap*>& bitmaps) | |
107 : ImageRep(Image::kImageRepSkia), | 101 : ImageRep(Image::kImageRepSkia), |
108 bitmaps_(bitmaps) { | 102 image_(image) { |
109 CHECK(!bitmaps_.empty()); | |
110 // TODO(rohitrao): Add a CHECK to ensure that !bitmap->isNull() for each | |
111 // vector element. | |
112 } | 103 } |
113 | 104 |
114 virtual ~ImageRepSkia() { | 105 virtual ~ImageRepSkia() { |
115 STLDeleteElements(&bitmaps_); | |
116 } | 106 } |
117 | 107 |
118 const SkBitmap* bitmap() const { return bitmaps_[0]; } | 108 ImageSkia* image() { return image_.get(); } |
119 | |
120 const std::vector<const SkBitmap*>& bitmaps() const { return bitmaps_; } | |
121 | 109 |
122 private: | 110 private: |
123 std::vector<const SkBitmap*> bitmaps_; | 111 scoped_ptr<ImageSkia> image_; |
124 | 112 |
125 DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); | 113 DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); |
126 }; | 114 }; |
127 | 115 |
128 #if defined(TOOLKIT_GTK) | 116 #if defined(TOOLKIT_GTK) |
129 class ImageRepGdk : public ImageRep { | 117 class ImageRepGdk : public ImageRep { |
130 public: | 118 public: |
131 explicit ImageRepGdk(GdkPixbuf* pixbuf) | 119 explicit ImageRepGdk(GdkPixbuf* pixbuf) |
132 : ImageRep(Image::kImageRepGdk), | 120 : ImageRep(Image::kImageRepGdk), |
133 pixbuf_(pixbuf) { | 121 pixbuf_(pixbuf) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 }; | 219 }; |
232 | 220 |
233 } // namespace internal | 221 } // namespace internal |
234 | 222 |
235 Image::Image() { | 223 Image::Image() { |
236 // |storage_| is NULL for empty Images. | 224 // |storage_| is NULL for empty Images. |
237 } | 225 } |
238 | 226 |
239 Image::Image(const SkBitmap* bitmap) | 227 Image::Image(const SkBitmap* bitmap) |
240 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { | 228 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { |
241 internal::ImageRepSkia* rep = new internal::ImageRepSkia(bitmap); | 229 internal::ImageRepSkia* rep = new internal::ImageRepSkia( |
| 230 new ImageSkia(bitmap)); |
242 AddRepresentation(rep); | 231 AddRepresentation(rep); |
243 } | 232 } |
244 | 233 |
245 Image::Image(const SkBitmap& bitmap) | 234 Image::Image(const SkBitmap& bitmap) |
246 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { | 235 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { |
247 internal::ImageRepSkia* rep = | 236 internal::ImageRepSkia* rep = |
248 new internal::ImageRepSkia(new SkBitmap(bitmap)); | 237 new internal::ImageRepSkia(new ImageSkia(new SkBitmap(bitmap))); |
249 AddRepresentation(rep); | 238 AddRepresentation(rep); |
250 } | 239 } |
251 | 240 |
252 Image::Image(const std::vector<const SkBitmap*>& bitmaps) | 241 Image::Image(const std::vector<const SkBitmap*>& bitmaps) |
253 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { | 242 : storage_(new internal::ImageStorage(Image::kImageRepSkia)) { |
254 internal::ImageRepSkia* rep = new internal::ImageRepSkia(bitmaps); | 243 internal::ImageRepSkia* rep = new internal::ImageRepSkia( |
| 244 new ImageSkia(bitmaps)); |
255 AddRepresentation(rep); | 245 AddRepresentation(rep); |
256 } | 246 } |
257 | 247 |
258 #if defined(TOOLKIT_GTK) | 248 #if defined(TOOLKIT_GTK) |
259 Image::Image(GdkPixbuf* pixbuf) | 249 Image::Image(GdkPixbuf* pixbuf) |
260 : storage_(new internal::ImageStorage(Image::kImageRepGdk)) { | 250 : storage_(new internal::ImageStorage(Image::kImageRepGdk)) { |
261 internal::ImageRepGdk* rep = new internal::ImageRepGdk(pixbuf); | 251 internal::ImageRepGdk* rep = new internal::ImageRepGdk(pixbuf); |
262 AddRepresentation(rep); | 252 AddRepresentation(rep); |
263 } | 253 } |
264 #endif | 254 #endif |
(...skipping 12 matching lines...) Expand all Loading... |
277 Image& Image::operator=(const Image& other) { | 267 Image& Image::operator=(const Image& other) { |
278 storage_ = other.storage_; | 268 storage_ = other.storage_; |
279 return *this; | 269 return *this; |
280 } | 270 } |
281 | 271 |
282 Image::~Image() { | 272 Image::~Image() { |
283 } | 273 } |
284 | 274 |
285 const SkBitmap* Image::ToSkBitmap() const { | 275 const SkBitmap* Image::ToSkBitmap() const { |
286 internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia); | 276 internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia); |
287 return rep->AsImageRepSkia()->bitmap(); | 277 return rep->AsImageRepSkia()->image()->bitmaps()[0]; |
| 278 } |
| 279 |
| 280 const ImageSkia* Image::ToImageSkia() const { |
| 281 internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia); |
| 282 return rep->AsImageRepSkia()->image(); |
288 } | 283 } |
289 | 284 |
290 #if defined(TOOLKIT_GTK) | 285 #if defined(TOOLKIT_GTK) |
291 GdkPixbuf* Image::ToGdkPixbuf() const { | 286 GdkPixbuf* Image::ToGdkPixbuf() const { |
292 internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); | 287 internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); |
293 return rep->AsImageRepGdk()->pixbuf(); | 288 return rep->AsImageRepGdk()->pixbuf(); |
294 } | 289 } |
295 | 290 |
296 CairoCachedSurface* const Image::ToCairo() const { | 291 CairoCachedSurface* const Image::ToCairo() const { |
297 internal::ImageRep* rep = GetRepresentation(Image::kImageRepCairoCache); | 292 internal::ImageRep* rep = GetRepresentation(Image::kImageRepCairoCache); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 | 370 |
376 // At this point, the requested rep does not exist, so it must be converted | 371 // At this point, the requested rep does not exist, so it must be converted |
377 // from the default rep. | 372 // from the default rep. |
378 | 373 |
379 // Handle native-to-Skia conversion. | 374 // Handle native-to-Skia conversion. |
380 if (rep_type == Image::kImageRepSkia) { | 375 if (rep_type == Image::kImageRepSkia) { |
381 internal::ImageRepSkia* rep = NULL; | 376 internal::ImageRepSkia* rep = NULL; |
382 #if defined(TOOLKIT_GTK) | 377 #if defined(TOOLKIT_GTK) |
383 if (storage_->default_representation_type() == Image::kImageRepGdk) { | 378 if (storage_->default_representation_type() == Image::kImageRepGdk) { |
384 internal::ImageRepGdk* pixbuf_rep = default_rep->AsImageRepGdk(); | 379 internal::ImageRepGdk* pixbuf_rep = default_rep->AsImageRepGdk(); |
385 rep = new internal::ImageRepSkia( | 380 rep = new internal::ImageRepSkia(new ImageSkia( |
386 internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf())); | 381 internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf()))); |
387 } | 382 } |
388 // We don't do conversions from CairoCachedSurfaces to Skia because the | 383 // We don't do conversions from CairoCachedSurfaces to Skia because the |
389 // data lives on the display server and we'll always have a GdkPixbuf if we | 384 // data lives on the display server and we'll always have a GdkPixbuf if we |
390 // have a CairoCachedSurface. | 385 // have a CairoCachedSurface. |
391 #elif defined(OS_MACOSX) | 386 #elif defined(OS_MACOSX) |
392 if (storage_->default_representation_type() == Image::kImageRepCocoa) { | 387 if (storage_->default_representation_type() == Image::kImageRepCocoa) { |
393 internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa(); | 388 internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa(); |
394 std::vector<const SkBitmap*> bitmaps; | 389 std::vector<const SkBitmap*> bitmaps; |
395 CHECK(internal::NSImageToSkBitmaps(nsimage_rep->image(), &bitmaps)); | 390 CHECK(internal::NSImageToSkBitmaps(nsimage_rep->image(), &bitmaps)); |
396 rep = new internal::ImageRepSkia(bitmaps); | 391 rep = new internal::ImageRepSkia(new ImageSkia(bitmaps)); |
397 } | 392 } |
398 #endif | 393 #endif |
399 CHECK(rep); | 394 CHECK(rep); |
400 AddRepresentation(rep); | 395 AddRepresentation(rep); |
401 return rep; | 396 return rep; |
402 } | 397 } |
403 #if defined(TOOLKIT_GTK) | 398 #if defined(TOOLKIT_GTK) |
404 else if (rep_type == Image::kImageRepCairoCache) { | 399 else if (rep_type == Image::kImageRepCairoCache) { |
405 // Handle any-to-Cairo conversion. This may recursively create an | 400 // Handle any-to-Cairo conversion. This may recursively create an |
406 // intermediate pixbuf before we send the data to the display server. | 401 // intermediate pixbuf before we send the data to the display server. |
407 internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); | 402 internal::ImageRep* rep = GetRepresentation(Image::kImageRepGdk); |
408 internal::ImageRepCairoCached* native_rep = | 403 internal::ImageRepCairoCached* native_rep = |
409 new internal::ImageRepCairoCached(rep->AsImageRepGdk()->pixbuf()); | 404 new internal::ImageRepCairoCached(rep->AsImageRepGdk()->pixbuf()); |
410 | 405 |
411 CHECK(native_rep); | 406 CHECK(native_rep); |
412 AddRepresentation(native_rep); | 407 AddRepresentation(native_rep); |
413 return native_rep; | 408 return native_rep; |
414 } | 409 } |
415 #endif | 410 #endif |
416 | 411 |
417 // Handle Skia-to-native conversions. | 412 // Handle Skia-to-native conversions. |
418 if (default_rep->type() == Image::kImageRepSkia) { | 413 if (default_rep->type() == Image::kImageRepSkia) { |
419 internal::ImageRep* native_rep = NULL; | 414 internal::ImageRep* native_rep = NULL; |
420 #if defined(USE_AURA) | 415 #if defined(USE_AURA) |
421 NOTIMPLEMENTED(); | 416 NOTIMPLEMENTED(); |
422 #elif defined(TOOLKIT_GTK) | 417 #elif defined(TOOLKIT_GTK) |
423 if (rep_type == Image::kImageRepGdk) { | 418 if (rep_type == Image::kImageRepGdk) { |
424 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap( | 419 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap( |
425 default_rep->AsImageRepSkia()->bitmap()); | 420 default_rep->AsImageRepSkia()->image()->bitmaps()[0]); |
426 native_rep = new internal::ImageRepGdk(pixbuf); | 421 native_rep = new internal::ImageRepGdk(pixbuf); |
427 } | 422 } |
428 #elif defined(OS_MACOSX) | 423 #elif defined(OS_MACOSX) |
429 if (rep_type == Image::kImageRepCocoa) { | 424 if (rep_type == Image::kImageRepCocoa) { |
430 NSImage* image = gfx::SkBitmapsToNSImage( | 425 NSImage* image = gfx::SkBitmapsToNSImage( |
431 default_rep->AsImageRepSkia()->bitmaps()); | 426 default_rep->AsImageRepSkia()->image()->bitmaps()); |
432 base::mac::NSObjectRetain(image); | 427 base::mac::NSObjectRetain(image); |
433 native_rep = new internal::ImageRepCocoa(image); | 428 native_rep = new internal::ImageRepCocoa(image); |
434 } | 429 } |
435 #endif | 430 #endif |
436 CHECK(native_rep); | 431 CHECK(native_rep); |
437 AddRepresentation(native_rep); | 432 AddRepresentation(native_rep); |
438 return native_rep; | 433 return native_rep; |
439 } | 434 } |
440 | 435 |
441 // Something went seriously wrong... | 436 // Something went seriously wrong... |
442 return NULL; | 437 return NULL; |
443 } | 438 } |
444 | 439 |
445 void Image::AddRepresentation(internal::ImageRep* rep) const { | 440 void Image::AddRepresentation(internal::ImageRep* rep) const { |
446 CHECK(storage_.get()); | 441 CHECK(storage_.get()); |
447 storage_->representations().insert(std::make_pair(rep->type(), rep)); | 442 storage_->representations().insert(std::make_pair(rep->type(), rep)); |
448 } | 443 } |
449 | 444 |
450 size_t Image::GetNumberOfSkBitmaps() const { | |
451 return GetRepresentation(Image::kImageRepSkia)->AsImageRepSkia()-> | |
452 bitmaps().size(); | |
453 } | |
454 | |
455 const SkBitmap* Image::GetSkBitmapAtIndex(size_t index) const { | |
456 return GetRepresentation(Image::kImageRepSkia)->AsImageRepSkia()-> | |
457 bitmaps()[index]; | |
458 } | |
459 | |
460 } // namespace gfx | 445 } // namespace gfx |
OLD | NEW |