diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-07 20:42:24 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-07 20:42:24 +0000 |
commit | 46728b1ff43220f8515deba08a60e079d193bf4c (patch) | |
tree | 0e1d2ccc770c132576c16acb245a0c5c277e835c /chrome/browser/icon_loader.cc | |
parent | 6b16d779369be1df91ab891e15f9a7e5fe7bce30 (diff) | |
download | chromium_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.cc | 243 |
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; -} |