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;
if (!themeProvider)
return;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
// Draw the background.
{
......@@ -103,8 +102,9 @@ const CGFloat kBorderRadius = 3.0;
// Fade in/out the background.
{
gfx::ScopedNSGraphicsContextSaveGState bgScopedState(context);
gfx::ScopedNSGraphicsContextSaveGState bgScopedState;
[border setClip];
NSGraphicsContext* context = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef)[context graphicsPort];
CGContextBeginTransparencyLayer(cgContext, NULL);
CGContextSetAlpha(cgContext, 1 - morph);
......
......@@ -406,14 +406,14 @@ const int kInterruptedAnimationDuration = 2.5;
nil];
NSPoint secondaryPos =
NSMakePoint(innerFrame.origin.x + kTextPosLeft, kSecondaryTextPosTop);
gfx::ScopedNSGraphicsContextSaveGState contextSave;
NSGraphicsContext* nsContext = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef)[nsContext graphicsPort];
[nsContext saveGraphicsState];
[nsContext setCompositingOperation:NSCompositeSourceOver];
CGContextSetAlpha(cgContext, statusAlpha_);
[secondaryText drawAtPoint:secondaryPos
withAttributes:secondaryTextAttributes];
[nsContext restoreGraphicsState];
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
......@@ -579,8 +579,7 @@ const int kInterruptedAnimationDuration = 2.5;
[triangle lineToPoint:p3];
[triangle closePath];
NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
[shadow.get() setShadowColor:[NSColor whiteColor]];
......
......@@ -64,8 +64,8 @@ CGFloat kCurveSize = 8;
controlPoint2:NSMakePoint(midRight2.x, topLeft.y)];
{
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
[path addClip];
// Set the pattern phase
......
......@@ -251,8 +251,8 @@ const CGFloat kRapidCloseDist = 2.5;
- (void)drawRect:(NSRect)dirtyRect {
const CGFloat lineWidth = [self cr_lineWidth];
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
gfx::ScopedNSGraphicsContextSaveGState scopedGState(context);
ThemeService* themeProvider =
static_cast<ThemeService*>([[self window] themeProvider]);
......@@ -288,7 +288,8 @@ const CGFloat kRapidCloseDist = 2.5;
[[[self window] backgroundColor] set];
[path fill];
gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context);
gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
CGContextRef cgContext =
static_cast<CGContextRef>([context graphicsPort]);
CGContextBeginTransparencyLayer(cgContext, 0);
......@@ -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];
CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2;
NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha];
......@@ -356,35 +308,87 @@ const CGFloat kRapidCloseDist = 2.5;
ThemeService::COLOR_TOOLBAR_BEZEL :
ThemeService::COLOR_TOOLBAR, true) : nil;
// 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];
{
gfx::ScopedNSGraphicsContextSaveGState contextSave;
[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;
NSGraphicsContext* context = [NSGraphicsContext currentContext];
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;
[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.
{
gfx::ScopedNSGraphicsContextSaveGState drawBorderState(context);
gfx::ScopedNSGraphicsContextSaveGState drawBorderState;
[borderColor set];
[path setLineWidth:lineWidth];
[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
// found in the LICENSE file.
......@@ -17,6 +17,7 @@
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "unicode/locid.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/npapi/default_plugin_shared.h"
......@@ -139,7 +140,7 @@ void PluginInstallerImpl::DownloadCancelled() {
}
int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) {
[NSGraphicsContext saveGraphicsState];
gfx::ScopedNSGraphicsContextSaveGState scoped_state;
NSGraphicsContext* ns_context = [NSGraphicsContext
graphicsContextWithGraphicsPort:context flipped:YES];
[NSGraphicsContext setCurrentContext:ns_context];
......@@ -183,7 +184,6 @@ int16 PluginInstallerImpl::OnDrawRect(CGContextRef context, CGRect dirty_rect) {
label_point = NSMakePoint(roundf(label_point.x), roundf(label_point.y));
[command_ drawAtPoint:label_point withAttributes:attributes];
[NSGraphicsContext restoreGraphicsState];
return 1;
}
......
......@@ -16,6 +16,7 @@
#import "third_party/mozilla/NSPasteboard+Utils.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/canvas_skia.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gfx/size.h"
namespace ui {
......@@ -248,6 +249,7 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
scoped_nsobject<NSImage> image(
[[NSImage alloc] initWithPasteboard:GetPasteboard()]);
if (image.get()) {
gfx::ScopedNSGraphicsContextSaveGState scoped_state;
[image setFlipped:YES];
int width = [image size].width;
int height = [image size].height;
......@@ -262,7 +264,6 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
fromRect:NSZeroRect
operation:NSCompositeCopy
fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
return canvas.ExtractBitmap();
}
return SkBitmap();
......
......@@ -4,23 +4,27 @@
#ifndef 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/memory/scoped_nsobject.h"
#include "ui/ui_api.h"
#if defined(__OBJC__)
@class NSGraphicsContext;
#else
class NSGraphicsContext;
#endif
namespace gfx {
// A class to save/restore the state of the current context.
class UI_API ScopedNSGraphicsContextSaveGState {
public:
// If |context| is nil, it will use the |+currentContext|.
explicit ScopedNSGraphicsContextSaveGState(NSGraphicsContext* context = nil);
ScopedNSGraphicsContextSaveGState();
~ScopedNSGraphicsContextSaveGState();
private:
scoped_nsobject<NSGraphicsContext> context_;
NSGraphicsContext* context_; // weak
DISALLOW_COPY_AND_ASSIGN(ScopedNSGraphicsContextSaveGState);
};
......
......@@ -4,19 +4,20 @@
#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 {
ScopedNSGraphicsContextSaveGState::ScopedNSGraphicsContextSaveGState(
NSGraphicsContext* context) : context_([context retain]) {
if (!context_)
context_.reset([[NSGraphicsContext currentContext] retain]);
[context_ saveGraphicsState];
ScopedNSGraphicsContextSaveGState::ScopedNSGraphicsContextSaveGState()
: context_([NSGraphicsContext currentContext]) {
[NSGraphicsContext saveGraphicsState];
}
ScopedNSGraphicsContextSaveGState::~ScopedNSGraphicsContextSaveGState() {
[context_ restoreGraphicsState];
[NSGraphicsContext restoreGraphicsState];
DCHECK_EQ(context_, [NSGraphicsContext currentContext]);
}
} // 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