Index: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
index 7bbea7884ebf282543688603aa75eb567b33833b..367c7a053e725ee3f6f3a4d29b3bb98e6897fcf8 100644 |
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm |
@@ -191,33 +191,16 @@ NSImage* CreateImageWithSize(NSSize size, |
// Takes a normal bitmap and a mask image and returns an image the size of the |
// mask that has pixels from |image| but alpha information from |mask|. |
NSImage* ApplyMask(NSImage* image, NSImage* mask) { |
- return [CreateImageWithSize([mask size], ^(NSSize size) { |
- // Skip a few pixels from the top of the tab background gradient, because |
- // the new tab button is not drawn at the very top of the browser window. |
- const int kYOffset = 10; |
- CGFloat width = size.width; |
- CGFloat height = size.height; |
- |
- // In some themes, the tab background image is narrower than the |
- // new tab button, so tile the background image. |
- CGFloat x = 0; |
- // The floor() is to make sure images with odd widths don't draw to the |
- // same pixel twice on retina displays. (Using NSDrawThreePartImage() |
- // caused a startup perf regression, so that cannot be used.) |
- CGFloat tileWidth = floor(std::min(width, [image size].width)); |
- while (x < width) { |
- [image drawAtPoint:NSMakePoint(x, 0) |
- fromRect:NSMakeRect(0, |
- [image size].height - height - kYOffset, |
- tileWidth, |
- height) |
- operation:NSCompositeCopy |
- fraction:1.0]; |
- x += tileWidth; |
- } |
+ DCHECK_EQ([image size].width, [mask size].width); |
+ DCHECK_EQ([image size].height, [mask size].height); |
+ return [CreateImageWithSize([mask size], ^(NSSize size) { |
+ [image drawAtPoint:NSZeroPoint |
+ fromRect:NSMakeRect(0, 0, size.width, size.height) |
+ operation:NSCompositeCopy |
+ fraction:1.0]; |
[mask drawAtPoint:NSZeroPoint |
- fromRect:NSMakeRect(0, 0, width, height) |
+ fromRect:NSMakeRect(0, 0, size.width, size.height) |
operation:NSCompositeDestinationIn |
fraction:1.0]; |
}) autorelease]; |
@@ -275,6 +258,33 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) { |
}) autorelease]; |
} |
+// Tiles |image| horizontally into a new NSImage of |size|. |y_inset| refers |
+// to the inset from the bottom of the returned image at which |image| should |
+// be painted. |
+NSImage* TileHorizontally(NSImage* image, CGFloat y_inset, NSSize size) { |
+ return [CreateImageWithSize(size, ^(NSSize size) { |
+ CGFloat width = size.width; |
+ CGFloat height = size.height; |
+ |
+ CGFloat x = 0; |
+ // The floor() is to make sure images with odd widths and height don't |
+ // draw to the same pixel twice on retina displays. (Using |
+ // NSDrawThreePartImage() caused a startup perf regression, so that |
+ // cannot be used.) |
+ CGFloat tileWidth = floor(std::min(width, [image size].width)); |
+ while (x < width) { |
+ [image drawAtPoint:NSMakePoint(x, 0) |
+ fromRect:NSMakeRect(0, |
+ [image size].height - y_inset, |
+ tileWidth, |
+ height) |
+ operation:NSCompositeCopy |
+ fraction:1.0]; |
+ x += tileWidth; |
+ } |
+ }) autorelease]; |
+} |
+ |
} // namespace |
@interface TabStripController (Private) |
@@ -2268,9 +2278,41 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) { |
NSImage* normal = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON).ToNSImage(); |
NSImage* hover = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_H).ToNSImage(); |
NSImage* pressed = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_P).ToNSImage(); |
- |
- NSImage* foreground = ApplyMask( |
- theme->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND, true), mask); |
+ NSImage* ntp_bg_active = theme->GetNSImageNamed( |
Nico
2013/07/17 18:03:04
useCamelCapsInObjCCode
|
+ IDR_THEME_TAB_BACKGROUND, true); |
+ NSImage* ntp_bg_active_overlay = theme->GetNSImageNamed( |
+ IDR_THEME_TAB_BACKGROUND_OVERLAY, false); |
+ |
+ // Compute the y insets so that |ntp_bg_active| lines up vertically with the |
+ // frame and that |ntp_bg_active_overlay| lines up vertically with the the |
+ // tab. The tab strip has not been layed out yet so |
+ // themePatternPhaseForAlignment cannot be used. |
+ int distance_between_tab_strip_and_button = [[self class] defaultTabHeight] - |
+ NSMaxY([newTabButton_ bounds]); |
+ int distance_between_frame_and_button = NSHeight([tabStripView_ bounds]) - |
Nico
2013/07/17 18:03:04
Can you move most of this stuff into a different m
pkotwicz
2013/08/15 07:09:59
I now compute this value in NewTabButtonThemeBackg
|
+ NSMaxY([newTabButton_ bounds]); |
+ // ImageButtonCell draws the image centered vertically. |
+ int y_offset_in_button = roundf( |
+ (NSHeight([newTabButton_ bounds]) - [mask size].height) / 2); |
+ // The constants below match those used in |
+ // BrowserWindowUtils::themePatternPhaseForAlignment |
Nico
2013/07/17 18:03:04
can they be shared somehow instead?
pkotwicz
2013/08/15 07:09:59
These values are now shared thanks to https://code
|
+ int y_inset_align_with_tab_strip = distance_between_tab_strip_and_button + |
+ y_offset_in_button + [mask size].height + 2; |
+ int y_inset_align_with_frame = distance_between_frame_and_button + |
+ y_offset_in_button + [mask size].height + 3; |
+ |
+ // Create the foreground image by combining the tinted frame image |
+ // (IDR_THEME_TAB_BACKGROUND) and the custom theme provided overlay |
+ // (IDR_THEME_TAB_BACKGROUND_OVERLAY). Tile the images because the images |
+ // are narrower than the new tab button for some themes. |
+ NSImage* unmasked_foreground = TileHorizontally(ntp_bg_active, |
+ y_inset_align_with_frame, [mask size]); |
+ if (ntp_bg_active_overlay) { |
+ NSImage* tiled_overlay = TileHorizontally(ntp_bg_active_overlay, |
+ y_inset_align_with_tab_strip, [mask size]); |
+ unmasked_foreground = Overlay(unmasked_foreground, tiled_overlay, 1.0); |
+ } |
+ NSImage* foreground = ApplyMask(unmasked_foreground, mask); |
[[newTabButton_ cell] setImage:Overlay(foreground, normal, 1.0) |
forButtonState:image_button_cell::kDefaultState]; |
@@ -2282,8 +2324,11 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) { |
// IDR_THEME_TAB_BACKGROUND_INACTIVE is only used with the default theme. |
if (theme->UsingDefaultTheme()) { |
const CGFloat alpha = tabs::kImageNoFocusAlpha; |
- NSImage* background = ApplyMask( |
- theme->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND_INACTIVE, true), mask); |
+ NSImage* unmasked_background = TileHorizontally( |
+ rb.GetNativeImageNamed(IDR_THEME_TAB_BACKGROUND_INACTIVE).ToNSImage(), |
+ y_inset_align_with_tab_strip, |
+ [mask size]); |
+ NSImage* background = ApplyMask(unmasked_background, mask); |
[[newTabButton_ cell] setImage:Overlay(background, normal, alpha) |
forButtonState:image_button_cell::kDefaultStateBackground]; |
[[newTabButton_ cell] setImage:Overlay(background, hover, alpha) |