summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/icon_loader.cc243
-rw-r--r--chrome/browser/icon_loader.h72
-rw-r--r--chrome/browser/icon_loader_win.cc80
-rw-r--r--chrome/browser/icon_loader_win.h40
-rw-r--r--chrome/browser/icon_manager.cc11
-rw-r--r--chrome/browser/icon_manager.h2
-rw-r--r--chrome/chrome.gyp4
8 files changed, 147 insertions, 313 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 879c790..def66f1 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -378,11 +378,15 @@
>
</File>
<File
- RelativePath=".\icon_loader.cc"
+ RelativePath=".\icon_loader.h"
>
</File>
<File
- RelativePath=".\icon_loader.h"
+ RelativePath=".\icon_loader_win.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\icon_loader_win.h"
>
</File>
<File
diff --git a/chrome/browser/icon_loader.cc b/chrome/browser/icon_loader.cc
deleted file mode 100644
index 99dbe40..0000000
--- a/chrome/browser/icon_loader.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// 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 "chrome/browser/icon_loader.h"
-
-#include <windows.h>
-#include <shellapi.h>
-
-#include "app/gfx/icon_util.h"
-#include "base/file_util.h"
-#include "base/gfx/size.h"
-#include "base/message_loop.h"
-#include "base/ref_counted.h"
-#include "base/string_util.h"
-#include "base/task.h"
-#include "base/thread.h"
-#include "chrome/browser/browser_process.h"
-
-#include "SkBitmap.h"
-
-namespace {
-
-class IconLoaderProcessor :
- public base::RefCountedThreadSafe<IconLoaderProcessor> {
- public:
- explicit IconLoaderProcessor(IconLoader* target)
- : target_(target),
- bitmap_(NULL),
- small_icon_(NULL),
- large_icon_(NULL),
- loading_from_resource_(target->loading_from_resource_),
- icon_size_(target->icon_size_) {
- DCHECK(target);
- path_ = target->path_;
- target_message_loop_ = MessageLoop::current();
- }
-
- virtual ~IconLoaderProcessor() {
- delete bitmap_;
- if (small_icon_)
- ::DestroyIcon(small_icon_);
- if (large_icon_) {
- ::DestroyIcon(large_icon_);
- }
- }
-
- // Loads the icon with the specified dimensions.
- HICON LoadSizedIcon(int width, int height) {
- return static_cast<HICON>(LoadImage(NULL,
- path_.value().c_str(),
- width, height,
- IMAGE_ICON,
- LR_LOADTRANSPARENT | LR_LOADFROMFILE));
- }
-
- // Invoked from the original thread.
- void Cancel() {
- target_ = NULL;
- }
-
- // Invoked in the file thread. Never access target_ from this method.
- void ReadIcon() {
- if (loading_from_resource_)
- ReadIconFromFileResource();
- else
- ReadIconFile();
-
- target_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &IconLoaderProcessor::NotifyFetcher));
- }
-
- // Invoked on the file thread to read a normal .ico file.
- void ReadIconFile() {
- // We start by loading the same icon image in the two desired dimensions,
- // based on the dimensions we get back when we query the system.
- int small_width = ::GetSystemMetrics(SM_CXSMICON);
- int small_height = ::GetSystemMetrics(SM_CYSMICON);
- int large_width = ::GetSystemMetrics(SM_CXICON);
- int large_height = ::GetSystemMetrics(SM_CYICON);
- small_icon_ = LoadSizedIcon(small_width, small_height);
- large_icon_ = LoadSizedIcon(large_width, large_height);
-
- // TODO(idana): Bug 991356. Currently, if the client asks for the icon in
- // the form of an SkBitmap object, then we try converting the large icon
- // into an SkBitmap, if the icon was successfully loaded. If the large icon
- // is not available, we convert the small icon. The problem with converting
- // the small or the large icon is that the resulting image is going to have
- // the same dimensions as the icon (for example, 32X32 pixels). This can be
- // problematic if, for example, the client tries to display the resulting
- // image as a thumbnail. This will result in the client streching the
- // bitmap from 32X32 to 128X128 which will decrease the image's quality.
- //
- // Since it is possible for web applications to define large .PNG images as
- // their icons, the resulting .ico files created for these web applications
- // contain icon images in sizes much larger the the system default sizes
- // for icons. We can solve the aforementioned limitation by allowing the
- // client to specify the size of the resulting image, when requesting an
- // SkBitmap. The IconLoader code can then load a larger icon from the .ico
- // file.
- //
- // Note that currently the components in Chrome that deal with SkBitmaps
- // that represent application icons use the images to display icon size
- // images and therefore the limitation above doesn't really manifest
- // itself.
- HICON icon_to_convert = NULL;
- gfx::Size s;
- if (large_icon_) {
- icon_to_convert = large_icon_;
- s.SetSize(large_width, large_height);
- } else if (small_icon_) {
- icon_to_convert = small_icon_;
- s.SetSize(small_width, small_height);
- }
-
- if (icon_to_convert) {
- bitmap_ = IconUtil::CreateSkBitmapFromHICON(icon_to_convert, s);
- DCHECK(bitmap_);
- if (small_icon_)
- ::DestroyIcon(small_icon_);
- if (large_icon_)
- ::DestroyIcon(large_icon_);
-
- small_icon_ = NULL;
- large_icon_ = NULL;
- }
- }
-
- void ReadIconFromFileResource() {
- int size = 0;
- switch (icon_size_) {
- case IconLoader::SMALL:
- size = SHGFI_SMALLICON;
- break;
- case IconLoader::NORMAL:
- size = 0;
- break;
- case IconLoader::LARGE:
- size = SHGFI_LARGEICON;
- break;
- default:
- NOTREACHED();
- }
- SHFILEINFO file_info = { 0 };
- if (!SHGetFileInfo(path_.value().c_str(), FILE_ATTRIBUTE_NORMAL, &file_info,
- sizeof(SHFILEINFO),
- SHGFI_ICON | size | SHGFI_USEFILEATTRIBUTES))
- return;
-
- ICONINFO icon_info = { 0 };
- BITMAP bitmap_info = { 0 };
-
- BOOL r = ::GetIconInfo(file_info.hIcon, &icon_info);
- DCHECK(r);
- r = ::GetObject(icon_info.hbmMask, sizeof(bitmap_info), &bitmap_info);
- DCHECK(r);
-
- gfx::Size icon_size(bitmap_info.bmWidth, bitmap_info.bmHeight);
- bitmap_ = IconUtil::CreateSkBitmapFromHICON(file_info.hIcon, icon_size);
- }
-
- // Invoked in the target thread.
- void NotifyFetcher() {
- if (target_ && target_->OnLoadComplete(bitmap_)) {
- // Receiver took ownership of the bitmap.
- bitmap_ = NULL;
- }
- }
-
- private:
- // The message loop object of the thread in which we notify the delegate.
- MessageLoop* target_message_loop_;
-
- // The corresponding file fetcher or NULL if this task has been canceled.
- IconLoader* target_;
-
- // The path of the file.
- FilePath path_;
-
- // Fields from IconLoader that we need to copy as we cannot access them
- // directly from the target_ in a thread-safe way.
- bool loading_from_resource_;
- IconLoader::IconSize icon_size_;
-
- // The result bitmap.
- SkBitmap* bitmap_;
-
- // The result small icon.
- HICON small_icon_;
-
- // The result large icon.
- HICON large_icon_;
-
- DISALLOW_COPY_AND_ASSIGN(IconLoaderProcessor);
-};
-
-} // namespace
-
-// static
-IconLoader* IconLoader::CreateIconLoaderForFileResource(
- const FilePath& path, IconSize size, Delegate* delegate) {
- return new IconLoader(path, true, size, delegate);
-}
-
-IconLoader::IconLoader(const FilePath& path,
- bool from_resource,
- IconSize size,
- Delegate* delegate)
- : path_(path),
- loading_from_resource_(from_resource),
- icon_size_(size),
- delegate_(delegate),
- processor_(NULL) {
- DCHECK(delegate_);
-}
-
-IconLoader::~IconLoader() {
- Cancel();
-}
-
-void IconLoader::Start() {
- processor_ = new IconLoaderProcessor(this);
- processor_->AddRef();
- g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(processor_, &IconLoaderProcessor::ReadIcon));
-}
-
-void IconLoader::Cancel() {
- if (processor_) {
- processor_->Cancel();
- processor_->Release();
- processor_ = NULL;
- }
- delegate_ = NULL;
-}
-
-bool IconLoader::OnLoadComplete(SkBitmap* bitmap) {
- if (delegate_) {
- return delegate_->OnSkBitmapLoaded(this, bitmap);
- // We are likely deleted after this point.
- }
- return false;
-}
diff --git a/chrome/browser/icon_loader.h b/chrome/browser/icon_loader.h
index ff1c5a4..a02c6ba 100644
--- a/chrome/browser/icon_loader.h
+++ b/chrome/browser/icon_loader.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -9,25 +9,17 @@
#include "base/basictypes.h"
#include "base/file_path.h"
-
-namespace {
-class IconLoaderProcessor;
-}
+#include "base/ref_counted.h"
class SkBitmap;
////////////////////////////////////////////////////////////////////////////////
//
// A facility to read a file containing an icon asynchronously in the IO
-// thread. Clients has the option to get the icon in the form of two HICON
-// handles (one for a small icon size and one for a large icon) or in the form
-// of an SkBitmap.
-//
-// This class currently only supports reading .ico files. Please extend as
-// needed.
+// thread. Returns the icon in the form of an SkBitmap.
//
////////////////////////////////////////////////////////////////////////////////
-class IconLoader {
+class IconLoader : public base::RefCountedThreadSafe<IconLoader> {
public:
enum IconSize {
SMALL = 0, // 16x16
@@ -40,61 +32,21 @@ class IconLoader {
// Invoked when an icon has been read. |source| is the IconLoader. If the
// icon has been successfully loaded, result is non-null. This method must
// return true if it is taking ownership of the returned bitmap.
- virtual bool OnSkBitmapLoaded(IconLoader* source, SkBitmap* result) = 0;
+ virtual bool OnBitmapLoaded(IconLoader* source, SkBitmap* result) = 0;
};
- // Create a new IconLoader that loads the icon from the data at contained in
- // the file at |path|.
- static IconLoader* CreateIconLoaderForFile(const FilePath& path,
- Delegate* delegate);
-
- // Create a new IconLoader that loads the icon in the resource of the file
- // at |path|. This is used with .exe/.dll files.
- // Note that this generates a SkBitmap (and consequently OnSkBitmapLoaded is
- // invoked on the delegate once the load has completed).
- static IconLoader* CreateIconLoaderForFileResource(const FilePath& path,
- IconSize size,
- Delegate* delegate);
+ IconLoader() { }
- ~IconLoader();
+ virtual ~IconLoader() { }
- // Start the read operation
- void Start();
+ // Start reading the icon on the file thread.
+ virtual void Start() = 0;
- // Cancel the read operation. The delegate will no longer be contacted. Call
- // this method if you need to delete the delegate.
- void Cancel();
+ // Factory method for returning a platform specific IconLoad.
+ static IconLoader* Create(const FilePath& path, IconSize size,
+ Delegate* delegate);
private:
- friend class IconLoaderProcessor;
-
- // Use the factory methods CreateIconLoader* instead of using this constructor
- IconLoader(const FilePath& path,
- bool from_resource,
- IconSize size,
- Delegate* delegate);
-
- // Invoked by the processor when the file has been read and an SkBitmap
- // object was requested.
- bool OnLoadComplete(SkBitmap* result);
-
- // The path.
- FilePath path_;
-
- // The delegate.
- Delegate* delegate_;
-
- // Whether we are loading the icon from the resource in the file (if false,
- // the icon is simply loaded from the file content).
- bool loading_from_resource_;
-
- // The size of the icon that should be loaded from the file resource.
- // Not used if loading_from_resource_ is false.
- IconSize icon_size_;
-
- // The underlying object performing the read.
- IconLoaderProcessor* processor_;
-
DISALLOW_COPY_AND_ASSIGN(IconLoader);
};
diff --git a/chrome/browser/icon_loader_win.cc b/chrome/browser/icon_loader_win.cc
new file mode 100644
index 0000000..998faf1
--- /dev/null
+++ b/chrome/browser/icon_loader_win.cc
@@ -0,0 +1,80 @@
+// 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/icon_loader_win.h"
+
+#include <windows.h>
+#include <shellapi.h>
+
+#include "app/gfx/icon_util.h"
+#include "base/gfx/size.h"
+#include "base/message_loop.h"
+#include "base/thread.h"
+#include "chrome/browser/browser_process.h"
+#include "skia/include/SkBitmap.h"
+
+IconLoader* IconLoader::Create(const FilePath& path, IconSize size,
+ Delegate* delegate) {
+ return new IconLoaderWin(path, size, delegate);
+}
+
+IconLoaderWin::IconLoaderWin(const FilePath& path, IconSize size,
+ Delegate* delegate)
+ : path_(path),
+ icon_size_(size),
+ bitmap_(NULL),
+ delegate_(delegate) {
+}
+
+IconLoaderWin::~IconLoaderWin() {
+ delete bitmap_;
+}
+
+void IconLoaderWin::Start() {
+ target_message_loop_ = MessageLoop::current();
+
+ g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &IconLoaderWin::ReadIcon));
+}
+
+void IconLoaderWin::ReadIcon() {
+ int size = 0;
+ switch (icon_size_) {
+ case IconLoader::SMALL:
+ size = SHGFI_SMALLICON;
+ break;
+ case IconLoader::NORMAL:
+ size = 0;
+ break;
+ case IconLoader::LARGE:
+ size = SHGFI_LARGEICON;
+ break;
+ default:
+ NOTREACHED();
+ }
+ SHFILEINFO file_info = { 0 };
+ if (!SHGetFileInfo(path_.value().c_str(), FILE_ATTRIBUTE_NORMAL, &file_info,
+ sizeof(SHFILEINFO),
+ SHGFI_ICON | size | SHGFI_USEFILEATTRIBUTES))
+ return;
+
+ ICONINFO icon_info = { 0 };
+ BITMAP bitmap_info = { 0 };
+
+ BOOL r = ::GetIconInfo(file_info.hIcon, &icon_info);
+ DCHECK(r);
+ r = ::GetObject(icon_info.hbmMask, sizeof(bitmap_info), &bitmap_info);
+ DCHECK(r);
+
+ gfx::Size icon_size(bitmap_info.bmWidth, bitmap_info.bmHeight);
+ bitmap_ = IconUtil::CreateSkBitmapFromHICON(file_info.hIcon, icon_size);
+
+ target_message_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &IconLoaderWin::NotifyDelegate));
+}
+
+void IconLoaderWin::NotifyDelegate() {
+ delegate_->OnBitmapLoaded(this, bitmap_);
+ bitmap_ = NULL;
+}
diff --git a/chrome/browser/icon_loader_win.h b/chrome/browser/icon_loader_win.h
new file mode 100644
index 0000000..ca6c96a
--- /dev/null
+++ b/chrome/browser/icon_loader_win.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef CHROME_BROWSER_ICON_LOADER_WIN_H_
+#define CHROME_BROWSER_ICON_LOADER_WIN_H_
+
+#include "chrome/browser/icon_loader.h"
+
+class MessageLoop;
+
+class IconLoaderWin : public IconLoader {
+ public:
+ IconLoaderWin(const FilePath& path, IconSize size, Delegate* delegate);
+
+ virtual ~IconLoaderWin();
+
+ // IconLoader implementation.
+ virtual void Start();
+
+ private:
+ void ReadIcon();
+
+ void NotifyDelegate();
+
+ // The message loop object of the thread in which we notify the delegate.
+ MessageLoop* target_message_loop_;
+
+ FilePath path_;
+
+ IconSize icon_size_;
+
+ SkBitmap* bitmap_;
+
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(IconLoaderWin);
+};
+
+#endif // CHROME_BROWSER_ICON_LOADER_WIN_H_
diff --git a/chrome/browser/icon_manager.cc b/chrome/browser/icon_manager.cc
index 4b0c21b..827e0b1 100644
--- a/chrome/browser/icon_manager.cc
+++ b/chrome/browser/icon_manager.cc
@@ -48,8 +48,8 @@ IconManager::Handle IconManager::LoadIcon(
IconRequest* request = new IconRequest(callback);
AddRequest(request, consumer);
- IconLoader* loader =
- IconLoader::CreateIconLoaderForFileResource(path, size, this);
+ IconLoader* loader = IconLoader::Create(path, size, this);
+ loader->AddRef();
loader->Start();
ClientRequest client_request = { request, path, size };
requests_[loader] = client_request;
@@ -58,11 +58,12 @@ IconManager::Handle IconManager::LoadIcon(
// IconLoader::Delegate implementation -----------------------------------------
-bool IconManager::OnSkBitmapLoaded(IconLoader* source, SkBitmap* result) {
- scoped_ptr<IconLoader> scoped_source(source);
+bool IconManager::OnBitmapLoaded(IconLoader* source, SkBitmap* result) {
+ ClientRequests::iterator rit = requests_.find(source);
+ // Balances the AddRef() in LoadIcon().
+ source->Release();
// Look up our client state.
- ClientRequests::iterator rit = requests_.find(source);
if (rit == requests_.end()) {
NOTREACHED();
return false; // Return false to indicate result should be deleted.
diff --git a/chrome/browser/icon_manager.h b/chrome/browser/icon_manager.h
index 4e44cf4..fbd0cd1 100644
--- a/chrome/browser/icon_manager.h
+++ b/chrome/browser/icon_manager.h
@@ -81,7 +81,7 @@ public:
IconRequestCallback* callback);
// IconLoader::Delegate interface.
- virtual bool OnSkBitmapLoaded(IconLoader* source, SkBitmap* result);
+ virtual bool OnBitmapLoaded(IconLoader* source, SkBitmap* result);
private:
struct CacheKey {
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 1bf6af6..e635d89 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -959,8 +959,9 @@
'browser/history/visitsegment_database.cc',
'browser/history/visitsegment_database.h',
'browser/hung_renderer_dialog.h',
- 'browser/icon_loader.cc',
'browser/icon_loader.h',
+ 'browser/icon_loader_win.cc',
+ 'browser/icon_loader_win.h',
'browser/icon_manager.cc',
'browser/icon_manager.h',
'browser/ime_input.cc',
@@ -1579,7 +1580,6 @@
'browser/history/history_indexer.idl',
'browser/history_tab_ui.cc',
'browser/history_view.cc',
- 'browser/icon_loader.cc',
'browser/icon_manager.cc',
'browser/ime_input.cc',
'browser/importer/ie_importer.cc',