| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/history/select_favicon_frames.h" | 5 #include "chrome/browser/history/select_favicon_frames.h" |
| 6 | 6 |
| 7 #include "skia/ext/image_operations.h" | 7 #include "skia/ext/image_operations.h" |
| 8 #include "third_party/skia/include/core/SkCanvas.h" | 8 #include "third_party/skia/include/core/SkCanvas.h" |
| 9 #include "ui/gfx/image/image.h" | 9 #include "ui/gfx/image/image.h" |
| 10 #include "ui/gfx/image/image_skia.h" | 10 #include "ui/gfx/image/image_skia.h" |
| 11 #include "ui/gfx/size.h" | 11 #include "ui/gfx/size.h" |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 // Return gfx::Size vector with the pixel sizes of |bitmaps|. |
| 15 void SizesFromBitmaps(const std::vector<SkBitmap>& bitmaps, | 16 void SizesFromBitmaps(const std::vector<SkBitmap>& bitmaps, |
| 16 std::vector<gfx::Size>* sizes) { | 17 std::vector<gfx::Size>* sizes) { |
| 17 for (size_t i = 0; i < bitmaps.size(); ++i) | 18 for (size_t i = 0; i < bitmaps.size(); ++i) |
| 18 sizes->push_back(gfx::Size(bitmaps[i].width(), bitmaps[i].height())); | 19 sizes->push_back(gfx::Size(bitmaps[i].width(), bitmaps[i].height())); |
| 19 } | 20 } |
| 20 | 21 |
| 22 // Return gfx::Size vector with the pixel sizes of |bitmap_id_sizes|. |
| 23 void SizesFromFaviconBitmapIDSizes( |
| 24 const std::vector<history::FaviconBitmapIDSize>& bitmap_id_sizes, |
| 25 std::vector<gfx::Size>* sizes) { |
| 26 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) |
| 27 sizes->push_back(bitmap_id_sizes[i].pixel_size); |
| 28 } |
| 29 |
| 21 size_t BiggestCandidate(const std::vector<gfx::Size>& candidate_sizes) { | 30 size_t BiggestCandidate(const std::vector<gfx::Size>& candidate_sizes) { |
| 22 size_t max_index = 0; | 31 size_t max_index = 0; |
| 23 int max_area = candidate_sizes[0].GetArea(); | 32 int max_area = candidate_sizes[0].GetArea(); |
| 24 for (size_t i = 1; i < candidate_sizes.size(); ++i) { | 33 for (size_t i = 1; i < candidate_sizes.size(); ++i) { |
| 25 int area = candidate_sizes[i].GetArea(); | 34 int area = candidate_sizes[i].GetArea(); |
| 26 if (area > max_area) { | 35 if (area > max_area) { |
| 27 max_area = area; | 36 max_area = area; |
| 28 max_index = i; | 37 max_index = i; |
| 29 } | 38 } |
| 30 } | 39 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 } | 141 } |
| 133 } | 142 } |
| 134 *score = 0.1f; | 143 *score = 0.1f; |
| 135 // c) Else, from the biggest smaller variant. | 144 // c) Else, from the biggest smaller variant. |
| 136 if (candidate_index == -1) { | 145 if (candidate_index == -1) { |
| 137 *score = 0; | 146 *score = 0; |
| 138 candidate_index = BiggestCandidate(candidate_sizes); | 147 candidate_index = BiggestCandidate(candidate_sizes); |
| 139 } | 148 } |
| 140 | 149 |
| 141 const gfx::Size& candidate_size = candidate_sizes[candidate_index]; | 150 const gfx::Size& candidate_size = candidate_sizes[candidate_index]; |
| 142 bool is_integer_multiple = desired_size % candidate_size.width() == 0 && | 151 if (candidate_size.IsEmpty()) { |
| 143 desired_size % candidate_size.height() == 0; | 152 *resize_method = NONE; |
| 144 *resize_method = is_integer_multiple ? SAMPLE_NEAREST_NEIGHBOUR : LANCZOS; | 153 } else if (desired_size % candidate_size.width() == 0 && |
| 154 desired_size % candidate_size.height() == 0) { |
| 155 *resize_method = SAMPLE_NEAREST_NEIGHBOUR; |
| 156 } else { |
| 157 *resize_method = LANCZOS; |
| 158 } |
| 145 return candidate_index; | 159 return candidate_index; |
| 146 } | 160 } |
| 147 | 161 |
| 148 // Represents the index of the best candidate for a |scale_factor| from the | 162 // Represents the index of the best candidate for a |scale_factor| from the |
| 149 // |candidate_sizes| passed into GetCandidateIndicesWithBestScores(). | 163 // |candidate_sizes| passed into GetCandidateIndicesWithBestScores(). |
| 150 struct SelectionResult { | 164 struct SelectionResult { |
| 151 // index in |candidate_sizes| of the best candidate. | 165 // index in |candidate_sizes| of the best candidate. |
| 152 size_t index; | 166 size_t index; |
| 153 | 167 |
| 154 // The ScaleFactor for which |index| is the best candidate. | 168 // The ScaleFactor for which |index| is the best candidate. |
| 155 ui::ScaleFactor scale_factor; | 169 ui::ScaleFactor scale_factor; |
| 156 | 170 |
| 157 // How the bitmap data that the bitmap with |candidate_sizes[index]| should | 171 // How the bitmap data that the bitmap with |candidate_sizes[index]| should |
| 158 // be resized for displaying in the UI. | 172 // be resized for displaying in the UI. |
| 159 ResizeMethod resize_method; | 173 ResizeMethod resize_method; |
| 160 }; | 174 }; |
| 161 | 175 |
| 162 void GetCandidateIndicesWithBestScores( | 176 void GetCandidateIndicesWithBestScores( |
| 163 const std::vector<gfx::Size>& candidate_sizes, | 177 const std::vector<gfx::Size>& candidate_sizes, |
| 164 const std::vector<ui::ScaleFactor>& scale_factors, | 178 const std::vector<ui::ScaleFactor>& scale_factors, |
| 165 int desired_size, | 179 int desired_size, |
| 166 float* match_score, | 180 float* match_score, |
| 167 std::vector<SelectionResult>* results) { | 181 std::vector<SelectionResult>* results) { |
| 168 if (candidate_sizes.empty()) | 182 if (candidate_sizes.empty()) { |
| 183 *match_score = 0.0f; |
| 169 return; | 184 return; |
| 185 } |
| 170 | 186 |
| 171 if (desired_size == 0) { | 187 if (desired_size == 0) { |
| 172 // Just return the biggest image available. | 188 // Just return the biggest image available. |
| 173 SelectionResult result; | 189 SelectionResult result; |
| 174 result.index = BiggestCandidate(candidate_sizes); | 190 result.index = BiggestCandidate(candidate_sizes); |
| 175 result.scale_factor = ui::SCALE_FACTOR_100P; | 191 result.scale_factor = ui::SCALE_FACTOR_100P; |
| 176 result.resize_method = NONE; | 192 result.resize_method = NONE; |
| 177 results->push_back(result); | 193 results->push_back(result); |
| 178 if (match_score) | 194 if (match_score) |
| 179 *match_score = 0.8f; | 195 *match_score = 0.8f; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 case LANCZOS: | 233 case LANCZOS: |
| 218 return skia::ImageOperations::Resize( | 234 return skia::ImageOperations::Resize( |
| 219 source_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, | 235 source_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, |
| 220 desired_size_in_pixel, desired_size_in_pixel); | 236 desired_size_in_pixel, desired_size_in_pixel); |
| 221 } | 237 } |
| 222 return source_bitmap; | 238 return source_bitmap; |
| 223 } | 239 } |
| 224 | 240 |
| 225 } // namespace | 241 } // namespace |
| 226 | 242 |
| 243 const float kSelectFaviconFramesInvalidScore = -1.0f; |
| 244 |
| 227 gfx::ImageSkia SelectFaviconFrames( | 245 gfx::ImageSkia SelectFaviconFrames( |
| 228 const std::vector<SkBitmap>& bitmaps, | 246 const std::vector<SkBitmap>& bitmaps, |
| 229 const std::vector<ui::ScaleFactor>& scale_factors, | 247 const std::vector<ui::ScaleFactor>& scale_factors, |
| 230 int desired_size, | 248 int desired_size, |
| 231 float* match_score) { | 249 float* match_score) { |
| 232 std::vector<gfx::Size> candidate_sizes; | 250 std::vector<gfx::Size> candidate_sizes; |
| 233 SizesFromBitmaps(bitmaps, &candidate_sizes); | 251 SizesFromBitmaps(bitmaps, &candidate_sizes); |
| 234 | 252 |
| 235 std::vector<SelectionResult> results; | 253 std::vector<SelectionResult> results; |
| 236 GetCandidateIndicesWithBestScores(candidate_sizes, scale_factors, | 254 GetCandidateIndicesWithBestScores(candidate_sizes, scale_factors, |
| 237 desired_size, match_score, &results); | 255 desired_size, match_score, &results); |
| 238 | 256 |
| 239 gfx::ImageSkia multi_image; | 257 gfx::ImageSkia multi_image; |
| 240 for (size_t i = 0; i < results.size(); ++i) { | 258 for (size_t i = 0; i < results.size(); ++i) { |
| 241 const SelectionResult& result = results[i]; | 259 const SelectionResult& result = results[i]; |
| 242 SkBitmap resized_bitmap = GetResizedBitmap(bitmaps[result.index], | 260 SkBitmap resized_bitmap = GetResizedBitmap(bitmaps[result.index], |
| 243 desired_size, result.scale_factor, result.resize_method); | 261 desired_size, result.scale_factor, result.resize_method); |
| 244 multi_image.AddRepresentation( | 262 multi_image.AddRepresentation( |
| 245 gfx::ImageSkiaRep(resized_bitmap, result.scale_factor)); | 263 gfx::ImageSkiaRep(resized_bitmap, result.scale_factor)); |
| 246 } | 264 } |
| 247 return multi_image; | 265 return multi_image; |
| 248 } | 266 } |
| 267 |
| 268 void SelectFaviconBitmapIDs( |
| 269 const std::vector<history::FaviconBitmapIDSize>& bitmap_id_sizes, |
| 270 const std::vector<ui::ScaleFactor>& scale_factors, |
| 271 int desired_size, |
| 272 std::vector<history::FaviconBitmapID>* filtered_favicon_bitmap_ids, |
| 273 float* match_score) { |
| 274 std::vector<gfx::Size> candidate_sizes; |
| 275 SizesFromFaviconBitmapIDSizes(bitmap_id_sizes, &candidate_sizes); |
| 276 |
| 277 std::vector<SelectionResult> results; |
| 278 GetCandidateIndicesWithBestScores(candidate_sizes, scale_factors, |
| 279 desired_size, match_score, &results); |
| 280 |
| 281 std::set<history::FaviconBitmapID> already_added; |
| 282 for (size_t i = 0; i < results.size(); ++i) { |
| 283 const SelectionResult& result = results[i]; |
| 284 history::FaviconBitmapID bitmap_id = |
| 285 bitmap_id_sizes[result.index].bitmap_id; |
| 286 |
| 287 // GetCandidateIndicesWithBestScores() will return duplicate indices if the |
| 288 // bitmap data for a |bitmap_id| should be used for multiple scale factors. |
| 289 // Remove duplicates here such that |filtered_favicon_bitmap_ids| contains |
| 290 // no duplicates. |
| 291 if (already_added.find(bitmap_id) == already_added.end()) { |
| 292 already_added.insert(bitmap_id); |
| 293 filtered_favicon_bitmap_ids->push_back(bitmap_id); |
| 294 } |
| 295 } |
| 296 } |
| OLD | NEW |