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

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: Respond to reviewer feedback. 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
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 const std::map<MapKey, gfx::Image>::const_iterator& other)
17 : map_iterator_(other) {}
18
19 ImageFamily::ImageFamily() {}
20 ImageFamily::~ImageFamily() {}
21
22 void ImageFamily::Add(const gfx::Image& image) {
23 gfx::Size size = image.Size();
24 if (size.IsEmpty()) {
25 map_[MapKey(1.0f, 0)] = image;
26 } else {
27 float aspect = static_cast<float>(size.width()) / size.height();
28 DCHECK_GT(aspect, 0.0f);
29 map_[MapKey(aspect, size.width())] = image;
30 }
31 }
32
33 void ImageFamily::Add(const gfx::ImageSkia& image_skia) {
34 Add(gfx::Image(image_skia));
35 }
36
37 const gfx::Image* ImageFamily::Get(int width, int height) const {
38 if (map_.empty())
39 return NULL;
40
41 // If either width or height is 0, both are.
42 float desired_aspect;
43 if (height == 0 || width == 0) {
44 desired_aspect = 1.0f;
45 height = 0;
46 width = 0;
47 } else {
48 desired_aspect = static_cast<float>(width) / height;
49 }
50 DCHECK_GT(desired_aspect, 0.0f);
51
52 float closest_aspect = GetClosestAspect(desired_aspect);
53
54 // If thinner than desired, search for images with width such that the
55 // corresponding height is greater than or equal to the desired height.
56 int desired_width = closest_aspect <= desired_aspect ?
57 width : static_cast<int>(ceilf(height * closest_aspect));
58
59 // Get the best-sized image with the aspect ratio.
60 return GetWithExactAspect(closest_aspect, desired_width);
61 }
62
63 float ImageFamily::GetClosestAspect(float desired_aspect) const {
64 // Find the two aspect ratios on either side of desired_aspect.
65 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal =
66 map_.lower_bound(MapKey(desired_aspect, 0.0f));
pkotwicz 2013/04/02 16:06:31 Nit: 0 instead of 0.0f to match std::pair<float, i
Matt Giuca 2013/04/03 00:37:43 Done. (Good catch.)
67 // Early exit optimization if there is an exact match.
68 if (greater_or_equal != map_.end() &&
69 greater_or_equal->first.aspect() == desired_aspect) {
70 return desired_aspect;
71 }
72
73 // No exact match; greater_or_equal will point to the first image with aspect
74 // ratio >= desired_aspect, and less_than will point to the last image with
pkotwicz 2013/04/02 16:06:31 Nits: ratio > |desired_aspect| |greater_or_e
Matt Giuca 2013/04/03 00:37:43 Done. (Also put || around all variable names in co
75 // aspect ratio < desired_aspect.
76 if (greater_or_equal != map_.begin()) {
77 std::map<MapKey, gfx::Image>::const_iterator less_than =
78 greater_or_equal;
79 --less_than;
80 float thinner_aspect = less_than->first.aspect();
81 DCHECK_GT(thinner_aspect, 0.0f);
82 DCHECK_LT(thinner_aspect, desired_aspect);
83 if (greater_or_equal != map_.end()) {
84 float wider_aspect = greater_or_equal->first.aspect();
85 DCHECK_GT(wider_aspect, desired_aspect);
86 if ((wider_aspect / desired_aspect) < (desired_aspect / thinner_aspect))
87 return wider_aspect;
88 }
89 return thinner_aspect;
90 } else {
91 // No aspect ratio is less than or equal to desired_aspect.
92 DCHECK(greater_or_equal != map_.end());
93 float wider_aspect = greater_or_equal->first.aspect();
94 DCHECK_GT(wider_aspect, desired_aspect);
95 return wider_aspect;
96 }
97 }
98
99 const gfx::Image* ImageFamily::GetWithExactAspect(float aspect,
100 int width) const {
101 // Find the two images of given aspect ratio on either side of width.
pkotwicz 2013/04/02 16:06:31 Nit: |width|
Matt Giuca 2013/04/03 00:37:43 Done.
102 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal =
103 map_.lower_bound(MapKey(aspect, width));
104 if (greater_or_equal != map_.end() &&
105 greater_or_equal->first.aspect() == aspect) {
106 // We have found the smallest image of the same size or greater.
107 return &greater_or_equal->second;
108 }
109
110 DCHECK(greater_or_equal != map_.begin());
111 std::map<MapKey, gfx::Image>::const_iterator less_than = greater_or_equal;
112 --less_than;
113 // This must be true because there must be at least one image with |aspect|.
114 DCHECK_EQ(less_than->first.aspect(), aspect);
115 // We have found the largest image smaller than desired.
116 return &less_than->second;
117 }
118
119 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698