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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 canvas.drawBitmapRect(rep_100p.sk_bitmap(), NULL, resized_bounds); | 473 canvas.drawBitmapRect(rep_100p.sk_bitmap(), NULL, resized_bounds); |
474 return gfx::ImageSkiaRep(resized_bitmap, scale_factor); | 474 return gfx::ImageSkiaRep(resized_bitmap, scale_factor); |
475 } | 475 } |
476 | 476 |
477 private: | 477 private: |
478 const gfx::ImageSkia source_; | 478 const gfx::ImageSkia source_; |
479 | 479 |
480 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource); | 480 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource); |
481 }; | 481 }; |
482 | 482 |
483 // An ImageSkiaSouce that delays decoding PNG data into bitmaps until needed | |
484 // and, if necessary, generates bitmaps for scale factors for which no PNG was | |
485 // provided. The first PNG will be used to compute the DIP size and will | |
486 // therefore be decoded when added. Once a PNG is decoded the resulting bitmap | |
487 // is stored for later use. | |
488 class ThemeImagePngSource : public gfx::ImageSkiaSource { | |
489 public: | |
490 ThemeImagePngSource() {} | |
pkotwicz
2013/06/14 18:23:05
Ideally we should not even cache the PNG data for
| |
491 | |
492 void AddPng(scoped_refptr<base::RefCountedMemory> png_memory, | |
493 ui::ScaleFactor scale_factor) { | |
494 png_map_[scale_factor] = png_memory; | |
495 if (bitmap_map_.empty()) | |
496 init(png_memory, scale_factor); | |
497 } | |
498 | |
499 gfx::Size size() const { return dip_size_; } | |
500 | |
501 private: | |
502 void init(scoped_refptr<base::RefCountedMemory> png_memory, | |
503 ui::ScaleFactor scale_factor) { | |
504 SkBitmap bitmap; | |
505 if (!gfx::PNGCodec::Decode(png_memory->front(), | |
506 png_memory->size(), | |
507 &bitmap)) { | |
508 NOTREACHED(); | |
509 return; | |
510 } | |
511 bitmap_map_[scale_factor] = bitmap; | |
512 dip_size_ = gfx::Size( | |
513 static_cast<int>(bitmap.width() / | |
514 ui::GetScaleFactorScale(scale_factor)), | |
515 static_cast<int>(bitmap.height() / | |
516 ui::GetScaleFactorScale(scale_factor))); | |
517 } | |
518 | |
519 virtual gfx::ImageSkiaRep GetImageForScale( | |
520 ui::ScaleFactor scale_factor) OVERRIDE { | |
521 // Look up the scale factor in the bitmap map. If found, use the bitmap and | |
522 // return it. | |
523 BitmapMap::const_iterator exact_bitmap = bitmap_map_.find(scale_factor); | |
524 if (exact_bitmap != bitmap_map_.end()) { | |
525 return gfx::ImageSkiaRep(exact_bitmap->second, scale_factor); | |
526 } | |
527 | |
528 // Look up the scale factor in the png map. If found, decode it, | |
529 // store the result in the bitmap map and return it. | |
530 PngMap::const_iterator exact_png = png_map_.find(scale_factor); | |
531 if (exact_png != png_map_.end()) { | |
532 SkBitmap bitmap; | |
533 if (!gfx::PNGCodec::Decode(exact_png->second->front(), | |
534 exact_png->second->size(), | |
535 &bitmap)) { | |
536 NOTREACHED(); | |
537 return gfx::ImageSkiaRep(SkBitmap(), scale_factor); | |
538 } | |
539 bitmap_map_[scale_factor] = bitmap; | |
540 return gfx::ImageSkiaRep(bitmap, scale_factor); | |
541 } | |
542 | |
543 // No exact match was found, find the scale factor with highest scale. | |
544 PngMap::const_iterator available_png = png_map_.end(); | |
545 for (PngMap::const_iterator it = png_map_.begin(); it != png_map_.end(); | |
546 ++it) { | |
547 if (available_png == png_map_.end() || | |
548 (ui::GetScaleFactorScale(it->first) > | |
549 ui::GetScaleFactorScale(available_png->first))) { | |
550 available_png = it; | |
551 } | |
552 } | |
553 if (available_png == png_map_.end()) { | |
554 NOTREACHED(); | |
555 return gfx::ImageSkiaRep(SkBitmap(), scale_factor); | |
556 } | |
557 | |
558 // Look up the found scale factor in the bitmap map. If not found, decode | |
559 // the corresponding png and store the result in bitmap map. | |
560 BitmapMap::const_iterator available_bitmap = | |
561 bitmap_map_.find(available_png->first); | |
562 if (available_bitmap == bitmap_map_.end()) { | |
563 SkBitmap bitmap; | |
564 if (!gfx::PNGCodec::Decode(available_png->second->front(), | |
565 available_png->second->size(), | |
566 &bitmap)) { | |
567 NOTREACHED(); | |
568 return gfx::ImageSkiaRep(SkBitmap(), scale_factor); | |
569 } | |
570 bitmap_map_[available_png->first] = bitmap; | |
571 available_bitmap = bitmap_map_.find(available_png->first); | |
572 } | |
573 | |
574 // Use available bitmap to create bitmap for desired scale factor by | |
575 // scaling, store the result in the bitmap map and return it. | |
576 gfx::Size scaled_size = gfx::ToCeiledSize( | |
577 gfx::ScaleSize(gfx::Size(available_bitmap->second.width(), | |
578 available_bitmap->second.height()), | |
579 ui::GetScaleFactorScale(scale_factor) / | |
580 ui::GetScaleFactorScale(available_bitmap->first))); | |
581 SkBitmap scaled_bitmap; | |
582 scaled_bitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
583 scaled_size.width(), | |
584 scaled_size.height()); | |
585 if (!scaled_bitmap.allocPixels()) | |
586 SK_CRASH(); | |
587 scaled_bitmap.eraseARGB(0, 0, 0, 0); | |
588 SkCanvas canvas(scaled_bitmap); | |
589 SkRect scaled_bounds = RectToSkRect(gfx::Rect(scaled_size)); | |
590 canvas.drawBitmapRect(available_bitmap->second, NULL, scaled_bounds); | |
591 bitmap_map_[scale_factor] = scaled_bitmap; | |
592 return gfx::ImageSkiaRep(scaled_bitmap, scale_factor); | |
593 } | |
594 | |
595 private: | |
596 typedef std::map<ui::ScaleFactor, | |
597 scoped_refptr<base::RefCountedMemory> > PngMap; | |
598 typedef std::map<ui::ScaleFactor, SkBitmap> BitmapMap; | |
599 PngMap png_map_; | |
600 BitmapMap bitmap_map_; | |
601 gfx::Size dip_size_; | |
602 }; | |
603 | |
483 class TabBackgroundImageSource: public gfx::CanvasImageSource { | 604 class TabBackgroundImageSource: public gfx::CanvasImageSource { |
484 public: | 605 public: |
485 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, | 606 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, |
486 const gfx::ImageSkia& overlay, | 607 const gfx::ImageSkia& overlay, |
487 const color_utils::HSL& hsl_shift, | 608 const color_utils::HSL& hsl_shift, |
488 int vertical_offset) | 609 int vertical_offset) |
489 : gfx::CanvasImageSource(image_to_tint.size(), false), | 610 : gfx::CanvasImageSource(image_to_tint.size(), false), |
490 image_to_tint_(image_to_tint), | 611 image_to_tint_(image_to_tint), |
491 overlay_(overlay), | 612 overlay_(overlay), |
492 hsl_shift_(hsl_shift), | 613 hsl_shift_(hsl_shift), |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { | 863 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { |
743 int prs_id = GetPersistentIDByIDR(idr_id); | 864 int prs_id = GetPersistentIDByIDR(idr_id); |
744 if (prs_id == -1) | 865 if (prs_id == -1) |
745 return gfx::Image(); | 866 return gfx::Image(); |
746 | 867 |
747 // Check if the image is cached. | 868 // Check if the image is cached. |
748 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); | 869 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); |
749 if (image_iter != images_on_ui_thread_.end()) | 870 if (image_iter != images_on_ui_thread_.end()) |
750 return image_iter->second; | 871 return image_iter->second; |
751 | 872 |
752 // TODO(pkotwicz): Do something better than loading the bitmaps | 873 ThemeImagePngSource* png_source = NULL; |
753 // for all the scale factors associated with |idr_id|. | 874 for (int pass = 0; pass < 2; ++pass) { |
754 // See crbug.com/243831. | 875 // Two passes: In the first pass, we process only scale factor 100%, if |
755 gfx::ImageSkia source_image_skia; | 876 // available, and in the second pass all other scale factors. The reason is |
756 for (size_t i = 0; i < scale_factors_.size(); ++i) { | 877 // that the first png added, determines the DIP size. |
757 scoped_refptr<base::RefCountedMemory> memory = | 878 for (size_t i = 0; i < scale_factors_.size(); ++i) { |
758 GetRawData(idr_id, scale_factors_[i]); | 879 if ((pass == 0 && scale_factors_[i] != ui::SCALE_FACTOR_100P) || |
759 if (memory.get()) { | 880 (pass == 1 && scale_factors_[i] == ui::SCALE_FACTOR_100P)) { |
760 // Decode the PNG. | |
761 SkBitmap bitmap; | |
762 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), | |
763 &bitmap)) { | |
764 NOTREACHED() << "Unable to decode theme image resource " << idr_id | |
765 << " from saved DataPack."; | |
766 continue; | 881 continue; |
767 } | 882 } |
768 source_image_skia.AddRepresentation( | 883 scoped_refptr<base::RefCountedMemory> memory = |
769 gfx::ImageSkiaRep(bitmap, scale_factors_[i])); | 884 GetRawData(idr_id, scale_factors_[i]); |
885 if (memory.get()) { | |
886 if (!png_source) | |
887 png_source = new ThemeImagePngSource; | |
888 png_source->AddPng(memory, scale_factors_[i]); | |
889 } | |
770 } | 890 } |
771 } | 891 } |
772 | 892 |
773 if (!source_image_skia.isNull()) { | 893 if (png_source) { |
774 ThemeImageSource* source = new ThemeImageSource(source_image_skia); | 894 // |image_skia| owns png_source. |
775 gfx::ImageSkia image_skia(source, source_image_skia.size()); | 895 gfx::ImageSkia image_skia(png_source, png_source->size()); |
776 gfx::Image ret = gfx::Image(image_skia); | 896 gfx::Image ret = gfx::Image(image_skia); |
777 images_on_ui_thread_[prs_id] = ret; | 897 images_on_ui_thread_[prs_id] = ret; |
778 return ret; | 898 return ret; |
779 } | 899 } |
900 | |
780 return gfx::Image(); | 901 return gfx::Image(); |
781 } | 902 } |
782 | 903 |
783 base::RefCountedMemory* BrowserThemePack::GetRawData( | 904 base::RefCountedMemory* BrowserThemePack::GetRawData( |
784 int idr_id, | 905 int idr_id, |
785 ui::ScaleFactor scale_factor) const { | 906 ui::ScaleFactor scale_factor) const { |
786 base::RefCountedMemory* memory = NULL; | 907 base::RefCountedMemory* memory = NULL; |
787 int prs_id = GetPersistentIDByIDR(idr_id); | 908 int prs_id = GetPersistentIDByIDR(idr_id); |
788 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); | 909 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); |
789 | 910 |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1526 false, | 1647 false, |
1527 &bitmap_data)) { | 1648 &bitmap_data)) { |
1528 NOTREACHED() << "Unable to encode theme image for prs_id=" | 1649 NOTREACHED() << "Unable to encode theme image for prs_id=" |
1529 << prs_id << " for scale_factor=" << scale_factors_[i]; | 1650 << prs_id << " for scale_factor=" << scale_factors_[i]; |
1530 break; | 1651 break; |
1531 } | 1652 } |
1532 image_memory_[scaled_raw_id] = | 1653 image_memory_[scaled_raw_id] = |
1533 base::RefCountedBytes::TakeVector(&bitmap_data); | 1654 base::RefCountedBytes::TakeVector(&bitmap_data); |
1534 } | 1655 } |
1535 } | 1656 } |
OLD | NEW |