diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-05 17:52:13 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-05 17:52:13 +0000 |
commit | 59723ccf4b1815ed73b42b9b4a4e9d7f3c76fb84 (patch) | |
tree | 99d06005cadb99487772429a61b414eae8cfce51 | |
parent | 931d10471ccadf4cff77f2159658244d0ef4469c (diff) | |
download | chromium_src-59723ccf4b1815ed73b42b9b4a4e9d7f3c76fb84.zip chromium_src-59723ccf4b1815ed73b42b9b4a4e9d7f3c76fb84.tar.gz chromium_src-59723ccf4b1815ed73b42b9b4a4e9d7f3c76fb84.tar.bz2 |
Crop images from custom themes before storing them into the theme pack.
BUG=176857
Test=None
R=erg
TBR=sky (For ui/linux_ui/linux_ui.h)
Review URL: https://chromiumcodereview.appspot.com/13497002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192595 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/themes/browser_theme_pack.cc | 136 | ||||
-rw-r--r-- | chrome/browser/themes/browser_theme_pack.h | 23 | ||||
-rw-r--r-- | chrome/browser/themes/theme_service.cc | 11 | ||||
-rw-r--r-- | chrome/browser/themes/theme_service_mac.mm | 6 | ||||
-rw-r--r-- | chrome/browser/ui/libgtk2ui/gtk2_ui.cc | 10 | ||||
-rw-r--r-- | chrome/browser/ui/libgtk2ui/gtk2_ui.h | 4 | ||||
-rw-r--r-- | ui/linux_ui/linux_ui.h | 2 |
7 files changed, 115 insertions, 77 deletions
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index ffa47dc..26b35d2 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc @@ -28,7 +28,6 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/image/canvas_image_source.h" -#include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/screen.h" @@ -332,7 +331,7 @@ struct IntToIntTable { int value; }; -// Mapping used in GenerateFrameImages() to associate frame images with the +// Mapping used in CreateFrameImages() to associate frame images with the // tint ID that should maybe be applied to it. IntToIntTable kFrameTintMap[] = { { PRS_THEME_FRAME, ThemeProperties::TINT_FRAME }, @@ -363,22 +362,59 @@ IntToIntTable kTabBackgroundMap[] = { #endif }; +struct CropEntry { + int prs_id; + + // The maximum useful height of the image at |prs_id|. + int max_height; + + // Whether cropping the image at |prs_id| should be skipped on OSes which + // have a frame border to the left and right of the web contents. + // This should be true for images which can be used to decorate the border to + // the left and the right of the web contents. + bool skip_if_frame_border; +}; + +// The images which should be cropped before being saved to the data pack. The +// maximum heights are meant to be conservative as to give room for the UI to +// change without the maximum heights having to be modified. +// |kThemePackVersion| must be incremented if any of the maximum heights below +// are modified. +struct CropEntry kImagesToCrop[] = { + { PRS_THEME_FRAME, 120, true }, + { PRS_THEME_FRAME_INACTIVE, 120, true }, + { PRS_THEME_FRAME_INCOGNITO, 120, true }, + { PRS_THEME_FRAME_INCOGNITO_INACTIVE, 120, true }, + { PRS_THEME_FRAME_OVERLAY, 120, true }, + { PRS_THEME_FRAME_OVERLAY_INACTIVE, 120, true }, + { PRS_THEME_TOOLBAR, 200, false }, + { PRS_THEME_BUTTON_BACKGROUND, 60, false }, + { PRS_THEME_WINDOW_CONTROL_BACKGROUND, 50, false }, +#if defined(OS_WIN) && defined(USE_AURA) + { PRS_THEME_TOOLBAR_WIN, 200, false } +#endif +}; + // A list of images that don't need tinting or any other modification and can // be byte-copied directly into the finished DataPack. This should contain the -// persistent IDs for all themeable image IDs that aren't in kFrameTintMap or -// kTabBackgroundMap. +// persistent IDs for all themeable image IDs that aren't in kFrameTintMap, +// kTabBackgroundMap or kImagesToCrop. const int kPreloadIDs[] = { - PRS_THEME_TOOLBAR, PRS_THEME_NTP_BACKGROUND, - PRS_THEME_BUTTON_BACKGROUND, PRS_THEME_NTP_ATTRIBUTION, - PRS_THEME_WINDOW_CONTROL_BACKGROUND, -#if defined(OS_WIN) && defined(USE_AURA) - PRS_THEME_TOOLBAR_WIN, -#endif }; +// Returns true if this OS uses a browser frame which has a non zero width to +// the left and the right of the web contents. +bool HasFrameBorder() { +#if defined(OS_CHROMEOS) || defined(OS_MACOSX) + return false; +#else + return true; +#endif +} + // Returns a piece of memory with the contents of the file |path|. base::RefCountedMemory* ReadFileData(const base::FilePath& path) { if (!path.empty()) { @@ -402,10 +438,10 @@ base::RefCountedMemory* ReadFileData(const base::FilePath& path) { // Shifts an image's HSL values. The caller is responsible for deleting // the returned image. -gfx::Image* CreateHSLShiftedImage(const gfx::Image& image, - const color_utils::HSL& hsl_shift) { +gfx::Image CreateHSLShiftedImage(const gfx::Image& image, + const color_utils::HSL& hsl_shift) { const gfx::ImageSkia* src_image = image.ToImageSkia(); - return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( + return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( *src_image, hsl_shift)); } @@ -495,9 +531,6 @@ BrowserThemePack::~BrowserThemePack() { delete [] display_properties_; delete [] source_images_; } - - STLDeleteValues(&images_on_ui_thread_); - STLDeleteValues(&images_on_file_thread_); } // static @@ -525,17 +558,15 @@ scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension( if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) return NULL; - pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_); - pack->CreateImages(&pack->images_on_ui_thread_); - pack->CreateImages(&pack->images_on_file_thread_); // Make sure the |images_on_file_thread_| has bitmaps for supported // scale factors before passing to FILE thread. + pack->images_on_file_thread_ = pack->images_on_ui_thread_; for (ImageCache::iterator it = pack->images_on_file_thread_.begin(); it != pack->images_on_file_thread_.end(); ++it) { gfx::ImageSkia* image_skia = - const_cast<gfx::ImageSkia*>(it->second->ToImageSkia()); + const_cast<gfx::ImageSkia*>(it->second.ToImageSkia()); image_skia->MakeThreadSafe(); } @@ -689,10 +720,10 @@ bool BrowserThemePack::GetDisplayProperty(int id, int* result) const { return false; } -const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { +gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { int prs_id = GetPersistentIDByIDR(idr_id); if (prs_id == -1) - return NULL; + return gfx::Image(); // Check if the image is cached. ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); @@ -722,11 +753,11 @@ const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const { if (!source_image_skia.isNull()) { ThemeImageSource* source = new ThemeImageSource(source_image_skia); gfx::ImageSkia image_skia(source, source_image_skia.size()); - gfx::Image* ret = new gfx::Image(image_skia); + gfx::Image ret = gfx::Image(image_skia); images_on_ui_thread_[prs_id] = ret; return ret; } - return NULL; + return gfx::Image(); } base::RefCountedMemory* BrowserThemePack::GetRawData( @@ -1096,7 +1127,7 @@ bool BrowserThemePack::LoadRawBitmapsTo( if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), &bitmap)) { (*image_cache)[prs_id] = - new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); + gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); } else { NOTREACHED() << "Unable to decode theme image resource " << it->first; } @@ -1107,11 +1138,30 @@ bool BrowserThemePack::LoadRawBitmapsTo( } void BrowserThemePack::CreateImages(ImageCache* images) const { + CropImages(images); CreateFrameImages(images); CreateTintedButtons(GetTintInternal(ThemeProperties::TINT_BUTTONS), images); CreateTabBackgroundImages(images); } +void BrowserThemePack::CropImages(ImageCache* images) const { + bool has_frame_border = HasFrameBorder(); + for (size_t i = 0; i < arraysize(kImagesToCrop); ++i) { + if (has_frame_border && kImagesToCrop[i].skip_if_frame_border) + continue; + + int prs_id = kImagesToCrop[i].prs_id; + ImageCache::iterator it = images->find(prs_id); + if (it == images->end()) + continue; + + int crop_height = kImagesToCrop[i].max_height; + gfx::ImageSkia image_skia = it->second.AsImageSkia(); + (*images)[prs_id] = gfx::Image(gfx::ImageSkiaOperations::ExtractSubset( + image_skia, gfx::Rect(0, 0, image_skia.width(), crop_height))); + } +} + void BrowserThemePack::CreateFrameImages(ImageCache* images) const { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); @@ -1121,7 +1171,7 @@ void BrowserThemePack::CreateFrameImages(ImageCache* images) const { for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { int prs_id = kFrameTintMap[i].key; - const gfx::Image* frame = NULL; + gfx::Image frame; // If there's no frame image provided for the specified id, then load // the default provided frame. If that's not provided, skip this whole // thing and just use the default images. @@ -1166,22 +1216,22 @@ void BrowserThemePack::CreateFrameImages(ImageCache* images) const { // If there is no theme overlay, don't tint the default frame, // because it will overwrite the custom frame image when we cache and // reload from disk. - frame = NULL; + frame = gfx::Image(); } } else { // If the theme doesn't specify an image, then apply the tint to // the default frame. - frame = &rb.GetImageNamed(IDR_THEME_FRAME); + frame = rb.GetImageNamed(IDR_THEME_FRAME); #if defined(OS_WIN) && defined(USE_AURA) if (prs_id >= PRS_THEME_FRAME_WIN && prs_id <= PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN) { - frame = &rb.GetImageNamed(IDR_THEME_FRAME_WIN); + frame = rb.GetImageNamed(IDR_THEME_FRAME_WIN); } #endif } - if (frame) { + if (!frame.IsEmpty()) { temp_output[prs_id] = CreateHSLShiftedImage( - *frame, GetTintInternal(kFrameTintMap[i].value)); + frame, GetTintInternal(kFrameTintMap[i].value)); } } MergeImageCaches(temp_output, images); @@ -1219,7 +1269,7 @@ void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { // with a PRS_THEME_FRAME. ImageCache::const_iterator it = images->find(prs_base_id); if (it != images->end()) { - const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia(); + gfx::ImageSkia image_to_tint = (it->second).AsImageSkia(); color_utils::HSL hsl_shift = GetTintInternal( ThemeProperties::TINT_BACKGROUND_TAB); int vertical_offset = images->count(prs_id) @@ -1228,13 +1278,13 @@ void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { gfx::ImageSkia overlay; ImageCache::const_iterator overlay_it = images->find(prs_id); if (overlay_it != images->end()) - overlay = *overlay_it->second->ToImageSkia(); + overlay = overlay_it->second.AsImageSkia(); gfx::ImageSkiaSource* source = new TabBackgroundImageSource( - *image_to_tint, overlay, hsl_shift, vertical_offset); + image_to_tint, overlay, hsl_shift, vertical_offset); // ImageSkia takes ownership of |source|. - temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source, - image_to_tint->size())); + temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, + image_to_tint.size())); } } MergeImageCaches(temp_output, images); @@ -1245,7 +1295,7 @@ void BrowserThemePack::RepackImages(const ImageCache& images, typedef std::vector<ui::ScaleFactor> ScaleFactors; for (ImageCache::const_iterator it = images.begin(); it != images.end(); ++it) { - gfx::ImageSkia image_skia = *it->second->ToImageSkia(); + gfx::ImageSkia image_skia = *it->second.ToImageSkia(); typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; ImageSkiaReps image_reps = image_skia.image_reps(); @@ -1271,22 +1321,10 @@ void BrowserThemePack::MergeImageCaches( const ImageCache& source, ImageCache* destination) const { for (ImageCache::const_iterator it = source.begin(); it != source.end(); ++it) { - ImageCache::const_iterator image_it = destination->find(it->first); - if (image_it != destination->end()) - delete image_it->second; - (*destination)[it->first] = it->second; } } -void BrowserThemePack::CopyImagesTo(const ImageCache& source, - ImageCache* destination) const { - for (ImageCache::const_iterator it = source.begin(); it != source.end(); - ++it) { - (*destination)[it->first] = new gfx::Image(*it->second); - } -} - void BrowserThemePack::AddRawImagesTo(const RawImages& images, RawDataForWriting* out) const { for (RawImages::const_iterator it = images.begin(); it != images.end(); diff --git a/chrome/browser/themes/browser_theme_pack.h b/chrome/browser/themes/browser_theme_pack.h index ce5b318..a30bf58 100644 --- a/chrome/browser/themes/browser_theme_pack.h +++ b/chrome/browser/themes/browser_theme_pack.h @@ -18,6 +18,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/base/layout.h" #include "ui/gfx/color_utils.h" +#include "ui/gfx/image/image.h" namespace base { class DictionaryValue; @@ -29,10 +30,6 @@ namespace extensions { class Extensions; } -namespace gfx { -class Image; -} - namespace ui { class DataPack; } @@ -84,8 +81,9 @@ class BrowserThemePack : public base::RefCountedThreadSafe< bool GetColor(int id, SkColor* color) const; bool GetDisplayProperty(int id, int* result) const; - // Returns an image if we have a custom image for |id|, otherwise NULL. - const gfx::Image* GetImageNamed(int id) const; + // Returns the theme pack image for |id|. Returns an empty image if an image + // is not found. + gfx::Image GetImageNamed(int id); // Returns the raw PNG encoded data for IDR_THEME_NTP_*. This method is only // supposed to work for the NTP attribution and background resources. @@ -105,10 +103,8 @@ class BrowserThemePack : public base::RefCountedThreadSafe< friend class base::DeleteHelper<BrowserThemePack>; friend class BrowserThemePackTest; - // Cached images. We cache all retrieved and generated images and keep - // track of the pointers. We own these and will delete them when we're done - // using them. - typedef std::map<int, const gfx::Image*> ImageCache; + // Cached images. + typedef std::map<int, gfx::Image> ImageCache; // The raw PNG memory associated with a certain id. typedef std::map<int, scoped_refptr<base::RefCountedMemory> > RawImages; @@ -161,6 +157,11 @@ class BrowserThemePack : public base::RefCountedThreadSafe< // Source and destination is |images|. void CreateImages(ImageCache* images) const; + // Crops images down to a size such that most of the cropped image will be + // displayed in the UI. Cropping is useful because images from custom themes + // can be of any size. Source and destination is |images|. + void CropImages(ImageCache* images) const; + // Creates tinted and composited frame images. Source and destination is // |images|. void CreateFrameImages(ImageCache* images) const; @@ -256,7 +257,7 @@ class BrowserThemePack : public base::RefCountedThreadSafe< // Loaded images. These are loaded from |image_memory_|, from |data_pack_|, // and by BuildFromExtension(). These images should only be accessed on the UI // thread. - mutable ImageCache images_on_ui_thread_; + ImageCache images_on_ui_thread_; // Cache of images created in BuildFromExtension(). Once the theme pack is // created, this cache should only be accessed on the file thread. There diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index d540b60..512855d 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc @@ -108,21 +108,20 @@ void ThemeService::Init(Profile* profile) { gfx::Image ThemeService::GetImageNamed(int id) const { DCHECK(CalledOnValidThread()); - const gfx::Image* image = NULL; - + gfx::Image image; if (theme_pack_.get()) image = theme_pack_->GetImageNamed(id); #if defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX) const ui::LinuxUI* linux_ui = ui::LinuxUI::instance(); - if (!image && linux_ui) + if (image.IsEmpty() && linux_ui) image = linux_ui->GetThemeImageNamed(id); #endif - if (!image) - image = &rb_.GetNativeImageNamed(id); + if (image.IsEmpty()) + image = rb_.GetNativeImageNamed(id); - return image ? *image : gfx::Image(); + return image; } gfx::ImageSkia* ThemeService::GetImageSkiaNamed(int id) const { diff --git a/chrome/browser/themes/theme_service_mac.mm b/chrome/browser/themes/theme_service_mac.mm index abb441b..146558e 100644 --- a/chrome/browser/themes/theme_service_mac.mm +++ b/chrome/browser/themes/theme_service_mac.mm @@ -52,9 +52,9 @@ NSImage* ThemeService::GetNSImageNamed(int id, bool allow_default) const { // - To get the generated tinted images. NSImage* nsimage = nil; if (theme_pack_.get()) { - const gfx::Image* image = theme_pack_->GetImageNamed(id); - if (image) - nsimage = image->ToNSImage(); + gfx::Image image = theme_pack_->GetImageNamed(id); + if (!image.IsEmpty()) + nsimage = image.ToNSImage(); } // If the theme didn't override this image then load it from the resource diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc index 7f8e18f..9e6443bc 100644 --- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc +++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc @@ -309,20 +309,20 @@ bool Gtk2UI::UseNativeTheme() const { return true; } -gfx::Image* Gtk2UI::GetThemeImageNamed(int id) const { +gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { // Try to get our cached version: ImageCache::const_iterator it = gtk_images_.find(id); if (it != gtk_images_.end()) return it->second; if (/*use_gtk_ && */ IsOverridableImage(id)) { - gfx::Image* image = new gfx::Image( + gfx::Image image = gfx::Image( gfx::ImageSkia::CreateFrom1xBitmap(GenerateGtkThemeBitmap(id))); gtk_images_[id] = image; return image; } - return NULL; + return gfx::Image(); } bool Gtk2UI::GetColor(int id, SkColor* color) const { @@ -795,7 +795,7 @@ SkBitmap Gtk2UI::GenerateFrameImage( } SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { - const SkBitmap* base_image = GetThemeImageNamed(base_id)->ToSkBitmap(); + const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); return SkBitmapOperations::CreateTiledBitmap( @@ -973,7 +973,7 @@ SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, } void Gtk2UI::ClearAllThemeData() { - STLDeleteValues(>k_images_); + gtk_images_.clear(); } } // namespace libgtk2ui diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.h b/chrome/browser/ui/libgtk2ui/gtk2_ui.h index 7e8ca67..5d1d681 100644 --- a/chrome/browser/ui/libgtk2ui/gtk2_ui.h +++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.h @@ -40,14 +40,14 @@ class Gtk2UI : public ui::LinuxUI { // ui::LinuxUI: virtual bool UseNativeTheme() const OVERRIDE; - virtual gfx::Image* GetThemeImageNamed(int id) const OVERRIDE; + virtual gfx::Image GetThemeImageNamed(int id) const OVERRIDE; virtual bool GetColor(int id, SkColor* color) const OVERRIDE; virtual ui::NativeTheme* GetNativeTheme() const OVERRIDE; private: typedef std::map<int, SkColor> ColorMap; typedef std::map<int, color_utils::HSL> TintMap; - typedef std::map<int, gfx::Image*> ImageCache; + typedef std::map<int, gfx::Image> ImageCache; // This method returns the colors webkit will use for the scrollbars. When no // colors are specified by the GTK+ theme, this function averages of the diff --git a/ui/linux_ui/linux_ui.h b/ui/linux_ui/linux_ui.h index 80f518f..85decc8 100644 --- a/ui/linux_ui/linux_ui.h +++ b/ui/linux_ui/linux_ui.h @@ -45,7 +45,7 @@ class LINUX_UI_EXPORT LinuxUI : public LinuxShellDialog { // Returns an themed image per theme_provider.h virtual bool UseNativeTheme() const = 0; - virtual gfx::Image* GetThemeImageNamed(int id) const = 0; + virtual gfx::Image GetThemeImageNamed(int id) const = 0; virtual bool GetColor(int id, SkColor* color) const = 0; // Returns a NativeTheme that will provide system colors and draw system |