Commit d6007316 authored by avi@chromium.org's avatar avi@chromium.org

Always call the class methods to save/restore contexts.

If the current context was ever nil, sending a "restore" message would be a no-op and would likely leave an out-of-scope context as current.

BUG=90140
TEST=repeatedly select items in an open file dialog in column mode; no crash

Review URL: http://codereview.chromium.org/7572031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95611 0039d316-1c4b-4281-b951-d872f2087c98
parent 7d304a9d
...@@ -56,8 +56,7 @@ const CGFloat kBorderRadius = 3.0; ...@@ -56,8 +56,7 @@ const CGFloat kBorderRadius = 3.0;
if (!themeProvider) if (!themeProvider)
return; return;
NSGraphicsContext* context = [NSGraphicsContext currentContext]; gfx::ScopedNSGraphicsContextSaveGState scopedGState;
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
// Draw the background. // Draw the background.
{ {
...@@ -103,8 +102,9 @@ const CGFloat kBorderRadius = 3.0; ...@@ -103,8 +102,9 @@ const CGFloat kBorderRadius = 3.0;
// Fade in/out the background. // Fade in/out the background.
{ {
gfx::ScopedNSGraphicsContextSaveGState bgScopedState(context); gfx::ScopedNSGraphicsContextSaveGState bgScopedState;
[border setClip]; [border setClip];
NSGraphicsContext* context = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef)[context graphicsPort]; CGContextRef cgContext = (CGContextRef)[context graphicsPort];
CGContextBeginTransparencyLayer(cgContext, NULL); CGContextBeginTransparencyLayer(cgContext, NULL);
CGContextSetAlpha(cgContext, 1 - morph); CGContextSetAlpha(cgContext, 1 - morph);
......
...@@ -406,14 +406,14 @@ const int kInterruptedAnimationDuration = 2.5; ...@@ -406,14 +406,14 @@ const int kInterruptedAnimationDuration = 2.5;
nil]; nil];
NSPoint secondaryPos = NSPoint secondaryPos =
NSMakePoint(innerFrame.origin.x + kTextPosLeft, kSecondaryTextPosTop); NSMakePoint(innerFrame.origin.x + kTextPosLeft, kSecondaryTextPosTop);
gfx::ScopedNSGraphicsContextSaveGState contextSave;
NSGraphicsContext* nsContext = [NSGraphicsContext currentContext]; NSGraphicsContext* nsContext = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef)[nsContext graphicsPort]; CGContextRef cgContext = (CGContextRef)[nsContext graphicsPort];
[nsContext saveGraphicsState];
[nsContext setCompositingOperation:NSCompositeSourceOver]; [nsContext setCompositingOperation:NSCompositeSourceOver];
CGContextSetAlpha(cgContext, statusAlpha_); CGContextSetAlpha(cgContext, statusAlpha_);
[secondaryText drawAtPoint:secondaryPos [secondaryText drawAtPoint:secondaryPos
withAttributes:secondaryTextAttributes]; withAttributes:secondaryTextAttributes];
[nsContext restoreGraphicsState];
} }
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
...@@ -579,8 +579,7 @@ const int kInterruptedAnimationDuration = 2.5; ...@@ -579,8 +579,7 @@ const int kInterruptedAnimationDuration = 2.5;
[triangle lineToPoint:p3]; [triangle lineToPoint:p3];
[triangle closePath]; [triangle closePath];
NSGraphicsContext* context = [NSGraphicsContext currentContext]; gfx::ScopedNSGraphicsContextSaveGState scopedGState;
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
[shadow.get() setShadowColor:[NSColor whiteColor]]; [shadow.get() setShadowColor:[NSColor whiteColor]];
......
...@@ -64,8 +64,8 @@ CGFloat kCurveSize = 8; ...@@ -64,8 +64,8 @@ CGFloat kCurveSize = 8;
controlPoint2:NSMakePoint(midRight2.x, topLeft.y)]; controlPoint2:NSMakePoint(midRight2.x, topLeft.y)];
{ {
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext* context = [NSGraphicsContext currentContext]; NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
[path addClip]; [path addClip];
// Set the pattern phase // Set the pattern phase
......
...@@ -251,8 +251,8 @@ const CGFloat kRapidCloseDist = 2.5; ...@@ -251,8 +251,8 @@ const CGFloat kRapidCloseDist = 2.5;
- (void)drawRect:(NSRect)dirtyRect { - (void)drawRect:(NSRect)dirtyRect {
const CGFloat lineWidth = [self cr_lineWidth]; const CGFloat lineWidth = [self cr_lineWidth];
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext* context = [NSGraphicsContext currentContext]; NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
ThemeService* themeProvider = ThemeService* themeProvider =
static_cast<ThemeService*>([[self window] themeProvider]); static_cast<ThemeService*>([[self window] themeProvider]);
...@@ -288,7 +288,8 @@ const CGFloat kRapidCloseDist = 2.5; ...@@ -288,7 +288,8 @@ const CGFloat kRapidCloseDist = 2.5;
[[[self window] backgroundColor] set]; [[[self window] backgroundColor] set];
[path fill]; [path fill];
gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
CGContextRef cgContext = CGContextRef cgContext =
static_cast<CGContextRef>([context graphicsPort]); static_cast<CGContextRef>([context graphicsPort]);
CGContextBeginTransparencyLayer(cgContext, 0); CGContextBeginTransparencyLayer(cgContext, 0);
...@@ -299,55 +300,6 @@ const CGFloat kRapidCloseDist = 2.5; ...@@ -299,55 +300,6 @@ const CGFloat kRapidCloseDist = 2.5;
} }
} }
[context saveGraphicsState];
[path addClip];
// Use the same overlay for the selected state and for hover and alert glows;
// for the selected state, it's fully opaque.
CGFloat hoverAlpha = [self hoverAlpha];
CGFloat alertAlpha = [self alertAlpha];
if (selected || hoverAlpha > 0 || alertAlpha > 0) {
// Draw the selected background / glow overlay.
gfx::ScopedNSGraphicsContextSaveGState drawHoverState(context);
CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]);
CGContextBeginTransparencyLayer(cgContext, 0);
if (!selected) {
// The alert glow overlay is like the selected state but at most at most
// 80% opaque. The hover glow brings up the overlay's opacity at most 50%.
CGFloat backgroundAlpha = 0.8 * alertAlpha;
backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha;
CGContextSetAlpha(cgContext, backgroundAlpha);
}
[path addClip];
{
gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context);
[super drawBackgroundWithOpaque:NO];
}
// Draw a mouse hover gradient for the default themes.
if (!selected && hoverAlpha > 0) {
if (themeProvider && !hasBackgroundImage) {
scoped_nsobject<NSGradient> glow([NSGradient alloc]);
[glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0
alpha:1.0 * hoverAlpha]
endingColor:[NSColor colorWithCalibratedWhite:1.0
alpha:0.0]];
NSPoint point = hoverPoint_;
point.y = NSHeight(rect);
[glow drawFromCenter:point
radius:0.0
toCenter:point
radius:NSWidth(rect) / 3.0
options:NSGradientDrawsBeforeStartingLocation];
[glow drawInBezierPath:path relativeCenterPosition:hoverPoint_];
}
}
CGContextEndTransparencyLayer(cgContext);
}
BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow];
CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2;
NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha];
...@@ -356,35 +308,87 @@ const CGFloat kRapidCloseDist = 2.5; ...@@ -356,35 +308,87 @@ const CGFloat kRapidCloseDist = 2.5;
ThemeService::COLOR_TOOLBAR_BEZEL : ThemeService::COLOR_TOOLBAR_BEZEL :
ThemeService::COLOR_TOOLBAR, true) : nil; ThemeService::COLOR_TOOLBAR, true) : nil;
// Draw the top inner highlight within the tab if using the default theme. {
if (themeProvider && themeProvider->UsingDefaultTheme()) { gfx::ScopedNSGraphicsContextSaveGState contextSave;
NSAffineTransform* highlightTransform = [NSAffineTransform transform]; [path addClip];
[highlightTransform translateXBy:lineWidth yBy:-lineWidth];
if (selected) { // Use the same overlay for the selected state and for hover and alert
scoped_nsobject<NSBezierPath> highlightPath([path copy]); // glows; for the selected state, it's fully opaque.
[highlightPath transformUsingAffineTransform:highlightTransform]; CGFloat hoverAlpha = [self hoverAlpha];
[highlightColor setStroke]; CGFloat alertAlpha = [self alertAlpha];
[highlightPath setLineWidth:lineWidth]; if (selected || hoverAlpha > 0 || alertAlpha > 0) {
[highlightPath stroke]; // Draw the selected background / glow overlay.
highlightTransform = [NSAffineTransform transform]; gfx::ScopedNSGraphicsContextSaveGState drawHoverState;
[highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; NSGraphicsContext* context = [NSGraphicsContext currentContext];
[highlightPath transformUsingAffineTransform:highlightTransform]; CGContextRef cgContext =
[highlightPath stroke]; static_cast<CGContextRef>([context graphicsPort]);
} else { CGContextBeginTransparencyLayer(cgContext, 0);
NSBezierPath* topHighlightPath = if (!selected) {
[self topHighlightBezierPathForRect:[self bounds]]; // The alert glow overlay is like the selected state but at most at most
[topHighlightPath transformUsingAffineTransform:highlightTransform]; // 80% opaque. The hover glow brings up the overlay's opacity at most
[highlightColor setStroke]; // 50%.
[topHighlightPath setLineWidth:lineWidth]; CGFloat backgroundAlpha = 0.8 * alertAlpha;
[topHighlightPath stroke]; backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha;
CGContextSetAlpha(cgContext, backgroundAlpha);
}
[path addClip];
{
gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState;
[super drawBackgroundWithOpaque:NO];
}
// Draw a mouse hover gradient for the default themes.
if (!selected && hoverAlpha > 0) {
if (themeProvider && !hasBackgroundImage) {
scoped_nsobject<NSGradient> glow([NSGradient alloc]);
[glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0
alpha:1.0 * hoverAlpha]
endingColor:[NSColor colorWithCalibratedWhite:1.0
alpha:0.0]];
NSPoint point = hoverPoint_;
point.y = NSHeight(rect);
[glow drawFromCenter:point
radius:0.0
toCenter:point
radius:NSWidth(rect) / 3.0
options:NSGradientDrawsBeforeStartingLocation];
[glow drawInBezierPath:path relativeCenterPosition:hoverPoint_];
}
}
CGContextEndTransparencyLayer(cgContext);
} }
}
[context restoreGraphicsState]; // Draw the top inner highlight within the tab if using the default theme.
if (themeProvider && themeProvider->UsingDefaultTheme()) {
NSAffineTransform* highlightTransform = [NSAffineTransform transform];
[highlightTransform translateXBy:lineWidth yBy:-lineWidth];
if (selected) {
scoped_nsobject<NSBezierPath> highlightPath([path copy]);
[highlightPath transformUsingAffineTransform:highlightTransform];
[highlightColor setStroke];
[highlightPath setLineWidth:lineWidth];
[highlightPath stroke];
highlightTransform = [NSAffineTransform transform];
[highlightTransform translateXBy:-2 * lineWidth yBy:0.0];
[highlightPath transformUsingAffineTransform:highlightTransform];
[highlightPath stroke];
} else {
NSBezierPath* topHighlightPath =
[self topHighlightBezierPathForRect:[self bounds]];
[topHighlightPath transformUsingAffineTransform:highlightTransform];
[highlightColor setStroke];
[topHighlightPath setLineWidth:lineWidth];
[topHighlightPath stroke];
}
}
}
// Draw the top stroke. // Draw the top stroke.
{ {
gfx::ScopedNSGraphicsContextSaveGState drawBorderState(context); gfx::ScopedNSGraphicsContextSaveGState drawBorderState;
[borderColor set]; [borderColor set];
[path setLineWidth:lineWidth]; [path setLineWidth:lineWidth];
[path stroke]; [path stroke];
......
// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "unicode/locid.h" #include "unicode/locid.h"
#include "webkit/glue/webkit_glue.h" #include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/npapi/default_plugin_shared.h" #include "webkit/plugins/npapi/default_plugin_shared.h"
...@@ -139,7 +140,7 @@ void PluginInstallerImpl::DownloadCancelled() { ...@@ -139,7 +140,7 @@ void PluginInstallerImpl::DownloadCancelled() {
} }
int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) { int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) {
[NSGraphicsContext saveGraphicsState]; gfx::ScopedNSGraphicsContextSaveGState scoped_state;
NSGraphicsContext* ns_context = [NSGraphicsContext NSGraphicsContext* ns_context = [NSGraphicsContext
graphicsContextWithGraphicsPort:context flipped:YES]; graphicsContextWithGraphicsPort:context flipped:YES];
[NSGraphicsContext setCurrentContext:ns_context]; [NSGraphicsContext setCurrentContext:ns_context];
...@@ -183,7 +184,6 @@ int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) { ...@@ -183,7 +184,6 @@ int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) {
label_point = NSMakePoint(roundf(label_point.x), roundf(label_point.y)); label_point = NSMakePoint(roundf(label_point.x), roundf(label_point.y));
[command_ drawAtPoint:label_point withAttributes:attributes]; [command_ drawAtPoint:label_point withAttributes:attributes];
[NSGraphicsContext restoreGraphicsState];
return 1; return 1;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#import "third_party/mozilla/NSPasteboard+Utils.h" #import "third_party/mozilla/NSPasteboard+Utils.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/canvas_skia.h" #include "ui/gfx/canvas_skia.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
namespace ui { namespace ui {
...@@ -248,6 +249,7 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const { ...@@ -248,6 +249,7 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
scoped_nsobject<NSImage> image( scoped_nsobject<NSImage> image(
[[NSImage alloc] initWithPasteboard:GetPasteboard()]); [[NSImage alloc] initWithPasteboard:GetPasteboard()]);
if (image.get()) { if (image.get()) {
gfx::ScopedNSGraphicsContextSaveGState scoped_state;
[image setFlipped:YES]; [image setFlipped:YES];
int width = [image size].width; int width = [image size].width;
int height = [image size].height; int height = [image size].height;
...@@ -262,7 +264,6 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const { ...@@ -262,7 +264,6 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
fromRect:NSZeroRect fromRect:NSZeroRect
operation:NSCompositeCopy operation:NSCompositeCopy
fraction:1.0]; fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
return canvas.ExtractBitmap(); return canvas.ExtractBitmap();
} }
return SkBitmap(); return SkBitmap();
......
...@@ -4,23 +4,27 @@ ...@@ -4,23 +4,27 @@
#ifndef UI_GFX_SCOPED_NS_GRAPHICS_CONTEXT_SAVE_GSTATE_MAC_H_ #ifndef UI_GFX_SCOPED_NS_GRAPHICS_CONTEXT_SAVE_GSTATE_MAC_H_
#define UI_GFX_SCOPED_NS_GRAPHICS_CONTEXT_SAVE_GSTATE_MAC_H_ #define UI_GFX_SCOPED_NS_GRAPHICS_CONTEXT_SAVE_GSTATE_MAC_H_
#pragma once
#include "ui/ui_api.h"
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_nsobject.h" #include "ui/ui_api.h"
#if defined(__OBJC__)
@class NSGraphicsContext; @class NSGraphicsContext;
#else
class NSGraphicsContext;
#endif
namespace gfx { namespace gfx {
// A class to save/restore the state of the current context.
class UI_API ScopedNSGraphicsContextSaveGState { class UI_API ScopedNSGraphicsContextSaveGState {
public: public:
// If |context| is nil, it will use the |+currentContext|. ScopedNSGraphicsContextSaveGState();
explicit ScopedNSGraphicsContextSaveGState(NSGraphicsContext* context = nil);
~ScopedNSGraphicsContextSaveGState(); ~ScopedNSGraphicsContextSaveGState();
private: private:
scoped_nsobject<NSGraphicsContext> context_; NSGraphicsContext* context_; // weak
DISALLOW_COPY_AND_ASSIGN(ScopedNSGraphicsContextSaveGState); DISALLOW_COPY_AND_ASSIGN(ScopedNSGraphicsContextSaveGState);
}; };
......
...@@ -4,19 +4,20 @@ ...@@ -4,19 +4,20 @@
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#include "base/logging.h"
namespace gfx { namespace gfx {
ScopedNSGraphicsContextSaveGState::ScopedNSGraphicsContextSaveGState( ScopedNSGraphicsContextSaveGState::ScopedNSGraphicsContextSaveGState()
NSGraphicsContext* context) : context_([context retain]) { : context_([NSGraphicsContext currentContext]) {
if (!context_) [NSGraphicsContext saveGraphicsState];
context_.reset([[NSGraphicsContext currentContext] retain]);
[context_ saveGraphicsState];
} }
ScopedNSGraphicsContextSaveGState::~ScopedNSGraphicsContextSaveGState() { ScopedNSGraphicsContextSaveGState::~ScopedNSGraphicsContextSaveGState() {
[context_ restoreGraphicsState]; [NSGraphicsContext restoreGraphicsState];
DCHECK_EQ(context_, [NSGraphicsContext currentContext]);
} }
} // namespace gfx } // namespace gfx
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment