blob: 90d9bb53200cec21fff88a23e660b28226596924 [file] [log] [blame]
// Copyright 2015 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 "content/public/browser/manifest_icon_selector.h"
#include <limits>
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
namespace content {
// static
GURL ManifestIconSelector::FindBestMatchingIcon(
const std::vector<Manifest::Icon>& icons,
int ideal_icon_size_in_px,
int minimum_icon_size_in_px,
Manifest::Icon::IconPurpose purpose) {
DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px);
// Icon with exact matching size has priority over icon with size "any", which
// has priority over icon with closest matching size.
int latest_size_any_index = -1;
int closest_size_match_index = -1;
int best_delta_in_size = std::numeric_limits<int>::min();
for (size_t i = 0; i < icons.size(); ++i) {
const auto& icon = icons[i];
// Check for supported image MIME types.
if (!icon.type.empty() &&
!blink::IsSupportedImageMimeType(base::UTF16ToUTF8(icon.type))) {
continue;
}
// Check for icon purpose.
if (!base::ContainsValue(icon.purpose, purpose))
continue;
// Check for size constraints.
for (const gfx::Size& size : icon.sizes) {
// Check for size "any". Return this icon if no better one is found.
if (size.IsEmpty()) {
latest_size_any_index = i;
continue;
}
// Check for squareness.
if (size.width() != size.height())
continue;
// Check for minimum size.
if (size.width() < minimum_icon_size_in_px)
continue;
// Check for ideal size. Return this icon immediately.
if (size.width() == ideal_icon_size_in_px)
return icon.src;
// Check for closest match.
int delta = size.width() - ideal_icon_size_in_px;
// Smallest icon larger than ideal size has priority over largest icon
// smaller than ideal size.
if (best_delta_in_size > 0 && delta < 0)
continue;
if ((best_delta_in_size > 0 && delta < best_delta_in_size) ||
(best_delta_in_size < 0 && delta > best_delta_in_size)) {
closest_size_match_index = i;
best_delta_in_size = delta;
}
}
}
if (latest_size_any_index != -1)
return icons[latest_size_any_index].src;
else if (closest_size_match_index != -1)
return icons[closest_size_match_index].src;
else
return GURL();
}
} // namespace content