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/themes/browser_theme_pack.h" | 5 #include "chrome/browser/themes/browser_theme_pack.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/memory/ref_counted_memory.h" | 9 #include "base/memory/ref_counted_memory.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "base/values.h" | 15 #include "base/values.h" |
16 #include "chrome/browser/themes/theme_service.h" | 16 #include "chrome/browser/themes/theme_service.h" |
17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
18 #include "grit/theme_resources.h" | 18 #include "grit/theme_resources.h" |
19 #include "grit/ui_resources.h" | 19 #include "grit/ui_resources.h" |
20 #include "net/base/file_stream.h" | 20 #include "net/base/file_stream.h" |
21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
22 #include "third_party/skia/include/core/SkCanvas.h" | 22 #include "third_party/skia/include/core/SkCanvas.h" |
23 #include "ui/base/resource/data_pack.h" | 23 #include "ui/base/resource/data_pack.h" |
24 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
25 #include "ui/gfx/canvas.h" | 25 #include "ui/gfx/canvas.h" |
26 #include "ui/gfx/codec/png_codec.h" | 26 #include "ui/gfx/codec/png_codec.h" |
| 27 #include "ui/gfx/image/canvas_image_source.h" |
27 #include "ui/gfx/image/image.h" | 28 #include "ui/gfx/image/image.h" |
28 #include "ui/gfx/image/image_skia.h" | 29 #include "ui/gfx/image/image_skia.h" |
29 #include "ui/gfx/skbitmap_operations.h" | 30 #include "ui/gfx/image/image_skia_operations.h" |
| 31 #include "ui/gfx/screen.h" |
30 | 32 |
31 using content::BrowserThread; | 33 using content::BrowserThread; |
32 using extensions::Extension; | 34 using extensions::Extension; |
33 | 35 |
34 namespace { | 36 namespace { |
35 | 37 |
36 // Version number of the current theme pack. We just throw out and rebuild | 38 // Version number of the current theme pack. We just throw out and rebuild |
37 // theme packs that aren't int-equal to this. Increment this number if you | 39 // theme packs that aren't int-equal to this. Increment this number if you |
38 // change default theme assets. | 40 // change default theme assets. |
39 const int kThemePackVersion = 24; | 41 const int kThemePackVersion = 24; |
40 | 42 |
41 // IDs that are in the DataPack won't clash with the positive integer | 43 // IDs that are in the DataPack won't clash with the positive integer |
42 // uint16. kHeaderID should always have the maximum value because we want the | 44 // uint16. kHeaderID should always have the maximum value because we want the |
43 // "header" to be written last. That way we can detect whether the pack was | 45 // "header" to be written last. That way we can detect whether the pack was |
44 // successfully written and ignore and regenerate if it was only partially | 46 // successfully written and ignore and regenerate if it was only partially |
45 // written (i.e. chrome crashed on a different thread while writing the pack). | 47 // written (i.e. chrome crashed on a different thread while writing the pack). |
46 const int kMaxID = 0x0000FFFF; // Max unsigned 16-bit int. | 48 const int kMaxID = 0x0000FFFF; // Max unsigned 16-bit int. |
47 const int kHeaderID = kMaxID - 1; | 49 const int kHeaderID = kMaxID - 1; |
48 const int kTintsID = kMaxID - 2; | 50 const int kTintsID = kMaxID - 2; |
49 const int kColorsID = kMaxID - 3; | 51 const int kColorsID = kMaxID - 3; |
50 const int kDisplayPropertiesID = kMaxID - 4; | 52 const int kDisplayPropertiesID = kMaxID - 4; |
51 const int kSourceImagesID = kMaxID - 5; | 53 const int kSourceImagesID = kMaxID - 5; |
| 54 const int kScaleFactorsID = kMaxID - 6; |
52 | 55 |
53 // Static size of the tint/color/display property arrays that are mmapped. | 56 // Static size of the tint/color/display property arrays that are mmapped. |
54 const int kTintArraySize = 6; | 57 const int kTintArraySize = 6; |
55 const int kColorArraySize = 19; | 58 const int kColorArraySize = 19; |
56 const int kDisplayPropertySize = 3; | 59 const int kDisplayPropertySize = 3; |
57 | 60 |
58 // The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from | 61 // The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from |
59 // OpaqueBrowserFrameView. | 62 // OpaqueBrowserFrameView. |
60 const int kRestoredTabVerticalOffset = 15; | 63 const int kRestoredTabVerticalOffset = 15; |
61 | 64 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, | 153 { 37, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, |
151 { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, | 154 { 38, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, |
152 { 39, IDR_TOOLS, NULL }, | 155 { 39, IDR_TOOLS, NULL }, |
153 { 40, IDR_TOOLS_H, NULL }, | 156 { 40, IDR_TOOLS_H, NULL }, |
154 { 41, IDR_TOOLS_P, NULL }, | 157 { 41, IDR_TOOLS_P, NULL }, |
155 { 42, IDR_MENU_DROPARROW, NULL }, | 158 { 42, IDR_MENU_DROPARROW, NULL }, |
156 { 43, IDR_THROBBER, NULL }, | 159 { 43, IDR_THROBBER, NULL }, |
157 { 44, IDR_THROBBER_WAITING, NULL }, | 160 { 44, IDR_THROBBER_WAITING, NULL }, |
158 { 45, IDR_THROBBER_LIGHT, NULL }, | 161 { 45, IDR_THROBBER_LIGHT, NULL }, |
159 }; | 162 }; |
| 163 size_t kPersistingImagesLength = arraysize(kPersistingImages); |
160 | 164 |
161 int GetPersistentIDByName(const std::string& key) { | 165 int GetPersistentIDByName(const std::string& key) { |
162 for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { | 166 for (size_t i = 0; i < kPersistingImagesLength; ++i) { |
163 if (kPersistingImages[i].key != NULL && | 167 if (kPersistingImages[i].key != NULL && |
164 base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) { | 168 base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) { |
165 return kPersistingImages[i].persistent_id; | 169 return kPersistingImages[i].persistent_id; |
166 } | 170 } |
167 } | 171 } |
168 | 172 |
169 return -1; | 173 return -1; |
170 } | 174 } |
171 | 175 |
172 int GetPersistentIDByIDR(int idr) { | 176 int GetPersistentIDByIDR(int idr) { |
173 for (size_t i = 0; i < arraysize(kPersistingImages); ++i) { | 177 static std::map<int,int>* lookup_table = new std::map<int,int>(); |
174 if (kPersistingImages[i].idr_id == idr) { | 178 if (lookup_table->empty()) { |
175 return kPersistingImages[i].persistent_id; | 179 for (size_t i = 0; i < kPersistingImagesLength; ++i) { |
| 180 int idr = kPersistingImages[i].idr_id; |
| 181 int prs_id = kPersistingImages[i].persistent_id; |
| 182 (*lookup_table)[idr] = prs_id; |
176 } | 183 } |
177 } | 184 } |
| 185 std::map<int,int>::iterator it = lookup_table->find(idr); |
| 186 return (it == lookup_table->end()) ? -1 : it->second; |
| 187 } |
178 | 188 |
179 return -1; | 189 // Returns true if the scales in |input| match those in |expected|. |
| 190 // The order must match as the index is used in determining the raw id. |
| 191 bool InputScalesValid(const char* input, |
| 192 const std::vector<ui::ScaleFactor>& expected) { |
| 193 const float* scales = reinterpret_cast<const float*>(input); |
| 194 size_t index = 0; |
| 195 for (const float* end = scales; *end != -1.0f; ++end) { |
| 196 if (index >= expected.size()) |
| 197 return false; |
| 198 if (*end != ui::GetScaleFactorScale(expected[index])) |
| 199 return false; |
| 200 index++; |
| 201 } |
| 202 return (index == expected.size()); |
| 203 } |
| 204 |
| 205 // Returns |scale_factors| as a string to be written to disk. |
| 206 base::StringPiece GetScaleFactorsAsString( |
| 207 const std::vector<ui::ScaleFactor>& scale_factors) { |
| 208 size_t scales_size = scale_factors.size() + 1; |
| 209 float* scales = new float[scales_size]; |
| 210 for (size_t i = 0; i < scale_factors.size(); ++i) |
| 211 scales[i] = ui::GetScaleFactorScale(scale_factors[i]); |
| 212 scales[scales_size - 1] = -1.0f; |
| 213 base::StringPiece out_string = base::StringPiece( |
| 214 reinterpret_cast<const char*>(&scales), |
| 215 scales_size * sizeof(float)); |
| 216 delete[] scales; |
| 217 return out_string; |
180 } | 218 } |
181 | 219 |
182 struct StringToIntTable { | 220 struct StringToIntTable { |
183 const char* key; | 221 const char* key; |
184 int id; | 222 int id; |
185 }; | 223 }; |
186 | 224 |
187 // Strings used by themes to identify tints in the JSON. | 225 // Strings used by themes to identify tints in the JSON. |
188 StringToIntTable kTintTable[] = { | 226 StringToIntTable kTintTable[] = { |
189 { "buttons", ThemeService::TINT_BUTTONS }, | 227 { "buttons", ThemeService::TINT_BUTTONS }, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 char* data = reinterpret_cast<char*>(&(raw_data.front())); | 339 char* data = reinterpret_cast<char*>(&(raw_data.front())); |
302 if (file.ReadUntilComplete(data, size) == avail) | 340 if (file.ReadUntilComplete(data, size) == avail) |
303 return base::RefCountedBytes::TakeVector(&raw_data); | 341 return base::RefCountedBytes::TakeVector(&raw_data); |
304 } | 342 } |
305 } | 343 } |
306 } | 344 } |
307 | 345 |
308 return NULL; | 346 return NULL; |
309 } | 347 } |
310 | 348 |
311 // Shifts a bitmap's HSL values. The caller is responsible for deleting | 349 // Shifts an image's HSL values. The caller is responsible for deleting |
312 // the returned image. | 350 // the returned image. |
313 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, | 351 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, |
314 const color_utils::HSL& hsl_shift) { | 352 const color_utils::HSL& hsl_shift) { |
315 const gfx::ImageSkia* src_image = image.ToImageSkia(); | 353 const gfx::ImageSkia* src_image = image.ToImageSkia(); |
316 std::vector<gfx::ImageSkiaRep> src_image_reps = src_image->image_reps(); | 354 return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( |
317 gfx::ImageSkia dst_image; | 355 *src_image, hsl_shift)); |
318 for (size_t i = 0; i < src_image_reps.size(); ++i) { | 356 } |
319 const gfx::ImageSkiaRep& image_rep = src_image_reps[i]; | 357 |
320 SkBitmap dst_bitmap = SkBitmapOperations::CreateHSLShiftedBitmap( | 358 class TabBackgroundImageSource: public gfx::CanvasImageSource { |
321 image_rep.sk_bitmap(), hsl_shift); | 359 public: |
322 dst_image.AddRepresentation(gfx::ImageSkiaRep(dst_bitmap, | 360 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, |
323 image_rep.scale_factor())); | 361 const gfx::ImageSkia& overlay, |
| 362 const color_utils::HSL& hsl_shift, |
| 363 int vertical_offset) |
| 364 : gfx::CanvasImageSource(image_to_tint.size(), false), |
| 365 image_to_tint_(image_to_tint), |
| 366 overlay_(overlay), |
| 367 hsl_shift_(hsl_shift), |
| 368 vertical_offset_(vertical_offset) { |
324 } | 369 } |
325 return new gfx::Image(dst_image); | 370 |
326 } | 371 virtual ~TabBackgroundImageSource() { |
| 372 } |
| 373 |
| 374 // Overridden from CanvasImageSource: |
| 375 virtual void Draw(gfx::Canvas* canvas) OVERRIDE { |
| 376 gfx::ImageSkia bg_tint = |
| 377 gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_, |
| 378 hsl_shift_); |
| 379 canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0, |
| 380 size().width(), size().height()); |
| 381 |
| 382 // If they've provided a custom image, overlay it. |
| 383 if (!overlay_.isNull()) { |
| 384 canvas->TileImageInt(overlay_, 0, 0, size().width(), |
| 385 overlay_.height()); |
| 386 } |
| 387 } |
| 388 |
| 389 private: |
| 390 const gfx::ImageSkia image_to_tint_; |
| 391 const gfx::ImageSkia overlay_; |
| 392 const color_utils::HSL hsl_shift_; |
| 393 const int vertical_offset_; |
| 394 |
| 395 DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource); |
| 396 }; |
327 | 397 |
328 } // namespace | 398 } // namespace |
329 | 399 |
330 BrowserThemePack::~BrowserThemePack() { | 400 BrowserThemePack::~BrowserThemePack() { |
331 if (!data_pack_.get()) { | 401 if (!data_pack_.get()) { |
332 delete header_; | 402 delete header_; |
333 delete [] tints_; | 403 delete [] tints_; |
334 delete [] colors_; | 404 delete [] colors_; |
335 delete [] display_properties_; | 405 delete [] display_properties_; |
336 delete [] source_images_; | 406 delete [] source_images_; |
337 } | 407 } |
338 | 408 |
339 STLDeleteValues(&prepared_images_); | 409 STLDeleteValues(&images_on_ui_thread_); |
340 STLDeleteValues(&loaded_images_); | 410 STLDeleteValues(&images_on_file_thread_); |
341 } | 411 } |
342 | 412 |
343 // static | 413 // static |
344 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( | 414 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( |
345 const Extension* extension) { | 415 const Extension* extension) { |
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
347 DCHECK(extension); | 417 DCHECK(extension); |
348 DCHECK(extension->is_theme()); | 418 DCHECK(extension->is_theme()); |
349 | 419 |
350 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); | 420 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); |
351 pack->BuildHeader(extension); | 421 pack->BuildHeader(extension); |
352 pack->BuildTintsFromJSON(extension->GetThemeTints()); | 422 pack->BuildTintsFromJSON(extension->GetThemeTints()); |
353 pack->BuildColorsFromJSON(extension->GetThemeColors()); | 423 pack->BuildColorsFromJSON(extension->GetThemeColors()); |
354 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); | 424 pack->BuildDisplayPropertiesFromJSON(extension->GetThemeDisplayProperties()); |
355 | 425 |
356 // Builds the images. (Image building is dependent on tints). | 426 // Builds the images. (Image building is dependent on tints). |
357 FilePathMap file_paths; | 427 FilePathMap file_paths; |
358 pack->ParseImageNamesFromJSON(extension->GetThemeImages(), | 428 pack->ParseImageNamesFromJSON(extension->GetThemeImages(), |
359 extension->path(), | 429 extension->path(), |
360 &file_paths); | 430 &file_paths); |
361 pack->BuildSourceImagesArray(file_paths); | 431 pack->BuildSourceImagesArray(file_paths); |
362 | 432 |
363 if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_)) | 433 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) |
364 return NULL; | 434 return NULL; |
365 | 435 |
366 pack->GenerateFrameImages(&pack->prepared_images_); | 436 pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_); |
367 | 437 |
368 pack->GenerateTintedButtons( | 438 pack->CreateImages(&pack->images_on_ui_thread_); |
369 pack->GetTintInternal(ThemeService::TINT_BUTTONS), | 439 pack->CreateImages(&pack->images_on_file_thread_); |
370 &pack->prepared_images_); | |
371 | 440 |
372 pack->GenerateTabBackgroundImages(&pack->prepared_images_); | 441 // For M22, as it is not possible to easily determine which scale factors are |
| 442 // in use, assume that the 1x scale factor is in use. |
| 443 std::vector<ui::ScaleFactor> scale_factors_in_use; |
| 444 scale_factors_in_use.push_back(ui::SCALE_FACTOR_100P); |
| 445 pack->GenerateImageReps(scale_factors_in_use); |
373 | 446 |
374 // The BrowserThemePack is now in a consistent state. | 447 // The BrowserThemePack is now in a consistent state. |
375 return pack; | 448 return pack; |
376 } | 449 } |
377 | 450 |
378 // static | 451 // static |
379 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( | 452 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( |
380 const FilePath& path, const std::string& expected_id) { | 453 const FilePath& path, const std::string& expected_id) { |
381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
382 // Allow IO on UI thread due to deep-seated theme design issues. | 455 // Allow IO on UI thread due to deep-seated theme design issues. |
383 // (see http://crbug.com/80206) | 456 // (see http://crbug.com/80206) |
384 base::ThreadRestrictions::ScopedAllowIO allow_io; | 457 base::ThreadRestrictions::ScopedAllowIO allow_io; |
385 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); | 458 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); |
| 459 // Scale factor parameter is moot as data pack has image resources for all |
| 460 // supported scale factors. |
386 pack->data_pack_.reset( | 461 pack->data_pack_.reset( |
387 new ui::DataPack(ui::SCALE_FACTOR_100P)); | 462 new ui::DataPack(ui::SCALE_FACTOR_NONE)); |
388 | 463 |
389 if (!pack->data_pack_->LoadFromPath(path)) { | 464 if (!pack->data_pack_->LoadFromPath(path)) { |
390 LOG(ERROR) << "Failed to load theme data pack."; | 465 LOG(ERROR) << "Failed to load theme data pack."; |
391 return NULL; | 466 return NULL; |
392 } | 467 } |
393 | 468 |
394 base::StringPiece pointer; | 469 base::StringPiece pointer; |
395 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) | 470 if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer)) |
396 return NULL; | 471 return NULL; |
397 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>( | 472 pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>( |
(...skipping 25 matching lines...) Expand all Loading... |
423 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) | 498 if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer)) |
424 return NULL; | 499 return NULL; |
425 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>( | 500 pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>( |
426 const_cast<char*>(pointer.data())); | 501 const_cast<char*>(pointer.data())); |
427 | 502 |
428 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) | 503 if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer)) |
429 return NULL; | 504 return NULL; |
430 pack->source_images_ = reinterpret_cast<int*>( | 505 pack->source_images_ = reinterpret_cast<int*>( |
431 const_cast<char*>(pointer.data())); | 506 const_cast<char*>(pointer.data())); |
432 | 507 |
| 508 if (!pack->data_pack_->GetStringPiece(kScaleFactorsID, &pointer)) |
| 509 return NULL; |
| 510 |
| 511 if (!InputScalesValid(const_cast<char*>(pointer.data()), |
| 512 pack->scale_factors_)) { |
| 513 DLOG(ERROR) << "BuildFromDataPack failure! The pack scale factors differ " |
| 514 << "from those supported by platform."; |
| 515 } |
| 516 |
433 return pack; | 517 return pack; |
434 } | 518 } |
435 | 519 |
436 bool BrowserThemePack::WriteToDisk(const FilePath& path) const { | 520 bool BrowserThemePack::WriteToDisk(const FilePath& path) const { |
437 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
438 // Add resources for each of the property arrays. | 522 // Add resources for each of the property arrays. |
439 RawDataForWriting resources; | 523 RawDataForWriting resources; |
440 resources[kHeaderID] = base::StringPiece( | 524 resources[kHeaderID] = base::StringPiece( |
441 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader)); | 525 reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader)); |
442 resources[kTintsID] = base::StringPiece( | 526 resources[kTintsID] = base::StringPiece( |
443 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize])); | 527 reinterpret_cast<const char*>(tints_), sizeof(TintEntry[kTintArraySize])); |
444 resources[kColorsID] = base::StringPiece( | 528 resources[kColorsID] = base::StringPiece( |
445 reinterpret_cast<const char*>(colors_), | 529 reinterpret_cast<const char*>(colors_), |
446 sizeof(ColorPair[kColorArraySize])); | 530 sizeof(ColorPair[kColorArraySize])); |
447 resources[kDisplayPropertiesID] = base::StringPiece( | 531 resources[kDisplayPropertiesID] = base::StringPiece( |
448 reinterpret_cast<const char*>(display_properties_), | 532 reinterpret_cast<const char*>(display_properties_), |
449 sizeof(DisplayPropertyPair[kDisplayPropertySize])); | 533 sizeof(DisplayPropertyPair[kDisplayPropertySize])); |
450 | 534 |
451 int source_count = 1; | 535 int source_count = 1; |
452 int* end = source_images_; | 536 int* end = source_images_; |
453 for (; *end != -1 ; end++) | 537 for (; *end != -1 ; end++) |
454 source_count++; | 538 source_count++; |
455 resources[kSourceImagesID] = base::StringPiece( | 539 resources[kSourceImagesID] = base::StringPiece( |
456 reinterpret_cast<const char*>(source_images_), | 540 reinterpret_cast<const char*>(source_images_), |
457 source_count * sizeof(*source_images_)); | 541 source_count * sizeof(*source_images_)); |
458 | 542 |
| 543 resources[kScaleFactorsID] = GetScaleFactorsAsString(scale_factors_); |
| 544 |
459 AddRawImagesTo(image_memory_, &resources); | 545 AddRawImagesTo(image_memory_, &resources); |
460 | 546 |
461 RawImages reencoded_images; | 547 RawImages reencoded_images; |
462 RepackImages(prepared_images_, &reencoded_images); | 548 RepackImages(images_on_file_thread_, &reencoded_images); |
463 AddRawImagesTo(reencoded_images, &resources); | 549 AddRawImagesTo(reencoded_images, &resources); |
464 | 550 |
465 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY); | 551 return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY); |
466 } | 552 } |
467 | 553 |
468 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { | 554 bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const { |
469 if (tints_) { | 555 if (tints_) { |
470 for (int i = 0; i < kTintArraySize; ++i) { | 556 for (int i = 0; i < kTintArraySize; ++i) { |
471 if (tints_[i].id == id) { | 557 if (tints_[i].id == id) { |
472 hsl->h = tints_[i].h; | 558 hsl->h = tints_[i].h; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 // to avoid changing the BrowserThemePack::GetBitmapNamed API. Once we | 601 // to avoid changing the BrowserThemePack::GetBitmapNamed API. Once we |
516 // switch to using gfx::Image everywhere this can be removed. | 602 // switch to using gfx::Image everywhere this can be removed. |
517 return const_cast<SkBitmap*>(image->ToSkBitmap()); | 603 return const_cast<SkBitmap*>(image->ToSkBitmap()); |
518 } | 604 } |
519 | 605 |
520 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { | 606 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { |
521 int prs_id = GetPersistentIDByIDR(idr_id); | 607 int prs_id = GetPersistentIDByIDR(idr_id); |
522 if (prs_id == -1) | 608 if (prs_id == -1) |
523 return NULL; | 609 return NULL; |
524 | 610 |
525 // Check our cache of prepared images, first. | 611 // Check if the image is cached. |
526 ImageCache::const_iterator image_iter = prepared_images_.find(prs_id); | 612 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); |
527 if (image_iter != prepared_images_.end()) | 613 if (image_iter != images_on_ui_thread_.end()) |
528 return image_iter->second; | 614 return image_iter->second; |
529 | 615 |
530 // Check if we've already loaded this image. | 616 // TODO(pkotwicz): Do something better than loading the bitmaps |
531 image_iter = loaded_images_.find(prs_id); | 617 // for all the scale factors associated with |idr_id|. |
532 if (image_iter != loaded_images_.end()) | 618 gfx::ImageSkia image_skia; |
533 return image_iter->second; | 619 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
| 620 scoped_refptr<base::RefCountedMemory> memory = |
| 621 GetRawData(idr_id, scale_factors_[i]); |
534 | 622 |
535 scoped_refptr<base::RefCountedMemory> memory; | 623 if (memory.get()) { |
536 if (data_pack_.get()) { | 624 // Decode the PNG. |
537 memory = data_pack_->GetStaticMemory(prs_id); | 625 SkBitmap bitmap; |
538 } else { | 626 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), |
539 RawImages::const_iterator it = image_memory_.find(prs_id); | 627 &bitmap)) { |
540 if (it != image_memory_.end()) { | 628 NOTREACHED() << "Unable to decode theme image resource " << idr_id |
541 memory = it->second; | 629 << " from saved DataPack."; |
| 630 return NULL; |
| 631 } |
| 632 image_skia.AddRepresentation( |
| 633 gfx::ImageSkiaRep(bitmap, scale_factors_[i])); |
542 } | 634 } |
543 } | 635 } |
544 | 636 |
545 if (memory.get()) { | 637 if (!image_skia.isNull()) { |
546 // Decode the PNG. | 638 gfx::Image* ret = new gfx::Image(image_skia); |
547 SkBitmap bitmap; | 639 images_on_ui_thread_[prs_id] = ret; |
548 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), | |
549 &bitmap)) { | |
550 NOTREACHED() << "Unable to decode theme image resource " << idr_id | |
551 << " from saved DataPack."; | |
552 return NULL; | |
553 } | |
554 | |
555 gfx::Image* ret = new gfx::Image(bitmap); | |
556 loaded_images_[prs_id] = ret; | |
557 | |
558 return ret; | 640 return ret; |
559 } | 641 } |
560 | 642 |
561 return NULL; | 643 return NULL; |
562 } | 644 } |
563 | 645 |
564 base::RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const { | 646 base::RefCountedMemory* BrowserThemePack::GetRawData( |
| 647 int idr_id, |
| 648 ui::ScaleFactor scale_factor) const { |
565 base::RefCountedMemory* memory = NULL; | 649 base::RefCountedMemory* memory = NULL; |
566 int prs_id = GetPersistentIDByIDR(idr_id); | 650 int prs_id = GetPersistentIDByIDR(idr_id); |
| 651 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); |
567 | 652 |
568 if (prs_id != -1) { | 653 if (raw_id != -1) { |
569 if (data_pack_.get()) { | 654 if (data_pack_.get()) { |
570 memory = data_pack_->GetStaticMemory(prs_id); | 655 memory = data_pack_->GetStaticMemory(raw_id); |
571 } else { | 656 } else { |
572 RawImages::const_iterator it = image_memory_.find(prs_id); | 657 RawImages::const_iterator it = image_memory_.find(raw_id); |
573 if (it != image_memory_.end()) { | 658 if (it != image_memory_.end()) { |
574 memory = it->second; | 659 memory = it->second; |
575 } | 660 } |
576 } | 661 } |
577 } | 662 } |
578 | 663 |
579 return memory; | 664 return memory; |
580 } | 665 } |
581 | 666 |
582 bool BrowserThemePack::HasCustomImage(int idr_id) const { | 667 bool BrowserThemePack::HasCustomImage(int idr_id) const { |
(...skipping 11 matching lines...) Expand all Loading... |
594 } | 679 } |
595 | 680 |
596 // private: | 681 // private: |
597 | 682 |
598 BrowserThemePack::BrowserThemePack() | 683 BrowserThemePack::BrowserThemePack() |
599 : header_(NULL), | 684 : header_(NULL), |
600 tints_(NULL), | 685 tints_(NULL), |
601 colors_(NULL), | 686 colors_(NULL), |
602 display_properties_(NULL), | 687 display_properties_(NULL), |
603 source_images_(NULL) { | 688 source_images_(NULL) { |
| 689 #if defined(OS_MACOSX) |
| 690 scale_factors_ = ui::GetSupportedScaleFactors(); |
| 691 #else |
| 692 scale_factors_.push_back(ui::SCALE_FACTOR_100P); |
| 693 #endif |
604 } | 694 } |
605 | 695 |
606 void BrowserThemePack::BuildHeader(const Extension* extension) { | 696 void BrowserThemePack::BuildHeader(const Extension* extension) { |
607 header_ = new BrowserThemePackHeader; | 697 header_ = new BrowserThemePackHeader; |
608 header_->version = kThemePackVersion; | 698 header_->version = kThemePackVersion; |
609 | 699 |
610 // TODO(erg): Need to make this endian safe on other computers. Prerequisite | 700 // TODO(erg): Need to make this endian safe on other computers. Prerequisite |
611 // is that ui::DataPack removes this same check. | 701 // is that ui::DataPack removes this same check. |
612 #if defined(__BYTE_ORDER) | 702 #if defined(__BYTE_ORDER) |
613 // Linux check | 703 // Linux check |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 ids.push_back(it->first); | 950 ids.push_back(it->first); |
861 } | 951 } |
862 | 952 |
863 source_images_ = new int[ids.size() + 1]; | 953 source_images_ = new int[ids.size() + 1]; |
864 std::copy(ids.begin(), ids.end(), source_images_); | 954 std::copy(ids.begin(), ids.end(), source_images_); |
865 source_images_[ids.size()] = -1; | 955 source_images_[ids.size()] = -1; |
866 } | 956 } |
867 | 957 |
868 bool BrowserThemePack::LoadRawBitmapsTo( | 958 bool BrowserThemePack::LoadRawBitmapsTo( |
869 const FilePathMap& file_paths, | 959 const FilePathMap& file_paths, |
870 ImageCache* raw_bitmaps) { | 960 ImageCache* image_cache) { |
871 // Themes should be loaded on the file thread, not the UI thread. | 961 // Themes should be loaded on the file thread, not the UI thread. |
872 // http://crbug.com/61838 | 962 // http://crbug.com/61838 |
873 base::ThreadRestrictions::ScopedAllowIO allow_io; | 963 base::ThreadRestrictions::ScopedAllowIO allow_io; |
874 | 964 |
875 for (FilePathMap::const_iterator it = file_paths.begin(); | 965 for (FilePathMap::const_iterator it = file_paths.begin(); |
876 it != file_paths.end(); ++it) { | 966 it != file_paths.end(); ++it) { |
877 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second)); | 967 scoped_refptr<base::RefCountedMemory> raw_data(ReadFileData(it->second)); |
878 if (!raw_data.get()) { | 968 if (!raw_data.get()) { |
879 LOG(ERROR) << "Could not load theme image"; | 969 LOG(ERROR) << "Could not load theme image"; |
880 return false; | 970 return false; |
881 } | 971 } |
882 | 972 |
883 int id = it->first; | 973 int prs_id = it->first; |
884 | 974 |
885 // Some images need to go directly into |image_memory_|. No modification is | 975 // Some images need to go directly into |image_memory_|. No modification is |
886 // necessary or desirable. | 976 // necessary or desirable. |
887 bool is_copyable = false; | 977 bool is_copyable = false; |
888 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { | 978 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { |
889 if (kPreloadIDs[i] == id) { | 979 if (kPreloadIDs[i] == prs_id) { |
890 is_copyable = true; | 980 is_copyable = true; |
891 break; | 981 break; |
892 } | 982 } |
893 } | 983 } |
894 | 984 |
895 if (is_copyable) { | 985 if (is_copyable) { |
896 image_memory_[id] = raw_data; | 986 int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P); |
| 987 image_memory_[raw_id] = raw_data; |
897 } else if (raw_data.get() && raw_data->size()) { | 988 } else if (raw_data.get() && raw_data->size()) { |
898 // Decode the PNG. | 989 // Decode the PNG. |
899 SkBitmap bitmap; | 990 SkBitmap bitmap; |
900 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), | 991 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), |
901 &bitmap)) { | 992 &bitmap)) { |
902 (*raw_bitmaps)[it->first] = new gfx::Image(bitmap); | 993 (*image_cache)[prs_id] = new gfx::Image(bitmap); |
903 } else { | 994 } else { |
904 NOTREACHED() << "Unable to decode theme image resource " << it->first; | 995 NOTREACHED() << "Unable to decode theme image resource " << it->first; |
905 } | 996 } |
906 } | 997 } |
907 } | 998 } |
908 | 999 |
909 return true; | 1000 return true; |
910 } | 1001 } |
911 | 1002 |
912 void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const { | 1003 void BrowserThemePack::CreateImages(ImageCache* images) const { |
| 1004 CreateFrameImages(images); |
| 1005 CreateTintedButtons(GetTintInternal(ThemeService::TINT_BUTTONS), images); |
| 1006 CreateTabBackgroundImages(images); |
| 1007 } |
| 1008 |
| 1009 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { |
913 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1010 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
914 | 1011 |
915 // Create all the output bitmaps in a separate cache and move them back into | 1012 // Create all the output images in a separate cache and move them back into |
916 // the input bitmaps because there can be name collisions. | 1013 // the input images because there can be name collisions. |
917 ImageCache temp_output; | 1014 ImageCache temp_output; |
918 | 1015 |
919 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { | 1016 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { |
920 int prs_id = kFrameTintMap[i].key; | 1017 int prs_id = kFrameTintMap[i].key; |
921 const gfx::Image* frame = NULL; | 1018 const gfx::Image* frame = NULL; |
922 // If there's no frame image provided for the specified id, then load | 1019 // If there's no frame image provided for the specified id, then load |
923 // the default provided frame. If that's not provided, skip this whole | 1020 // the default provided frame. If that's not provided, skip this whole |
924 // thing and just use the default images. | 1021 // thing and just use the default images. |
925 int prs_base_id; | 1022 int prs_base_id; |
926 | 1023 |
927 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { | 1024 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { |
928 prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ? | 1025 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ? |
929 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; | 1026 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; |
930 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { | 1027 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { |
931 prs_base_id = PRS_THEME_FRAME_OVERLAY; | 1028 prs_base_id = PRS_THEME_FRAME_OVERLAY; |
932 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { | 1029 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { |
933 prs_base_id = PRS_THEME_FRAME; | 1030 prs_base_id = PRS_THEME_FRAME; |
934 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && | 1031 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && |
935 !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) { | 1032 !images->count(PRS_THEME_FRAME_INCOGNITO)) { |
936 prs_base_id = PRS_THEME_FRAME; | 1033 prs_base_id = PRS_THEME_FRAME; |
937 } else { | 1034 } else { |
938 prs_base_id = prs_id; | 1035 prs_base_id = prs_id; |
939 } | 1036 } |
940 | 1037 |
941 if (bitmaps->count(prs_id)) { | 1038 if (images->count(prs_id)) { |
942 frame = (*bitmaps)[prs_id]; | 1039 frame = (*images)[prs_id]; |
943 } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) { | 1040 } else if (prs_base_id != prs_id && images->count(prs_base_id)) { |
944 frame = (*bitmaps)[prs_base_id]; | 1041 frame = (*images)[prs_base_id]; |
945 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && | 1042 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY && |
946 bitmaps->count(PRS_THEME_FRAME)) { | 1043 images->count(PRS_THEME_FRAME)) { |
947 // If there is no theme overlay, don't tint the default frame, | 1044 // If there is no theme overlay, don't tint the default frame, |
948 // because it will overwrite the custom frame image when we cache and | 1045 // because it will overwrite the custom frame image when we cache and |
949 // reload from disk. | 1046 // reload from disk. |
950 frame = NULL; | 1047 frame = NULL; |
951 } else { | 1048 } else { |
952 // If the theme doesn't specify an image, then apply the tint to | 1049 // If the theme doesn't specify an image, then apply the tint to |
953 // the default frame. | 1050 // the default frame. |
954 frame = &rb.GetImageNamed(IDR_THEME_FRAME); | 1051 frame = &rb.GetImageNamed(IDR_THEME_FRAME); |
955 } | 1052 } |
956 | 1053 |
957 if (frame) { | 1054 if (frame) { |
958 temp_output[prs_id] = CreateHSLShiftedImage( | 1055 temp_output[prs_id] = CreateHSLShiftedImage( |
959 *frame, GetTintInternal(kFrameTintMap[i].value)); | 1056 *frame, GetTintInternal(kFrameTintMap[i].value)); |
960 } | 1057 } |
961 } | 1058 } |
962 | 1059 MergeImageCaches(temp_output, images); |
963 MergeImageCaches(temp_output, bitmaps); | |
964 } | 1060 } |
965 | 1061 |
966 void BrowserThemePack::GenerateTintedButtons( | 1062 void BrowserThemePack::CreateTintedButtons( |
967 const color_utils::HSL& button_tint, | 1063 const color_utils::HSL& button_tint, |
968 ImageCache* processed_bitmaps) const { | 1064 ImageCache* processed_images) const { |
969 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { | 1065 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { |
970 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1066 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
971 const std::set<int>& idr_ids = | 1067 const std::set<int>& idr_ids = |
972 ThemeService::GetTintableToolbarButtons(); | 1068 ThemeService::GetTintableToolbarButtons(); |
973 for (std::set<int>::const_iterator it = idr_ids.begin(); | 1069 for (std::set<int>::const_iterator it = idr_ids.begin(); |
974 it != idr_ids.end(); ++it) { | 1070 it != idr_ids.end(); ++it) { |
975 int prs_id = GetPersistentIDByIDR(*it); | 1071 int prs_id = GetPersistentIDByIDR(*it); |
976 DCHECK(prs_id > 0); | 1072 DCHECK(prs_id > 0); |
977 | 1073 |
978 // Fetch the image by IDR... | 1074 // Fetch the image by IDR... |
979 gfx::Image& button = rb.GetImageNamed(*it); | 1075 gfx::Image& button = rb.GetImageNamed(*it); |
980 | 1076 |
981 // but save a version with the persistent ID. | 1077 // but save a version with the persistent ID. |
982 (*processed_bitmaps)[prs_id] = | 1078 (*processed_images)[prs_id] = |
983 CreateHSLShiftedImage(button, button_tint); | 1079 CreateHSLShiftedImage(button, button_tint); |
984 } | 1080 } |
985 } | 1081 } |
986 } | 1082 } |
987 | 1083 |
988 void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const { | 1084 void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { |
989 ImageCache temp_output; | 1085 ImageCache temp_output; |
990 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { | 1086 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { |
991 int prs_id = kTabBackgroundMap[i].key; | 1087 int prs_id = kTabBackgroundMap[i].key; |
992 int prs_base_id = kTabBackgroundMap[i].value; | 1088 int prs_base_id = kTabBackgroundMap[i].value; |
993 | 1089 |
994 // We only need to generate the background tab images if we were provided | 1090 // We only need to generate the background tab images if we were provided |
995 // with a PRS_THEME_FRAME. | 1091 // with a PRS_THEME_FRAME. |
996 ImageCache::const_iterator it = bitmaps->find(prs_base_id); | 1092 ImageCache::const_iterator it = images->find(prs_base_id); |
997 if (it != bitmaps->end()) { | 1093 if (it != images->end()) { |
998 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); | 1094 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); |
999 const std::vector<gfx::ImageSkiaRep> image_reps_to_tint = | 1095 color_utils::HSL hsl_shift = GetTintInternal( |
1000 image_to_tint->image_reps(); | 1096 ThemeService::TINT_BACKGROUND_TAB); |
1001 gfx::ImageSkia tinted_image; | 1097 int vertical_offset = images->count(prs_id) |
1002 for (size_t j = 0; j < image_reps_to_tint.size(); ++j) { | 1098 ? kRestoredTabVerticalOffset : 0; |
1003 gfx::ImageSkiaRep image_rep_to_tint = image_reps_to_tint[j]; | |
1004 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( | |
1005 image_rep_to_tint.sk_bitmap(), GetTintInternal( | |
1006 ThemeService::TINT_BACKGROUND_TAB)); | |
1007 gfx::Size bg_tint_dip_size(image_rep_to_tint.GetWidth(), | |
1008 image_rep_to_tint.GetHeight()); | |
1009 int vertical_offset = bitmaps->count(prs_id) | |
1010 ? kRestoredTabVerticalOffset : 0; | |
1011 gfx::Canvas canvas(gfx::Size(bg_tint.width(), bg_tint.height()), | |
1012 image_rep_to_tint.scale_factor(), | |
1013 false); | |
1014 canvas.TileImageInt(bg_tint, 0, vertical_offset, 0, 0, | |
1015 bg_tint_dip_size.width(), bg_tint_dip_size.height()); | |
1016 | 1099 |
1017 // If they've provided a custom image, overlay it. | 1100 gfx::ImageSkia overlay; |
1018 ImageCache::const_iterator overlay_it = bitmaps->find(prs_id); | 1101 ImageCache::const_iterator overlay_it = images->find(prs_id); |
1019 if (overlay_it != bitmaps->end()) { | 1102 if (overlay_it != images->end()) |
1020 const gfx::ImageSkia* overlay = overlay_it->second->ToImageSkia(); | 1103 overlay = *overlay_it->second->ToImageSkia(); |
1021 canvas.TileImageInt(*overlay, 0, 0, bg_tint_dip_size.width(), | |
1022 overlay->height()); | |
1023 } | |
1024 tinted_image.AddRepresentation(canvas.ExtractImageRep()); | |
1025 } | |
1026 | 1104 |
1027 temp_output[prs_id] = new gfx::Image(tinted_image); | 1105 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( |
| 1106 *image_to_tint, overlay, hsl_shift, vertical_offset); |
| 1107 // ImageSkia takes ownership of |source|. |
| 1108 temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source, |
| 1109 image_to_tint->size())); |
1028 } | 1110 } |
1029 } | 1111 } |
1030 | 1112 MergeImageCaches(temp_output, images); |
1031 MergeImageCaches(temp_output, bitmaps); | |
1032 } | 1113 } |
1033 | 1114 |
1034 void BrowserThemePack::RepackImages(const ImageCache& images, | 1115 void BrowserThemePack::RepackImages(const ImageCache& images, |
1035 RawImages* reencoded_images) const { | 1116 RawImages* reencoded_images) const { |
| 1117 |
1036 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 1119 |
| 1120 typedef std::vector<ui::ScaleFactor> ScaleFactors; |
1037 for (ImageCache::const_iterator it = images.begin(); | 1121 for (ImageCache::const_iterator it = images.begin(); |
1038 it != images.end(); ++it) { | 1122 it != images.end(); ++it) { |
1039 std::vector<unsigned char> image_data; | 1123 gfx::ImageSkia image_skia = *it->second->ToImageSkia(); |
1040 if (!gfx::PNGCodec::EncodeBGRASkBitmap(*it->second->ToSkBitmap(), false, | 1124 |
1041 &image_data)) { | 1125 // Attempt to generate image reps for all supported scale factors. |
1042 NOTREACHED() << "Image file for resource " << it->first | 1126 for (ScaleFactors::const_iterator factor_it = scale_factors_.begin(); |
1043 << " could not be encoded."; | 1127 factor_it != scale_factors_.end(); ++factor_it) { |
1044 } else { | 1128 // Ask for representation to force the representation to be generated |
1045 (*reencoded_images)[it->first] = | 1129 // if it wasn't already. |
1046 base::RefCountedBytes::TakeVector(&image_data); | 1130 image_skia.GetRepresentation(*factor_it); |
| 1131 } |
| 1132 |
| 1133 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; |
| 1134 ImageSkiaReps image_reps = image_skia.image_reps(); |
| 1135 if (image_reps.empty()) { |
| 1136 NOTREACHED() << "No image reps for resource " << it->first << "."; |
| 1137 } |
| 1138 for (ImageSkiaReps::iterator rep_it = image_reps.begin(); |
| 1139 rep_it != image_reps.end(); ++rep_it) { |
| 1140 std::vector<unsigned char> bitmap_data; |
| 1141 if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false, |
| 1142 &bitmap_data)) { |
| 1143 NOTREACHED() << "Image file for resource " << it->first |
| 1144 << " could not be encoded."; |
| 1145 } |
| 1146 int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor()); |
| 1147 (*reencoded_images)[raw_id] = |
| 1148 base::RefCountedBytes::TakeVector(&bitmap_data); |
1047 } | 1149 } |
1048 } | 1150 } |
1049 } | 1151 } |
| 1152 |
| 1153 void BrowserThemePack::GenerateImageReps( |
| 1154 const std::vector<ui::ScaleFactor>& scale_factors) { |
| 1155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1156 for (ImageCache::const_iterator it = images_on_ui_thread_.begin(); |
| 1157 it != images_on_ui_thread_.end(); |
| 1158 ++it) { |
| 1159 const gfx::ImageSkia* image1 = it->second->ToImageSkia(); |
| 1160 const gfx::ImageSkia* image2 = |
| 1161 images_on_file_thread_[it->first]->ToImageSkia(); |
| 1162 |
| 1163 // Ensure that image reps are generated and cached in |image1| by |
| 1164 // calling GetRepresentation(). |
| 1165 for (size_t i = 0; i < scale_factors.size(); ++i) |
| 1166 image1->GetRepresentation(scale_factors[i]); |
| 1167 |
| 1168 // |image1| and |image2| have ImageSkiaSources which produce pixel |
| 1169 // equivalent output. Instead of regenerating again, copy the image reps |
| 1170 // which were generated for |image1| into |image2|. |
| 1171 // Don't do a deep copy of the SkBitmaps as SkBitmap is thread safe. |
| 1172 std::vector<gfx::ImageSkiaRep> image1_reps = image1->image_reps(); |
| 1173 for (size_t i = 0; i < image1_reps.size(); ++i) { |
| 1174 gfx::ImageSkiaRep image1_rep = image1_reps[i]; |
| 1175 const_cast<gfx::ImageSkia*>(image2)->AddRepresentation(gfx::ImageSkiaRep( |
| 1176 image1_rep.sk_bitmap(), image1_rep.scale_factor())); |
| 1177 } |
| 1178 } |
| 1179 } |
1050 | 1180 |
1051 void BrowserThemePack::MergeImageCaches( | 1181 void BrowserThemePack::MergeImageCaches( |
1052 const ImageCache& source, ImageCache* destination) const { | 1182 const ImageCache& source, ImageCache* destination) const { |
1053 for (ImageCache::const_iterator it = source.begin(); it != source.end(); | 1183 for (ImageCache::const_iterator it = source.begin(); it != source.end(); |
1054 ++it) { | 1184 ++it) { |
1055 ImageCache::const_iterator bitmap_it = destination->find(it->first); | 1185 ImageCache::const_iterator image_it = destination->find(it->first); |
1056 if (bitmap_it != destination->end()) | 1186 if (image_it != destination->end()) |
1057 delete bitmap_it->second; | 1187 delete image_it->second; |
1058 | 1188 |
1059 (*destination)[it->first] = it->second; | 1189 (*destination)[it->first] = it->second; |
1060 } | 1190 } |
1061 } | 1191 } |
1062 | 1192 |
| 1193 void BrowserThemePack::CopyImagesTo(const ImageCache& source, |
| 1194 ImageCache* destination) const { |
| 1195 for (ImageCache::const_iterator it = source.begin(); it != source.end(); |
| 1196 ++it) { |
| 1197 (*destination)[it->first] = new gfx::Image(*it->second); |
| 1198 } |
| 1199 } |
| 1200 |
1063 void BrowserThemePack::AddRawImagesTo(const RawImages& images, | 1201 void BrowserThemePack::AddRawImagesTo(const RawImages& images, |
1064 RawDataForWriting* out) const { | 1202 RawDataForWriting* out) const { |
1065 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
1066 for (RawImages::const_iterator it = images.begin(); it != images.end(); | 1204 for (RawImages::const_iterator it = images.begin(); it != images.end(); |
1067 ++it) { | 1205 ++it) { |
1068 (*out)[it->first] = base::StringPiece( | 1206 (*out)[it->first] = base::StringPiece( |
1069 reinterpret_cast<const char*>(it->second->front()), it->second->size()); | 1207 reinterpret_cast<const char*>(it->second->front()), it->second->size()); |
1070 } | 1208 } |
1071 } | 1209 } |
1072 | 1210 |
1073 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { | 1211 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { |
1074 if (tints_) { | 1212 if (tints_) { |
1075 for (int i = 0; i < kTintArraySize; ++i) { | 1213 for (int i = 0; i < kTintArraySize; ++i) { |
1076 if (tints_[i].id == id) { | 1214 if (tints_[i].id == id) { |
1077 color_utils::HSL hsl; | 1215 color_utils::HSL hsl; |
1078 hsl.h = tints_[i].h; | 1216 hsl.h = tints_[i].h; |
1079 hsl.s = tints_[i].s; | 1217 hsl.s = tints_[i].s; |
1080 hsl.l = tints_[i].l; | 1218 hsl.l = tints_[i].l; |
1081 return hsl; | 1219 return hsl; |
1082 } | 1220 } |
1083 } | 1221 } |
1084 } | 1222 } |
1085 | 1223 |
1086 return ThemeService::GetDefaultTint(id); | 1224 return ThemeService::GetDefaultTint(id); |
1087 } | 1225 } |
| 1226 |
| 1227 int BrowserThemePack::GetRawIDByPersistentID( |
| 1228 int prs_id, |
| 1229 ui::ScaleFactor scale_factor) const { |
| 1230 if (prs_id < 0) |
| 1231 return -1; |
| 1232 |
| 1233 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
| 1234 if (scale_factors_[i] == scale_factor) |
| 1235 return static_cast<int>(kPersistingImagesLength * i) + prs_id; |
| 1236 } |
| 1237 return -1; |
| 1238 } |
OLD | NEW |