Index: chrome/browser/themes/browser_theme_pack.cc |
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc |
index 988450ed95488717afee60735f164790046d14ec..60f254d99c49f41e49c6d65f6cf69521e3999ef4 100644 |
--- a/chrome/browser/themes/browser_theme_pack.cc |
+++ b/chrome/browser/themes/browser_theme_pack.cc |
@@ -44,7 +44,7 @@ namespace { |
// Version number of the current theme pack. We just throw out and rebuild |
// theme packs that aren't int-equal to this. Increment this number if you |
// change default theme assets. |
-const int kThemePackVersion = 31; |
+const int kThemePackVersion = 32; |
// IDs that are in the DataPack won't clash with the positive integer |
// uint16. kHeaderID should always have the maximum value because we want the |
@@ -59,10 +59,6 @@ const int kDisplayPropertiesID = kMaxID - 4; |
const int kSourceImagesID = kMaxID - 5; |
const int kScaleFactorsID = kMaxID - 6; |
-// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from |
-// OpaqueBrowserFrameView. |
-const int kRestoredTabVerticalOffset = 15; |
- |
// Persistent constants for the main images that we need. These have the same |
// names as their IDR_* counterparts but these values will always stay the |
// same. |
@@ -71,15 +67,17 @@ const int PRS_THEME_FRAME_INACTIVE = 2; |
const int PRS_THEME_FRAME_INCOGNITO = 3; |
const int PRS_THEME_FRAME_INCOGNITO_INACTIVE = 4; |
const int PRS_THEME_TOOLBAR = 5; |
-const int PRS_THEME_TAB_BACKGROUND = 6; |
-const int PRS_THEME_TAB_BACKGROUND_INCOGNITO = 7; |
-const int PRS_THEME_TAB_BACKGROUND_V = 8; |
+const int PRS_THEME_TAB_BACKGROUND_OVERLAY = 6; |
+const int PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY = 7; |
+const int PRS_THEME_TAB_BACKGROUND_V_OVERLAY = 8; |
const int PRS_THEME_NTP_BACKGROUND = 9; |
const int PRS_THEME_FRAME_OVERLAY = 10; |
const int PRS_THEME_FRAME_OVERLAY_INACTIVE = 11; |
const int PRS_THEME_BUTTON_BACKGROUND = 12; |
const int PRS_THEME_NTP_ATTRIBUTION = 13; |
const int PRS_THEME_WINDOW_CONTROL_BACKGROUND = 14; |
+const int PRS_THEME_TAB_BACKGROUND = 15; |
+const int PRS_THEME_TAB_BACKGROUND_INCOGNITO = 16; |
struct PersistingImagesTable { |
// A non-changing integer ID meant to be saved in theme packs. This ID must |
@@ -108,11 +106,12 @@ PersistingImagesTable kPersistingImages[] = { |
"theme_frame_incognito_inactive" }, |
{ PRS_THEME_TOOLBAR, IDR_THEME_TOOLBAR, |
"theme_toolbar" }, |
- { PRS_THEME_TAB_BACKGROUND, IDR_THEME_TAB_BACKGROUND, |
+ { PRS_THEME_TAB_BACKGROUND_OVERLAY, IDR_THEME_TAB_BACKGROUND_OVERLAY, |
"theme_tab_background" }, |
- { PRS_THEME_TAB_BACKGROUND_INCOGNITO, IDR_THEME_TAB_BACKGROUND_INCOGNITO, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY, |
+ IDR_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY, |
"theme_tab_background_incognito" }, |
- { PRS_THEME_TAB_BACKGROUND_V, IDR_THEME_TAB_BACKGROUND_V, |
+ { PRS_THEME_TAB_BACKGROUND_V_OVERLAY, IDR_THEME_TAB_BACKGROUND_V_OVERLAY, |
"theme_tab_background_v"}, |
{ PRS_THEME_NTP_BACKGROUND, IDR_THEME_NTP_BACKGROUND, |
"theme_ntp_background" }, |
@@ -129,37 +128,40 @@ PersistingImagesTable kPersistingImages[] = { |
// The rest of these entries have no key because they can't be overridden |
// from the json manifest. |
- { 15, IDR_BACK, NULL }, |
- { 16, IDR_BACK_D, NULL }, |
- { 17, IDR_BACK_H, NULL }, |
- { 18, IDR_BACK_P, NULL }, |
- { 19, IDR_FORWARD, NULL }, |
- { 20, IDR_FORWARD_D, NULL }, |
- { 21, IDR_FORWARD_H, NULL }, |
- { 22, IDR_FORWARD_P, NULL }, |
- { 23, IDR_HOME, NULL }, |
- { 24, IDR_HOME_H, NULL }, |
- { 25, IDR_HOME_P, NULL }, |
- { 26, IDR_RELOAD, NULL }, |
- { 27, IDR_RELOAD_H, NULL }, |
- { 28, IDR_RELOAD_P, NULL }, |
- { 29, IDR_STOP, NULL }, |
- { 30, IDR_STOP_D, NULL }, |
- { 31, IDR_STOP_H, NULL }, |
- { 32, IDR_STOP_P, NULL }, |
- { 33, IDR_BROWSER_ACTIONS_OVERFLOW, NULL }, |
- { 34, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, |
- { 35, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, |
- { 36, IDR_TOOLS, NULL }, |
- { 37, IDR_TOOLS_H, NULL }, |
- { 38, IDR_TOOLS_P, NULL }, |
- { 39, IDR_MENU_DROPARROW, NULL }, |
- { 40, IDR_THROBBER, NULL }, |
- { 41, IDR_THROBBER_WAITING, NULL }, |
- { 42, IDR_THROBBER_LIGHT, NULL }, |
- { 43, IDR_TOOLBAR_BEZEL_HOVER, NULL }, |
- { 44, IDR_TOOLBAR_BEZEL_PRESSED, NULL }, |
- { 45, IDR_TOOLS_BAR, NULL }, |
+ { PRS_THEME_TAB_BACKGROUND, IDR_THEME_TAB_BACKGROUND, NULL }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO, |
+ IDR_THEME_TAB_BACKGROUND_INCOGNITO, NULL }, |
+ { 17, IDR_BACK, NULL }, |
+ { 18, IDR_BACK_D, NULL }, |
+ { 19, IDR_BACK_H, NULL }, |
+ { 20, IDR_BACK_P, NULL }, |
+ { 21, IDR_FORWARD, NULL }, |
+ { 22, IDR_FORWARD_D, NULL }, |
+ { 23, IDR_FORWARD_H, NULL }, |
+ { 24, IDR_FORWARD_P, NULL }, |
+ { 25, IDR_HOME, NULL }, |
+ { 26, IDR_HOME_H, NULL }, |
+ { 27, IDR_HOME_P, NULL }, |
+ { 28, IDR_RELOAD, NULL }, |
+ { 29, IDR_RELOAD_H, NULL }, |
+ { 30, IDR_RELOAD_P, NULL }, |
+ { 31, IDR_STOP, NULL }, |
+ { 32, IDR_STOP_D, NULL }, |
+ { 33, IDR_STOP_H, NULL }, |
+ { 34, IDR_STOP_P, NULL }, |
+ { 35, IDR_BROWSER_ACTIONS_OVERFLOW, NULL }, |
+ { 36, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL }, |
+ { 37, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL }, |
+ { 38, IDR_TOOLS, NULL }, |
+ { 39, IDR_TOOLS_H, NULL }, |
+ { 40, IDR_TOOLS_P, NULL }, |
+ { 41, IDR_MENU_DROPARROW, NULL }, |
+ { 42, IDR_THROBBER, NULL }, |
+ { 43, IDR_THROBBER_WAITING, NULL }, |
+ { 44, IDR_THROBBER_LIGHT, NULL }, |
+ { 45, IDR_TOOLBAR_BEZEL_HOVER, NULL }, |
+ { 46, IDR_TOOLBAR_BEZEL_PRESSED, NULL }, |
+ { 47, IDR_TOOLS_BAR, NULL }, |
}; |
const size_t kPersistingImagesLength = arraysize(kPersistingImages); |
@@ -170,8 +172,10 @@ const int PRS_THEME_FRAME_INACTIVE_WIN = 101; |
const int PRS_THEME_FRAME_INCOGNITO_WIN = 102; |
const int PRS_THEME_FRAME_INCOGNITO_INACTIVE_WIN = 103; |
const int PRS_THEME_TOOLBAR_WIN = 104; |
-const int PRS_THEME_TAB_BACKGROUND_WIN = 105; |
-const int PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN = 106; |
+const int PRS_THEME_TAB_BACKGROUND_OVERLAY_WIN = 105; |
+const int PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY_WIN = 106; |
+const int PRS_THEME_TAB_BACKGROUND_WIN = 107; |
+const int PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN = 108; |
// Persistent theme to resource id mapping for Windows AURA. |
PersistingImagesTable kPersistingImagesWinDesktopAura[] = { |
@@ -186,11 +190,15 @@ PersistingImagesTable kPersistingImagesWinDesktopAura[] = { |
"theme_frame_incognito_inactive" }, |
{ PRS_THEME_TOOLBAR_WIN, IDR_THEME_TOOLBAR_WIN, |
"theme_toolbar" }, |
- { PRS_THEME_TAB_BACKGROUND_WIN, IDR_THEME_TAB_BACKGROUND_WIN, |
+ { PRS_THEME_TAB_BACKGROUND_OVERLAY_WIN, IDR_THEME_TAB_BACKGROUND_OVERLAY_WIN, |
"theme_tab_background" }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY_WIN, |
+ IDR_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY_WIN, |
+ "theme_tab_background_incognito" }, |
+ { PRS_THEME_TAB_BACKGROUND_WIN, IDR_THEME_TAB_BACKGROUND_WIN, NULL }, |
{ PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN, |
IDR_THEME_TAB_BACKGROUND_INCOGNITO_WIN, |
- "theme_tab_background_incognito" }, |
+ NULL }, |
}; |
const size_t kPersistingImagesWinDesktopAuraLength = |
arraysize(kPersistingImagesWinDesktopAura); |
@@ -351,7 +359,7 @@ IntToIntTable kFrameTintMap[] = { |
#endif |
}; |
-// Mapping used in GenerateTabBackgroundImages() to associate what frame image |
+// Mapping used in CreateTabBackgroundImages() to associate what frame image |
// goes with which tab background. |
IntToIntTable kTabBackgroundMap[] = { |
{ PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME }, |
@@ -362,6 +370,17 @@ IntToIntTable kTabBackgroundMap[] = { |
#endif |
}; |
+// The tab background overlay images. For the sake of simplicity, these images |
+// are resized to have the exact height listed in |kImagesToCrop|. |
+int kTabBackgroundOverlayImages[] = { |
+ PRS_THEME_TAB_BACKGROUND_OVERLAY, |
+ PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY, |
+#if defined(OS_WIN) && defined(USE_AURA) |
+ PRS_THEME_TAB_BACKGROUND_OVERLAY_WIN, |
+ PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY_WIN |
+#endif |
+}; |
+ |
struct CropEntry { |
int prs_id; |
@@ -380,7 +399,7 @@ struct CropEntry { |
// 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[] = { |
+CropEntry kImagesToCrop[] = { |
{ PRS_THEME_FRAME, 120, true }, |
{ PRS_THEME_FRAME_INACTIVE, 120, true }, |
{ PRS_THEME_FRAME_INCOGNITO, 120, true }, |
@@ -388,14 +407,22 @@ struct CropEntry kImagesToCrop[] = { |
{ PRS_THEME_FRAME_OVERLAY, 120, true }, |
{ PRS_THEME_FRAME_OVERLAY_INACTIVE, 120, true }, |
{ PRS_THEME_TOOLBAR, 200, false }, |
+ { PRS_THEME_TAB_BACKGROUND_OVERLAY, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_V_OVERLAY, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO, 120, 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 } |
+ { PRS_THEME_TOOLBAR_WIN, 200, false }, |
+ { PRS_THEME_TAB_BACKGROUND_OVERLAY_WIN, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO_OVERLAY_WIN, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_WIN, 120, false }, |
+ { PRS_THEME_TAB_BACKGROUND_INCOGNITO_WIN, 120, 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, |
@@ -436,13 +463,41 @@ base::RefCountedMemory* ReadFileData(const base::FilePath& path) { |
return NULL; |
} |
-// 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) { |
- const gfx::ImageSkia* src_image = image.ToImageSkia(); |
+// Returns the maximum height for |prs_id|. Returns -1 if there is no maximum |
+// height. |
+int GetMaxHeight(int prs_id) { |
+ for (size_t i = 0; i < arraysize(kImagesToCrop); ++i) { |
+ if (kImagesToCrop[i].prs_id != prs_id) |
+ continue; |
+ |
+ if (HasFrameBorder() && kImagesToCrop[i].skip_if_frame_border) |
+ return -1; |
+ return kImagesToCrop[i].max_height; |
+ } |
+ return -1; |
+} |
+ |
+// Returns an image which is cropped based on the maximum height for |
+// |destination_prs_id|. This method is a no-op if no cropping is necessary. |
+gfx::Image CreateCroppedImage(const gfx::Image& source_image, |
+ int destination_prs_id) { |
+ int crop_height = GetMaxHeight(destination_prs_id); |
+ if (crop_height < 0) |
+ return source_image; |
+ |
+ gfx::ImageSkia image_skia = source_image.AsImageSkia(); |
+ return gfx::Image(gfx::ImageSkiaOperations::ExtractSubset( |
+ image_skia, gfx::Rect(0, 0, image_skia.width(), crop_height))); |
+} |
+ |
+// Returns an image which is cropped based on the maximum height for |
+// |destination_prs_id| and which is shifted by |hsl_shift|. |
+gfx::Image CreateHSLShiftedAndCroppedImage(const gfx::Image& image, |
+ const color_utils::HSL& hsl_shift, |
+ int destination_prs_id) { |
+ gfx::Image cropped = CreateCroppedImage(image, destination_prs_id); |
return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( |
- *src_image, hsl_shift)); |
+ cropped.AsImageSkia(), hsl_shift)); |
} |
// Computes a bitmap at one scale from a bitmap at a different scale. |
@@ -582,44 +637,27 @@ class ThemeImagePngSource : public gfx::ImageSkiaSource { |
DISALLOW_COPY_AND_ASSIGN(ThemeImagePngSource); |
}; |
-class TabBackgroundImageSource: public gfx::CanvasImageSource { |
+// ImageSkiaSource which resizes |image| to |size| by adding transparent pixels |
+// to the bottom and to the right of |image|. |
+class PadWithTransparentImageSource : public gfx::CanvasImageSource { |
public: |
- TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, |
- const gfx::ImageSkia& overlay, |
- const color_utils::HSL& hsl_shift, |
- int vertical_offset) |
- : gfx::CanvasImageSource(image_to_tint.size(), false), |
- image_to_tint_(image_to_tint), |
- overlay_(overlay), |
- hsl_shift_(hsl_shift), |
- vertical_offset_(vertical_offset) { |
+ PadWithTransparentImageSource(const gfx::ImageSkia& image, |
+ const gfx::Size& size) |
+ : gfx::CanvasImageSource(size, false), |
+ image_(image) { |
} |
- |
- virtual ~TabBackgroundImageSource() { |
+ virtual ~PadWithTransparentImageSource() { |
} |
+ private: |
// Overridden from CanvasImageSource: |
virtual void Draw(gfx::Canvas* canvas) OVERRIDE { |
- gfx::ImageSkia bg_tint = |
- gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_, |
- hsl_shift_); |
- canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0, |
- size().width(), size().height()); |
- |
- // If they've provided a custom image, overlay it. |
- if (!overlay_.isNull()) { |
- canvas->TileImageInt(overlay_, 0, 0, size().width(), |
- overlay_.height()); |
- } |
+ canvas->DrawImageInt(image_, 0, 0); |
} |
- private: |
- const gfx::ImageSkia image_to_tint_; |
- const gfx::ImageSkia overlay_; |
- const color_utils::HSL hsl_shift_; |
- const int vertical_offset_; |
+ const gfx::ImageSkia image_; |
- DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource); |
+ DISALLOW_COPY_AND_ASSIGN(PadWithTransparentImageSource); |
}; |
} // namespace |
@@ -1308,21 +1346,12 @@ void BrowserThemePack::CreateImages(ImageCache* images) const { |
} |
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))); |
+ ImageCache temp_output; |
+ for (ImageCache::const_iterator it = images->begin(); |
+ it != images->end(); ++it) { |
+ temp_output[it->first] = CreateCroppedImage(it->second, it->first); |
} |
+ MergeImageCaches(temp_output, images); |
} |
void BrowserThemePack::CreateFrameImages(ImageCache* images) const { |
@@ -1393,8 +1422,8 @@ void BrowserThemePack::CreateFrameImages(ImageCache* images) const { |
#endif |
} |
if (!frame.IsEmpty()) { |
- temp_output[prs_id] = CreateHSLShiftedImage( |
- frame, GetTintInternal(kFrameTintMap[i].value)); |
+ temp_output[prs_id] = CreateHSLShiftedAndCroppedImage( |
+ frame, GetTintInternal(kFrameTintMap[i].value), prs_id); |
} |
} |
MergeImageCaches(temp_output, images); |
@@ -1417,7 +1446,7 @@ void BrowserThemePack::CreateTintedButtons( |
// but save a version with the persistent ID. |
(*processed_images)[prs_id] = |
- CreateHSLShiftedImage(button, button_tint); |
+ CreateHSLShiftedAndCroppedImage(button, button_tint, prs_id); |
} |
} |
} |
@@ -1425,30 +1454,41 @@ void BrowserThemePack::CreateTintedButtons( |
void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { |
ImageCache temp_output; |
for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) { |
- int prs_id = kTabBackgroundMap[i].key; |
- int prs_base_id = kTabBackgroundMap[i].value; |
- |
- // We only need to generate the background tab images if we were provided |
- // with a PRS_THEME_FRAME. |
- ImageCache::const_iterator it = images->find(prs_base_id); |
- if (it != images->end()) { |
- 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) |
- ? kRestoredTabVerticalOffset : 0; |
- |
- gfx::ImageSkia overlay; |
- ImageCache::const_iterator overlay_it = images->find(prs_id); |
- if (overlay_it != images->end()) |
- overlay = overlay_it->second.AsImageSkia(); |
- |
- gfx::ImageSkiaSource* source = new TabBackgroundImageSource( |
- image_to_tint, overlay, hsl_shift, vertical_offset); |
- // ImageSkia takes ownership of |source|. |
- temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, |
- image_to_tint.size())); |
+ int prs_frame_id = kTabBackgroundMap[i].value; |
+ ImageCache::const_iterator frame_it = images->find(prs_frame_id); |
+ if (frame_it == images->end()) { |
+ // There is no image to tint. |
+ continue; |
} |
+ |
+ int prs_dest_id = kTabBackgroundMap[i].key; |
+ color_utils::HSL tint = GetTintInternal( |
+ ThemeProperties::TINT_BACKGROUND_TAB); |
+ temp_output[prs_dest_id] = CreateHSLShiftedAndCroppedImage( |
+ frame_it->second, tint, prs_dest_id); |
+ } |
+ |
+ // The tab background overlay images are tiled horizontally but not |
+ // vertically. We have always done it this way. Pad the overlay images |
+ // with enough transparent pixels so that they do not get tiled vertically |
+ // to simplify the code which deals with the tab background overlay images. |
+ // TODO: Investigate if any themes rely on the vertical tiling behavior. |
+ for (size_t i = 0; i < arraysize(kTabBackgroundOverlayImages); ++i) { |
+ int prs_overlay_id = kTabBackgroundOverlayImages[i]; |
+ ImageCache::const_iterator overlay_it = images->find(prs_overlay_id); |
+ if (overlay_it == images->end()) |
+ continue; |
+ |
+ int desired_height = GetMaxHeight(prs_overlay_id); |
+ gfx::ImageSkia overlay = overlay_it->second.AsImageSkia(); |
+ if (overlay.height() == desired_height) |
+ continue; |
+ |
+ // The ImageSkia takes ownership of |source|. |
+ PadWithTransparentImageSource* source = new PadWithTransparentImageSource( |
+ overlay, gfx::Size(overlay.width(), desired_height)); |
+ temp_output[prs_overlay_id] = gfx::Image(gfx::ImageSkia( |
+ source, source->size())); |
} |
MergeImageCaches(temp_output, images); |
} |