summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/DEPS8
-rw-r--r--app/app.vcproj139
-rw-r--r--app/app.vsprops8
-rw-r--r--app/resource_bundle.cc205
-rw-r--r--app/resource_bundle.h203
-rw-r--r--app/resource_bundle_linux.cc209
-rw-r--r--app/resource_bundle_mac.mm120
-rw-r--r--app/resource_bundle_win.cc157
8 files changed, 1049 insertions, 0 deletions
diff --git a/app/DEPS b/app/DEPS
new file mode 100644
index 0000000..9ff54fa
--- /dev/null
+++ b/app/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+ "+net",
+ # TODO(beng): Sever this link once we have extracted all deps from
+ # chrome/common.
+ "+chrome/common",
+ # TODO(beng): Sever this link after glen fixes it.
+ "+chrome/browser/extensions/extension.h",
+]
diff --git a/app/app.vcproj b/app/app.vcproj
new file mode 100644
index 0000000..22c1e1f
--- /dev/null
+++ b/app/app.vcproj
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="app"
+ ProjectGUID="{4631946D-7D5F-44BD-A5A8-504C0A7033BE}"
+ RootNamespace="app"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\app.vsprops;$(SolutionDir)..\build\debug.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\app.vsprops;$(SolutionDir)..\build\release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\resource_bundle.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\resource_bundle.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource_bundle_win.cc"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/app/app.vsprops b/app/app.vsprops
new file mode 100644
index 0000000..fb267c1
--- /dev/null
+++ b/app/app.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="app"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\third_party\zlib\using_zlib.vsprops;$(SolutionDir)..\third_party\libpng\using_libpng.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\tools\grit\build\using_generated_resources.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\npapi\using_npapi.vsprops;$(SolutionDir)..\chrome\third_party\wtl\using_wtl.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/app/resource_bundle.cc b/app/resource_bundle.cc
new file mode 100644
index 0000000..5b3c034
--- /dev/null
+++ b/app/resource_bundle.cc
@@ -0,0 +1,205 @@
+// Copyright (c) 2006-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/resource_bundle.h"
+
+#include "base/gfx/png_decoder.h"
+#include "base/logging.h"
+#include "base/string_piece.h"
+#include "net/base/file_stream.h"
+#include "net/base/net_errors.h"
+#include "chrome/common/gfx/chrome_font.h"
+#include "SkBitmap.h"
+
+ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;
+
+/* static */
+void ResourceBundle::InitSharedInstance(const std::wstring& pref_locale) {
+ DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
+ g_shared_instance_ = new ResourceBundle();
+
+ g_shared_instance_->LoadResources(pref_locale);
+}
+
+/* static */
+void ResourceBundle::CleanupSharedInstance() {
+ if (g_shared_instance_) {
+ delete g_shared_instance_;
+ g_shared_instance_ = NULL;
+ }
+}
+
+/* static */
+ResourceBundle& ResourceBundle::GetSharedInstance() {
+ // Must call InitSharedInstance before this function.
+ CHECK(g_shared_instance_ != NULL);
+ return *g_shared_instance_;
+}
+
+ResourceBundle::ResourceBundle()
+ : resources_data_(NULL),
+ locale_resources_data_(NULL),
+ theme_data_(NULL) {
+}
+
+void ResourceBundle::FreeImages() {
+ for (SkImageMap::iterator i = skia_images_.begin();
+ i != skia_images_.end(); i++) {
+ delete i->second;
+ }
+ skia_images_.clear();
+}
+
+void ResourceBundle::SetThemeExtension(const Extension& e) {
+ theme_extension_.reset(new Extension(e));
+}
+
+/* static */
+SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) {
+ std::vector<unsigned char> raw_data, png_data;
+ bool success = false;
+ // First check to see if we have a registered theme extension and whether
+ // it can handle this resource.
+ // TODO(erikkay): It would be nice to use something less brittle than
+ // resource_id here.
+ if (g_shared_instance_->theme_extension_.get()) {
+ FilePath path =
+ g_shared_instance_->theme_extension_->GetThemeResourcePath(resource_id);
+ if (!path.empty()) {
+ net::FileStream file;
+ int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
+ if (file.Open(path, flags) == net::OK) {
+ 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) {
+ success= true;
+ } else {
+ raw_data.resize(0);
+ }
+ }
+ }
+ }
+ }
+ if (!success)
+ success = LoadResourceBytes(data_handle, resource_id, &raw_data);
+ if (!success)
+ return NULL;
+
+ // Decode the PNG.
+ int image_width;
+ int image_height;
+ if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
+ PNGDecoder::FORMAT_BGRA,
+ &png_data, &image_width, &image_height)) {
+ NOTREACHED() << "Unable to decode image resource " << resource_id;
+ return NULL;
+ }
+
+ return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
+ image_width,
+ image_height);
+}
+
+std::string ResourceBundle::GetDataResource(int resource_id) {
+ return GetRawDataResource(resource_id).as_string();
+}
+
+bool ResourceBundle::LoadImageResourceBytes(int resource_id,
+ std::vector<unsigned char>* bytes) {
+ return LoadResourceBytes(theme_data_, resource_id, bytes);
+}
+
+bool ResourceBundle::LoadDataResourceBytes(int resource_id,
+ std::vector<unsigned char>* bytes) {
+ return LoadResourceBytes(resources_data_, resource_id, bytes);
+}
+
+SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
+ // Check to see if we already have the Skia image in the cache.
+ {
+ AutoLock lock_scope(lock_);
+ SkImageMap::const_iterator found = skia_images_.find(resource_id);
+ if (found != skia_images_.end())
+ return found->second;
+ }
+
+ scoped_ptr<SkBitmap> bitmap;
+
+ if (theme_data_)
+ bitmap.reset(LoadBitmap(theme_data_, resource_id));
+
+ // If we did not find the bitmap in the theme DLL, try the current one.
+ if (!bitmap.get())
+ bitmap.reset(LoadBitmap(resources_data_, resource_id));
+
+ // We loaded successfully. Cache the Skia version of the bitmap.
+ if (bitmap.get()) {
+ AutoLock lock_scope(lock_);
+
+ // Another thread raced us, and has already cached the skia image.
+ if (skia_images_.count(resource_id))
+ return skia_images_[resource_id];
+
+ skia_images_[resource_id] = bitmap.get();
+ return bitmap.release();
+ }
+
+ // We failed to retrieve the bitmap, show a debugging red square.
+ {
+ LOG(WARNING) << "Unable to load bitmap with id " << resource_id;
+ NOTREACHED(); // Want to assert in debug mode.
+
+ AutoLock lock_scope(lock_); // Guard empty_bitmap initialization.
+
+ static SkBitmap* empty_bitmap = NULL;
+ if (!empty_bitmap) {
+ // The placeholder bitmap is bright red so people notice the problem.
+ // This bitmap will be leaked, but this code should never be hit.
+ empty_bitmap = new SkBitmap();
+ empty_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
+ empty_bitmap->allocPixels();
+ empty_bitmap->eraseARGB(255, 255, 0, 0);
+ }
+ return empty_bitmap;
+ }
+}
+
+void ResourceBundle::LoadFontsIfNecessary() {
+ AutoLock lock_scope(lock_);
+ if (!base_font_.get()) {
+ base_font_.reset(new ChromeFont());
+
+ small_font_.reset(new ChromeFont());
+ *small_font_ = base_font_->DeriveFont(-2);
+
+ medium_font_.reset(new ChromeFont());
+ *medium_font_ = base_font_->DeriveFont(3);
+
+ medium_bold_font_.reset(new ChromeFont());
+ *medium_bold_font_ =
+ base_font_->DeriveFont(3, base_font_->style() | ChromeFont::BOLD);
+
+ large_font_.reset(new ChromeFont());
+ *large_font_ = base_font_->DeriveFont(8);
+ }
+}
+
+ChromeFont ResourceBundle::GetFont(FontStyle style) {
+ LoadFontsIfNecessary();
+ switch(style) {
+ case SmallFont:
+ return *small_font_;
+ case MediumFont:
+ return *medium_font_;
+ case MediumBoldFont:
+ return *medium_bold_font_;
+ case LargeFont:
+ return *large_font_;
+ default:
+ return *base_font_;
+ }
+}
diff --git a/app/resource_bundle.h b/app/resource_bundle.h
new file mode 100644
index 0000000..e3c572c
--- /dev/null
+++ b/app/resource_bundle.h
@@ -0,0 +1,203 @@
+// Copyright (c) 2006-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.
+
+#ifndef CHROME_COMMON_RESOURCE_BUNDLE_H__
+#define CHROME_COMMON_RESOURCE_BUNDLE_H__
+
+#include "build/build_config.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/lock.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/extensions/extension.h"
+
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+namespace base {
+ class DataPack;
+};
+#endif
+#if defined(OS_LINUX)
+typedef struct _GdkPixbuf GdkPixbuf;
+#endif
+class ChromeFont;
+class Extension;
+class SkBitmap;
+class StringPiece;
+
+// ResourceBundle is a central facility to load images and other resources,
+// such as theme graphics.
+// Every resource is loaded only once.
+class ResourceBundle {
+ public:
+ // An enumeration of the various font styles used throughout Chrome.
+ // The following holds true for the font sizes:
+ // Small <= Base <= Medium <= MediumBold <= Large.
+ enum FontStyle {
+ SmallFont,
+ BaseFont,
+ MediumFont,
+ // NOTE: depending upon the locale, this may *not* result in a bold font.
+ MediumBoldFont,
+ LargeFont,
+ };
+
+ // Initialize the ResourceBundle for this process.
+ // NOTE: Mac ignores this and always loads up resources for the language
+ // defined by the Cocoa UI (ie-NSBundle does the langange work).
+ static void InitSharedInstance(const std::wstring& pref_locale);
+
+ // Delete the ResourceBundle for this process if it exists.
+ static void CleanupSharedInstance();
+
+ // Return the global resource loader instance.
+ static ResourceBundle& GetSharedInstance();
+
+ // Load the data file that contains theme resources if present.
+ void LoadThemeResources();
+
+ // Gets the bitmap with the specified resource_id, first by looking into the
+ // theme data, than in the current module data if applicable.
+ // Returns a pointer to a shared instance of the SkBitmap. This shared bitmap
+ // is owned by the resource bundle and should not be freed.
+ //
+ // The bitmap is assumed to exist. This function will log in release, and
+ // assert in debug mode if it does not. On failure, this will return a
+ // pointer to a shared empty placeholder bitmap so it will be visible what
+ // is missing.
+ SkBitmap* GetBitmapNamed(int resource_id);
+
+ // Loads the raw bytes of an image resource into |bytes|,
+ // without doing any processing or interpretation of
+ // the resource. Returns whether we successfully read the resource.
+ bool LoadImageResourceBytes(int resource_id,
+ std::vector<unsigned char>* bytes);
+
+ // Loads the raw bytes of a data resource into |bytes|,
+ // without doing any processing or interpretation of
+ // the resource. Returns whether we successfully read the resource.
+ bool LoadDataResourceBytes(int resource_id,
+ std::vector<unsigned char>* bytes);
+
+ // Return the contents of a file in a string given the resource id.
+ // This will copy the data from the resource and return it as a string.
+ // TODO(port): deprecate this and replace with GetRawDataResource to avoid
+ // needless copying.
+ std::string GetDataResource(int resource_id);
+
+ // Like GetDataResource(), but avoids copying the resource. Instead, it
+ // returns a StringPiece which points into the actual resource in the image.
+ StringPiece GetRawDataResource(int resource_id);
+
+ // Get a localized string given a message id. Returns an empty
+ // string if the message_id is not found.
+ string16 GetLocalizedString(int message_id);
+
+ // Returns the font for the specified style.
+ ChromeFont GetFont(FontStyle style);
+
+#if defined(OS_WIN)
+ // Loads and returns an icon from the theme dll.
+ HICON LoadThemeIcon(int icon_id);
+
+ // Loads and returns a cursor from the app module.
+ HCURSOR LoadCursor(int cursor_id);
+#elif defined(OS_LINUX)
+ // Gets the GdkPixbuf with the specified resource_id, first by looking into
+ // the theme data, than in the current module data if applicable. Returns a
+ // pointer to a shared instance of the GdkPixbuf. This shared GdkPixbuf is
+ // owned by the resource bundle and should not be freed.
+ //
+ // The bitmap is assumed to exist. This function will log in release, and
+ // assert in debug mode if it does not. On failure, this will return a
+ // pointer to a shared empty placeholder bitmap so it will be visible what
+ // is missing.
+ GdkPixbuf* GetPixbufNamed(int resource_id);
+#endif
+
+ // Sets an Extension object that can handle theme resource requests.
+ void SetThemeExtension(const Extension& e);
+
+ private:
+ // We define a DataHandle typedef to abstract across how data is stored
+ // across platforms.
+#if defined(OS_WIN)
+ // Windows stores resources in DLLs, which are managed by HINSTANCE.
+ typedef HINSTANCE DataHandle;
+#elif defined(OS_LINUX) || defined(OS_MACOSX)
+ // Linux uses base::DataPack.
+ typedef base::DataPack* DataHandle;
+#endif
+
+ // Ctor/dtor are private, since we're a singleton.
+ ResourceBundle();
+ ~ResourceBundle();
+
+ // Free skia_images_.
+ void FreeImages();
+
+ // Try to load the main resources and the locale specific strings from an
+ // external data module.
+ void LoadResources(const std::wstring& pref_locale);
+
+ // Initialize all the ChromeFont members if they haven't yet been initialized.
+ void LoadFontsIfNecessary();
+
+ // Returns the full pathname of the locale file to load. May return an empty
+ // string if no locale data files are found.
+ FilePath GetLocaleFilePath(const std::wstring& pref_locale);
+
+ // Loads the raw bytes of a resource from |module| into |bytes|,
+ // without doing any processing or interpretation of
+ // the resource. Returns whether we successfully read the resource.
+ static bool LoadResourceBytes(DataHandle module,
+ int resource_id,
+ std::vector<unsigned char>* bytes);
+
+ // Creates and returns a new SkBitmap given the data file to look in and the
+ // resource id. It's up to the caller to free the returned bitmap when
+ // done.
+ static SkBitmap* LoadBitmap(DataHandle dll_inst, int resource_id);
+
+ // Class level lock. Used to protect internal data structures that may be
+ // accessed from other threads (e.g., skia_images_).
+ Lock lock_;
+
+ // Handles for data sources.
+ DataHandle resources_data_;
+ DataHandle locale_resources_data_;
+ DataHandle theme_data_;
+
+ // Cached images. The ResourceBundle caches all retrieved bitmaps and keeps
+ // ownership of the pointers.
+ typedef std::map<int, SkBitmap*> SkImageMap;
+ SkImageMap skia_images_;
+#if defined(OS_LINUX)
+ typedef std::map<int, GdkPixbuf*> GdkPixbufMap;
+ GdkPixbufMap gdk_pixbufs_;
+#endif
+
+ // The various fonts used. Cached to avoid repeated GDI creation/destruction.
+ scoped_ptr<ChromeFont> base_font_;
+ scoped_ptr<ChromeFont> small_font_;
+ scoped_ptr<ChromeFont> medium_font_;
+ scoped_ptr<ChromeFont> medium_bold_font_;
+ scoped_ptr<ChromeFont> large_font_;
+ scoped_ptr<ChromeFont> web_font_;
+
+ static ResourceBundle* g_shared_instance_;
+
+ scoped_ptr<Extension> theme_extension_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ResourceBundle);
+};
+
+#endif // CHROME_COMMON_RESOURCE_BUNDLE_H__
diff --git a/app/resource_bundle_linux.cc b/app/resource_bundle_linux.cc
new file mode 100644
index 0000000..9c866b2
--- /dev/null
+++ b/app/resource_bundle_linux.cc
@@ -0,0 +1,209 @@
+// Copyright (c) 2006-2008 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/resource_bundle.h"
+
+#include <gtk/gtk.h>
+
+#include "base/base_paths.h"
+#include "base/data_pack.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/gfx/gtk_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/gfx/chrome_font.h"
+#include "chrome/common/gtk_util.h"
+#include "chrome/common/l10n_util.h"
+#include "SkBitmap.h"
+
+namespace {
+
+// Convert the raw image data into a GdkPixbuf. The GdkPixbuf that is returned
+// has a ref count of 1 so the caller must call g_object_unref to free the
+// memory.
+GdkPixbuf* LoadPixbuf(std::vector<unsigned char>& data) {
+ ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new());
+ bool ok = gdk_pixbuf_loader_write(loader.get(),
+ static_cast<guint8*>(data.data()), data.size(), NULL);
+ if (!ok)
+ return NULL;
+ // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
+ // loader. We must do this before calling gdk_pixbuf_loader_get_pixbuf.
+ ok = gdk_pixbuf_loader_close(loader.get(), NULL);
+ if (!ok)
+ return NULL;
+ GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader.get());
+ if (!pixbuf)
+ return NULL;
+
+ // The pixbuf is owned by the loader, so add a ref so when we delete the
+ // loader (when the ScopedGObject goes out of scope), the pixbuf still
+ // exists.
+ g_object_ref(pixbuf);
+
+ return pixbuf;
+}
+
+} // namespace
+
+ResourceBundle::~ResourceBundle() {
+ FreeImages();
+ // Free GdkPixbufs.
+ for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
+ i != gdk_pixbufs_.end(); i++) {
+ g_object_unref(i->second);
+ }
+ gdk_pixbufs_.clear();
+
+ delete locale_resources_data_;
+ locale_resources_data_ = NULL;
+ delete theme_data_;
+ theme_data_ = NULL;
+ delete resources_data_;
+ resources_data_ = NULL;
+}
+
+void ResourceBundle::LoadResources(const std::wstring& pref_locale) {
+ FilePath resources_data_path;
+ PathService::Get(base::DIR_EXE, &resources_data_path);
+ resources_data_path = resources_data_path.Append(
+ FILE_PATH_LITERAL("chrome.pak"));
+ DCHECK(resources_data_ == NULL) << "resource data already loaded!";
+ resources_data_ = new base::DataPack;
+ bool success = resources_data_->Load(resources_data_path);
+ DCHECK(success) << "failed to load chrome.pak";
+
+ DCHECK(locale_resources_data_ == NULL) << "locale data already loaded!";
+ const FilePath& locale_path = GetLocaleFilePath(pref_locale);
+ if (locale_path.value().empty()) {
+ // It's possible that there are no locale dlls found, in which case we just
+ // return.
+ NOTREACHED();
+ return;
+ }
+
+ locale_resources_data_ = new base::DataPack;
+ success = locale_resources_data_->Load(locale_path);
+ DCHECK(success) << "failed to load locale pak file";
+}
+
+FilePath ResourceBundle::GetLocaleFilePath(const std::wstring& pref_locale) {
+ FilePath locale_path;
+ PathService::Get(chrome::DIR_LOCALES, &locale_path);
+
+ const std::wstring app_locale = l10n_util::GetApplicationLocale(pref_locale);
+ if (app_locale.empty())
+ return FilePath();
+
+ return locale_path.Append(WideToASCII(app_locale + L".pak"));
+}
+
+void ResourceBundle::LoadThemeResources() {
+ FilePath theme_data_path;
+ PathService::Get(chrome::DIR_THEMES, &theme_data_path);
+ theme_data_path = theme_data_path.Append(FILE_PATH_LITERAL("default.pak"));
+ theme_data_ = new base::DataPack;
+ bool success = theme_data_->Load(theme_data_path);
+ DCHECK(success) << "failed to load theme data";
+}
+
+/* static */
+bool ResourceBundle::LoadResourceBytes(DataHandle module, int resource_id,
+ std::vector<unsigned char>* bytes) {
+ DCHECK(module);
+ StringPiece data;
+ if (!module->Get(resource_id, &data))
+ return false;
+
+ bytes->resize(data.length());
+ memcpy(&(bytes->front()), data.data(), data.length());
+
+ return true;
+}
+
+StringPiece ResourceBundle::GetRawDataResource(int resource_id) {
+ DCHECK(resources_data_);
+ StringPiece data;
+ if (!resources_data_->Get(resource_id, &data))
+ return StringPiece();
+ return data;
+}
+
+string16 ResourceBundle::GetLocalizedString(int message_id) {
+ // If for some reason we were unable to load a resource dll, return an empty
+ // string (better than crashing).
+ if (!locale_resources_data_) {
+ LOG(WARNING) << "locale resources are not loaded";
+ return string16();
+ }
+
+ StringPiece data;
+ if (!locale_resources_data_->Get(message_id, &data)) {
+ // Fall back on the main data pack (shouldn't be any strings here except in
+ // unittests).
+ data = GetRawDataResource(message_id);
+ if (data.empty()) {
+ NOTREACHED() << "unable to find resource: " << message_id;
+ return string16();
+ }
+ }
+
+ // Data pack encodes strings as UTF16.
+ string16 msg(reinterpret_cast<const char16*>(data.data()),
+ data.length() / 2);
+ return msg;
+}
+
+GdkPixbuf* ResourceBundle::GetPixbufNamed(int resource_id) {
+ // Check to see if we already have the pixbuf in the cache.
+ {
+ AutoLock lock_scope(lock_);
+ GdkPixbufMap::const_iterator found = gdk_pixbufs_.find(resource_id);
+ if (found != gdk_pixbufs_.end())
+ return found->second;
+ }
+
+
+ std::vector<unsigned char> data;
+ LoadImageResourceBytes(resource_id, &data);
+ GdkPixbuf* pixbuf = LoadPixbuf(data);
+
+ // We loaded successfully. Cache the pixbuf.
+ if (pixbuf) {
+ AutoLock lock_scope(lock_);
+
+ // Another thread raced us, and has already cached the pixbuf.
+ if (gdk_pixbufs_.count(resource_id)) {
+ g_object_unref(pixbuf);
+ return gdk_pixbufs_[resource_id];
+ }
+
+ gdk_pixbufs_[resource_id] = pixbuf;
+ return pixbuf;
+ }
+
+ // We failed to retrieve the bitmap, show a debugging red square.
+ {
+ LOG(WARNING) << "Unable to load GdkPixbuf with id " << resource_id;
+ NOTREACHED(); // Want to assert in debug mode.
+
+ AutoLock lock_scope(lock_); // Guard empty_bitmap initialization.
+
+ static GdkPixbuf* empty_bitmap = NULL;
+ if (!empty_bitmap) {
+ // The placeholder bitmap is bright red so people notice the problem.
+ // This bitmap will be leaked, but this code should never be hit.
+ scoped_ptr<SkBitmap> skia_bitmap(new SkBitmap());
+ skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
+ skia_bitmap->allocPixels();
+ skia_bitmap->eraseARGB(255, 255, 0, 0);
+ empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get());
+ }
+ return empty_bitmap;
+ }
+}
diff --git a/app/resource_bundle_mac.mm b/app/resource_bundle_mac.mm
new file mode 100644
index 0000000..d24271c
--- /dev/null
+++ b/app/resource_bundle_mac.mm
@@ -0,0 +1,120 @@
+// Copyright (c) 2006-2008 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/resource_bundle.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/base_paths.h"
+#include "base/data_pack.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/mac_util.h"
+#include "base/path_service.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/gfx/chrome_font.h"
+#include "chrome/common/l10n_util.h"
+
+
+ResourceBundle::~ResourceBundle() {
+ FreeImages();
+
+ delete locale_resources_data_;
+ locale_resources_data_ = NULL;
+ delete theme_data_;
+ theme_data_ = NULL;
+ delete resources_data_;
+ resources_data_ = NULL;
+}
+
+namespace {
+
+base::DataPack *LoadResourceDataPack(NSString *name) {
+ base::DataPack *resource_pack = NULL;
+
+ NSString *resource_path = [mac_util::MainAppBundle() pathForResource:name
+ ofType:@"pak"];
+ if (resource_path) {
+ FilePath resources_pak_path([resource_path fileSystemRepresentation]);
+ resource_pack = new base::DataPack;
+ bool success = resource_pack->Load(resources_pak_path);
+ if (!success) {
+ delete resource_pack;
+ resource_pack = NULL;
+ }
+ }
+
+ return resource_pack;
+}
+
+} // namespace
+
+void ResourceBundle::LoadResources(const std::wstring& pref_locale) {
+ DLOG_IF(WARNING, pref_locale.size() != 0)
+ << "ignoring requested locale in favor of NSBundle's selection";
+
+ DCHECK(resources_data_ == NULL) << "resource data already loaded!";
+ resources_data_ = LoadResourceDataPack(@"chrome");
+ DCHECK(resources_data_) << "failed to load chrome.pak";
+
+ DCHECK(locale_resources_data_ == NULL) << "locale data already loaded!";
+ locale_resources_data_ = LoadResourceDataPack(@"locale");
+ DCHECK(locale_resources_data_) << "failed to load locale.pak";
+}
+
+void ResourceBundle::LoadThemeResources() {
+ DCHECK(theme_data_ == NULL) << "theme data already loaded!";
+ theme_data_ = LoadResourceDataPack(@"theme");
+ DCHECK(theme_data_) << "failed to load theme.pak";
+}
+
+/* static */
+bool ResourceBundle::LoadResourceBytes(DataHandle module, int resource_id,
+ std::vector<unsigned char>* bytes) {
+ DCHECK(module);
+ StringPiece data;
+ if (!module->Get(resource_id, &data))
+ return false;
+
+ bytes->resize(data.length());
+ memcpy(&(bytes->front()), data.data(), data.length());
+
+ return true;
+}
+
+StringPiece ResourceBundle::GetRawDataResource(int resource_id) {
+ DCHECK(resources_data_);
+ StringPiece data;
+ if (!resources_data_->Get(resource_id, &data))
+ return StringPiece();
+ return data;
+}
+
+string16 ResourceBundle::GetLocalizedString(int message_id) {
+ // If for some reason we were unable to load a resource dll, return an empty
+ // string (better than crashing).
+ if (!locale_resources_data_) {
+ LOG(WARNING) << "locale resources are not loaded";
+ return string16();
+ }
+
+ StringPiece data;
+ if (!locale_resources_data_->Get(message_id, &data)) {
+ // Fall back on the main data pack (shouldn't be any strings here except in
+ // unittests).
+ data = GetRawDataResource(message_id);
+ if (data.empty()) {
+ NOTREACHED() << "unable to find resource: " << message_id;
+ return string16();
+ }
+ }
+
+ // Data pack encodes strings as UTF16.
+ string16 msg(reinterpret_cast<const char16*>(data.data()),
+ data.length() / 2);
+ return msg;
+}
diff --git a/app/resource_bundle_win.cc b/app/resource_bundle_win.cc
new file mode 100644
index 0000000..dff34c8
--- /dev/null
+++ b/app/resource_bundle_win.cc
@@ -0,0 +1,157 @@
+// Copyright (c) 2006-2008 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/resource_bundle.h"
+
+#include <atlbase.h>
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/resource_util.h"
+#include "base/string_piece.h"
+#include "base/win_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/l10n_util.h"
+
+namespace {
+
+// Returns the flags that should be passed to LoadLibraryEx.
+DWORD GetDataDllLoadFlags() {
+ if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA)
+ return LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE;
+
+ return DONT_RESOLVE_DLL_REFERENCES;
+}
+
+} // end anonymous namespace
+
+ResourceBundle::~ResourceBundle() {
+ FreeImages();
+
+ if (locale_resources_data_) {
+ BOOL rv = FreeLibrary(locale_resources_data_);
+ DCHECK(rv);
+ }
+ if (theme_data_) {
+ BOOL rv = FreeLibrary(theme_data_);
+ DCHECK(rv);
+ }
+}
+
+void ResourceBundle::LoadResources(const std::wstring& pref_locale) {
+ // As a convenience, set resources_data_ to the current module.
+ resources_data_ = _AtlBaseModule.GetModuleInstance();
+
+ DCHECK(NULL == locale_resources_data_) << "locale dll already loaded";
+ const FilePath& locale_path = GetLocaleFilePath(pref_locale);
+ if (locale_path.value().empty()) {
+ // It's possible that there are no locale dlls found, in which case we just
+ // return.
+ NOTREACHED();
+ return;
+ }
+
+ // The dll should only have resources, not executable code.
+ locale_resources_data_ = LoadLibraryEx(locale_path.value().c_str(), NULL,
+ GetDataDllLoadFlags());
+ DCHECK(locale_resources_data_ != NULL) <<
+ "unable to load generated resources";
+}
+
+FilePath ResourceBundle::GetLocaleFilePath(const std::wstring& pref_locale) {
+ FilePath locale_path;
+ PathService::Get(chrome::DIR_LOCALES, &locale_path);
+
+ const std::wstring app_locale = l10n_util::GetApplicationLocale(pref_locale);
+ if (app_locale.empty())
+ return FilePath();
+
+ return locale_path.Append(app_locale + L".dll");
+}
+
+void ResourceBundle::LoadThemeResources() {
+ DCHECK(NULL == theme_data_) << "theme dll already loaded";
+ std::wstring theme_data_path;
+ PathService::Get(chrome::DIR_THEMES, &theme_data_path);
+ file_util::AppendToPath(&theme_data_path, L"default.dll");
+
+ // The dll should only have resources, not executable code.
+ theme_data_ = LoadLibraryEx(theme_data_path.c_str(), NULL,
+ GetDataDllLoadFlags());
+ DCHECK(theme_data_ != NULL) << "unable to load " << theme_data_path;
+}
+
+/* static */
+bool ResourceBundle::LoadResourceBytes(
+ DataHandle module,
+ int resource_id,
+ std::vector<unsigned char>* bytes) {
+ void* data_ptr;
+ size_t data_size;
+ if (base::GetDataResourceFromModule(module, resource_id, &data_ptr,
+ &data_size)) {
+ bytes->resize(data_size);
+ memcpy(&(bytes->front()), data_ptr, data_size);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+HICON ResourceBundle::LoadThemeIcon(int icon_id) {
+ return ::LoadIcon(theme_data_, MAKEINTRESOURCE(icon_id));
+}
+
+StringPiece ResourceBundle::GetRawDataResource(int resource_id) {
+ void* data_ptr;
+ size_t data_size;
+ if (base::GetDataResourceFromModule(_AtlBaseModule.GetModuleInstance(),
+ resource_id,
+ &data_ptr,
+ &data_size)) {
+ return StringPiece(static_cast<const char*>(data_ptr), data_size);
+ } else if (locale_resources_data_ &&
+ base::GetDataResourceFromModule(locale_resources_data_,
+ resource_id,
+ &data_ptr,
+ &data_size)) {
+ return StringPiece(static_cast<const char*>(data_ptr), data_size);
+ }
+ return StringPiece();
+}
+
+// Loads and returns a cursor from the current module.
+HCURSOR ResourceBundle::LoadCursor(int cursor_id) {
+ return ::LoadCursor(_AtlBaseModule.GetModuleInstance(),
+ MAKEINTRESOURCE(cursor_id));
+}
+
+string16 ResourceBundle::GetLocalizedString(int message_id) {
+ // If for some reason we were unable to load a resource dll, return an empty
+ // string (better than crashing).
+ if (!locale_resources_data_) {
+ LOG(WARNING) << "locale resources are not loaded";
+ return string16();
+ }
+
+ DCHECK(IS_INTRESOURCE(message_id));
+
+ // Get a reference directly to the string resource.
+ HINSTANCE hinstance = locale_resources_data_;
+ const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage(hinstance,
+ message_id);
+ if (!image) {
+ // Fall back on the current module (shouldn't be any strings here except
+ // in unittests).
+ image = AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(),
+ message_id);
+ if (!image) {
+ NOTREACHED() << "unable to find resource: " << message_id;
+ return std::wstring();
+ }
+ }
+ // Copy into a string16 and return.
+ return string16(image->achString, image->nLength);
+}