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 true when ImageSkia looks up the resource pack with the closest 82 // scale factor and rescale the fetched image. 83 static bool IsDSFScalingInImageSkiaEnabled(); 84 85 // Returns a deep copy of this ImageSkia which has its own storage with 86 // the ImageSkiaRep instances that this ImageSkia currently has. 87 // This can be safely passed to and manipulated by another thread. 88 // Note that this does NOT generate ImageSkiaReps from its source. 89 // If you want to create a deep copy with ImageSkiaReps for supported 90 // scale factors, you need to explicitly call 91 // |EnsureRepsForSupportedScales()| first. 92 scoped_ptr<ImageSkia> DeepCopy() const; 93 94 // Returns true if this object is backed by the same ImageSkiaStorage as 95 // |other|. Will also return true if both images are isNull(). 96 bool BackedBySameObjectAs(const gfx::ImageSkia& other) const; 97 98 // Adds |image_rep| to the image reps contained by this object. 99 void AddRepresentation(const gfx::ImageSkiaRep& image_rep); 100 101 // Removes the image rep of |scale| if present. 102 void RemoveRepresentation(float scale); 103 104 // Returns true if the object owns an image rep whose density matches 105 // |scale| exactly. 106 bool HasRepresentation(float scale) const; 107 108 // Returns the image rep whose density best matches |scale|. 109 // Returns a null image rep if the object contains no image reps. 110 const gfx::ImageSkiaRep& GetRepresentation(float scale) const; 111 112 // Make the ImageSkia instance read-only. Note that this only prevent 113 // modification from client code, and the storage may still be 114 // modified by the source if any (thus, it's not thread safe). This 115 // detaches the storage from currently accessing thread, so its safe 116 // to pass it to other thread as long as it is accessed only by that 117 // thread. If this ImageSkia's storage will be accessed by multiple 118 // threads, use |MakeThreadSafe()| method. 119 void SetReadOnly(); 120 121 // Make the image thread safe by making the storage read only and remove 122 // its source if any. All ImageSkia that shares the same storage will also 123 // become thread safe. Note that in order to make it 100% thread safe, 124 // this must be called before it's been passed to anther thread. 125 void MakeThreadSafe(); 126 bool IsThreadSafe() const; 127 128 // Returns true if this is a null object. isNull()129 bool isNull() const { return storage_.get() == NULL; } 130 131 // Width and height of image in DIP coordinate system. 132 int width() const; 133 int height() const; 134 gfx::Size size() const; 135 136 // Returns pointer to 1x bitmap contained by this object. If there is no 1x 137 // bitmap, the bitmap whose scale factor is closest to 1x is returned. 138 // This function should only be used in unittests and on platforms which do 139 // not support scale factors other than 1x. 140 // TODO(pkotwicz): Return null SkBitmap when the object has no 1x bitmap. bitmap()141 const SkBitmap* bitmap() const { return &GetBitmap(); } 142 143 // Returns a vector with the image reps contained in this object. 144 // There is no guarantee that this will return all images rep for 145 // supported scale factors. 146 std::vector<gfx::ImageSkiaRep> image_reps() const; 147 148 // When the source is available, generates all ImageReps for 149 // supported scale factors. This method is defined as const as 150 // the state change in the storage is agnostic to the caller. 151 void EnsureRepsForSupportedScales() const; 152 153 private: 154 friend class test::TestOnThread; 155 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, EmptyOnThreadTest); 156 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, StaticOnThreadTest); 157 FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, SourceOnThreadTest); 158 159 // Initialize ImageSkiaStorage with passed in parameters. 160 // If the image rep's bitmap is empty, ImageStorage is set to NULL. 161 void Init(const gfx::ImageSkiaRep& image_rep); 162 163 SkBitmap& GetBitmap() const; 164 165 // Checks if the current thread can read/modify the ImageSkia. 166 bool CanRead() const; 167 bool CanModify() const; 168 169 // Detach the storage from the currently assinged thread 170 // so that other thread can access the storage. 171 void DetachStorageFromThread(); 172 173 // A refptr so that ImageRepSkia can be copied cheaply. 174 scoped_refptr<internal::ImageSkiaStorage> storage_; 175 }; 176 177 } // namespace gfx 178 179 #endif // UI_GFX_IMAGE_IMAGE_SKIA_H_ 180