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

Unified Diff: ui/gfx/icon_family.cc

Issue 12881003: ShortcutInfo::favicon is now a gfx::ImageFamily instead of gfx::Image. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Added test suite for icon_family. Created 7 years, 9 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
Index: ui/gfx/icon_family.cc
diff --git a/ui/gfx/icon_family.cc b/ui/gfx/icon_family.cc
new file mode 100644
index 0000000000000000000000000000000000000000..092114881768bcfca9419d8d20789343b443b93d
--- /dev/null
+++ b/ui/gfx/icon_family.cc
@@ -0,0 +1,120 @@
+// Copyright 2013 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 "ui/gfx/icon_family.h"
+
+#include <algorithm>
+
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace gfx {
+
+IconFamily::IconFamily() {}
+IconFamily::~IconFamily() {}
+
+void IconFamily::Add(const gfx::Image& icon)
+{
+ if (icon.IsEmpty())
+ return;
+ const gfx::ImageSkia* imageskia = icon.ToImageSkia();
+ if (imageskia)
+ Add(*imageskia);
+}
+
+void IconFamily::Add(const gfx::ImageSkia& icon)
+{
+ int width = icon.width();
+ int height = icon.height();
+ float aspect;
+ if (height == 0) {
+ // Assume the image is square.
+ aspect = 1.0f;
+ } else {
+ aspect = static_cast<float>(width) / height;
+ }
+ int size = std::min(width, height);
+ map_[MapKey(aspect, size)] = icon;
+}
+
+const gfx::ImageSkia* IconFamily::Get(int width, int height) const
+{
+ if (map_.empty())
+ return NULL;
+
+ float desired_aspect;
+ if (height == 0) {
+ if (width == 0) {
+ // Choose a square image if possible.
+ desired_aspect = 1.0f;
+ } else {
+ // Choose the widest possible aspect ratio (since infinity is not a
+ // well-defined concept in C++).
+ desired_aspect = (--map_.end())->first.first;
+ }
+ } else {
+ desired_aspect = static_cast<float>(width) / height;
+ }
+ int desired_size = std::max(width, height);
+
+ // Get iterator to images >= and < the desired aspect ratio and size.
+ std::map<MapKey, gfx::ImageSkia>::const_iterator greater_or_equal =
+ map_.lower_bound(MapKey(desired_aspect, desired_size));
+ if (greater_or_equal != map_.end() &&
+ greater_or_equal->first.aspect() == desired_aspect) {
+ // Exact same aspect ratio, and we have found the smallest image of the same
+ // size or greater. This is ideal.
+ return &greater_or_equal->second;
+ }
+
+ float closest_aspect; // Closest aspect ratio to the desired one.
+ if (greater_or_equal != map_.begin()) {
+ std::map<MapKey, gfx::ImageSkia>::const_iterator less_than =
+ greater_or_equal;
+ --less_than;
+ if (less_than->first.aspect() == desired_aspect) {
+ // Exact same aspect ratio, and we have found the largest image smaller
+ // than desired.
+ return &less_than->second;
+ }
+
+ float thinner_aspect = less_than->first.aspect();
+ DCHECK(thinner_aspect < desired_aspect);
+ closest_aspect = thinner_aspect;
+ if (greater_or_equal != map_.end()) {
+ float wider_aspect = greater_or_equal->first.aspect();
+ DCHECK(wider_aspect > desired_aspect);
+ if ((wider_aspect - desired_aspect) < (desired_aspect - thinner_aspect))
+ closest_aspect = wider_aspect;
+ }
+ } else {
+ // No aspect ratio is less than or equal to desired_aspect.
+ DCHECK(greater_or_equal != map_.end());
+ closest_aspect = greater_or_equal->first.aspect();
+ DCHECK(closest_aspect > desired_aspect);
+ }
+
+ // Search again, this time with the aspect ratio we know exists.
+ greater_or_equal = map_.lower_bound(MapKey(closest_aspect, desired_size));
+ if (greater_or_equal != map_.end() &&
+ greater_or_equal->first.aspect() == closest_aspect) {
+ // We have found the smallest image of the same size or greater.
+ return &greater_or_equal->second;
+ }
+
+ DCHECK(greater_or_equal != map_.begin());
+ std::map<MapKey, gfx::ImageSkia>::const_iterator less_than = greater_or_equal;
+ --less_than;
+ // This must be true because there must be at least one image with
+ // closest_aspect.
+ DCHECK(less_than->first.aspect() == closest_aspect);
+ // We have found the largest image smaller than desired.
+ return &less_than->second;
+}
+
+IconFamily::const_iterator::const_iterator(
+ const std::map<MapKey, gfx::ImageSkia>::const_iterator& other)
+ : map_iterator_(other) {}
+
+} // namespace gfx

Powered by Google App Engine
This is Rietveld 408576698