Chromium Code Reviews| Index: chrome/browser/extensions/bookmark_app_helper.cc |
| diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc |
| index 476faa2055591d71039e6d7f8d429775d5058db1..2efd0627dcfbd871a989f40e575c2fd6e42b9673 100644 |
| --- a/chrome/browser/extensions/bookmark_app_helper.cc |
| +++ b/chrome/browser/extensions/bookmark_app_helper.cc |
| @@ -4,6 +4,8 @@ |
| #include "chrome/browser/extensions/bookmark_app_helper.h" |
| +#include <cctype> |
| + |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/crx_installer.h" |
| @@ -18,11 +20,20 @@ |
| #include "extensions/common/extension.h" |
| #include "extensions/common/manifest_handlers/icons_handler.h" |
| #include "extensions/common/url_pattern.h" |
| +#include "grit/app_locale_settings.h" |
| +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| #include "skia/ext/image_operations.h" |
| #include "skia/ext/platform_canvas.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| +#include "ui/base/l10n/l10n_util.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/canvas.h" |
| #include "ui/gfx/color_analysis.h" |
| +#include "ui/gfx/color_utils.h" |
| +#include "ui/gfx/font.h" |
| +#include "ui/gfx/font_list.h" |
| #include "ui/gfx/image/image.h" |
| +#include "ui/gfx/rect.h" |
| namespace extensions { |
| @@ -63,86 +74,47 @@ std::map<int, SkBitmap> BookmarkAppHelper::ConstrainBitmapsToSizes( |
| } |
| // static |
| -void BookmarkAppHelper::GenerateContainerIcon(std::map<int, SkBitmap>* bitmaps, |
| - int output_size) { |
| - std::map<int, SkBitmap>::const_iterator it = |
| - bitmaps->lower_bound(output_size); |
| - // Do nothing if there is no icon smaller than the desired size or there is |
| - // already an icon of |output_size|. |
| - if (it == bitmaps->begin() || bitmaps->count(output_size)) |
| +void BookmarkAppHelper::GenerateIcon(std::map<int, SkBitmap>* bitmaps, |
| + int output_size, |
| + SkColor color, |
| + char letter) { |
| + // Do nothing if there is already an icon of |output_size|. |
| + if (bitmaps->count(output_size)) |
| return; |
| - --it; |
| - // This is the biggest icon smaller than |output_size|. |
| - const SkBitmap& base_icon = it->second; |
| - |
| - const size_t kBorderRadius = 5; |
| - const size_t kColorStripHeight = 3; |
| - const SkColor kBorderColor = 0xFFD5D5D5; |
| - const SkColor kBackgroundColor = 0xFFFFFFFF; |
| - |
| - // Create a separate canvas for the color strip. |
| - scoped_ptr<SkCanvas> color_strip_canvas( |
| - skia::CreateBitmapCanvas(output_size, output_size, false)); |
| - DCHECK(color_strip_canvas); |
| - |
| - // Draw a rounded rect of the |base_icon|'s dominant color. |
| - SkPaint color_strip_paint; |
| - color_utils::GridSampler sampler; |
| - color_strip_paint.setFlags(SkPaint::kAntiAlias_Flag); |
| - color_strip_paint.setColor(color_utils::CalculateKMeanColorOfPNG( |
| - gfx::Image::CreateFrom1xBitmap(base_icon).As1xPNGBytes(), |
| - 100, |
| - 665, |
| - &sampler)); |
| - color_strip_canvas->drawRoundRect(SkRect::MakeWH(output_size, output_size), |
| - kBorderRadius, |
| - kBorderRadius, |
| - color_strip_paint); |
| - |
| - // Erase the top of the rounded rect to leave a color strip. |
| - SkPaint clear_paint; |
| - clear_paint.setColor(SK_ColorTRANSPARENT); |
| - clear_paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| - color_strip_canvas->drawRect( |
| - SkRect::MakeWH(output_size, output_size - kColorStripHeight), |
| - clear_paint); |
| - |
| - // Draw each element to an output canvas. |
| - scoped_ptr<SkCanvas> canvas( |
| - skia::CreateBitmapCanvas(output_size, output_size, false)); |
| + const unsigned char kLuminanceThreshold = 190; |
| + const int icon_size = output_size * 3 / 4; |
| + const int icon_inset = output_size / 8; |
| + const size_t border_radius = output_size / 16; |
| + const size_t font_size = output_size * 7 / 16; |
| + |
| + scoped_ptr<gfx::Canvas> canvas( |
| + new gfx::Canvas(gfx::Size(output_size, output_size), 1.0f, false)); |
| DCHECK(canvas); |
| - // Draw the background. |
| + // Draw a rounded rect of the given |color|. |
| SkPaint background_paint; |
| - background_paint.setColor(kBackgroundColor); |
| + background_paint.setColor(color); |
| background_paint.setFlags(SkPaint::kAntiAlias_Flag); |
| - canvas->drawRoundRect(SkRect::MakeWH(output_size, output_size), |
| - kBorderRadius, |
| - kBorderRadius, |
| - background_paint); |
| - |
| - // Draw the color strip. |
| - canvas->drawBitmap( |
| - color_strip_canvas->getDevice()->accessBitmap(false), 0, 0); |
| - |
| - // Draw the border. |
| - SkPaint border_paint; |
| - border_paint.setColor(kBorderColor); |
| - border_paint.setStyle(SkPaint::kStroke_Style); |
| - border_paint.setFlags(SkPaint::kAntiAlias_Flag); |
| - canvas->drawRoundRect(SkRect::MakeWH(output_size, output_size), |
| - kBorderRadius, |
| - kBorderRadius, |
| - border_paint); |
| - |
| - // Draw the centered base icon to the output canvas. |
| - canvas->drawBitmap(base_icon, |
| - (output_size - base_icon.width()) / 2, |
| - (output_size - base_icon.height()) / 2); |
| - |
| - const SkBitmap& generated_icon = canvas->getDevice()->accessBitmap(false); |
| - generated_icon.deepCopyTo(&(*bitmaps)[output_size]); |
| + |
| + gfx::Rect icon_rect(icon_inset, icon_inset, icon_size, icon_size); |
| + canvas->DrawRoundRect(icon_rect, border_radius, background_paint); |
| + |
| + // The text rect's size needs to be odd to center the text correctly. |
| + gfx::Rect text_rect(icon_inset, icon_inset, icon_size + 1, icon_size + 1); |
| + // Draw the letter onto the rounded rect. The letter's color depends on the |
| + // luminance of |color|. |
| + unsigned char luminance = color_utils::GetLuminanceForColor(color); |
| + canvas->DrawStringRectWithFlags( |
| + base::string16(1, std::toupper(letter)), |
| + gfx::FontList( |
| + gfx::Font(l10n_util::GetStringUTF8(IDS_WEB_FONT_FAMILY), font_size)), |
| + luminance > kLuminanceThreshold ? SK_ColorBLACK : SK_ColorWHITE, |
| + text_rect, |
| + gfx::Canvas::TEXT_ALIGN_CENTER); |
| + |
| + gfx::ImageSkia icon_image(canvas->ExtractImageRep()); |
| + icon_image.bitmap()->deepCopyTo(&(*bitmaps)[output_size]); |
| } |
| BookmarkAppHelper::BookmarkAppHelper(ExtensionService* service, |
| @@ -231,16 +203,42 @@ void BookmarkAppHelper::OnIconsDownloaded( |
| // Only generate icons if larger icons don't exist. This means the app |
| // launcher and the taskbar will do their best downsizing large icons and |
| - // these container icons are only generated as a last resort against upscaling |
| - // a smaller icon. |
| + // these icons are only generated as a last resort against upscaling a smaller |
| + // icon. |
| if (resized_bitmaps.lower_bound(*generate_sizes.rbegin()) == |
| resized_bitmaps.end()) { |
| - // Generate these from biggest to smallest so we don't end up with |
| - // concentric container icons. |
| - for (std::set<int>::const_reverse_iterator it = generate_sizes.rbegin(); |
| - it != generate_sizes.rend(); |
| + GURL app_url = web_app_info_.app_url; |
| + |
| + // The letter that will be painted on the generated icon. |
| + char icon_letter = ' '; |
| + std::string domain_and_registry( |
| + net::registry_controlled_domains::GetDomainAndRegistry( |
| + app_url, |
| + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); |
| + if (!domain_and_registry.empty()) { |
| + icon_letter = domain_and_registry[0]; |
| + } else if (!app_url.host().empty()) { |
| + icon_letter = app_url.host()[0]; |
| + } |
| + |
| + // The color that will be used for the icon's background. |
| + SkColor background_color = SK_ColorBLACK; |
| + if (resized_bitmaps.size()) { |
| + color_utils::GridSampler sampler; |
| + background_color = color_utils::CalculateKMeanColorOfPNG( |
| + gfx::Image::CreateFrom1xBitmap(resized_bitmaps.begin()->second) |
| + .As1xPNGBytes(), |
| + 100, |
| + 658, |
| + &sampler); |
| + } |
| + |
| + for (std::set<int>::const_iterator it = generate_sizes.begin(); |
| + it != generate_sizes.end(); |
| ++it) { |
| - GenerateContainerIcon(&resized_bitmaps, *it); |
| + GenerateIcon(&resized_bitmaps, *it, background_color, icon_letter); |
| + // Also generate the 2x resource for this size. |
|
benwells
2014/04/24 03:35:58
This seems to be new to this patch. Can you call t
calamity
2014/04/24 04:28:39
Done.
|
| + GenerateIcon(&resized_bitmaps, *it * 2, background_color, icon_letter); |
| } |
| } |