summaryrefslogtreecommitdiffstats
path: root/chromium/ui/gfx/image/image_skia.h
blob: 8765457b432bd9a371aff036426d6b7cf5a5205e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GFX_IMAGE_IMAGE_SKIA_H_
#define UI_GFX_IMAGE_IMAGE_SKIA_H_

#include <vector>

#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/gfx_export.h"
#include "ui/gfx/image/image_skia_rep.h"

namespace gfx {
class ImageSkiaSource;
class Size;

namespace internal {
class ImageSkiaStorage;
}  // namespace internal

namespace test {
class TestOnThread;
}

// Container for the same image at different densities, similar to NSImage.
// Image height and width are in DIP (Density Indepent Pixel) coordinates.
//
// ImageSkia should be used whenever possible instead of SkBitmap.
// Functions that mutate the image should operate on the gfx::ImageSkiaRep
// returned from ImageSkia::GetRepresentation, not on ImageSkia.
//
// ImageSkia is cheap to copy and intentionally supports copy semantics.
class GFX_EXPORT ImageSkia {
 public:
  typedef std::vector<ImageSkiaRep> ImageSkiaReps;

  // Creates an instance with no bitmaps.
  ImageSkia();

  // Creates an instance that will use the |source| to get the image
  // for scale factors. |size| specifes the size of the image in DIP.
  // ImageSkia owns |source|.
  ImageSkia(ImageSkiaSource* source, const gfx::Size& size);

  // Creates an instance that uses the |source|. The constructor loads the image
  // at |scale| and uses its dimensions to calculate the size in DIP. ImageSkia
  // owns |source|.
  ImageSkia(ImageSkiaSource* source, float scale);

  explicit ImageSkia(const gfx::ImageSkiaRep& image_rep);

  // Copies a reference to |other|'s storage.
  ImageSkia(const ImageSkia& other);

  // Copies a reference to |other|'s storage.
  ImageSkia& operator=(const ImageSkia& other);

  ~ImageSkia();

  // Changes the value of GetSupportedScales() to |scales|.
  static void SetSupportedScales(const std::vector<float>& scales);

  // Returns a vector with the scale factors which are supported by this
  // platform, in ascending order.
  static const std::vector<float>& GetSupportedScales();

  // Returns the maximum scale supported by this platform.
  static float GetMaxSupportedScale();

  // Creates an image from the passed in bitmap.
  // DIP width and height are based on scale factor of 1x.
  // Adds ref to passed in bitmap.
  // WARNING: The resulting image will be pixelated when painted on a high
  // density display.
  static ImageSkia CreateFrom1xBitmap(const SkBitmap& bitmap);

  // Returns true when ImageSkia looks up the resource pack with the closest
  // scale factor and rescale the fetched image.
  static bool IsDSFScalingInImageSkiaEnabled();

  // Returns a deep copy of this ImageSkia which has its own storage with
  // the ImageSkiaRep instances that this ImageSkia currently has.
  // This can be safely passed to and manipulated by another thread.
  // Note that this does NOT generate ImageSkiaReps from its source.
  // If you want to create a deep copy with ImageSkiaReps for supported
  // scale factors, you need to explicitly call
  // |EnsureRepsForSupportedScales()| first.
  scoped_ptr<ImageSkia> DeepCopy() const;

  // Returns true if this object is backed by the same ImageSkiaStorage as
  // |other|. Will also return true if both images are isNull().
  bool BackedBySameObjectAs(const gfx::ImageSkia& other) const;

  // Adds |image_rep| to the image reps contained by this object.
  void AddRepresentation(const gfx::ImageSkiaRep& image_rep);

  // Removes the image rep of |scale| if present.
  void RemoveRepresentation(float scale);

  // Returns true if the object owns an image rep whose density matches
  // |scale| exactly.
  bool HasRepresentation(float scale) const;

  // Returns the image rep whose density best matches |scale|.
  // Returns a null image rep if the object contains no image reps.
  const gfx::ImageSkiaRep& GetRepresentation(float scale) const;

  // Make the ImageSkia instance read-only. Note that this only prevent
  // modification from client code, and the storage may still be
  // modified by the source if any (thus, it's not thread safe).  This
  // detaches the storage from currently accessing thread, so its safe
  // to pass it to other thread as long as it is accessed only by that
  // thread. If this ImageSkia's storage will be accessed by multiple
  // threads, use |MakeThreadSafe()| method.
  void SetReadOnly();

  // Make the image thread safe by making the storage read only and remove
  // its source if any. All ImageSkia that shares the same storage will also
  // become thread safe. Note that in order to make it 100% thread safe,
  // this must be called before it's been passed to anther thread.
  void MakeThreadSafe();
  bool IsThreadSafe() const;

  // Returns true if this is a null object.
  bool isNull() const { return storage_.get() == NULL; }

  // Width and height of image in DIP coordinate system.
  int width() const;
  int height() const;
  gfx::Size size() const;

  // Returns pointer to 1x bitmap contained by this object. If there is no 1x
  // bitmap, the bitmap whose scale factor is closest to 1x is returned.
  // This function should only be used in unittests and on platforms which do
  // not support scale factors other than 1x.
  // TODO(pkotwicz): Return null SkBitmap when the object has no 1x bitmap.
  const SkBitmap* bitmap() const { return &GetBitmap(); }

  // Returns a vector with the image reps contained in this object.
  // There is no guarantee that this will return all images rep for
  // supported scale factors.
  std::vector<gfx::ImageSkiaRep> image_reps() const;

  // When the source is available, generates all ImageReps for
  // supported scale factors. This method is defined as const as
  // the state change in the storage is agnostic to the caller.
  void EnsureRepsForSupportedScales() const;

 private:
  friend class test::TestOnThread;
  FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, EmptyOnThreadTest);
  FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, StaticOnThreadTest);
  FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, SourceOnThreadTest);

  // Initialize ImageSkiaStorage with passed in parameters.
  // If the image rep's bitmap is empty, ImageStorage is set to NULL.
  void Init(const gfx::ImageSkiaRep& image_rep);

  SkBitmap& GetBitmap() const;

  // Checks if the current thread can read/modify the ImageSkia.
  bool CanRead() const;
  bool CanModify() const;

  // Detach the storage from the currently assinged thread
  // so that other thread can access the storage.
  void DetachStorageFromThread();

  // A refptr so that ImageRepSkia can be copied cheaply.
  scoped_refptr<internal::ImageSkiaStorage> storage_;
};

}  // namespace gfx

#endif  // UI_GFX_IMAGE_IMAGE_SKIA_H_