summaryrefslogtreecommitdiffstats
path: root/chrome/browser/icon_loader.cc
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-07 20:42:24 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-07 20:42:24 +0000
commit46728b1ff43220f8515deba08a60e079d193bf4c (patch)
tree0e1d2ccc770c132576c16acb245a0c5c277e835c /chrome/browser/icon_loader.cc
parent6b16d779369be1df91ab891e15f9a7e5fe7bce30 (diff)
downloadchromium_src-46728b1ff43220f8515deba08a60e079d193bf4c.zip
chromium_src-46728b1ff43220f8515deba08a60e079d193bf4c.tar.gz
chromium_src-46728b1ff43220f8515deba08a60e079d193bf4c.tar.bz2
Windows icon loader refactor in preparation for port.
Review URL: http://codereview.chromium.org/115056 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15577 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/icon_loader.cc')
-rw-r--r--chrome/browser/icon_loader.cc243
1 files changed, 0 insertions, 243 deletions
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;
-}