summaryrefslogtreecommitdiffstats
path: root/components/favicon_base
diff options
context:
space:
mode:
authorhuangs <huangs@chromium.org>2015-02-11 14:18:38 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-11 22:19:03 +0000
commit3382fc9d60d79fc9d829fd626a4d591d2f2a23ff (patch)
tree67ba7273e057d307aaf37a56262217f1ac2a0e4d /components/favicon_base
parent17d1302c86810f3313c18894f601e21eb6a45f19 (diff)
downloadchromium_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.gn4
-rw-r--r--components/favicon_base/DEPS1
-rw-r--r--components/favicon_base/fallback_icon_service.cc98
-rw-r--r--components/favicon_base/fallback_icon_service.h51
-rw-r--r--components/favicon_base/fallback_icon_style.cc48
-rw-r--r--components/favicon_base/fallback_icon_style.h42
-rw-r--r--components/favicon_base/favicon_types.cc7
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