Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: ui/gfx/icon_util.cc

Issue 11742007: Add support for adding 256x256 pngs to Windows .ico files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/icon_util.h ('k') | ui/gfx/icon_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/icon_util.cc
===================================================================
--- ui/gfx/icon_util.cc (revision 174803)
+++ ui/gfx/icon_util.cc (working copy)
@@ -13,6 +13,7 @@
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/gdi_util.h"
+#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
namespace {
@@ -282,15 +283,25 @@
}
bool IconUtil::CreateIconFileFromSkBitmap(const SkBitmap& bitmap,
+ const SkBitmap& large_bitmap,
const FilePath& icon_path) {
// Only 32 bit ARGB bitmaps are supported. We also make sure the bitmap has
// been properly initialized.
SkAutoLockPixels bitmap_lock(bitmap);
if ((bitmap.config() != SkBitmap::kARGB_8888_Config) ||
(bitmap.height() <= 0) || (bitmap.width() <= 0) ||
- (bitmap.getPixels() == NULL))
+ (bitmap.getPixels() == NULL)) {
return false;
+ }
+ // If |large_bitmap| was specified, validate its dimension and convert to PNG.
+ scoped_refptr<base::RefCountedMemory> png_bytes;
+ if (!large_bitmap.empty()) {
+ CHECK_EQ(256, large_bitmap.width());
sky 2013/01/07 17:05:24 Why CHECK and not DCHECK?
Alexei Svitkine (slow) 2013/01/07 17:51:28 I could do a DCHECK. I guess I wanted to make sure
sky 2013/01/07 22:18:56 See http://dev.chromium.org/developers/coding-styl
Alexei Svitkine (slow) 2013/01/07 22:25:23 Ah, I didn't realise CHECKs had to meet those crit
+ CHECK_EQ(256, large_bitmap.height());
+ png_bytes = gfx::Image(large_bitmap).As1xPNGBytes();
+ }
+
// We start by creating the file.
base::win::ScopedHandle icon_file(::CreateFile(icon_path.value().c_str(),
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
@@ -309,21 +320,29 @@
// Computing the total size of the buffer we need in order to store the
// images in the desired icon format.
size_t buffer_size = ComputeIconFileBufferSize(bitmaps);
- unsigned char* buffer = new unsigned char[buffer_size];
- DCHECK(buffer != NULL);
- memset(buffer, 0, buffer_size);
+ // Account for the bytes needed for the PNG entry.
+ if (png_bytes.get())
+ buffer_size += sizeof(ICONDIRENTRY) + png_bytes->size();
// Setting the information in the structures residing within the buffer.
// First, we set the information which doesn't require iterating through the
// bitmap set and then we set the bitmap specific structures. In the latter
// step we also copy the actual bits.
- ICONDIR* icon_dir = reinterpret_cast<ICONDIR*>(buffer);
+ std::vector<uint8> buffer(buffer_size);
+ ICONDIR* icon_dir = reinterpret_cast<ICONDIR*>(&buffer[0]);
icon_dir->idType = kResourceTypeIcon;
icon_dir->idCount = bitmap_count;
size_t icon_dir_count = bitmap_count - 1; // Note DCHECK(!bitmaps.empty())!
+
+ // Increment counts if a PNG entry will be added.
+ if (png_bytes.get()) {
+ icon_dir->idCount++;
+ icon_dir_count++;
+ }
+
size_t offset = sizeof(ICONDIR) + (sizeof(ICONDIRENTRY) * icon_dir_count);
for (size_t i = 0; i < bitmap_count; i++) {
- ICONIMAGE* image = reinterpret_cast<ICONIMAGE*>(buffer + offset);
+ ICONIMAGE* image = reinterpret_cast<ICONIMAGE*>(&buffer[offset]);
DCHECK_LT(offset, buffer_size);
size_t icon_image_size = 0;
SetSingleIconImageInformation(bitmaps[i], i, icon_dir, image, offset,
@@ -331,17 +350,32 @@
DCHECK_GT(icon_image_size, 0U);
offset += icon_image_size;
}
+
+ // Add the PNG entry, if necessary.
+ if (png_bytes.get()) {
+ ICONDIRENTRY* entry = &icon_dir->idEntries[bitmap_count];
+ entry->bWidth = 0;
+ entry->bHeight = 0;
+ entry->wPlanes = 1;
+ entry->wBitCount = 32;
+ entry->dwBytesInRes = png_bytes->size();
+ entry->dwImageOffset = offset;
+ memcpy(&buffer[offset], png_bytes->front(), png_bytes->size());
+ offset += png_bytes->size();
+ }
+
DCHECK_EQ(offset, buffer_size);
- // Finally, writing the data info the file.
+ // Finally, write the data to the file.
DWORD bytes_written;
bool delete_file = false;
- if (!WriteFile(icon_file.Get(), buffer, buffer_size, &bytes_written, NULL) ||
- bytes_written != buffer_size)
+ if (!WriteFile(icon_file.Get(), &buffer[0], buffer_size, &bytes_written,
+ NULL) ||
+ bytes_written != buffer_size) {
delete_file = true;
+ }
::CloseHandle(icon_file.Take());
- delete [] buffer;
if (delete_file) {
bool success = file_util::Delete(icon_path, false);
DCHECK(success);
« no previous file with comments | « ui/gfx/icon_util.h ('k') | ui/gfx/icon_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698