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
|
// 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 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_
|