diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 14:41:32 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-21 14:41:32 +0000 |
commit | f6b50339c9344e050baffe0f9062799fa14c4665 (patch) | |
tree | f9123f028e98c1d7c98ac33118295238a1f3208f /gfx | |
parent | 7d5ac9e5a0f5f18cac2f2a8b45de1eeab2751a79 (diff) | |
download | chromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.zip chromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.tar.gz chromium_src-f6b50339c9344e050baffe0f9062799fa14c4665.tar.bz2 |
Create gfx::ScopedImage. This wraps a gfx::NativeImage and hides the underlying
memory management for each platform under a consistent interface.
BUG=none
TEST=Compile and gfx_unittests
Review URL: http://codereview.chromium.org/3841002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63359 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/gfx.gyp | 2 | ||||
-rw-r--r-- | gfx/native_widget_types.h | 9 | ||||
-rw-r--r-- | gfx/scoped_image.h | 147 | ||||
-rw-r--r-- | gfx/scoped_image_unittest.cc | 98 |
4 files changed, 252 insertions, 4 deletions
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp index 67cd8c1..0d3b3d0 100644 --- a/gfx/gfx.gyp +++ b/gfx/gfx.gyp @@ -30,6 +30,7 @@ 'insets_unittest.cc', 'rect_unittest.cc', 'run_all_unittests.cc', + 'scoped_image_unittest.cc', 'skbitmap_operations_unittest.cc', 'test_suite.h', '<(SHARED_INTERMEDIATE_DIR)/gfx/gfx_resources.rc', @@ -124,6 +125,7 @@ 'point.h', 'rect.cc', 'rect.h', + 'scoped_image.h', 'scrollbar_size.cc', 'scrollbar_size.h', 'size.cc', diff --git a/gfx/native_widget_types.h b/gfx/native_widget_types.h index b7ff4bb..9c85edd 100644 --- a/gfx/native_widget_types.h +++ b/gfx/native_widget_types.h @@ -96,12 +96,13 @@ typedef GdkRegion* NativeRegion; #endif #if defined(OS_MACOSX) -typedef NSImage* NativeImage; -#elif defined(USE_X11) && !defined(TOOLKIT_VIEWS) -typedef GdkPixbuf* NativeImage; +typedef NSImage NativeImageType; +#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) +typedef GdkPixbuf NativeImageType; #else -typedef const SkBitmap* NativeImage; +typedef SkBitmap NativeImageType; #endif +typedef NativeImageType* NativeImage; // Note: for test_shell we're packing a pointer into the NativeViewId. So, if // you make it a type which is smaller than a pointer, you have to fix diff --git a/gfx/scoped_image.h b/gfx/scoped_image.h new file mode 100644 index 0000000..c539a94 --- /dev/null +++ b/gfx/scoped_image.h @@ -0,0 +1,147 @@ +// Copyright (c) 2010 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 GFX_SCOPED_IMAGE_H_ +#define GFX_SCOPED_IMAGE_H_ +#pragma once + +#include "base/basictypes.h" +#include "build/build_config.h" +#include "gfx/native_widget_types.h" +#include "third_party/skia/include/core/SkBitmap.h" + +#if defined(OS_LINUX) +#include <glib-object.h> +#elif defined(OS_MACOSX) +#include "base/mac_util.h" +#endif + +namespace gfx { + +namespace internal { + +// ScopedImage is class that encapsulates one of the three platform-specific +// images used: SkBitmap, NSImage, and GdkPixbuf. This is the abstract interface +// that all ScopedImages respond to. This wrapper expects to own the image it +// holds, unless it is Release()ed or Free()ed. +// +// This class is abstract and callers should use the specialized versions below, +// which are not in the internal namespace. +template <class ImageType> +class ScopedImage { + public: + virtual ~ScopedImage() {} + + // Frees the actual image that this boxes. + virtual void Free() = 0; + + // Returns the image that this boxes. + ImageType* Get() { + return image_; + } + + // Frees the current image and sets a new one. + void Set(ImageType* new_image) { + Free(); + image_ = new_image; + } + + // Returns the image this boxes and relinquishes ownership. + ImageType* Release() { + ImageType* tmp = image_; + image_ = NULL; + return tmp; + } + + protected: + explicit ScopedImage(ImageType* image) : image_(image) {} + ImageType* image_; + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImage); +}; + +} // namespace internal + +// Generic template. +template <class ImageType = gfx::NativeImageType> +class ScopedImage : public gfx::internal::ScopedImage<ImageType> { + public: + explicit ScopedImage(gfx::NativeImage image) + : gfx::internal::ScopedImage<ImageType>(image) {} + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImage<ImageType>); +}; + +// Specialization for SkBitmap on all platforms. +template <> +class ScopedImage<SkBitmap> : public gfx::internal::ScopedImage<SkBitmap> { + public: + explicit ScopedImage(SkBitmap* image) + : gfx::internal::ScopedImage<SkBitmap>(image) {} + virtual ~ScopedImage() { + Free(); + } + + virtual void Free() { + delete image_; + image_ = NULL; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImage); +}; + +// Specialization for the NSImage type on Mac OS X. +#if defined(OS_MACOSX) +template <> +class ScopedImage<NSImage> : public gfx::internal::ScopedImage<NSImage> { + public: + explicit ScopedImage(NSImage* image) + : gfx::internal::ScopedImage<NSImage>(image) {} + virtual ~ScopedImage() { + Free(); + } + + virtual void Free() { + mac_util::NSObjectRelease(image_); + image_ = NULL; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImage); +}; +#endif // defined(OS_MACOSX) + +// Specialization for the GdkPixbuf type on Linux. +#if defined(OS_LINUX) +template <> +class ScopedImage<GdkPixbuf> : public gfx::internal::ScopedImage<GdkPixbuf> { + public: + explicit ScopedImage(GdkPixbuf* image) + : gfx::internal::ScopedImage<GdkPixbuf>(image) {} + virtual ~ScopedImage() { + Free(); + } + + virtual void Free() { + if (image_) { + g_object_unref(image_); + image_ = NULL; + } + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedImage); +}; +#endif // defined(OS_LINUX) + +// Typedef ScopedNativeImage to the default template argument. This allows for +// easy exchange between gfx::NativeImage and a gfx::ScopedNativeImage. +typedef ScopedImage<> ScopedNativeImage; + +} // namespace gfx + +#endif // GFX_SCOPED_IMAGE_H_ diff --git a/gfx/scoped_image_unittest.cc b/gfx/scoped_image_unittest.cc new file mode 100644 index 0000000..c43dd43 --- /dev/null +++ b/gfx/scoped_image_unittest.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2010 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. + +#include "base/scoped_ptr.h" +#include "gfx/scoped_image.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" + +#if defined(OS_LINUX) +#include "gfx/gtk_util.h" +#elif defined(OS_MACOSX) +#include "base/mac_util.h" +#include "skia/ext/skia_utils_mac.h" +#endif + +namespace { + +class ScopedImageTest : public testing::Test { + public: + SkBitmap* CreateBitmap() { + SkBitmap* bitmap = new SkBitmap(); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, 25, 25); + bitmap->allocPixels(); + bitmap->eraseRGB(255, 0, 0); + return bitmap; + } + + gfx::NativeImage CreateNativeImage() { + scoped_ptr<SkBitmap> bitmap(CreateBitmap()); +#if defined(OS_MACOSX) + NSImage* image = gfx::SkBitmapToNSImage(*(bitmap.get())); + mac_util::NSObjectRetain(image); + return image; +#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) + return gfx::GdkPixbufFromSkBitmap(bitmap.get()); +#else + return bitmap.release(); +#endif + } +}; + +TEST_F(ScopedImageTest, Initialize) { + gfx::ScopedImage<SkBitmap> image(CreateBitmap()); + EXPECT_TRUE(image.Get()); +} + +TEST_F(ScopedImageTest, Free) { + gfx::ScopedImage<SkBitmap> image(CreateBitmap()); + EXPECT_TRUE(image.Get()); + image.Free(); + EXPECT_FALSE(image.Get()); +} + +TEST_F(ScopedImageTest, Release) { + gfx::ScopedImage<SkBitmap> image(CreateBitmap()); + EXPECT_TRUE(image.Get()); + scoped_ptr<SkBitmap> bitmap(image.Release()); + EXPECT_FALSE(image.Get()); +} + +TEST_F(ScopedImageTest, Set) { + gfx::ScopedImage<SkBitmap> image(CreateBitmap()); + EXPECT_TRUE(image.Get()); + SkBitmap* image2 = CreateBitmap(); + image.Set(image2); + EXPECT_EQ(image2, image.Get()); +} + +TEST_F(ScopedImageTest, NativeInitialize) { + gfx::ScopedNativeImage image(CreateNativeImage()); + EXPECT_TRUE(image.Get()); +} + +TEST_F(ScopedImageTest, NativeFree) { + gfx::ScopedNativeImage image(CreateNativeImage()); + EXPECT_TRUE(image.Get()); + image.Free(); + EXPECT_FALSE(image.Get()); +} + +TEST_F(ScopedImageTest, NativeRelease) { + gfx::ScopedNativeImage image(CreateNativeImage()); + EXPECT_TRUE(image.Get()); + gfx::ScopedNativeImage image2(image.Release()); + EXPECT_FALSE(image.Get()); + EXPECT_TRUE(image2.Get()); +} + +TEST_F(ScopedImageTest, NativeSet) { + gfx::ScopedNativeImage image(CreateNativeImage()); + EXPECT_TRUE(image.Get()); + gfx::NativeImage image2 = CreateNativeImage(); + image.Set(image2); + EXPECT_EQ(image2, image.Get()); +} + +} // namespace |