diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 01:08:51 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 01:08:51 +0000 |
commit | 8779d8bd47ddd9893809e73a9a552a0b463e3188 (patch) | |
tree | af4c18d2146edcb2f55013c472867a5a2d4b7dbf /ui/gfx/image.cc | |
parent | 7c719877de70f70a25d0549671603728d8dc8f77 (diff) | |
download | chromium_src-8779d8bd47ddd9893809e73a9a552a0b463e3188.zip chromium_src-8779d8bd47ddd9893809e73a9a552a0b463e3188.tar.gz chromium_src-8779d8bd47ddd9893809e73a9a552a0b463e3188.tar.bz2 |
Move the internals of gfx::Image into a ref-counted storage class.
This will allow gfx::Image to be cheaply copied like an SkBitmap.
BUG=none
TEST=ui_unittests
Review URL: http://codereview.chromium.org/6880121
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/image.cc')
-rw-r--r-- | ui/gfx/image.cc | 81 |
1 files changed, 62 insertions, 19 deletions
diff --git a/ui/gfx/image.cc b/ui/gfx/image.cc index b42e215..9395279 100644 --- a/ui/gfx/image.cc +++ b/ui/gfx/image.cc @@ -150,35 +150,74 @@ class NSImageRep : public ImageRep { }; #endif +// The Storage class acts similarly to the pixels in a SkBitmap: the Image +// class holds a refptr instance of Storage, which in turn holds all the +// ImageReps. This way, the Image can be cheaply copied. +class ImageStorage : public base::RefCounted<ImageStorage> { + public: + ImageStorage(gfx::Image::RepresentationType default_type) + : default_representation_type_(default_type) { + } + + gfx::Image::RepresentationType default_representation_type() { + return default_representation_type_; + } + gfx::Image::RepresentationMap& representations() { return representations_; } + + private: + ~ImageStorage() { + for (gfx::Image::RepresentationMap::iterator it = representations_.begin(); + it != representations_.end(); + ++it) { + delete it->second; + } + representations_.clear(); + } + + // The type of image that was passed to the constructor. This key will always + // exist in the |representations_| map. + gfx::Image::RepresentationType default_representation_type_; + + // All the representations of an Image. Size will always be at least one, with + // more for any converted representations. + gfx::Image::RepresentationMap representations_; + + friend class base::RefCounted<ImageStorage>; +}; + } // namespace internal Image::Image(const SkBitmap* bitmap) - : default_representation_(Image::kSkBitmapRep) { + : storage_(new internal::ImageStorage(Image::kSkBitmapRep)) { internal::SkBitmapRep* rep = new internal::SkBitmapRep(bitmap); AddRepresentation(rep); } #if defined(OS_LINUX) Image::Image(GdkPixbuf* pixbuf) - : default_representation_(Image::kGdkPixbufRep) { + : storage_(new internal::ImageStorage(Image::kGdkPixbufRep)) { internal::GdkPixbufRep* rep = new internal::GdkPixbufRep(pixbuf); AddRepresentation(rep); } #endif #if defined(OS_MACOSX) -Image::Image(NSImage* image) : default_representation_(Image::kNSImageRep) { +Image::Image(NSImage* image) + : storage_(new internal::ImageStorage(Image::kNSImageRep)) { internal::NSImageRep* rep = new internal::NSImageRep(image); AddRepresentation(rep); } #endif +Image::Image(const Image& other) : storage_(other.storage_) { +} + +Image& Image::operator=(const Image& other) { + storage_ = other.storage_; + return *this; +} + Image::~Image() { - for (RepresentationMap::iterator it = representations_.begin(); - it != representations_.end(); ++it) { - delete it->second; - } - representations_.clear(); } Image::operator const SkBitmap*() { @@ -205,30 +244,34 @@ Image::operator NSImage*() { #endif bool Image::HasRepresentation(RepresentationType type) { - return representations_.count(type) != 0; + return storage_->representations().count(type) != 0; +} + +size_t Image::RepresentationCount() { + return storage_->representations().size(); } void Image::SwapRepresentations(gfx::Image* other) { - representations_.swap(other->representations_); - std::swap(default_representation_, other->default_representation_); + storage_.swap(other->storage_); } internal::ImageRep* Image::DefaultRepresentation() { + RepresentationMap& representations = storage_->representations(); RepresentationMap::iterator it = - representations_.find(default_representation_); - DCHECK(it != representations_.end()); + representations.find(storage_->default_representation_type()); + DCHECK(it != representations.end()); return it->second; } internal::ImageRep* Image::GetRepresentation(RepresentationType rep_type) { // If the requested rep is the default, return it. internal::ImageRep* default_rep = DefaultRepresentation(); - if (rep_type == default_representation_) + if (rep_type == storage_->default_representation_type()) return default_rep; // Check to see if the representation already exists. - RepresentationMap::iterator it = representations_.find(rep_type); - if (it != representations_.end()) + RepresentationMap::iterator it = storage_->representations().find(rep_type); + if (it != storage_->representations().end()) return it->second; // At this point, the requested rep does not exist, so it must be converted @@ -238,13 +281,13 @@ internal::ImageRep* Image::GetRepresentation(RepresentationType rep_type) { if (rep_type == Image::kSkBitmapRep) { internal::SkBitmapRep* rep = NULL; #if defined(OS_LINUX) - if (default_representation_ == Image::kGdkPixbufRep) { + if (storage_->default_representation_type() == Image::kGdkPixbufRep) { internal::GdkPixbufRep* pixbuf_rep = default_rep->AsGdkPixbufRep(); rep = new internal::SkBitmapRep( internal::GdkPixbufToSkBitmap(pixbuf_rep->pixbuf())); } #elif defined(OS_MACOSX) - if (default_representation_ == Image::kNSImageRep) { + if (storage_->default_representation_type() == Image::kNSImageRep) { internal::NSImageRep* nsimage_rep = default_rep->AsNSImageRep(); rep = new internal::SkBitmapRep( internal::NSImageToSkBitmap(nsimage_rep->image())); @@ -281,7 +324,7 @@ internal::ImageRep* Image::GetRepresentation(RepresentationType rep_type) { } void Image::AddRepresentation(internal::ImageRep* rep) { - representations_.insert(std::make_pair(rep->type(), rep)); + storage_->representations().insert(std::make_pair(rep->type(), rep)); } } // namespace gfx |