• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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