summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-22 18:34:10 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-22 18:34:10 +0000
commit1279d5f395182c6fa783da0d85216777d931af6b (patch)
tree65eac9c68a5896e0fb3b39bc62344d8a8fb6b03d
parent3e3f0eb47762a85110fb11b850df776b59073f8d (diff)
downloadchromium_src-1279d5f395182c6fa783da0d85216777d931af6b.zip
chromium_src-1279d5f395182c6fa783da0d85216777d931af6b.tar.gz
chromium_src-1279d5f395182c6fa783da0d85216777d931af6b.tar.bz2
Theme image support for the Mac.
BUG=none TEST=none Review URL: http://codereview.chromium.org/140007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18925 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/app.gyp1
-rw-r--r--app/theme_provider.cc12
-rw-r--r--app/theme_provider.h18
-rw-r--r--chrome/browser/browser_theme_provider.cc77
-rw-r--r--chrome/browser/browser_theme_provider.h21
-rw-r--r--chrome/browser/browser_theme_provider_gtk.cc11
-rw-r--r--chrome/browser/browser_theme_provider_mac.mm50
-rw-r--r--chrome/chrome.gyp1
8 files changed, 147 insertions, 44 deletions
diff --git a/app/app.gyp b/app/app.gyp
index e316d41d..faced76 100644
--- a/app/app.gyp
+++ b/app/app.gyp
@@ -101,6 +101,7 @@
'resource_bundle_mac.mm',
'slide_animation.cc',
'slide_animation.h',
+ 'theme_provider.cc',
'theme_provider.h',
'throb_animation.cc',
'throb_animation.h',
diff --git a/app/theme_provider.cc b/app/theme_provider.cc
new file mode 100644
index 0000000..7593e15
--- /dev/null
+++ b/app/theme_provider.cc
@@ -0,0 +1,12 @@
+// Copyright (c) 2009 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 "app/theme_provider.h"
+
+// We have the destructor here because GCC puts the vtable in the first file
+// that includes a virtual function of the class. Leaving it just in the .h file
+// means that GCC will fail to link.
+
+ThemeProvider::~ThemeProvider() {
+}
diff --git a/app/theme_provider.h b/app/theme_provider.h
index 774810e..75e9255 100644
--- a/app/theme_provider.h
+++ b/app/theme_provider.h
@@ -10,7 +10,13 @@
#if defined(OS_LINUX)
#include <gdk/gdk.h>
-#endif
+#elif defined(OS_MACOSX)
+#ifdef __OBJC__
+@class NSImage;
+#else
+class NSImage;
+#endif // __OBJC__
+#endif // OS_*
class SkBitmap;
@@ -25,7 +31,7 @@ class SkBitmap;
class ThemeProvider {
public:
- virtual ~ThemeProvider() { }
+ virtual ~ThemeProvider();
// Get the bitmap specified by |id|. An implementation of ThemeProvider should
// have its own source of ids (e.g. an enum, or external resource bundle).
@@ -56,6 +62,14 @@ class ThemeProvider {
// pointer to a shared empty placeholder bitmap so it will be visible what
// is missing.
virtual GdkPixbuf* GetPixbufNamed(int id) = 0;
+#elif defined(OS_MACOSX)
+ // Gets the NSImage with the specified |id|. Returns a pointer to a shared
+ // instance of the NSImage. This shared NSImage is owned by the theme
+ // provider and should not be freed.
+ //
+ // The bitmap is not assumed to exist. If a theme does not provide an image,
+ // this function will return nil.
+ virtual NSImage* GetNSImageNamed(int id) = 0;
#endif
};
diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc
index 6307c86..03b8575 100644
--- a/chrome/browser/browser_theme_provider.cc
+++ b/chrome/browser/browser_theme_provider.cc
@@ -136,14 +136,6 @@ BrowserThemeProvider::BrowserThemeProvider()
BrowserThemeProvider::~BrowserThemeProvider() {
FreeImages();
-#if defined(OS_LINUX)
- // Free GdkPixbufs.
- for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
- i != gdk_pixbufs_.end(); i++) {
- g_object_unref(i->second);
- }
- gdk_pixbufs_.clear();
-#endif
}
void BrowserThemeProvider::Init(Profile* profile) {
@@ -311,10 +303,8 @@ void BrowserThemeProvider::UseDefaultTheme() {
UserMetrics::RecordAction(L"Themes_Reset", profile_);
}
-SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) {
- DCHECK(CalledOnValidThread());
- // Attempt to find the image in our theme bundle.
- std::vector<unsigned char> raw_data, png_data;
+bool BrowserThemeProvider::ReadThemeFileData(
+ int id, std::vector<unsigned char>* raw_data) {
if (images_.count(id)) {
// First check to see if we have a registered theme extension and whether
// it can handle this resource.
@@ -330,35 +320,43 @@ SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) {
int64 avail = file.Available();
if (avail > 0 && avail < INT_MAX) {
size_t size = static_cast<size_t>(avail);
- raw_data.resize(size);
- char* data = reinterpret_cast<char*>(&(raw_data.front()));
- if (file.ReadUntilComplete(data, size) == avail) {
- // Decode the PNG.
- int image_width = 0;
- int image_height = 0;
-
- if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
- PNGDecoder::FORMAT_BGRA, &png_data,
- &image_width, &image_height)) {
- NOTREACHED() << "Unable to decode theme image resource " << id;
- return NULL;
- }
-
- return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
- image_width,
- image_height);
- }
+ raw_data->resize(size);
+ char* data = reinterpret_cast<char*>(&(raw_data->front()));
+ if (file.ReadUntilComplete(data, size) == avail)
+ return true;
}
- } else {
- // TODO(glen): File no-longer exists, we're out of date. We should
- // clear the theme (or maybe just the pref that points to this
- // image).
- return NULL;
}
}
}
- return NULL;
+ return false;
+}
+
+SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) {
+ DCHECK(CalledOnValidThread());
+ // Attempt to find the image in our theme bundle.
+ std::vector<unsigned char> raw_data, png_data;
+ if (ReadThemeFileData(id, &raw_data)) {
+ // Decode the PNG.
+ int image_width = 0;
+ int image_height = 0;
+
+ if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
+ PNGDecoder::FORMAT_BGRA, &png_data,
+ &image_width, &image_height)) {
+ NOTREACHED() << "Unable to decode theme image resource " << id;
+ return NULL;
+ }
+
+ return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
+ image_width,
+ image_height);
+ } else {
+ // TODO(glen): File no-longer exists, we're out of date. We should
+ // clear the theme (or maybe just the pref that points to this
+ // image).
+ return NULL;
+ }
}
skia::HSL BrowserThemeProvider::GetTint(int id) {
@@ -732,6 +730,7 @@ SkColor BrowserThemeProvider::FindColor(const char* id,
}
void BrowserThemeProvider::FreeImages() {
+ FreePlatformImages();
for (std::vector<SkBitmap*>::iterator i = generated_images_.begin();
i != generated_images_.end(); i++) {
delete *i;
@@ -739,3 +738,9 @@ void BrowserThemeProvider::FreeImages() {
generated_images_.clear();
image_cache_.clear();
}
+
+#if defined(OS_WIN)
+void BrowserThemeProvider::FreePlatformImages() {
+ // Windows has no platform image cache to clear.
+}
+#endif
diff --git a/chrome/browser/browser_theme_provider.h b/chrome/browser/browser_theme_provider.h
index 9883c67..b5817a2 100644
--- a/chrome/browser/browser_theme_provider.h
+++ b/chrome/browser/browser_theme_provider.h
@@ -16,10 +16,6 @@
#include "base/ref_counted.h"
#include "skia/ext/skia_utils.h"
-#if defined(OS_LINUX)
-#include <gdk/gdk.h>
-#endif
-
class Extension;
class Profile;
class DictionaryValue;
@@ -74,8 +70,10 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>,
virtual bool GetDisplayProperty(int id, int* result);
virtual bool ShouldUseNativeFrame();
virtual bool HasCustomImage(int id);
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
virtual GdkPixbuf* GetPixbufNamed(int id);
+#elif defined(OS_MACOSX)
+ virtual NSImage* GetNSImageNamed(int id);
#endif
// Set the current theme to the theme defined in |extension|.
@@ -98,6 +96,10 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>,
typedef std::map<const std::string, skia::HSL> TintMap;
typedef std::map<const std::string, int> DisplayPropertyMap;
+ // Reads the image data from the theme file into the specified vector. Returns
+ // true on success.
+ bool ReadThemeFileData(int id, std::vector<unsigned char>* raw_data);
+
// Loads a bitmap from the theme, which may be tinted or
// otherwise modified, or an application default.
SkBitmap* LoadThemeBitmap(int id);
@@ -158,13 +160,20 @@ class BrowserThemeProvider : public base::RefCounted<BrowserThemeProvider>,
// Frees generated images and clears the image cache.
void FreeImages();
+ // Clears the platform-specific image cache. Do not call directly; it's called
+ // from FreeImages().
+ void FreePlatformImages();
+
// Cached images. We cache all retrieved and generated bitmaps and keep
// track of the pointers.
typedef std::map<int, SkBitmap*> ImageCache;
ImageCache image_cache_;
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
typedef std::map<int, GdkPixbuf*> GdkPixbufMap;
GdkPixbufMap gdk_pixbufs_;
+#elif defined(OS_MACOSX)
+ typedef std::map<int, NSImage*> NSImageMap;
+ NSImageMap nsimage_cache_;
#endif
// List of generate images that aren't stored in ResourceBundles image cache
diff --git a/chrome/browser/browser_theme_provider_gtk.cc b/chrome/browser/browser_theme_provider_gtk.cc
index 84ad293..370e773 100644
--- a/chrome/browser/browser_theme_provider_gtk.cc
+++ b/chrome/browser/browser_theme_provider_gtk.cc
@@ -40,3 +40,14 @@ GdkPixbuf* BrowserThemeProvider::GetPixbufNamed(int id) {
}
return empty_bitmap;
}
+
+void BrowserThemeProvider::FreePlatformImages() {
+ DCHECK(CalledOnValidThread());
+
+ // Free GdkPixbufs.
+ for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
+ i != gdk_pixbufs_.end(); i++) {
+ g_object_unref(i->second);
+ }
+ gdk_pixbufs_.clear();
+}
diff --git a/chrome/browser/browser_theme_provider_mac.mm b/chrome/browser/browser_theme_provider_mac.mm
new file mode 100644
index 0000000..a1709f9
--- /dev/null
+++ b/chrome/browser/browser_theme_provider_mac.mm
@@ -0,0 +1,50 @@
+// Copyright (c) 2009 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 "chrome/browser/browser_theme_provider.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/logging.h"
+
+NSImage* BrowserThemeProvider::GetNSImageNamed(int id) {
+ DCHECK(CalledOnValidThread());
+
+ // Check to see if we already have the image in the cache.
+ NSImageMap::const_iterator found = nsimage_cache_.find(id);
+ if (found != nsimage_cache_.end())
+ return found->second;
+
+ // Why do we load the file directly into the image rather than doing the whole
+ // SkBitmap > native conversion that others do? Going direct means:
+ // - we use the color profiles and other embedded info in the image file
+ // - we don't fall back to the default resources which we don't use on the Mac
+ std::vector<unsigned char> raw_data;
+ if (ReadThemeFileData(id, &raw_data)) {
+ NSData* ns_data = [NSData dataWithBytes:&raw_data.front()
+ length:raw_data.size()];
+ if (ns_data) {
+ NSImage* nsimage = [[NSImage alloc] initWithData:ns_data];
+
+ // We loaded successfully. Cache the image.
+ if (nsimage) {
+ nsimage_cache_[id] = nsimage;
+ return nsimage;
+ }
+ }
+ }
+
+ return nil;
+}
+
+void BrowserThemeProvider::FreePlatformImages() {
+ DCHECK(CalledOnValidThread());
+
+ // Free images.
+ for (NSImageMap::iterator i = nsimage_cache_.begin();
+ i != nsimage_cache_.end(); i++) {
+ [i->second release];
+ }
+ nsimage_cache_.clear();
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 09513d8..1fcfa58 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -668,6 +668,7 @@
'browser/browser_shutdown.cc',
'browser/browser_shutdown.h',
'browser/browser_theme_provider_gtk.cc',
+ 'browser/browser_theme_provider_mac.mm',
'browser/browser_theme_provider.cc',
'browser/browser_theme_provider.h',
'browser/browser_trial.cc',