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