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 3 // found in the LICENSE file. 4 5 #ifndef UI_GFX_IMAGE_IMAGE_SKIA_H_ 6 #define UI_GFX_IMAGE_IMAGE_SKIA_H_ 7 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "ui/gfx/gfx_export.h" 15 #include "ui/gfx/image/image_skia_rep.h" 16 17 namespace gfx { 18 class ImageSkiaSource; 19 class Size; 20 21 namespace internal { 22 class ImageSkiaStorage; 23 } // namespace internal 24 25 namespace test { 26 class TestOnThread; 27 } 28 29 // Container for the same image at different densities, similar to NSImage. 30 // Image height and width are in DIP (Density Indepent Pixel) coordinates. 31 // 32 // ImageSkia should be used whenever possible instead of SkBitmap. 33 // Functions that mutate the image should operate on the gfx::ImageSkiaRep 34 // returned from ImageSkia::GetRepresentation, not on ImageSkia. 35 // 36 // ImageSkia is cheap to copy and intentionally supports copy semantics. 37 class GFX_EXPORT ImageSkia { 38 public: 39 typedef std::vector<ImageSkiaRep> ImageSkiaReps; 40 41 // Creates an instance with no bitmaps. 42 ImageSkia(); 43 44 // Creates an instance that will use the |source| to get the image 45 // for scale factors. |size| specifes the size of the image in DIP. 46 // ImageSkia owns |source|. 47 ImageSkia(ImageSkiaSource* source, const gfx::Size& size); 48 49 // Creates an instance that uses the |source|. The constructor loads the image 50 // at |scale| and uses its dimensions to calculate the size in DIP. ImageSkia 51 // owns |source|. 52 ImageSkia(ImageSkiaSource* source, float scale); 53 54 explicit ImageSkia(const gfx::ImageSkiaRep& image_rep); 55 56 // Copies a reference to |other|'s storage. 57 ImageSkia(const ImageSkia& other); 58 59 // Copies a reference to |other|'s storage. 60 ImageSkia& operator=(const ImageSkia& other); 61 62 ~ImageSkia(); 63 64 // Changes the value of GetSupportedScales() to |scales|. 65 static void SetSupportedScales(const std::vector<float>& scales); 66 67 // Returns a vector with the scale factors which are supported by this 68 // platform, in ascending order. 69 static const std::vector<float>& GetSupportedScales(); 70 71 // Returns the maximum scale supported by this platform. 72 static float GetMaxSupportedScale(); 73 74 // Creates an image from the passed in bitmap. 75 // DIP width and height are based on scale factor of 1x. 76 // Adds ref to passed in bitmap. 77 // WARNING: The resulting image will be pixelated when painted on a high 78 // density display. 79 static ImageSkia CreateFrom1xBitmap(const SkBitmap& bitmap); 80 81 // Returns a deep copy of this ImageSkia which has its own storage with 82 // the ImageSkiaRep instances that this ImageSkia currently has. 83 // This can be safely passed to and manipulated by another thread. 84 // Note that this does NOT generate ImageSkiaReps from its source. 85 // If you want to create a deep copy with ImageSkiaReps for supported 86 // scale factors, you need to explicitly call 87 // |EnsureRepsForSupportedScales()| first. 88 scoped_ptr<ImageSkia> DeepCopy() const; 89 90 // Returns true if this object is backed by the same ImageSkiaStorage as 91 // |other|. Will also return true if both images are isNull(). 92 bool BackedBySameObjectAs(const gfx::ImageSkia& other) const; 93 94 // Adds |image_rep| to the image reps contained by this object. 95 void AddRepresentation(const gfx::ImageSkiaRep& image_rep); 96 97 // Removes the image rep of |scale| if present. 98 void RemoveRepresentation(float scale); 99 100 // Returns true if the object owns an image rep whose density matches 101 // |scale| exactly. 102 bool HasRepresentation(float scale) const; 103 104 // Returns the image rep whose density best matches |scale|. 105 // Returns a null image rep if the object contains no image reps. 106 const gfx::ImageSkiaRep& GetRepresentation(float scale) const; 107 108 // Make the ImageSkia instance read-only. Note that this only prevent 109 // modification from client code, and the storage may still be 110 // modified by the source if any (thus, it's not thread safe). This 111 // detaches the storage from currently accessing thread, so its safe 112 // to pass it to other thread as long as it is accessed only by that 113 // thread. If this ImageSkia's storage will be accessed by multiple 114 // threads, use |MakeThreadSafe()| method. 115 void SetReadOnly(); 116 117 // Make the image thread safe by making the storage read only and remove 118 // its source if any. All ImageSkia that shares the same storage will also 119 // become thread safe. Note that in order to make it 100% thread safe, 120 // this must be called before it's been passed to anther thread. 121 void MakeThreadSafe(); 122 bool IsThreadSafe() const; 123 124 // Returns true if this is a null object. 125 bool isNull() const { return storage_.get() == NULL; } 126 127 // Width and height of image in DIP coordinate system. 128 int width() const; 129 int height() const; 130 gfx::Size size() const; 131 132 // Returns pointer to 1x bitmap contained by this object. If there is no 1x 133 // bitmap, the bitmap whose scale factor is closest to 1x is returned. 134 // This function should only be used in unittests and on platforms which do 135 // not support scale factors other than 1x. 136 // TODO(pkotwicz): Return null SkBitmap when the object has no 1x bitmap. 137 const SkBitmap* bitmap() const { return &GetBitmap(); } 138 139 // Returns a vector with the image reps contained in this object. 140 // There is no guarantee that this will return all images rep for 141 // supported scale factors. 142 std::vector<gfx::ImageSkiaRep> image_reps() const; 143 144 // When the source is available, generates all ImageReps for 145 // supported scale factors. This method is defined as const as 146 // the state change in the storage is agnostic to the caller. 147 void EnsureRepsForSupportedScales() const; 148 149 private: 150 friend class test::TestOnThread; 151 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, EmptyOnThreadTest); 152 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, StaticOnThreadTest); 153 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, SourceOnThreadTest); 154 155 // Initialize ImageSkiaStorage with passed in parameters. 156 // If the image rep's bitmap is empty, ImageStorage is set to NULL. 157 void Init(const gfx::ImageSkiaRep& image_rep); 158 159 SkBitmap& GetBitmap() const; 160 161 // Checks if the current thread can read/modify the ImageSkia. 162 bool CanRead() const; 163 bool CanModify() const; 164 165 // Detach the storage from the currently assinged thread 166 // so that other thread can access the storage. 167 void DetachStorageFromThread(); 168 169 // A refptr so that ImageRepSkia can be copied cheaply. 170 scoped_refptr<internal::ImageSkiaStorage> storage_; 171 }; 172 173 } // namespace gfx 174 175 #endif // UI_GFX_IMAGE_IMAGE_SKIA_H_ 176