summaryrefslogtreecommitdiffstats
path: root/chrome/common/resource_bundle.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/common/resource_bundle.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/resource_bundle.cc')
-rw-r--r--chrome/common/resource_bundle.cc333
1 files changed, 333 insertions, 0 deletions
diff --git a/chrome/common/resource_bundle.cc b/chrome/common/resource_bundle.cc
new file mode 100644
index 0000000..3beccb4
--- /dev/null
+++ b/chrome/common/resource_bundle.cc
@@ -0,0 +1,333 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/common/resource_bundle.h"
+
+#include <atlbase.h>
+
+#include "base/file_util.h"
+#include "base/gfx/png_decoder.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/resource_util.h"
+#include "base/scoped_ptr.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "base/win_util.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/gfx/chrome_font.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/win_util.h"
+#include "SkBitmap.h"
+
+using namespace std;
+
+ResourceBundle *ResourceBundle::g_shared_instance_ = NULL;
+
+// 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 0;
+}
+
+/* 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_->LoadLocaleResources(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()
+ : locale_resources_dll_(NULL),
+ theme_dll_(NULL) {
+}
+
+ResourceBundle::~ResourceBundle() {
+ for (SkImageMap::iterator i = skia_images_.begin();
+ i != skia_images_.end(); i++) {
+ delete i->second;
+ }
+ skia_images_.clear();
+
+ if (locale_resources_dll_) {
+ BOOL rv = FreeLibrary(locale_resources_dll_);
+ DCHECK(rv);
+ }
+ if (theme_dll_) {
+ BOOL rv = FreeLibrary(theme_dll_);
+ DCHECK(rv);
+ }
+}
+
+void ResourceBundle::LoadLocaleResources(const std::wstring& pref_locale) {
+ DCHECK(NULL == locale_resources_dll_) << "locale dll already loaded";
+ const std::wstring& locale_path = GetLocaleDllPath(pref_locale);
+ if (locale_path.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_dll_ = LoadLibraryEx(locale_path.c_str(), NULL,
+ GetDataDllLoadFlags());
+ DCHECK(locale_resources_dll_ != NULL) << "unable to load generated resources";
+}
+
+std::wstring ResourceBundle::GetLocaleDllPath(const std::wstring& pref_locale) {
+ std::wstring locale_path;
+ PathService::Get(chrome::DIR_LOCALES, &locale_path);
+
+ const std::wstring app_locale = l10n_util::GetApplicationLocale(pref_locale);
+ if (app_locale.empty())
+ return app_locale;
+
+ file_util::AppendToPath(&locale_path, app_locale + L".dll");
+ return locale_path;
+}
+
+void ResourceBundle::LoadThemeResources() {
+ DCHECK(NULL == theme_dll_) << "theme dll already loaded";
+ std::wstring theme_dll_path;
+ PathService::Get(chrome::DIR_THEMES, &theme_dll_path);
+ file_util::AppendToPath(&theme_dll_path, L"default.dll");
+
+ // The dll should only have resources, not executable code.
+ theme_dll_ = LoadLibraryEx(theme_dll_path.c_str(), NULL,
+ GetDataDllLoadFlags());
+ DCHECK(theme_dll_ != NULL) << "unable to load " << theme_dll_path;
+}
+
+/* static */
+SkBitmap* ResourceBundle::LoadBitmap(HINSTANCE dll_inst, int resource_id) {
+ void* data_ptr = NULL;
+ size_t data_size;
+ bool success = base::GetDataResourceFromModule(dll_inst, resource_id,
+ &data_ptr, &data_size);
+ if (!success)
+ return NULL;
+
+ unsigned char* data = static_cast<unsigned char*>(data_ptr);
+
+ // Decode the PNG.
+ vector<unsigned char> png_data;
+ int image_width;
+ int image_height;
+ if (!PNGDecoder::Decode(data, data_size, PNGDecoder::FORMAT_BGRA,
+ &png_data, &image_width, &image_height)) {
+ NOTREACHED() << "Unable to decode theme resource " << resource_id;
+ return NULL;
+ }
+
+ return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
+ image_width,
+ image_height);
+}
+
+SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
+ AutoLock lock_scope(lock_);
+
+ SkImageMap::const_iterator found = skia_images_.find(resource_id);
+ SkBitmap* bitmap = NULL;
+
+ // If not found load and store the image
+ if (found == skia_images_.end()) {
+ // Load the image
+ bitmap = LoadBitmap(theme_dll_, resource_id);
+ // We did not find the bitmap in the theme DLL, try the current one.
+ if (!bitmap)
+ bitmap = LoadBitmap(_AtlBaseModule.GetModuleInstance(), resource_id);
+ skia_images_[resource_id] = bitmap;
+ } else {
+ bitmap = found->second;
+ }
+
+ // This bitmap will be returned when a bitmap is requested that can not be
+ // found. The data inside is lazily initialized, so users must lock and
+ static SkBitmap* empty_bitmap = NULL;
+
+ // Handle the case where loading the bitmap failed.
+ if (!bitmap) {
+ LOG(WARNING) << "Unable to load bitmap with id " << resource_id;
+ NOTREACHED(); // Want to assert in debug mode.
+ if (!empty_bitmap) {
+ // The placeholder bitmap is bright red so people notice the problem.
+ 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;
+ }
+ return bitmap;
+}
+
+bool ResourceBundle::LoadImageResourceBytes(int resource_id,
+ vector<unsigned char>* bytes) {
+ return LoadModuleResourceBytes(theme_dll_, resource_id, bytes);
+}
+
+bool ResourceBundle::LoadDataResourceBytes(int resource_id,
+ vector<unsigned char>* bytes) {
+ return LoadModuleResourceBytes(_AtlBaseModule.GetModuleInstance(),
+ resource_id, bytes);
+}
+
+bool ResourceBundle::LoadModuleResourceBytes(
+ HINSTANCE 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_dll_, MAKEINTRESOURCE(icon_id));
+}
+
+std::string ResourceBundle::GetDataResource(int resource_id) {
+ return GetRawDataResource(resource_id).as_string();
+}
+
+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);
+ return StringPiece();
+}
+
+// Loads and returns the global accelerators from the current module.
+HACCEL ResourceBundle::GetGlobalAccelerators() {
+ return ::LoadAccelerators(_AtlBaseModule.GetModuleInstance(),
+ MAKEINTRESOURCE(IDR_MAINFRAME));
+}
+
+// Loads and returns a cursor from the current module.
+HCURSOR ResourceBundle::LoadCursor(int cursor_id) {
+ return ::LoadCursor(_AtlBaseModule.GetModuleInstance(),
+ MAKEINTRESOURCE(cursor_id));
+}
+
+std::wstring 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_dll_)
+ return std::wstring();
+
+ DCHECK(IS_INTRESOURCE(message_id));
+
+ // Get a reference directly to the string resource.
+ HINSTANCE hinstance = locale_resources_dll_;
+ 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 wstring and return.
+ return std::wstring(image->achString, image->nLength);
+}
+
+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);
+
+ web_font_.reset(new ChromeFont());
+ *web_font_ = base_font_->DeriveFont(1,
+ base_font_->style() | ChromeFont::WEB);
+ }
+}
+
+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_;
+ case WebFont:
+ return *web_font_;
+ default:
+ return *base_font_;
+ }
+}