diff options
author | huangs <huangs@chromium.org> | 2015-02-11 14:18:38 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-11 22:19:03 +0000 |
commit | 3382fc9d60d79fc9d829fd626a4d591d2f2a23ff (patch) | |
tree | 67ba7273e057d307aaf37a56262217f1ac2a0e4d /components/favicon_base | |
parent | 17d1302c86810f3313c18894f601e21eb6a45f19 (diff) | |
download | chromium_src-3382fc9d60d79fc9d829fd626a4d591d2f2a23ff.zip chromium_src-3382fc9d60d79fc9d829fd626a4d591d2f2a23ff.tar.gz chromium_src-3382fc9d60d79fc9d829fd626a4d591d2f2a23ff.tar.bz2 |
[Favicon] Add FallbackIconStyle and FallbackIconService.
Design: go/chrome-fallback-icons
This implements
- FallbackIconStyle: A struct to specify fallback data.
- FallbackIconService: Helper class to render the fallback icon as a
filled rounded square with a single letter from the URL.
- Extra dependencies are needed to convert URL to the icon letter.
This CL is sliced off from https://codereview.chromium.org/835903005/ .
BUG=455063
Review URL: https://codereview.chromium.org/886163003
Cr-Commit-Position: refs/heads/master@{#315854}
Diffstat (limited to 'components/favicon_base')
-rw-r--r-- | components/favicon_base/BUILD.gn | 4 | ||||
-rw-r--r-- | components/favicon_base/DEPS | 1 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_service.cc | 98 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_service.h | 51 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_style.cc | 48 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_style.h | 42 | ||||
-rw-r--r-- | components/favicon_base/favicon_types.cc | 7 |
7 files changed, 248 insertions, 3 deletions
diff --git a/components/favicon_base/BUILD.gn b/components/favicon_base/BUILD.gn index cf060fe..57c42a4 100644 --- a/components/favicon_base/BUILD.gn +++ b/components/favicon_base/BUILD.gn @@ -4,6 +4,10 @@ source_set("favicon_base") { sources = [ + "fallback_icon_service.cc", + "fallback_icon_service.h", + "fallback_icon_style.cc", + "fallback_icon_style.h", "favicon_callback.h", "favicon_types.cc", "favicon_types.h", diff --git a/components/favicon_base/DEPS b/components/favicon_base/DEPS index 0265afa..dc47487 100644 --- a/components/favicon_base/DEPS +++ b/components/favicon_base/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+net/base/registry_controlled_domains/registry_controlled_domain.h", "+skia/ext", "+third_party/skia/include", "+ui/base", diff --git a/components/favicon_base/fallback_icon_service.cc b/components/favicon_base/fallback_icon_service.cc new file mode 100644 index 0000000..1642b20 --- /dev/null +++ b/components/favicon_base/fallback_icon_service.cc @@ -0,0 +1,98 @@ +// Copyright 2015 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 "components/favicon_base/fallback_icon_service.h" + +#include <algorithm> + +#include "base/i18n/case_conversion.h" +#include "base/strings/utf_string_conversions.h" +#include "components/favicon_base/fallback_icon_style.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/font_list.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "url/gurl.h" + +namespace favicon_base { + +namespace { + +// Arbitrary maximum icon size, can be reasonably increased if needed. +const int kMaxFallbackFaviconSize = 288; + +// Returns a single character to represent a page URL. To do this we take the +// first letter in a domain's name and make it upper case. +// TODO(huangs): Handle non-ASCII ("xn--") domain names. +base::string16 GetFallbackIconText(const GURL& url) { + std::string domain = net::registry_controlled_domains::GetDomainAndRegistry( + url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + return domain.empty() ? base::string16() : + base::i18n::ToUpper(base::ASCIIToUTF16(domain.substr(0, 1))); +} + +} // namespace + +FallbackIconService::FallbackIconService( + const std::vector<std::string>& font_list) + : font_list_(font_list) { +} + +FallbackIconService::~FallbackIconService() { +} + +std::vector<unsigned char> FallbackIconService::RenderFallbackIconBitmap( + const GURL& icon_url, + int size, + const FallbackIconStyle& style) { + int size_to_use = std::min(kMaxFallbackFaviconSize, size); + gfx::Canvas canvas(gfx::Size(size_to_use, size_to_use), 1.0f, false); + DrawFallbackIcon(icon_url, size_to_use, style, &canvas); + + std::vector<unsigned char> bitmap_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(canvas.ExtractImageRep().sk_bitmap(), + false, &bitmap_data)) { + bitmap_data.clear(); + } + return bitmap_data; +} + +void FallbackIconService::DrawFallbackIcon(const GURL& icon_url, + int size, + const FallbackIconStyle& style, + gfx::Canvas* canvas) { + const int kOffsetX = 0; + const int kOffsetY = 0; + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + + // Draw a filled, colored rounded square. + paint.setColor(style.background_color); + int corner_radius = static_cast<int>(size * style.roundness * 0.5 + 0.5); + canvas->DrawRoundRect( + gfx::Rect(kOffsetX, kOffsetY, size, size), corner_radius, paint); + + // Draw text. + base::string16 icon_text = GetFallbackIconText(icon_url); + if (icon_text.empty()) + return; + int font_size = static_cast<int>(size * style.font_size_ratio); + if (font_size <= 0) + return; + + // TODO(huangs): See how expensive gfx::FontList() is, and possibly cache. + canvas->DrawStringRectWithFlags( + icon_text, + gfx::FontList(font_list_, gfx::Font::NORMAL, font_size), + style.text_color, + gfx::Rect(kOffsetX, kOffsetY, size, size), + gfx::Canvas::TEXT_ALIGN_CENTER); +} + +} // namespace favicon_base diff --git a/components/favicon_base/fallback_icon_service.h b/components/favicon_base/fallback_icon_service.h new file mode 100644 index 0000000..cc98adf --- /dev/null +++ b/components/favicon_base/fallback_icon_service.h @@ -0,0 +1,51 @@ +// Copyright 2015 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 COMPONENTS_FAVICON_BASE_FALLBACK_ICON_SERVICE_H_ +#define COMPONENTS_FAVICON_BASE_FALLBACK_ICON_SERVICE_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" + +class GURL; + +namespace gfx { +class Canvas; +} + +namespace favicon_base { + +struct FallbackIconStyle; + +// A service to provide methods to render fallback favicons. +class FallbackIconService { + public: + explicit FallbackIconService(const std::vector<std::string>& font_list); + ~FallbackIconService(); + + // Renders a fallback icon synchronously and returns the bitmap. Returns an + // empty std::vector on failure. |size| is icon width and height in pixels. + std::vector<unsigned char> RenderFallbackIconBitmap( + const GURL& icon_url, + int size, + const FallbackIconStyle& style); + + private: + // Renders a fallback icon on |canvas| at position (|x|, |y|). |size| is icon + // width and height in pixels. + void DrawFallbackIcon(const GURL& icon_url, + int size, + const FallbackIconStyle& style, + gfx::Canvas* canvas); + + std::vector<std::string> font_list_; + + DISALLOW_COPY_AND_ASSIGN(FallbackIconService); +}; + +} // namespace favicon_base + +#endif // COMPONENTS_FAVICON_BASE_FALLBACK_ICON_SERVICE_H_ diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc new file mode 100644 index 0000000..e620613 --- /dev/null +++ b/components/favicon_base/fallback_icon_style.cc @@ -0,0 +1,48 @@ +// Copyright 2015 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 "components/favicon_base/fallback_icon_style.h" + +#include "ui/gfx/color_utils.h" + +namespace favicon_base { + +namespace { + +// Luminance threshold for background color determine whether to use dark or +// light text color. +int kDarkTextLuminanceThreshold = 190; + +// Default values for FallbackIconStyle. +SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80); +SkColor kDefaultTextColorDark = SK_ColorBLACK; +SkColor kDefaultTextColorLight = SK_ColorWHITE; +double kDefaultFontSizeRatio = 0.8; +double kDefaultRoundness = 0.125; // 1 / 8. + +} // namespace + +FallbackIconStyle::FallbackIconStyle() + : background_color(kDefaultBackgroundColor), + text_color(kDefaultTextColorLight), + font_size_ratio(kDefaultFontSizeRatio), + roundness(kDefaultRoundness) { +} + +FallbackIconStyle::~FallbackIconStyle() { +} + +void MatchFallbackIconTextColorAgainstBackgroundColor( + FallbackIconStyle* style) { + int luminance = color_utils::GetLuminanceForColor(style->background_color); + style->text_color = (luminance >= kDarkTextLuminanceThreshold ? + kDefaultTextColorDark : kDefaultTextColorLight); +} + +bool ValidateFallbackIconStyle(const FallbackIconStyle& style) { + return style.font_size_ratio >= 0.0 && style.font_size_ratio <= 1.0 && + style.roundness >= 0.0 && style.roundness <= 1.0; +} + +} // namespace favicon_base diff --git a/components/favicon_base/fallback_icon_style.h b/components/favicon_base/fallback_icon_style.h new file mode 100644 index 0000000..097636b --- /dev/null +++ b/components/favicon_base/fallback_icon_style.h @@ -0,0 +1,42 @@ +// Copyright 2015 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 COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ +#define COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ + +#include "third_party/skia/include/core/SkColor.h" + +namespace favicon_base { + +// Styling specifications of a fallback icon. The icon is composed of a solid +// rounded square containing a single letter. The specification excludes the +// icon URL and size, which are given when the icon is rendered. +struct FallbackIconStyle { + FallbackIconStyle(); + ~FallbackIconStyle(); + + // If any member changes, also update FallbackIconStyleBuilder. + + // Icon background fill color. + SkColor background_color; + + // Icon text color. + SkColor text_color; + + // Ratio in [0.0, 1.0] of the text font size (pixels) to the icon size. + double font_size_ratio; + + // The roundness of the icon's corners. 0 => square icon, 1 => circle icon. + double roundness; +}; + +// Reassigns |style|'s |text_color| to matches well against |background_color|. +void MatchFallbackIconTextColorAgainstBackgroundColor(FallbackIconStyle* style); + +// Returns whether |style| values are within bounds. +bool ValidateFallbackIconStyle(const FallbackIconStyle& style); + +} // namespace favicon_base + +#endif // COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ diff --git a/components/favicon_base/favicon_types.cc b/components/favicon_base/favicon_types.cc index eb0e7bc..0188f1e 100644 --- a/components/favicon_base/favicon_types.cc +++ b/components/favicon_base/favicon_types.cc @@ -6,14 +6,15 @@ namespace favicon_base { -// FaviconImageResult --------------------------------------------------------- +// --------------------------------------------------------- +// FaviconImageResult FaviconImageResult::FaviconImageResult() {} FaviconImageResult::~FaviconImageResult() {} -// FaviconRawBitmapResult // -------------------------------------------------------- +// FaviconRawBitmapResult FaviconRawBitmapResult::FaviconRawBitmapResult() : expired(false), icon_type(INVALID_ICON) { @@ -22,4 +23,4 @@ FaviconRawBitmapResult::FaviconRawBitmapResult() FaviconRawBitmapResult::~FaviconRawBitmapResult() { } -} // namespace chrome +} // namespace favicon_base |