OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "chrome/browser/manifest/manifest_icon_selector.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/stl_util.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "components/mime_util/mime_util.h" | |
12 | |
13 // static | |
14 GURL ManifestIconSelector::FindBestMatchingIcon( | |
15 const std::vector<content::Manifest::Icon>& icons, | |
16 int ideal_icon_size_in_px, | |
17 int minimum_icon_size_in_px, | |
18 content::Manifest::Icon::IconPurpose purpose) { | |
19 DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px); | |
20 | |
21 // Icon with exact matching size has priority over icon with size "any", which | |
22 // has priority over icon with closest matching size. | |
23 int latest_size_any_index = -1; | |
24 int closest_size_match_index = -1; | |
25 int best_delta_in_size = std::numeric_limits<int>::min(); | |
26 | |
27 for (size_t i = 0; i < icons.size(); ++i) { | |
28 const auto& icon = icons[i]; | |
29 | |
30 // Check for supported image MIME types. | |
31 if (!icon.type.empty() && | |
32 !mime_util::IsSupportedImageMimeType(base::UTF16ToUTF8(icon.type))) { | |
33 continue; | |
34 } | |
35 | |
36 // Check for icon purpose. | |
37 if (!base::ContainsValue(icon.purpose, purpose)) | |
38 continue; | |
39 | |
40 // Check for size constraints. | |
41 for (const gfx::Size& size : icon.sizes) { | |
42 // Check for size "any". Return this icon if no better one is found. | |
43 if (size.IsEmpty()) { | |
44 latest_size_any_index = i; | |
45 continue; | |
46 } | |
47 | |
48 // Check for squareness. | |
49 if (size.width() != size.height()) | |
50 continue; | |
51 | |
52 // Check for minimum size. | |
53 if (size.width() < minimum_icon_size_in_px) | |
54 continue; | |
55 | |
56 // Check for ideal size. Return this icon immediately. | |
57 if (size.width() == ideal_icon_size_in_px) | |
58 return icon.src; | |
59 | |
60 // Check for closest match. | |
61 int delta = size.width() - ideal_icon_size_in_px; | |
62 | |
63 // Smallest icon larger than ideal size has priority over largest icon | |
64 // smaller than ideal size. | |
65 if (best_delta_in_size > 0 && delta < 0) | |
66 continue; | |
67 | |
68 if ((best_delta_in_size > 0 && delta < best_delta_in_size) || | |
69 (best_delta_in_size < 0 && delta > best_delta_in_size)) { | |
70 closest_size_match_index = i; | |
71 best_delta_in_size = delta; | |
72 } | |
73 } | |
74 } | |
75 | |
76 if (latest_size_any_index != -1) | |
77 return icons[latest_size_any_index].src; | |
78 else if (closest_size_match_index != -1) | |
79 return icons[closest_size_match_index].src; | |
80 else | |
81 return GURL(); | |
82 } | |
OLD | NEW |