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

Side by Side Diff: ui/gfx/image/image_family.cc

Issue 12704026: Added new class gfx::ImageFamily. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed Windows build (missing UI_EXPORT). Created 7 years, 8 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 unified diff | Download patch
« no previous file with comments | « ui/gfx/image/image_family.h ('k') | ui/gfx/image/image_family_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gfx/image/image_family.h"
6
7 #include <cmath>
8
9 #include "ui/gfx/image/image.h"
10 #include "ui/gfx/image/image_skia.h"
11 #include "ui/gfx/size.h"
12
13 namespace gfx {
14
15 ImageFamily::const_iterator::const_iterator() {}
16
17 ImageFamily::const_iterator::const_iterator(const const_iterator& other)
18 : map_iterator_(other.map_iterator_) {}
19
20 ImageFamily::const_iterator::const_iterator(
21 const std::map<MapKey, gfx::Image>::const_iterator& other)
22 : map_iterator_(other) {}
23
24 ImageFamily::ImageFamily() {}
25 ImageFamily::~ImageFamily() {}
26
27 void ImageFamily::Add(const gfx::Image& image) {
28 gfx::Size size = image.Size();
29 if (size.IsEmpty()) {
30 map_[MapKey(1.0f, 0)] = image;
31 } else {
32 float aspect = static_cast<float>(size.width()) / size.height();
33 DCHECK_GT(aspect, 0.0f);
34 map_[MapKey(aspect, size.width())] = image;
35 }
36 }
37
38 void ImageFamily::Add(const gfx::ImageSkia& image_skia) {
39 Add(gfx::Image(image_skia));
40 }
41
42 const gfx::Image* ImageFamily::Get(int width, int height) const {
43 if (map_.empty())
44 return NULL;
45
46 // If either |width| or |height| is 0, both are.
47 float desired_aspect;
48 if (height == 0 || width == 0) {
49 desired_aspect = 1.0f;
50 height = 0;
51 width = 0;
52 } else {
53 desired_aspect = static_cast<float>(width) / height;
54 }
55 DCHECK_GT(desired_aspect, 0.0f);
56
57 float closest_aspect = GetClosestAspect(desired_aspect);
58
59 // If thinner than desired, search for images with width such that the
60 // corresponding height is greater than or equal to the desired |height|.
61 int desired_width = closest_aspect <= desired_aspect ?
62 width : static_cast<int>(ceilf(height * closest_aspect));
63
64 // Get the best-sized image with the aspect ratio.
65 return GetWithExactAspect(closest_aspect, desired_width);
66 }
67
68 float ImageFamily::GetClosestAspect(float desired_aspect) const {
69 // Find the two aspect ratios on either side of |desired_aspect|.
70 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal =
71 map_.lower_bound(MapKey(desired_aspect, 0));
72 // Early exit optimization if there is an exact match.
73 if (greater_or_equal != map_.end() &&
74 greater_or_equal->first.aspect() == desired_aspect) {
75 return desired_aspect;
76 }
77
78 // No exact match; |greater_or_equal| will point to the first image with
79 // aspect ratio >= |desired_aspect|, and |less_than| will point to the last
80 // image with aspect ratio < |desired_aspect|.
81 if (greater_or_equal != map_.begin()) {
82 std::map<MapKey, gfx::Image>::const_iterator less_than =
83 greater_or_equal;
84 --less_than;
85 float thinner_aspect = less_than->first.aspect();
86 DCHECK_GT(thinner_aspect, 0.0f);
87 DCHECK_LT(thinner_aspect, desired_aspect);
88 if (greater_or_equal != map_.end()) {
89 float wider_aspect = greater_or_equal->first.aspect();
90 DCHECK_GT(wider_aspect, desired_aspect);
91 if ((wider_aspect / desired_aspect) < (desired_aspect / thinner_aspect))
92 return wider_aspect;
93 }
94 return thinner_aspect;
95 } else {
96 // No aspect ratio is less than or equal to |desired_aspect|.
97 DCHECK(greater_or_equal != map_.end());
98 float wider_aspect = greater_or_equal->first.aspect();
99 DCHECK_GT(wider_aspect, desired_aspect);
100 return wider_aspect;
101 }
102 }
103
104 const gfx::Image* ImageFamily::GetWithExactAspect(float aspect,
105 int width) const {
106 // Find the two images of given aspect ratio on either side of |width|.
107 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal =
108 map_.lower_bound(MapKey(aspect, width));
109 if (greater_or_equal != map_.end() &&
110 greater_or_equal->first.aspect() == aspect) {
111 // We have found the smallest image of the same size or greater.
112 return &greater_or_equal->second;
113 }
114
115 DCHECK(greater_or_equal != map_.begin());
116 std::map<MapKey, gfx::Image>::const_iterator less_than = greater_or_equal;
117 --less_than;
118 // This must be true because there must be at least one image with |aspect|.
119 DCHECK_EQ(less_than->first.aspect(), aspect);
120 // We have found the largest image smaller than desired.
121 return &less_than->second;
122 }
123
124 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/image/image_family.h ('k') | ui/gfx/image/image_family_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698