summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-04 18:21:12 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-04 18:21:12 +0000
commitd60655b86f1d6a15e88ca51a77ccb7d3a3945612 (patch)
treeef45576279e8b904b3ffb50a25df5401d9098ec4 /chrome
parente9b084c2af3b8831f1d872691184da32e7df5b92 (diff)
downloadchromium_src-d60655b86f1d6a15e88ca51a77ccb7d3a3945612.zip
chromium_src-d60655b86f1d6a15e88ca51a77ccb7d3a3945612.tar.gz
chromium_src-d60655b86f1d6a15e88ca51a77ccb7d3a3945612.tar.bz2
[Mac] Image-drawing which doesn't require image-flipping.
Snow Leopard deprecated -[NSImage setFlipped:] for good reasons. This implements a method similar to the new -[NSImage drawInRect:*:respectFlipped:] method, which allows images to be drawn so that they always look right visually regardless of the -isFlipped status of the view being drawn. BUG=38943 TEST=Autocomplete, download, and reload button look right. Review URL: http://codereview.chromium.org/2587003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48954 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view_mac.mm5
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.mm9
-rw-r--r--chrome/browser/cocoa/bookmark_bar_folder_window.mm9
-rw-r--r--chrome/browser/cocoa/bookmark_button_cell.mm5
-rw-r--r--chrome/browser/cocoa/download_item_cell.mm5
-rw-r--r--chrome/browser/cocoa/gradient_button_cell.mm5
-rw-r--r--chrome/browser/cocoa/image_utils.h25
-rw-r--r--chrome/browser/cocoa/image_utils.mm37
-rw-r--r--chrome/browser/cocoa/image_utils_unittest.mm142
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
11 files changed, 229 insertions, 16 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm
index c0e4f93..5d31764 100644
--- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm
+++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm
@@ -11,6 +11,7 @@
#include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/cocoa/event_utils.h"
+#include "chrome/browser/cocoa/image_utils.h"
#include "gfx/rect.h"
#include "grit/theme_resources.h"
#import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h"
@@ -484,11 +485,11 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) {
imageRect.origin.y +=
floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2);
imageRect.origin.x += kLeftRightMargin;
- [image setFlipped:[controlView isFlipped]];
[image drawInRect:imageRect
fromRect:NSZeroRect // Entire image
operation:NSCompositeSourceOver
- fraction:1.0];
+ fraction:1.0
+ neverFlipped:YES];
}
// Adjust the title position to be lined up under the field's text.
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
index 9801892..7558c70 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
@@ -6,6 +6,7 @@
#include "app/resource_bundle.h"
#include "base/logging.h"
+#import "chrome/browser/cocoa/image_utils.h"
#include "gfx/font.h"
#include "grit/theme_resources.h"
@@ -17,7 +18,7 @@
// down relative to the containing text's baseline.
// Draw the image using |DrawImageInRect()| helper function for
-// |-setFlipped:| consistency with other image drawing.
+// flipped consistency with other image drawing.
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView;
@end
@@ -85,11 +86,11 @@ void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) {
// If there is an image, make sure we calculated the target size
// correctly.
DCHECK(!image || NSEqualSizes([image size], rect.size));
- [image setFlipped:[view isFlipped]];
[image drawInRect:rect
fromRect:NSZeroRect // Entire image
operation:NSCompositeSourceOver
- fraction:1.0];
+ fraction:1.0
+ neverFlipped:YES];
}
// Helper function to generate an attributed string containing
@@ -120,7 +121,7 @@ NSAttributedString* AttributedStringForImage(NSImage* anImage,
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView {
// Draw image with |DrawImageInRect()| to get consistent
- // |-setFlipped:| treatment.
+ // flipped treatment.
DrawImageInRect([self image], aView, cellFrame);
}
diff --git a/chrome/browser/cocoa/bookmark_bar_folder_window.mm b/chrome/browser/cocoa/bookmark_bar_folder_window.mm
index da0455e..1d0e863 100644
--- a/chrome/browser/cocoa/bookmark_bar_folder_window.mm
+++ b/chrome/browser/cocoa/bookmark_bar_folder_window.mm
@@ -8,6 +8,7 @@
#include "base/nsimage_cache_mac.h"
#import "base/scoped_nsobject.h"
#import "chrome/browser/cocoa/bookmark_bar_folder_controller.h"
+#import "chrome/browser/cocoa/image_utils.h"
#import "third_party/GTM/AppKit/GTMNSColor+Luminance.h"
#import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h"
@@ -54,7 +55,6 @@ const CGFloat kViewCornerRadius = 4.0;
NSRect visibleRect = [self bounds];
// On top
- [arrowUpImage_ setFlipped:[self isFlipped]];
NSRect imageRect = NSZeroRect;
imageRect.size = [arrowUpImage_ size];
NSRect drawRect = NSOffsetRect(
@@ -64,10 +64,10 @@ const CGFloat kViewCornerRadius = 4.0;
[arrowUpImage_ drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
- fraction:1.0];
+ fraction:1.0
+ neverFlipped:YES];
// On bottom
- [arrowDownImage_ setFlipped:[self isFlipped]];
imageRect = NSZeroRect;
imageRect.size = [arrowDownImage_ size];
drawRect = NSOffsetRect(imageRect,
@@ -76,7 +76,8 @@ const CGFloat kViewCornerRadius = 4.0;
[arrowDownImage_ drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
- fraction:1.0];
+ fraction:1.0
+ neverFlipped:YES];
}
- (void)drawRect:(NSRect)rect {
diff --git a/chrome/browser/cocoa/bookmark_button_cell.mm b/chrome/browser/cocoa/bookmark_button_cell.mm
index d2a30b9..f8d0ffc 100644
--- a/chrome/browser/cocoa/bookmark_button_cell.mm
+++ b/chrome/browser/cocoa/bookmark_button_cell.mm
@@ -11,6 +11,7 @@
#import "chrome/browser/bookmarks/bookmark_model.h"
#import "chrome/browser/cocoa/bookmark_menu.h"
#import "chrome/browser/cocoa/bookmark_button.h"
+#import "chrome/browser/cocoa/image_utils.h"
#include "grit/generated_resources.h"
@@ -225,11 +226,11 @@
NSWidth(cellFrame) - NSWidth(imageRect),
(NSHeight(cellFrame) / 2.0) -
(NSHeight(imageRect) / 2.0));
- [arrowImage_ setFlipped:[controlView isFlipped]];
[arrowImage_ drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
- fraction:[self isEnabled] ? 1.0 : 0.5];
+ fraction:[self isEnabled] ? 1.0 : 0.5
+ neverFlipped:YES];
}
}
diff --git a/chrome/browser/cocoa/download_item_cell.mm b/chrome/browser/cocoa/download_item_cell.mm
index cabde16..84d4421 100644
--- a/chrome/browser/cocoa/download_item_cell.mm
+++ b/chrome/browser/cocoa/download_item_cell.mm
@@ -10,6 +10,7 @@
#include "base/sys_string_conversions.h"
#import "chrome/browser/browser_theme_provider.h"
#import "chrome/browser/cocoa/download_item_cell.h"
+#import "chrome/browser/cocoa/image_utils.h"
#import "chrome/browser/cocoa/themed_window.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
@@ -587,11 +588,11 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const {
// Draw icon
NSRect imageRect = NSZeroRect;
imageRect.size = [[self image] size];
- [[self image] setFlipped:[controlView isFlipped]];
[[self image] drawInRect:[self imageRectForBounds:cellFrame]
fromRect:imageRect
operation:NSCompositeSourceOver
- fraction:[self isEnabled] ? 1.0 : 0.5];
+ fraction:[self isEnabled] ? 1.0 : 0.5
+ neverFlipped:YES];
// Separator between button and popup parts
CGFloat lx = NSMaxX(cellFrame) - kDropdownAreaWidth + 0.5;
diff --git a/chrome/browser/cocoa/gradient_button_cell.mm b/chrome/browser/cocoa/gradient_button_cell.mm
index 002116d..ac71474 100644
--- a/chrome/browser/cocoa/gradient_button_cell.mm
+++ b/chrome/browser/cocoa/gradient_button_cell.mm
@@ -7,6 +7,7 @@
#include "base/logging.h"
#import "base/scoped_nsobject.h"
#import "chrome/browser/browser_theme_provider.h"
+#import "chrome/browser/cocoa/image_utils.h"
#import "chrome/browser/cocoa/themed_window.h"
#include "grit/theme_resources.h"
#import "third_party/GTM/AppKit/GTMNSColor+Luminance.h"
@@ -415,11 +416,11 @@ static const NSTimeInterval kAnimationHideDuration = 0.4;
NSRect imageRect = NSZeroRect;
imageRect.size = [[self image] size];
NSRect drawRect = [self imageRectForBounds:cellFrame];
- [[self image] setFlipped:[controlView isFlipped]];
[[self image] drawInRect:drawRect
fromRect:imageRect
operation:NSCompositeSourceOver
- fraction:[self isEnabled] ? 1.0 : 0.5];
+ fraction:[self isEnabled] ? 1.0 : 0.5
+ neverFlipped:YES];
if (isTemplate) {
if (color) {
[color set];
diff --git a/chrome/browser/cocoa/image_utils.h b/chrome/browser/cocoa/image_utils.h
new file mode 100644
index 0000000..36a3bb45
--- /dev/null
+++ b/chrome/browser/cocoa/image_utils.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COCOA_IMAGE_UTILS_H_
+#define CHROME_BROWSER_COCOA_IMAGE_UTILS_H_
+
+#import <Cocoa/Cocoa.h>
+
+@interface NSImage (FlippedAdditions)
+
+// Works like |-drawInRect:fromRect:operation:fraction:|, except that
+// if |neverFlipped| is |YES|, and the context is flipped, the a
+// transform is applied to flip it again before drawing the image.
+//
+// Compare to the 10.6 method
+// |-drawInRect:fromRect:operation:fraction:respectFlipped:hints:|.
+- (void)drawInRect:(NSRect)dstRect
+ fromRect:(NSRect)srcRect
+ operation:(NSCompositingOperation)op
+ fraction:(CGFloat)requestedAlpha
+ neverFlipped:(BOOL)neverFlipped;
+@end
+
+#endif // CHROME_BROWSER_COCOA_IMAGE_UTILS_H_
diff --git a/chrome/browser/cocoa/image_utils.mm b/chrome/browser/cocoa/image_utils.mm
new file mode 100644
index 0000000..80188e5
--- /dev/null
+++ b/chrome/browser/cocoa/image_utils.mm
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/image_utils.h"
+
+@implementation NSImage (FlippedAdditions)
+
+- (void)drawInRect:(NSRect)dstRect
+ fromRect:(NSRect)srcRect
+ operation:(NSCompositingOperation)op
+ fraction:(CGFloat)requestedAlpha
+ neverFlipped:(BOOL)neverFlipped {
+ NSAffineTransform *transform = nil;
+
+ // Flip drawing and adjust the origin to make the image come out
+ // right.
+ if (neverFlipped && [[NSGraphicsContext currentContext] isFlipped]) {
+ transform = [NSAffineTransform transform];
+ [transform scaleXBy:1.0 yBy:-1.0];
+ [transform concat];
+
+ // The lower edge of the image is as far from the origin as the
+ // upper edge was, plus it's on the other side of the origin.
+ dstRect.origin.y -= NSMaxY(dstRect) + NSMinY(dstRect);
+ }
+
+ [self drawInRect:dstRect
+ fromRect:srcRect
+ operation:op
+ fraction:requestedAlpha];
+
+ // Flip drawing back, if needed.
+ [transform concat];
+}
+
+@end
diff --git a/chrome/browser/cocoa/image_utils_unittest.mm b/chrome/browser/cocoa/image_utils_unittest.mm
new file mode 100644
index 0000000..4398371
--- /dev/null
+++ b/chrome/browser/cocoa/image_utils_unittest.mm
@@ -0,0 +1,142 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "chrome/browser/cocoa/image_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+@interface ImageUtilsTestView : NSView {
+ @private
+ // Determine whether the view is flipped.
+ BOOL isFlipped_;
+
+ // Determines whether to draw using the new method with
+ // |neverFlipped:|.
+ BOOL useNeverFlipped_;
+
+ // Passed to |neverFlipped:| when drawing |image_|.
+ BOOL neverFlipped_;
+
+ scoped_nsobject<NSImage> image_;
+}
+@property(assign, nonatomic) BOOL isFlipped;
+@property(assign, nonatomic) BOOL useNeverFlipped;
+@property(assign, nonatomic) BOOL neverFlipped;
+@end
+
+@implementation ImageUtilsTestView
+@synthesize isFlipped = isFlipped_;
+@synthesize useNeverFlipped = useNeverFlipped_;
+@synthesize neverFlipped = neverFlipped_;
+
+- (id)initWithFrame:(NSRect)rect {
+ self = [super initWithFrame:rect];
+ if (self) {
+ rect = NSInsetRect(rect, 5.0, 5.0);
+ rect.origin = NSZeroPoint;
+ const NSSize imageSize = NSInsetRect(rect, 5.0, 5.0).size;
+ image_.reset([[NSImage alloc] initWithSize:imageSize]);
+
+ NSBezierPath* path = [NSBezierPath bezierPath];
+ [path moveToPoint:NSMakePoint(NSMinX(rect), NSMinY(rect))];
+ [path lineToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))];
+ [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMinY(rect))];
+ [path closePath];
+
+ [image_ lockFocus];
+ [[NSColor blueColor] setFill];
+ [path fill];
+ [image_ unlockFocus];
+ }
+ return self;
+}
+
+- (void)drawRect:(NSRect)rect {
+ NSBezierPath* path = [NSBezierPath bezierPath];
+ [path moveToPoint:NSMakePoint(NSMinX(rect), NSMinY(rect))];
+ [path lineToPoint:NSMakePoint(NSMinX(rect), NSMaxY(rect))];
+ [path lineToPoint:NSMakePoint(NSMaxX(rect), NSMinY(rect))];
+ [path closePath];
+
+ [[NSColor redColor] setFill];
+ [path fill];
+
+ rect = NSInsetRect(rect, 5.0, 5.0);
+ rect = NSOffsetRect(rect, 2.0, 2.0);
+
+ if (useNeverFlipped_) {
+ [image_ drawInRect:rect
+ fromRect:NSZeroRect
+ operation:NSCompositeCopy
+ fraction:1.0
+ neverFlipped:neverFlipped_];
+ } else {
+ [image_ drawInRect:rect
+ fromRect:NSZeroRect
+ operation:NSCompositeCopy
+ fraction:1.0];
+ }
+}
+
+@end
+
+namespace {
+
+class ImageUtilTest : public CocoaTest {
+ public:
+ ImageUtilTest() {
+ const NSRect frame = NSMakeRect(0, 0, 300, 100);
+ scoped_nsobject<ImageUtilsTestView> view(
+ [[ImageUtilsTestView alloc] initWithFrame: frame]);
+ view_ = view.get();
+ [[test_window() contentView] addSubview:view_];
+ }
+
+ NSData* SnapshotView() {
+ [view_ display];
+
+ const NSRect bounds = [view_ bounds];
+
+ [view_ lockFocus];
+ scoped_nsobject<NSBitmapImageRep> bitmap(
+ [[NSBitmapImageRep alloc] initWithFocusedViewRect:bounds]);
+ [view_ unlockFocus];
+
+ scoped_nsobject<NSImage> image(
+ [[NSImage alloc] initWithSize:bounds.size]);
+ [image addRepresentation:bitmap];
+
+ return [image TIFFRepresentation];
+ }
+
+ NSData* SnapshotViewBase() {
+ [view_ setUseNeverFlipped:NO];
+ return SnapshotView();
+ }
+
+ NSData* SnapshotViewNeverFlipped(BOOL neverFlipped) {
+ [view_ setUseNeverFlipped:YES];
+ [view_ setNeverFlipped:neverFlipped];
+ return SnapshotView();
+ }
+
+ ImageUtilsTestView* view_;
+};
+
+TEST_F(ImageUtilTest, Test) {
+ // When not flipped, both drawing methods return the same data.
+ [view_ setIsFlipped:NO];
+ NSData* baseSnapshotData = SnapshotViewBase();
+ EXPECT_TRUE([baseSnapshotData isEqualToData:SnapshotViewNeverFlipped(YES)]);
+ EXPECT_TRUE([baseSnapshotData isEqualToData:SnapshotViewNeverFlipped(NO)]);
+
+ // When flipped, there's only a difference when the context flip is
+ // not being respected.
+ [view_ setIsFlipped:YES];
+ baseSnapshotData = SnapshotViewBase();
+ EXPECT_FALSE([baseSnapshotData isEqualToData:SnapshotViewNeverFlipped(YES)]);
+ EXPECT_TRUE([baseSnapshotData isEqualToData:SnapshotViewNeverFlipped(NO)]);
+}
+
+} // namespace
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 2f163e8..9b50d5b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -753,6 +753,8 @@
'browser/cocoa/hyperlink_button_cell.mm',
'browser/cocoa/hung_renderer_controller.h',
'browser/cocoa/hung_renderer_controller.mm',
+ 'browser/cocoa/image_utils.h',
+ 'browser/cocoa/image_utils.mm',
'browser/cocoa/import_progress_dialog.h',
'browser/cocoa/import_progress_dialog.mm',
'browser/cocoa/import_settings_dialog.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index ab39a51..4aad2dc 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -697,6 +697,7 @@
'browser/cocoa/html_dialog_window_controller_unittest.mm',
'browser/cocoa/hung_renderer_controller_unittest.mm',
'browser/cocoa/hyperlink_button_cell_unittest.mm',
+ 'browser/cocoa/image_utils_unittest.mm',
'browser/cocoa/import_settings_dialog_unittest.mm',
'browser/cocoa/info_bubble_view_unittest.mm',
'browser/cocoa/info_bubble_window_unittest.mm',