summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/favicon/favicon_handler.cc9
-rw-r--r--chrome/browser/favicon/favicon_service.cc9
-rw-r--r--chrome/browser/history/select_favicon_frames_unittest.cc137
-rw-r--r--chrome/browser/ui/views/create_application_shortcut_view.cc25
-rw-r--r--components/favicon_base/select_favicon_frames.cc152
-rw-r--r--components/favicon_base/select_favicon_frames.h17
6 files changed, 209 insertions, 140 deletions
diff --git a/chrome/browser/favicon/favicon_handler.cc b/chrome/browser/favicon/favicon_handler.cc
index dade696..18fa447 100644
--- a/chrome/browser/favicon/favicon_handler.cc
+++ b/chrome/browser/favicon/favicon_handler.cc
@@ -427,11 +427,10 @@ void FaviconHandler::OnDidDownloadFavicon(
if (index != -1)
image_skia = gfx::ImageSkia(gfx::ImageSkiaRep(bitmaps[index], 1));
} else {
- image_skia = SelectFaviconFrames(bitmaps,
- original_bitmap_sizes,
- favicon_base::GetFaviconScales(),
- preferred_icon_size(),
- &score);
+ image_skia = CreateFaviconImageSkia(bitmaps,
+ original_bitmap_sizes,
+ preferred_icon_size(),
+ &score);
}
if (!image_skia.isNull()) {
diff --git a/chrome/browser/favicon/favicon_service.cc b/chrome/browser/favicon/favicon_service.cc
index 4df4387..994a62a 100644
--- a/chrome/browser/favicon/favicon_service.cc
+++ b/chrome/browser/favicon/favicon_service.cc
@@ -312,7 +312,15 @@ void FaviconService::SetFavicons(const GURL& page_url,
image_skia.EnsureRepsForSupportedScales();
const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps();
std::vector<favicon_base::FaviconRawBitmapData> favicon_bitmap_data;
+ const std::vector<float> favicon_scales = favicon_base::GetFaviconScales();
for (size_t i = 0; i < image_reps.size(); ++i) {
+ // Don't save if the scale isn't one of supported favicon scale.
+ if (std::find(favicon_scales.begin(),
+ favicon_scales.end(),
+ image_reps[i].scale()) == favicon_scales.end()) {
+ continue;
+ }
+
scoped_refptr<base::RefCountedBytes> bitmap_data(
new base::RefCountedBytes());
if (gfx::PNGCodec::EncodeBGRASkBitmap(image_reps[i].sk_bitmap(),
@@ -328,7 +336,6 @@ void FaviconService::SetFavicons(const GURL& page_url,
favicon_bitmap_data.push_back(bitmap_data_element);
}
}
-
history_service_->SetFavicons(page_url, icon_type, favicon_bitmap_data);
}
diff --git a/chrome/browser/history/select_favicon_frames_unittest.cc b/chrome/browser/history/select_favicon_frames_unittest.cc
index 543dc21..822f4fa 100644
--- a/chrome/browser/history/select_favicon_frames_unittest.cc
+++ b/chrome/browser/history/select_favicon_frames_unittest.cc
@@ -7,22 +7,30 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/layout.h"
#include "ui/gfx/image/image_skia.h"
using std::vector;
namespace {
-vector<float> FaviconScale1x() {
- return vector<float>(1, 1.0f);
-}
+const ui::ScaleFactor FaviconScaleFactor1x[] = {
+ ui::SCALE_FACTOR_100P,
+};
-vector<float> FaviconScale1x2x() {
- vector<float> scales;
- scales.push_back(1.0f);
- scales.push_back(2.0f);
- return scales;
-}
+const ui::ScaleFactor FaviconScaleFactor1xAnd2x[] = {
+ ui::SCALE_FACTOR_100P,
+ ui::SCALE_FACTOR_200P,
+};
+
+#define SCOPED_FAVICON_SCALE_FACTOR(list) \
+ ui::test::ScopedSetSupportedScaleFactors scoped( \
+ std::vector<ui::ScaleFactor>(list, list + arraysize(list)))
+
+#define SCOPED_FAVICON_SCALE_FACTOR_1X \
+ SCOPED_FAVICON_SCALE_FACTOR(FaviconScaleFactor1x)
+#define SCOPED_FAVICON_SCALE_FACTOR_1XAND2X \
+ SCOPED_FAVICON_SCALE_FACTOR(FaviconScaleFactor1xAnd2x)
// Return gfx::Size vector with the pixel sizes of |bitmaps|.
vector<gfx::Size> SizesFromBitmaps(const vector<SkBitmap>& bitmaps) {
@@ -68,8 +76,8 @@ TEST(SelectFaviconFramesTest, ZeroSizePicksLargest) {
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 48, 48));
bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 32, 32));
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x(), 0, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 0, NULL);
EXPECT_EQ(1u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
EXPECT_EQ(48, image.width());
@@ -79,28 +87,44 @@ TEST(SelectFaviconFramesTest, ZeroSizePicksLargest) {
}
TEST(SelectFaviconFramesTest, _16From16) {
+ SCOPED_FAVICON_SCALE_FACTOR_1X;
+
vector<SkBitmap> bitmaps;
bitmaps.push_back(MakeBitmap(SK_ColorRED, 15, 15));
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16));
bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 17, 17));
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x(), 16, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 16, NULL);
+ image.EnsureRepsForSupportedScales();
EXPECT_EQ(1u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
EXPECT_EQ(16, image.width());
EXPECT_EQ(16, image.height());
EXPECT_EQ(SK_ColorGREEN, GetColor1x(image));
+
+#if !defined(OS_IOS)
+ const gfx::ImageSkiaRep& rep = image.GetRepresentation(1.5f);
+ EXPECT_EQ(1.5f, rep.scale());
+ EXPECT_EQ(16, rep.GetWidth());
+ EXPECT_EQ(16, rep.GetHeight());
+ EXPECT_EQ(24, rep.pixel_width());
+ EXPECT_EQ(24, rep.pixel_height());
+ EXPECT_EQ(2u, image.image_reps().size());
+#endif
}
TEST(SelectFaviconFramesTest, _16From17) {
+ SCOPED_FAVICON_SCALE_FACTOR_1X;
+
vector<SkBitmap> bitmaps;
bitmaps.push_back(MakeBitmap(SK_ColorRED, 15, 15));
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 17, 17));
// Should resample from the bigger candidate.
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x(), 16, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 16, NULL);
+ image.EnsureRepsForSupportedScales();
EXPECT_EQ(1u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
EXPECT_EQ(16, image.width());
@@ -109,14 +133,17 @@ TEST(SelectFaviconFramesTest, _16From17) {
}
TEST(SelectFaviconFramesTest, _16From15) {
+ SCOPED_FAVICON_SCALE_FACTOR_1X;
+
vector<SkBitmap> bitmaps;
bitmaps.push_back(MakeBitmap(SK_ColorRED, 14, 14));
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 15, 15));
// If nothing else is available, should resample from the next smaller
// candidate.
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x(), 16, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 16, NULL);
+ image.EnsureRepsForSupportedScales();
EXPECT_EQ(1u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
EXPECT_EQ(16, image.width());
@@ -125,11 +152,13 @@ TEST(SelectFaviconFramesTest, _16From15) {
}
TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_16) {
+ SCOPED_FAVICON_SCALE_FACTOR_1XAND2X;
vector<SkBitmap> bitmaps;
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16));
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x2x(), 16, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 16, NULL);
+ image.EnsureRepsForSupportedScales();
EXPECT_EQ(2u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
ASSERT_TRUE(image.HasRepresentation(2.0f));
@@ -140,12 +169,15 @@ TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_16) {
}
TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_32) {
+ SCOPED_FAVICON_SCALE_FACTOR_1XAND2X;
+
vector<SkBitmap> bitmaps;
bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16));
bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 32, 32));
- gfx::ImageSkia image = SelectFaviconFrames(bitmaps,
- SizesFromBitmaps(bitmaps), FaviconScale1x2x(), 16, NULL);
+ gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps,
+ SizesFromBitmaps(bitmaps), 16, NULL);
+ image.EnsureRepsForSupportedScales();
EXPECT_EQ(2u, image.image_reps().size());
ASSERT_TRUE(image.HasRepresentation(1.0f));
ASSERT_TRUE(image.HasRepresentation(2.0f));
@@ -153,21 +185,32 @@ TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_32) {
EXPECT_EQ(16, image.height());
EXPECT_EQ(SK_ColorGREEN, GetColor1x(image));
EXPECT_EQ(SK_ColorBLUE, GetColor2x(image));
+
+#if !defined(OS_IOS)
+ const gfx::ImageSkiaRep& rep = image.GetRepresentation(1.5f);
+ EXPECT_EQ(1.5f, rep.scale());
+ EXPECT_EQ(16, rep.GetWidth());
+ EXPECT_EQ(16, rep.GetHeight());
+ EXPECT_EQ(24, rep.pixel_width());
+ EXPECT_EQ(24, rep.pixel_height());
+ EXPECT_EQ(3u, image.image_reps().size());
+#endif
}
TEST(SelectFaviconFramesTest, ExactMatchBetterThanLargeBitmap) {
float score1;
vector<SkBitmap> bitmaps1;
bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 48, 48));
- SelectFaviconFrames(bitmaps1,
- SizesFromBitmaps(bitmaps1), FaviconScale1x2x(), 16, &score1);
+ CreateFaviconImageSkia(
+ bitmaps1,
+ SizesFromBitmaps(bitmaps1), 16, &score1);
float score2;
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 16, 16));
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 32, 32));
- SelectFaviconFrames(bitmaps2,
- SizesFromBitmaps(bitmaps2), FaviconScale1x2x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2,
+ SizesFromBitmaps(bitmaps2), 16, &score2);
EXPECT_GT(score2, score1);
}
@@ -176,26 +219,26 @@ TEST(SelectFaviconFramesTest, UpsampleABitBetterThanHugeBitmap) {
float score1;
vector<SkBitmap> bitmaps1;
bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 128, 128));
- SelectFaviconFrames(bitmaps1,
- SizesFromBitmaps(bitmaps1), FaviconScale1x2x(), 16, &score1);
+ CreateFaviconImageSkia(bitmaps1,
+ SizesFromBitmaps(bitmaps1), 16, &score1);
float score2;
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 24, 24));
- SelectFaviconFrames(bitmaps2,
- SizesFromBitmaps(bitmaps2), FaviconScale1x2x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2,
+ SizesFromBitmaps(bitmaps2), 16, &score2);
float score3;
vector<SkBitmap> bitmaps3;
bitmaps3.push_back(MakeBitmap(SK_ColorGREEN, 16, 16));
- SelectFaviconFrames(bitmaps3,
- SizesFromBitmaps(bitmaps3), FaviconScale1x2x(), 16, &score3);
+ CreateFaviconImageSkia(bitmaps3,
+ SizesFromBitmaps(bitmaps3), 16, &score3);
float score4;
vector<SkBitmap> bitmaps4;
bitmaps4.push_back(MakeBitmap(SK_ColorGREEN, 15, 15));
- SelectFaviconFrames(bitmaps4,
- SizesFromBitmaps(bitmaps4), FaviconScale1x2x(), 16, &score4);
+ CreateFaviconImageSkia(bitmaps4,
+ SizesFromBitmaps(bitmaps4), 16, &score4);
EXPECT_GT(score2, score1);
EXPECT_GT(score3, score1);
@@ -206,14 +249,14 @@ TEST(SelectFaviconFramesTest, DownsamplingBetterThanUpsampling) {
float score1;
vector<SkBitmap> bitmaps1;
bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 8, 8));
- SelectFaviconFrames(bitmaps1,
- SizesFromBitmaps(bitmaps1), FaviconScale1x(), 16, &score1);
+ CreateFaviconImageSkia(bitmaps1,
+ SizesFromBitmaps(bitmaps1), 16, &score1);
float score2;
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 24, 24));
- SelectFaviconFrames(bitmaps2,
- SizesFromBitmaps(bitmaps2), FaviconScale1x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2,
+ SizesFromBitmaps(bitmaps2), 16, &score2);
EXPECT_GT(score2, score1);
}
@@ -222,14 +265,14 @@ TEST(SelectFaviconFramesTest, DownsamplingLessIsBetter) {
float score1;
vector<SkBitmap> bitmaps1;
bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 34, 34));
- SelectFaviconFrames(bitmaps1,
- SizesFromBitmaps(bitmaps1), FaviconScale1x2x(), 16, &score1);
+ CreateFaviconImageSkia(bitmaps1,
+ SizesFromBitmaps(bitmaps1), 16, &score1);
float score2;
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 33, 33));
- SelectFaviconFrames(bitmaps2,
- SizesFromBitmaps(bitmaps2), FaviconScale1x2x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2,
+ SizesFromBitmaps(bitmaps2), 16, &score2);
EXPECT_GT(score2, score1);
}
@@ -238,14 +281,14 @@ TEST(SelectFaviconFramesTest, UpsamplingLessIsBetter) {
float score1;
vector<SkBitmap> bitmaps1;
bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 8, 8));
- SelectFaviconFrames(bitmaps1,
- SizesFromBitmaps(bitmaps1), FaviconScale1x2x(), 16, &score1);
+ CreateFaviconImageSkia(bitmaps1,
+ SizesFromBitmaps(bitmaps1), 16, &score1);
float score2;
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 9, 9));
- SelectFaviconFrames(bitmaps2,
- SizesFromBitmaps(bitmaps2), FaviconScale1x2x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2,
+ SizesFromBitmaps(bitmaps2), 16, &score2);
EXPECT_GT(score2, score1);
}
@@ -258,14 +301,14 @@ TEST(SelectFaviconFramesTest, ScoreDeterminedByOriginalSizes) {
vector<gfx::Size> sizes1;
sizes1.push_back(gfx::Size(256, 256));
float score1;
- SelectFaviconFrames(bitmaps1, sizes1, FaviconScale1x(), 16, &score1);
+ CreateFaviconImageSkia(bitmaps1, sizes1, 16, &score1);
vector<SkBitmap> bitmaps2;
bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 15, 15));
vector<gfx::Size> sizes2;
sizes2.push_back(gfx::Size(15, 15));
float score2;
- SelectFaviconFrames(bitmaps2, sizes2, FaviconScale1x(), 16, &score2);
+ CreateFaviconImageSkia(bitmaps2, sizes2, 16, &score2);
EXPECT_GT(score2, score1);
}
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc
index 550faa4..360c908 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.cc
+++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -495,24 +495,13 @@ void CreateUrlApplicationShortcutView::DidDownloadFavicon(
return;
pending_download_id_ = -1;
- SkBitmap image;
-
- if (!bitmaps.empty()) {
- std::vector<int> requested_sizes_in_pixel;
- float scale = ui::GetScaleFactorForNativeView(
- web_contents_->GetRenderViewHost()->GetView()->GetNativeView());
- requested_sizes_in_pixel.push_back(ceil(requested_size * scale));
- std::vector<size_t> closest_indices;
- SelectFaviconFrameIndices(original_bitmap_sizes,
- requested_sizes_in_pixel,
- &closest_indices,
- NULL);
- size_t closest_index = closest_indices[0];
- image = bitmaps[closest_index];
- }
-
- if (!image.isNull()) {
- shortcut_info_.favicon.Add(gfx::ImageSkia::CreateFrom1xBitmap(image));
+ gfx::ImageSkia image_skia = CreateFaviconImageSkia(
+ bitmaps,
+ original_bitmap_sizes,
+ requested_size,
+ NULL);
+ if (!image_skia.isNull()) {
+ shortcut_info_.favicon.Add(image_skia);
static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
} else {
FetchIcon();
diff --git a/components/favicon_base/select_favicon_frames.cc b/components/favicon_base/select_favicon_frames.cc
index 0315408..3122365 100644
--- a/components/favicon_base/select_favicon_frames.cc
+++ b/components/favicon_base/select_favicon_frames.cc
@@ -10,10 +10,12 @@
#include <map>
#include <set>
+#include "components/favicon_base/favicon_util.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/size.h"
namespace {
@@ -47,13 +49,10 @@ SkBitmap SampleNearestNeighbor(const SkBitmap& contents, int desired_size) {
return bitmap;
}
-enum ResizeMethod { NONE, SAMPLE_NEAREST_NEIGHBOUR, LANCZOS };
-
size_t GetCandidateIndexWithBestScore(
const std::vector<gfx::Size>& candidate_sizes,
int desired_size,
- float* score,
- ResizeMethod* resize_method) {
+ float* score) {
DCHECK_NE(desired_size, 0);
// Try to find an exact match.
@@ -61,7 +60,6 @@ size_t GetCandidateIndexWithBestScore(
if (candidate_sizes[i].width() == desired_size &&
candidate_sizes[i].height() == desired_size) {
*score = 1;
- *resize_method = NONE;
return i;
}
}
@@ -99,17 +97,6 @@ size_t GetCandidateIndexWithBestScore(
}
*score = candidate_score;
- // Integer multiples are built using nearest neighbor sampling. Otherwise,
- // Lanczos scaling is used.
- const gfx::Size& candidate_size = candidate_sizes[candidate_index];
- if (candidate_size.IsEmpty()) {
- *resize_method = NONE;
- } else if (desired_size % candidate_size.width() == 0 &&
- desired_size % candidate_size.height() == 0) {
- *resize_method = SAMPLE_NEAREST_NEIGHBOUR;
- } else {
- *resize_method = LANCZOS;
- }
return candidate_index;
}
@@ -121,10 +108,6 @@ struct SelectionResult {
// The desired size for which |index| is the best candidate.
int desired_size;
-
- // How the bitmap data that the bitmap with |candidate_sizes[index]| should
- // be resized for displaying in the UI.
- ResizeMethod resize_method;
};
void GetCandidateIndicesWithBestScores(
@@ -145,7 +128,6 @@ void GetCandidateIndicesWithBestScores(
SelectionResult result;
result.index = BiggestCandidate(candidate_sizes);
result.desired_size = 0;
- result.resize_method = NONE;
results->push_back(result);
if (match_score)
*match_score = 1.0f;
@@ -158,7 +140,7 @@ void GetCandidateIndicesWithBestScores(
SelectionResult result;
result.desired_size = desired_sizes[i];
result.index = GetCandidateIndexWithBestScore(
- candidate_sizes, result.desired_size, &score, &result.resize_method);
+ candidate_sizes, result.desired_size, &score);
results->push_back(result);
total_score += score;
}
@@ -167,65 +149,111 @@ void GetCandidateIndicesWithBestScores(
*match_score = total_score / desired_sizes.size();
}
-// Resize |source_bitmap| using |resize_method|.
+// Resize |source_bitmap|
SkBitmap GetResizedBitmap(const SkBitmap& source_bitmap,
- int desired_size,
- ResizeMethod resize_method) {
- switch (resize_method) {
- case NONE:
- return source_bitmap;
- case SAMPLE_NEAREST_NEIGHBOUR:
- return SampleNearestNeighbor(source_bitmap, desired_size);
- case LANCZOS:
- return skia::ImageOperations::Resize(
- source_bitmap,
- skia::ImageOperations::RESIZE_LANCZOS3,
- desired_size,
- desired_size);
+ gfx::Size original_size,
+ int desired_size_in_pixel) {
+ if (desired_size_in_pixel == 0 ||
+ (original_size.width() == desired_size_in_pixel &&
+ original_size.height() == desired_size_in_pixel)) {
+ return source_bitmap;
+ }
+ if (desired_size_in_pixel % original_size.width() == 0 &&
+ desired_size_in_pixel % original_size.height() == 0) {
+ return SampleNearestNeighbor(source_bitmap, desired_size_in_pixel);
}
- return source_bitmap;
+ return skia::ImageOperations::Resize(source_bitmap,
+ skia::ImageOperations::RESIZE_LANCZOS3,
+ desired_size_in_pixel,
+ desired_size_in_pixel);
}
+class FaviconImageSource : public gfx::ImageSkiaSource {
+ public:
+ FaviconImageSource() {}
+ virtual ~FaviconImageSource() {}
+
+ // gfx::ImageSkiaSource:
+ virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
+ const gfx::ImageSkiaRep* rep = NULL;
+ // gfx::ImageSkia passes one of the resource scale factors. The source
+ // should return:
+ // 1) The ImageSkiaRep with the highest scale if all available
+ // scales are smaller than |scale|.
+ // 2) The ImageSkiaRep with the smallest one that is larger than |scale|.
+ // Note: Keep this logic consistent with the PNGImageSource in
+ // ui/gfx/image.cc.
+ // TODO(oshima): consolidate these logic into one place.
+ for (std::vector<gfx::ImageSkiaRep>::const_iterator iter =
+ image_skia_reps_.begin();
+ iter != image_skia_reps_.end(); ++iter) {
+ if ((*iter).scale() == scale)
+ return (*iter);
+ if (!rep || rep->scale() < (*iter).scale())
+ rep = &(*iter);
+ if (rep->scale() >= scale)
+ break;
+ }
+ DCHECK(rep);
+ return rep ? *rep : gfx::ImageSkiaRep();
+ }
+
+ void AddImageSkiaRep(const gfx::ImageSkiaRep& rep) {
+ image_skia_reps_.push_back(rep);
+ }
+
+ private:
+ std::vector<gfx::ImageSkiaRep> image_skia_reps_;
+ DISALLOW_COPY_AND_ASSIGN(FaviconImageSource);
+};
+
} // namespace
const float kSelectFaviconFramesInvalidScore = -1.0f;
-gfx::ImageSkia SelectFaviconFrames(const std::vector<SkBitmap>& bitmaps,
- const std::vector<gfx::Size>& original_sizes,
- const std::vector<float>& favicon_scales,
- int desired_size_in_dip,
- float* match_score) {
+gfx::ImageSkia CreateFaviconImageSkia(
+ const std::vector<SkBitmap>& bitmaps,
+ const std::vector<gfx::Size>& original_sizes,
+ int desired_size_in_dip,
+ float* score) {
+
+ const std::vector<float>& favicon_scales = favicon_base::GetFaviconScales();
std::vector<int> desired_sizes;
- std::map<int, float> scale_map;
+
if (desired_size_in_dip == 0) {
desired_sizes.push_back(0);
- scale_map[0] = 1.0f;
} else {
- for (size_t i = 0; i < favicon_scales.size(); ++i) {
- float scale = favicon_scales[i];
- int desired_size = ceil(desired_size_in_dip * scale);
- desired_sizes.push_back(desired_size);
- scale_map[desired_size] = scale;
+ for (std::vector<float>::const_iterator iter = favicon_scales.begin();
+ iter != favicon_scales.end(); ++iter) {
+ desired_sizes.push_back(ceil(desired_size_in_dip * (*iter)));
}
}
std::vector<SelectionResult> results;
- GetCandidateIndicesWithBestScores(
- original_sizes, desired_sizes, match_score, &results);
+ GetCandidateIndicesWithBestScores(original_sizes,
+ desired_sizes,
+ score,
+ &results);
+ if (results.size() == 0)
+ return gfx::ImageSkia();
+
+ if (desired_size_in_dip == 0) {
+ size_t index = results[0].index;
+ return gfx::ImageSkia(gfx::ImageSkiaRep(bitmaps[index], 1.0f));
+ }
+
+ FaviconImageSource* image_source = new FaviconImageSource;
- gfx::ImageSkia multi_image;
for (size_t i = 0; i < results.size(); ++i) {
- const SelectionResult& result = results[i];
- SkBitmap resized_bitmap = GetResizedBitmap(
- bitmaps[result.index], result.desired_size, result.resize_method);
-
- std::map<int, float>::const_iterator it =
- scale_map.find(result.desired_size);
- DCHECK(it != scale_map.end());
- float scale = it->second;
- multi_image.AddRepresentation(gfx::ImageSkiaRep(resized_bitmap, scale));
+ size_t index = results[i].index;
+ image_source->AddImageSkiaRep(
+ gfx::ImageSkiaRep(GetResizedBitmap(bitmaps[index],
+ original_sizes[index],
+ desired_sizes[i]),
+ favicon_scales[i]));
}
- return multi_image;
+ return gfx::ImageSkia(image_source,
+ gfx::Size(desired_size_in_dip, desired_size_in_dip));
}
void SelectFaviconFrameIndices(const std::vector<gfx::Size>& frame_pixel_sizes,
diff --git a/components/favicon_base/select_favicon_frames.h b/components/favicon_base/select_favicon_frames.h
index 9c1b80e..81d39d85 100644
--- a/components/favicon_base/select_favicon_frames.h
+++ b/components/favicon_base/select_favicon_frames.h
@@ -21,8 +21,9 @@ class Size;
extern const float kSelectFaviconFramesInvalidScore;
// Takes a list of all bitmaps found in a .ico file, and creates an
-// ImageSkia that's |desired_size_in_dip| x |desired_size_in_dip| big. This
-// function adds a representation at every entry in |favicon_scales|.
+// ImageSkia that's |desired_size_in_dip| x |desired_size_in_dip| big.
+// Bitmaps are selected by using |SelectFaviconFrameIndices| and the
+// platform's supported favicon scales (favicon_base::GetFaviconScales()).
// If |desired_size_in_dip| is 0, the largest bitmap is returned unmodified.
// |original_sizes| are the original sizes of the bitmaps. (For instance,
// WebContents::DownloadImage() does resampling if it is passed a max size.)
@@ -34,11 +35,13 @@ extern const float kSelectFaviconFramesInvalidScore;
// If the resampling algorithm is modified, the resampling done in
// FaviconUtil::SelectFaviconFramesFromPNGs() should probably be modified too as
// it inspired by this method.
-gfx::ImageSkia SelectFaviconFrames(const std::vector<SkBitmap>& bitmaps,
- const std::vector<gfx::Size>& original_sizes,
- const std::vector<float>& favicon_scales,
- int desired_size_in_dip,
- float* score);
+// If an unsupported scale (not in the favicon_base::GetFaviconScales())
+// is requested, the ImageSkia will automatically scales using lancoz3.
+gfx::ImageSkia CreateFaviconImageSkia(
+ const std::vector<SkBitmap>& bitmaps,
+ const std::vector<gfx::Size>& original_sizes,
+ int desired_size_in_dip,
+ float* score);
// Takes a list of the pixel sizes of a favicon's favicon bitmaps and returns
// the indices of the best sizes to use to create an ImageSkia with