Chromium Code Reviews| OLD | NEW |
|---|---|
| (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::ImageFamily() {} | |
| 16 ImageFamily::~ImageFamily() {} | |
| 17 | |
| 18 void ImageFamily::Add(const gfx::Image& image) { | |
| 19 gfx::Size size = image.Size(); | |
| 20 if (size.IsEmpty()) { | |
| 21 map_[MapKey(1.0f, 0)] = image; | |
|
pkotwicz
2013/03/29 00:25:35
Should we just not store |image| if size.IsEmpty()
Matt Giuca
2013/03/30 00:54:14
I think that would be more surprising semantics. T
pkotwicz
2013/04/02 16:06:31
Fair enough
| |
| 22 } else { | |
| 23 float aspect = static_cast<float>(size.width()) / size.height(); | |
| 24 DCHECK_GT(aspect, 0.0f); | |
| 25 map_[MapKey(aspect, size.width())] = image; | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 void ImageFamily::Add(const gfx::ImageSkia& image_skia) { | |
| 30 Add(gfx::Image(image_skia)); | |
| 31 } | |
| 32 | |
| 33 const gfx::Image* ImageFamily::Get(int width, int height) const { | |
| 34 if (map_.empty()) | |
| 35 return NULL; | |
| 36 | |
| 37 // If either width or height is 0, both are. | |
| 38 float desired_aspect; | |
| 39 if (height == 0 || width == 0) { | |
| 40 desired_aspect = 1.0f; | |
| 41 height = 0; | |
| 42 width = 0; | |
| 43 } else { | |
| 44 desired_aspect = static_cast<float>(width) / height; | |
| 45 } | |
| 46 DCHECK_GT(desired_aspect, 0.0f); | |
| 47 | |
| 48 // Find the closest aspect ratio in the map to the desired one. | |
|
pkotwicz
2013/03/29 00:25:35
Nit: I am unsure if the comment above says anythin
Matt Giuca
2013/03/30 00:54:14
Done.
| |
| 49 float closest_aspect = GetClosestAspect(desired_aspect); | |
| 50 | |
| 51 // If thinner than desired, search for images with width such that the | |
| 52 // corresponding height is greater than or equal to the desired height. | |
| 53 int desired_width = closest_aspect <= desired_aspect ? width : | |
|
pkotwicz
2013/03/29 00:25:35
Nit, fix alignment like so:
int desired_width = cl
Matt Giuca
2013/03/30 00:54:14
Done.
| |
| 54 static_cast<int>(ceilf(height * closest_aspect)); | |
| 55 | |
| 56 // Get the best-sized image with the aspect ratio. | |
| 57 return GetWithExactAspect(closest_aspect, desired_width); | |
| 58 } | |
| 59 | |
| 60 float ImageFamily::GetClosestAspect(float desired_aspect) const { | |
| 61 // Find the two aspect ratios on either side of desired_aspect. | |
| 62 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal = | |
| 63 map_.lower_bound(MapKey(desired_aspect, 0.0f)); | |
| 64 // Early exit optimization if there is an exact match. | |
| 65 if (greater_or_equal != map_.end() && | |
| 66 greater_or_equal->first.aspect() == desired_aspect) { | |
| 67 return desired_aspect; | |
| 68 } | |
| 69 | |
| 70 // No exact match; greater_or_equal will point to the first image with aspect | |
| 71 // ratio >= desired_aspect, and less_than will point to the last image with | |
| 72 // aspect ratio < desired_aspect. | |
| 73 if (greater_or_equal != map_.begin()) { | |
| 74 std::map<MapKey, gfx::Image>::const_iterator less_than = | |
| 75 greater_or_equal; | |
| 76 --less_than; | |
| 77 float thinner_aspect = less_than->first.aspect(); | |
| 78 DCHECK_GT(thinner_aspect, 0.0f); | |
| 79 DCHECK_LT(thinner_aspect, desired_aspect); | |
| 80 if (greater_or_equal != map_.end()) { | |
| 81 float wider_aspect = greater_or_equal->first.aspect(); | |
| 82 DCHECK_GT(wider_aspect, desired_aspect); | |
| 83 if ((wider_aspect / desired_aspect) < (desired_aspect / thinner_aspect)) | |
| 84 return wider_aspect; | |
| 85 } | |
| 86 return thinner_aspect; | |
| 87 } else { | |
| 88 // No aspect ratio is less than or equal to desired_aspect. | |
| 89 DCHECK(greater_or_equal != map_.end()); | |
| 90 float wider_aspect = greater_or_equal->first.aspect(); | |
| 91 DCHECK_GT(wider_aspect, desired_aspect); | |
| 92 return wider_aspect; | |
| 93 } | |
|
pkotwicz
2013/03/29 00:25:35
Nit, this MIGHT be simpler:
DCHECK(!map_.empty())
Matt Giuca
2013/03/30 00:54:14
Using float max to avoid having a special case whe
pkotwicz
2013/04/02 16:06:31
Fair enough
| |
| 94 } | |
| 95 | |
| 96 const gfx::Image* ImageFamily::GetWithExactAspect(float aspect, int width) | |
|
pkotwicz
2013/03/29 00:25:35
For the sake of wrapping:
const gfx::Image* ImageF
Matt Giuca
2013/03/30 00:54:14
Done.
| |
| 97 const { | |
| 98 // Find the two images of given aspect ratio on either side of width. | |
| 99 std::map<MapKey, gfx::Image>::const_iterator greater_or_equal = | |
| 100 map_.lower_bound(MapKey(aspect, width)); | |
| 101 if (greater_or_equal != map_.end() && | |
| 102 greater_or_equal->first.aspect() == aspect) { | |
| 103 // We have found the smallest image of the same size or greater. | |
|
pkotwicz
2013/03/29 00:25:35
Nit: I am unsure if this comment says anything tha
Matt Giuca
2013/03/30 00:54:14
It's not obvious to me as a reader exactly how low
| |
| 104 return &greater_or_equal->second; | |
| 105 } | |
| 106 | |
| 107 DCHECK(greater_or_equal != map_.begin()); | |
| 108 std::map<MapKey, gfx::Image>::const_iterator less_than = greater_or_equal; | |
| 109 --less_than; | |
| 110 // This must be true because there must be at least one image with aspect. | |
|
pkotwicz
2013/03/29 00:25:35
Nit: |aspect|.
Matt Giuca
2013/03/30 00:54:14
Done.
| |
| 111 DCHECK_EQ(less_than->first.aspect(), aspect); | |
| 112 // We have found the largest image smaller than desired. | |
| 113 return &less_than->second; | |
| 114 } | |
| 115 | |
| 116 ImageFamily::const_iterator::const_iterator( | |
| 117 const std::map<MapKey, gfx::Image>::const_iterator& other) | |
| 118 : map_iterator_(other) {} | |
| 119 | |
| 120 } // namespace gfx | |
| OLD | NEW |