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" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "grit/theme_resources.h" | 21 #include "grit/theme_resources.h" |
22 #include "grit/ui_resources.h" | 22 #include "grit/ui_resources.h" |
23 #include "net/base/file_stream.h" | 23 #include "net/base/file_stream.h" |
24 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
25 #include "third_party/skia/include/core/SkCanvas.h" | 25 #include "third_party/skia/include/core/SkCanvas.h" |
26 #include "ui/base/resource/data_pack.h" | 26 #include "ui/base/resource/data_pack.h" |
27 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
28 #include "ui/gfx/canvas.h" | 28 #include "ui/gfx/canvas.h" |
29 #include "ui/gfx/codec/png_codec.h" | 29 #include "ui/gfx/codec/png_codec.h" |
30 #include "ui/gfx/image/canvas_image_source.h" | 30 #include "ui/gfx/image/canvas_image_source.h" |
31 #include "ui/gfx/image/image.h" | |
32 #include "ui/gfx/image/image_skia.h" | 31 #include "ui/gfx/image/image_skia.h" |
33 #include "ui/gfx/image/image_skia_operations.h" | 32 #include "ui/gfx/image/image_skia_operations.h" |
34 #include "ui/gfx/screen.h" | 33 #include "ui/gfx/screen.h" |
35 #include "ui/gfx/skia_util.h" | 34 #include "ui/gfx/skia_util.h" |
36 | 35 |
37 using content::BrowserThread; | 36 using content::BrowserThread; |
38 using extensions::Extension; | 37 using extensions::Extension; |
39 | 38 |
40 namespace { | 39 namespace { |
41 | 40 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 } | 324 } |
326 | 325 |
327 return -1; | 326 return -1; |
328 } | 327 } |
329 | 328 |
330 struct IntToIntTable { | 329 struct IntToIntTable { |
331 int key; | 330 int key; |
332 int value; | 331 int value; |
333 }; | 332 }; |
334 | 333 |
335 // Mapping used in GenerateFrameImages() to associate frame images with the | 334 // Mapping used in CreateFrameImages() to associate frame images with the |
336 // tint ID that should maybe be applied to it. | 335 // tint ID that should maybe be applied to it. |
337 IntToIntTable kFrameTintMap[] = { | 336 IntToIntTable kFrameTintMap[] = { |
338 { PRS_THEME_FRAME, ThemeProperties::TINT_FRAME }, | 337 { PRS_THEME_FRAME, ThemeProperties::TINT_FRAME }, |
339 { PRS_THEME_FRAME_INACTIVE, ThemeProperties::TINT_FRAME_INACTIVE }, | 338 { PRS_THEME_FRAME_INACTIVE, ThemeProperties::TINT_FRAME_INACTIVE }, |
340 { PRS_THEME_FRAME_OVERLAY, ThemeProperties::TINT_FRAME }, | 339 { PRS_THEME_FRAME_OVERLAY, ThemeProperties::TINT_FRAME }, |
341 { PRS_THEME_FRAME_OVERLAY_INACTIVE, | 340 { PRS_THEME_FRAME_OVERLAY_INACTIVE, |
342 ThemeProperties::TINT_FRAME_INACTIVE }, | 341 ThemeProperties::TINT_FRAME_INACTIVE }, |
343 { PRS_THEME_FRAME_INCOGNITO, ThemeProperties::TINT_FRAME_INCOGNITO }, | 342 { PRS_THEME_FRAME_INCOGNITO, ThemeProperties::TINT_FRAME_INCOGNITO }, |
344 { PRS_THEME_FRAME_INCOGNITO_INACTIVE, | 343 { PRS_THEME_FRAME_INCOGNITO_INACTIVE, |
345 ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE }, | 344 ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE }, |
(...skipping 10 matching lines...) Expand all Loading... |
356 // goes with which tab background. | 355 // goes with which tab background. |
357 IntToIntTable kTabBackgroundMap[] = { | 356 IntToIntTable kTabBackgroundMap[] = { |
358 { PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME }, | 357 { PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME }, |
359 { PRS_THEME_TAB_BACKGROUND_INCOGNITO, PRS_THEME_FRAME_INCOGNITO }, | 358 { PRS_THEME_TAB_BACKGROUND_INCOGNITO, PRS_THEME_FRAME_INCOGNITO }, |
360 #if defined(OS_WIN) && defined(USE_AURA) | 359 #if defined(OS_WIN) && defined(USE_AURA) |
361 { PRS_THEME_TAB_BACKGROUND_WIN, PRS_THEME_FRAME_WIN }, | 360 { PRS_THEME_TAB_BACKGROUND_WIN, PRS_THEME_FRAME_WIN }, |
362 { PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN, PRS_THEME_FRAME_INCOGNITO_WIN }, | 361 { PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN, PRS_THEME_FRAME_INCOGNITO_WIN }, |
363 #endif | 362 #endif |
364 }; | 363 }; |
365 | 364 |
| 365 struct CropEntry { |
| 366 int prs_id; |
| 367 |
| 368 // The maximum useful height of the image at |prs_id|. |
| 369 int max_height; |
| 370 |
| 371 // Whether cropping the image at |prs_id| should be skipped on OSes which |
| 372 // have a frame border to the left and right of the web contents. |
| 373 // This should be true for images which can be used to decorate the border to |
| 374 // the left and the right of the web contents. |
| 375 bool skip_if_frame_border; |
| 376 }; |
| 377 |
| 378 // The images which should be cropped before being saved to the data pack. The |
| 379 // maximum heights are meant to be conservative as to give room for the UI to |
| 380 // change without the maximum heights having to be modified. |
| 381 // |kThemePackVersion| must be incremented if any of the maximum heights below |
| 382 // are modified. |
| 383 struct CropEntry kImagesToCrop[] = { |
| 384 { PRS_THEME_FRAME, 120, true }, |
| 385 { PRS_THEME_FRAME_INACTIVE, 120, true }, |
| 386 { PRS_THEME_FRAME_INCOGNITO, 120, true }, |
| 387 { PRS_THEME_FRAME_INCOGNITO_INACTIVE, 120, true }, |
| 388 { PRS_THEME_FRAME_OVERLAY, 120, true }, |
| 389 { PRS_THEME_FRAME_OVERLAY_INACTIVE, 120, true }, |
| 390 { PRS_THEME_TOOLBAR, 200, false }, |
| 391 { PRS_THEME_BUTTON_BACKGROUND, 60, false }, |
| 392 { PRS_THEME_WINDOW_CONTROL_BACKGROUND, 50, false }, |
| 393 #if defined(OS_WIN) && defined(USE_AURA) |
| 394 { PRS_THEME_TOOLBAR_WIN, 200, false } |
| 395 #endif |
| 396 }; |
| 397 |
366 | 398 |
367 // A list of images that don't need tinting or any other modification and can | 399 // A list of images that don't need tinting or any other modification and can |
368 // be byte-copied directly into the finished DataPack. This should contain the | 400 // be byte-copied directly into the finished DataPack. This should contain the |
369 // persistent IDs for all themeable image IDs that aren't in kFrameTintMap or | 401 // persistent IDs for all themeable image IDs that aren't in kFrameTintMap, |
370 // kTabBackgroundMap. | 402 // kTabBackgroundMap or kImagesToCrop. |
371 const int kPreloadIDs[] = { | 403 const int kPreloadIDs[] = { |
372 PRS_THEME_TOOLBAR, | |
373 PRS_THEME_NTP_BACKGROUND, | 404 PRS_THEME_NTP_BACKGROUND, |
374 PRS_THEME_BUTTON_BACKGROUND, | |
375 PRS_THEME_NTP_ATTRIBUTION, | 405 PRS_THEME_NTP_ATTRIBUTION, |
376 PRS_THEME_WINDOW_CONTROL_BACKGROUND, | 406 }; |
377 #if defined(OS_WIN) && defined(USE_AURA) | 407 |
378 PRS_THEME_TOOLBAR_WIN, | 408 // Returns true if this OS uses a browser frame which has a non zero width to |
| 409 // the left and the right of the web contents. |
| 410 bool HasFrameBorder() { |
| 411 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) |
| 412 return false; |
| 413 #else |
| 414 return true; |
379 #endif | 415 #endif |
380 }; | 416 } |
381 | 417 |
382 // Returns a piece of memory with the contents of the file |path|. | 418 // Returns a piece of memory with the contents of the file |path|. |
383 base::RefCountedMemory* ReadFileData(const base::FilePath& path) { | 419 base::RefCountedMemory* ReadFileData(const base::FilePath& path) { |
384 if (!path.empty()) { | 420 if (!path.empty()) { |
385 net::FileStream file(NULL); | 421 net::FileStream file(NULL); |
386 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; | 422 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; |
387 if (file.OpenSync(path, flags) == net::OK) { | 423 if (file.OpenSync(path, flags) == net::OK) { |
388 int64 avail = file.Available(); | 424 int64 avail = file.Available(); |
389 if (avail > 0 && avail < INT_MAX) { | 425 if (avail > 0 && avail < INT_MAX) { |
390 size_t size = static_cast<size_t>(avail); | 426 size_t size = static_cast<size_t>(avail); |
391 std::vector<unsigned char> raw_data; | 427 std::vector<unsigned char> raw_data; |
392 raw_data.resize(size); | 428 raw_data.resize(size); |
393 char* data = reinterpret_cast<char*>(&(raw_data.front())); | 429 char* data = reinterpret_cast<char*>(&(raw_data.front())); |
394 if (file.ReadUntilComplete(data, size) == avail) | 430 if (file.ReadUntilComplete(data, size) == avail) |
395 return base::RefCountedBytes::TakeVector(&raw_data); | 431 return base::RefCountedBytes::TakeVector(&raw_data); |
396 } | 432 } |
397 } | 433 } |
398 } | 434 } |
399 | 435 |
400 return NULL; | 436 return NULL; |
401 } | 437 } |
402 | 438 |
403 // Shifts an image's HSL values. The caller is responsible for deleting | 439 // Shifts an image's HSL values. The caller is responsible for deleting |
404 // the returned image. | 440 // the returned image. |
405 gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, | 441 gfx::Image CreateHSLShiftedImage(const gfx::Image& image, |
406 const color_utils::HSL& hsl_shift) { | 442 const color_utils::HSL& hsl_shift) { |
407 const gfx::ImageSkia* src_image = image.ToImageSkia(); | 443 const gfx::ImageSkia* src_image = image.ToImageSkia(); |
408 return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( | 444 return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( |
409 *src_image, hsl_shift)); | 445 *src_image, hsl_shift)); |
410 } | 446 } |
411 | 447 |
412 // A ImageSkiaSource that scales 100P image to the target scale factor | 448 // A ImageSkiaSource that scales 100P image to the target scale factor |
413 // if the ImageSkiaRep for the target scale factor isn't available. | 449 // if the ImageSkiaRep for the target scale factor isn't available. |
414 class ThemeImageSource: public gfx::ImageSkiaSource { | 450 class ThemeImageSource: public gfx::ImageSkiaSource { |
415 public: | 451 public: |
416 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) { | 452 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) { |
417 } | 453 } |
418 virtual ~ThemeImageSource() {} | 454 virtual ~ThemeImageSource() {} |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 } // namespace | 524 } // namespace |
489 | 525 |
490 BrowserThemePack::~BrowserThemePack() { | 526 BrowserThemePack::~BrowserThemePack() { |
491 if (!data_pack_.get()) { | 527 if (!data_pack_.get()) { |
492 delete header_; | 528 delete header_; |
493 delete [] tints_; | 529 delete [] tints_; |
494 delete [] colors_; | 530 delete [] colors_; |
495 delete [] display_properties_; | 531 delete [] display_properties_; |
496 delete [] source_images_; | 532 delete [] source_images_; |
497 } | 533 } |
498 | |
499 STLDeleteValues(&images_on_ui_thread_); | |
500 STLDeleteValues(&images_on_file_thread_); | |
501 } | 534 } |
502 | 535 |
503 // static | 536 // static |
504 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( | 537 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( |
505 const Extension* extension) { | 538 const Extension* extension) { |
506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
507 DCHECK(extension); | 540 DCHECK(extension); |
508 DCHECK(extension->is_theme()); | 541 DCHECK(extension->is_theme()); |
509 | 542 |
510 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); | 543 scoped_refptr<BrowserThemePack> pack(new BrowserThemePack); |
511 pack->BuildHeader(extension); | 544 pack->BuildHeader(extension); |
512 pack->BuildTintsFromJSON(extensions::ThemeInfo::GetThemeTints(extension)); | 545 pack->BuildTintsFromJSON(extensions::ThemeInfo::GetThemeTints(extension)); |
513 pack->BuildColorsFromJSON(extensions::ThemeInfo::GetThemeColors(extension)); | 546 pack->BuildColorsFromJSON(extensions::ThemeInfo::GetThemeColors(extension)); |
514 pack->BuildDisplayPropertiesFromJSON( | 547 pack->BuildDisplayPropertiesFromJSON( |
515 extensions::ThemeInfo::GetThemeDisplayProperties(extension)); | 548 extensions::ThemeInfo::GetThemeDisplayProperties(extension)); |
516 | 549 |
517 // Builds the images. (Image building is dependent on tints). | 550 // Builds the images. (Image building is dependent on tints). |
518 FilePathMap file_paths; | 551 FilePathMap file_paths; |
519 pack->ParseImageNamesFromJSON( | 552 pack->ParseImageNamesFromJSON( |
520 extensions::ThemeInfo::GetThemeImages(extension), | 553 extensions::ThemeInfo::GetThemeImages(extension), |
521 extension->path(), | 554 extension->path(), |
522 &file_paths); | 555 &file_paths); |
523 pack->BuildSourceImagesArray(file_paths); | 556 pack->BuildSourceImagesArray(file_paths); |
524 | 557 |
525 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) | 558 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) |
526 return NULL; | 559 return NULL; |
527 | 560 |
528 pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_); | |
529 | |
530 pack->CreateImages(&pack->images_on_ui_thread_); | 561 pack->CreateImages(&pack->images_on_ui_thread_); |
531 pack->CreateImages(&pack->images_on_file_thread_); | |
532 | 562 |
533 // Make sure the |images_on_file_thread_| has bitmaps for supported | 563 // Make sure the |images_on_file_thread_| has bitmaps for supported |
534 // scale factors before passing to FILE thread. | 564 // scale factors before passing to FILE thread. |
| 565 pack->images_on_file_thread_ = pack->images_on_ui_thread_; |
535 for (ImageCache::iterator it = pack->images_on_file_thread_.begin(); | 566 for (ImageCache::iterator it = pack->images_on_file_thread_.begin(); |
536 it != pack->images_on_file_thread_.end(); ++it) { | 567 it != pack->images_on_file_thread_.end(); ++it) { |
537 gfx::ImageSkia* image_skia = | 568 gfx::ImageSkia* image_skia = |
538 const_cast<gfx::ImageSkia*>(it->second->ToImageSkia()); | 569 const_cast<gfx::ImageSkia*>(it->second.ToImageSkia()); |
539 image_skia->MakeThreadSafe(); | 570 image_skia->MakeThreadSafe(); |
540 } | 571 } |
541 | 572 |
542 // The BrowserThemePack is now in a consistent state. | 573 // The BrowserThemePack is now in a consistent state. |
543 return pack; | 574 return pack; |
544 } | 575 } |
545 | 576 |
546 // static | 577 // static |
547 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( | 578 scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( |
548 const base::FilePath& path, const std::string& expected_id) { | 579 const base::FilePath& path, const std::string& expected_id) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 if (display_properties_[i].id == id) { | 713 if (display_properties_[i].id == id) { |
683 *result = display_properties_[i].property; | 714 *result = display_properties_[i].property; |
684 return true; | 715 return true; |
685 } | 716 } |
686 } | 717 } |
687 } | 718 } |
688 | 719 |
689 return false; | 720 return false; |
690 } | 721 } |
691 | 722 |
692 const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { | 723 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { |
693 int prs_id = GetPersistentIDByIDR(idr_id); | 724 int prs_id = GetPersistentIDByIDR(idr_id); |
694 if (prs_id == -1) | 725 if (prs_id == -1) |
695 return NULL; | 726 return gfx::Image(); |
696 | 727 |
697 // Check if the image is cached. | 728 // Check if the image is cached. |
698 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); | 729 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); |
699 if (image_iter != images_on_ui_thread_.end()) | 730 if (image_iter != images_on_ui_thread_.end()) |
700 return image_iter->second; | 731 return image_iter->second; |
701 | 732 |
702 // TODO(pkotwicz): Do something better than loading the bitmaps | 733 // TODO(pkotwicz): Do something better than loading the bitmaps |
703 // for all the scale factors associated with |idr_id|. | 734 // for all the scale factors associated with |idr_id|. |
704 gfx::ImageSkia source_image_skia; | 735 gfx::ImageSkia source_image_skia; |
705 for (size_t i = 0; i < scale_factors_.size(); ++i) { | 736 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
706 scoped_refptr<base::RefCountedMemory> memory = | 737 scoped_refptr<base::RefCountedMemory> memory = |
707 GetRawData(idr_id, scale_factors_[i]); | 738 GetRawData(idr_id, scale_factors_[i]); |
708 if (memory.get()) { | 739 if (memory.get()) { |
709 // Decode the PNG. | 740 // Decode the PNG. |
710 SkBitmap bitmap; | 741 SkBitmap bitmap; |
711 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), | 742 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), |
712 &bitmap)) { | 743 &bitmap)) { |
713 NOTREACHED() << "Unable to decode theme image resource " << idr_id | 744 NOTREACHED() << "Unable to decode theme image resource " << idr_id |
714 << " from saved DataPack."; | 745 << " from saved DataPack."; |
715 continue; | 746 continue; |
716 } | 747 } |
717 source_image_skia.AddRepresentation( | 748 source_image_skia.AddRepresentation( |
718 gfx::ImageSkiaRep(bitmap, scale_factors_[i])); | 749 gfx::ImageSkiaRep(bitmap, scale_factors_[i])); |
719 } | 750 } |
720 } | 751 } |
721 | 752 |
722 if (!source_image_skia.isNull()) { | 753 if (!source_image_skia.isNull()) { |
723 ThemeImageSource* source = new ThemeImageSource(source_image_skia); | 754 ThemeImageSource* source = new ThemeImageSource(source_image_skia); |
724 gfx::ImageSkia image_skia(source, source_image_skia.size()); | 755 gfx::ImageSkia image_skia(source, source_image_skia.size()); |
725 gfx::Image* ret = new gfx::Image(image_skia); | 756 gfx::Image ret = gfx::Image(image_skia); |
726 images_on_ui_thread_[prs_id] = ret; | 757 images_on_ui_thread_[prs_id] = ret; |
727 return ret; | 758 return ret; |
728 } | 759 } |
729 return NULL; | 760 return gfx::Image(); |
730 } | 761 } |
731 | 762 |
732 base::RefCountedMemory* BrowserThemePack::GetRawData( | 763 base::RefCountedMemory* BrowserThemePack::GetRawData( |
733 int idr_id, | 764 int idr_id, |
734 ui::ScaleFactor scale_factor) const { | 765 ui::ScaleFactor scale_factor) const { |
735 base::RefCountedMemory* memory = NULL; | 766 base::RefCountedMemory* memory = NULL; |
736 int prs_id = GetPersistentIDByIDR(idr_id); | 767 int prs_id = GetPersistentIDByIDR(idr_id); |
737 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); | 768 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); |
738 | 769 |
739 if (raw_id != -1) { | 770 if (raw_id != -1) { |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 | 1120 |
1090 if (is_copyable) { | 1121 if (is_copyable) { |
1091 int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P); | 1122 int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P); |
1092 image_memory_[raw_id] = raw_data; | 1123 image_memory_[raw_id] = raw_data; |
1093 } else if (raw_data.get() && raw_data->size()) { | 1124 } else if (raw_data.get() && raw_data->size()) { |
1094 // Decode the PNG. | 1125 // Decode the PNG. |
1095 SkBitmap bitmap; | 1126 SkBitmap bitmap; |
1096 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), | 1127 if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), |
1097 &bitmap)) { | 1128 &bitmap)) { |
1098 (*image_cache)[prs_id] = | 1129 (*image_cache)[prs_id] = |
1099 new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); | 1130 gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); |
1100 } else { | 1131 } else { |
1101 NOTREACHED() << "Unable to decode theme image resource " << it->first; | 1132 NOTREACHED() << "Unable to decode theme image resource " << it->first; |
1102 } | 1133 } |
1103 } | 1134 } |
1104 } | 1135 } |
1105 | 1136 |
1106 return true; | 1137 return true; |
1107 } | 1138 } |
1108 | 1139 |
1109 void BrowserThemePack::CreateImages(ImageCache* images) const { | 1140 void BrowserThemePack::CreateImages(ImageCache* images) const { |
| 1141 CropImages(images); |
1110 CreateFrameImages(images); | 1142 CreateFrameImages(images); |
1111 CreateTintedButtons(GetTintInternal(ThemeProperties::TINT_BUTTONS), images); | 1143 CreateTintedButtons(GetTintInternal(ThemeProperties::TINT_BUTTONS), images); |
1112 CreateTabBackgroundImages(images); | 1144 CreateTabBackgroundImages(images); |
1113 } | 1145 } |
1114 | 1146 |
| 1147 void BrowserThemePack::CropImages(ImageCache* images) const { |
| 1148 bool has_frame_border = HasFrameBorder(); |
| 1149 for (size_t i = 0; i < arraysize(kImagesToCrop); ++i) { |
| 1150 if (has_frame_border && kImagesToCrop[i].skip_if_frame_border) |
| 1151 continue; |
| 1152 |
| 1153 int prs_id = kImagesToCrop[i].prs_id; |
| 1154 ImageCache::iterator it = images->find(prs_id); |
| 1155 if (it == images->end()) |
| 1156 continue; |
| 1157 |
| 1158 int crop_height = kImagesToCrop[i].max_height; |
| 1159 gfx::ImageSkia image_skia = it->second.AsImageSkia(); |
| 1160 (*images)[prs_id] = gfx::Image(gfx::ImageSkiaOperations::ExtractSubset( |
| 1161 image_skia, gfx::Rect(0, 0, image_skia.width(), crop_height))); |
| 1162 } |
| 1163 } |
| 1164 |
1115 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { | 1165 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { |
1116 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1166 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
1117 | 1167 |
1118 // Create all the output images in a separate cache and move them back into | 1168 // Create all the output images in a separate cache and move them back into |
1119 // the input images because there can be name collisions. | 1169 // the input images because there can be name collisions. |
1120 ImageCache temp_output; | 1170 ImageCache temp_output; |
1121 | 1171 |
1122 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { | 1172 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { |
1123 int prs_id = kFrameTintMap[i].key; | 1173 int prs_id = kFrameTintMap[i].key; |
1124 const gfx::Image* frame = NULL; | 1174 gfx::Image frame; |
1125 // If there's no frame image provided for the specified id, then load | 1175 // If there's no frame image provided for the specified id, then load |
1126 // the default provided frame. If that's not provided, skip this whole | 1176 // the default provided frame. If that's not provided, skip this whole |
1127 // thing and just use the default images. | 1177 // thing and just use the default images. |
1128 int prs_base_id = 0; | 1178 int prs_base_id = 0; |
1129 | 1179 |
1130 #if defined(OS_WIN) && defined(USE_AURA) | 1180 #if defined(OS_WIN) && defined(USE_AURA) |
1131 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN) { | 1181 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN) { |
1132 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO_WIN) ? | 1182 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO_WIN) ? |
1133 PRS_THEME_FRAME_INCOGNITO_WIN : PRS_THEME_FRAME_WIN; | 1183 PRS_THEME_FRAME_INCOGNITO_WIN : PRS_THEME_FRAME_WIN; |
1134 } else if (prs_id == PRS_THEME_FRAME_INACTIVE_WIN) { | 1184 } else if (prs_id == PRS_THEME_FRAME_INACTIVE_WIN) { |
(...skipping 24 matching lines...) Expand all Loading... |
1159 frame = (*images)[prs_base_id]; | 1209 frame = (*images)[prs_base_id]; |
1160 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY) { | 1210 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY) { |
1161 #if defined(OS_WIN) && defined(USE_AURA) | 1211 #if defined(OS_WIN) && defined(USE_AURA) |
1162 if (images->count(PRS_THEME_FRAME_WIN)) { | 1212 if (images->count(PRS_THEME_FRAME_WIN)) { |
1163 #else | 1213 #else |
1164 if (images->count(PRS_THEME_FRAME)) { | 1214 if (images->count(PRS_THEME_FRAME)) { |
1165 #endif | 1215 #endif |
1166 // If there is no theme overlay, don't tint the default frame, | 1216 // If there is no theme overlay, don't tint the default frame, |
1167 // because it will overwrite the custom frame image when we cache and | 1217 // because it will overwrite the custom frame image when we cache and |
1168 // reload from disk. | 1218 // reload from disk. |
1169 frame = NULL; | 1219 frame = gfx::Image(); |
1170 } | 1220 } |
1171 } else { | 1221 } else { |
1172 // If the theme doesn't specify an image, then apply the tint to | 1222 // If the theme doesn't specify an image, then apply the tint to |
1173 // the default frame. | 1223 // the default frame. |
1174 frame = &rb.GetImageNamed(IDR_THEME_FRAME); | 1224 frame = rb.GetImageNamed(IDR_THEME_FRAME); |
1175 #if defined(OS_WIN) && defined(USE_AURA) | 1225 #if defined(OS_WIN) && defined(USE_AURA) |
1176 if (prs_id >= PRS_THEME_FRAME_WIN && | 1226 if (prs_id >= PRS_THEME_FRAME_WIN && |
1177 prs_id <= PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN) { | 1227 prs_id <= PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN) { |
1178 frame = &rb.GetImageNamed(IDR_THEME_FRAME_WIN); | 1228 frame = rb.GetImageNamed(IDR_THEME_FRAME_WIN); |
1179 } | 1229 } |
1180 #endif | 1230 #endif |
1181 } | 1231 } |
1182 if (frame) { | 1232 if (!frame.IsEmpty()) { |
1183 temp_output[prs_id] = CreateHSLShiftedImage( | 1233 temp_output[prs_id] = CreateHSLShiftedImage( |
1184 *frame, GetTintInternal(kFrameTintMap[i].value)); | 1234 frame, GetTintInternal(kFrameTintMap[i].value)); |
1185 } | 1235 } |
1186 } | 1236 } |
1187 MergeImageCaches(temp_output, images); | 1237 MergeImageCaches(temp_output, images); |
1188 } | 1238 } |
1189 | 1239 |
1190 void BrowserThemePack::CreateTintedButtons( | 1240 void BrowserThemePack::CreateTintedButtons( |
1191 const color_utils::HSL& button_tint, | 1241 const color_utils::HSL& button_tint, |
1192 ImageCache* processed_images) const { | 1242 ImageCache* processed_images) const { |
1193 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { | 1243 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { |
1194 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1244 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 17 matching lines...) Expand all Loading... |
1212 void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { | 1262 void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { |
1213 ImageCache temp_output; | 1263 ImageCache temp_output; |
1214 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { | 1264 for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { |
1215 int prs_id = kTabBackgroundMap[i].key; | 1265 int prs_id = kTabBackgroundMap[i].key; |
1216 int prs_base_id = kTabBackgroundMap[i].value; | 1266 int prs_base_id = kTabBackgroundMap[i].value; |
1217 | 1267 |
1218 // We only need to generate the background tab images if we were provided | 1268 // We only need to generate the background tab images if we were provided |
1219 // with a PRS_THEME_FRAME. | 1269 // with a PRS_THEME_FRAME. |
1220 ImageCache::const_iterator it = images->find(prs_base_id); | 1270 ImageCache::const_iterator it = images->find(prs_base_id); |
1221 if (it != images->end()) { | 1271 if (it != images->end()) { |
1222 const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); | 1272 gfx::ImageSkia image_to_tint = (it->second).AsImageSkia(); |
1223 color_utils::HSL hsl_shift = GetTintInternal( | 1273 color_utils::HSL hsl_shift = GetTintInternal( |
1224 ThemeProperties::TINT_BACKGROUND_TAB); | 1274 ThemeProperties::TINT_BACKGROUND_TAB); |
1225 int vertical_offset = images->count(prs_id) | 1275 int vertical_offset = images->count(prs_id) |
1226 ? kRestoredTabVerticalOffset : 0; | 1276 ? kRestoredTabVerticalOffset : 0; |
1227 | 1277 |
1228 gfx::ImageSkia overlay; | 1278 gfx::ImageSkia overlay; |
1229 ImageCache::const_iterator overlay_it = images->find(prs_id); | 1279 ImageCache::const_iterator overlay_it = images->find(prs_id); |
1230 if (overlay_it != images->end()) | 1280 if (overlay_it != images->end()) |
1231 overlay = *overlay_it->second->ToImageSkia(); | 1281 overlay = overlay_it->second.AsImageSkia(); |
1232 | 1282 |
1233 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( | 1283 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( |
1234 *image_to_tint, overlay, hsl_shift, vertical_offset); | 1284 image_to_tint, overlay, hsl_shift, vertical_offset); |
1235 // ImageSkia takes ownership of |source|. | 1285 // ImageSkia takes ownership of |source|. |
1236 temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source, | 1286 temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, |
1237 image_to_tint->size())); | 1287 image_to_tint.size())); |
1238 } | 1288 } |
1239 } | 1289 } |
1240 MergeImageCaches(temp_output, images); | 1290 MergeImageCaches(temp_output, images); |
1241 } | 1291 } |
1242 | 1292 |
1243 void BrowserThemePack::RepackImages(const ImageCache& images, | 1293 void BrowserThemePack::RepackImages(const ImageCache& images, |
1244 RawImages* reencoded_images) const { | 1294 RawImages* reencoded_images) const { |
1245 typedef std::vector<ui::ScaleFactor> ScaleFactors; | 1295 typedef std::vector<ui::ScaleFactor> ScaleFactors; |
1246 for (ImageCache::const_iterator it = images.begin(); | 1296 for (ImageCache::const_iterator it = images.begin(); |
1247 it != images.end(); ++it) { | 1297 it != images.end(); ++it) { |
1248 gfx::ImageSkia image_skia = *it->second->ToImageSkia(); | 1298 gfx::ImageSkia image_skia = *it->second.ToImageSkia(); |
1249 | 1299 |
1250 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; | 1300 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; |
1251 ImageSkiaReps image_reps = image_skia.image_reps(); | 1301 ImageSkiaReps image_reps = image_skia.image_reps(); |
1252 if (image_reps.empty()) { | 1302 if (image_reps.empty()) { |
1253 NOTREACHED() << "No image reps for resource " << it->first << "."; | 1303 NOTREACHED() << "No image reps for resource " << it->first << "."; |
1254 } | 1304 } |
1255 for (ImageSkiaReps::iterator rep_it = image_reps.begin(); | 1305 for (ImageSkiaReps::iterator rep_it = image_reps.begin(); |
1256 rep_it != image_reps.end(); ++rep_it) { | 1306 rep_it != image_reps.end(); ++rep_it) { |
1257 std::vector<unsigned char> bitmap_data; | 1307 std::vector<unsigned char> bitmap_data; |
1258 if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false, | 1308 if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false, |
1259 &bitmap_data)) { | 1309 &bitmap_data)) { |
1260 NOTREACHED() << "Image file for resource " << it->first | 1310 NOTREACHED() << "Image file for resource " << it->first |
1261 << " could not be encoded."; | 1311 << " could not be encoded."; |
1262 } | 1312 } |
1263 int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor()); | 1313 int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor()); |
1264 (*reencoded_images)[raw_id] = | 1314 (*reencoded_images)[raw_id] = |
1265 base::RefCountedBytes::TakeVector(&bitmap_data); | 1315 base::RefCountedBytes::TakeVector(&bitmap_data); |
1266 } | 1316 } |
1267 } | 1317 } |
1268 } | 1318 } |
1269 | 1319 |
1270 void BrowserThemePack::MergeImageCaches( | 1320 void BrowserThemePack::MergeImageCaches( |
1271 const ImageCache& source, ImageCache* destination) const { | 1321 const ImageCache& source, ImageCache* destination) const { |
1272 for (ImageCache::const_iterator it = source.begin(); it != source.end(); | 1322 for (ImageCache::const_iterator it = source.begin(); it != source.end(); |
1273 ++it) { | 1323 ++it) { |
1274 ImageCache::const_iterator image_it = destination->find(it->first); | |
1275 if (image_it != destination->end()) | |
1276 delete image_it->second; | |
1277 | |
1278 (*destination)[it->first] = it->second; | 1324 (*destination)[it->first] = it->second; |
1279 } | 1325 } |
1280 } | 1326 } |
1281 | 1327 |
1282 void BrowserThemePack::CopyImagesTo(const ImageCache& source, | |
1283 ImageCache* destination) const { | |
1284 for (ImageCache::const_iterator it = source.begin(); it != source.end(); | |
1285 ++it) { | |
1286 (*destination)[it->first] = new gfx::Image(*it->second); | |
1287 } | |
1288 } | |
1289 | |
1290 void BrowserThemePack::AddRawImagesTo(const RawImages& images, | 1328 void BrowserThemePack::AddRawImagesTo(const RawImages& images, |
1291 RawDataForWriting* out) const { | 1329 RawDataForWriting* out) const { |
1292 for (RawImages::const_iterator it = images.begin(); it != images.end(); | 1330 for (RawImages::const_iterator it = images.begin(); it != images.end(); |
1293 ++it) { | 1331 ++it) { |
1294 (*out)[it->first] = base::StringPiece( | 1332 (*out)[it->first] = base::StringPiece( |
1295 reinterpret_cast<const char*>(it->second->front()), it->second->size()); | 1333 reinterpret_cast<const char*>(it->second->front()), it->second->size()); |
1296 } | 1334 } |
1297 } | 1335 } |
1298 | 1336 |
1299 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { | 1337 color_utils::HSL BrowserThemePack::GetTintInternal(int id) const { |
(...skipping 17 matching lines...) Expand all Loading... |
1317 ui::ScaleFactor scale_factor) const { | 1355 ui::ScaleFactor scale_factor) const { |
1318 if (prs_id < 0) | 1356 if (prs_id < 0) |
1319 return -1; | 1357 return -1; |
1320 | 1358 |
1321 for (size_t i = 0; i < scale_factors_.size(); ++i) { | 1359 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
1322 if (scale_factors_[i] == scale_factor) | 1360 if (scale_factors_[i] == scale_factor) |
1323 return static_cast<int>(kPersistingImagesLength * i) + prs_id; | 1361 return static_cast<int>(kPersistingImagesLength * i) + prs_id; |
1324 } | 1362 } |
1325 return -1; | 1363 return -1; |
1326 } | 1364 } |
OLD | NEW |