summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/mac/WidgetMac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/mac/WidgetMac.mm')
-rw-r--r--Source/WebCore/platform/mac/WidgetMac.mm84
1 files changed, 71 insertions, 13 deletions
diff --git a/Source/WebCore/platform/mac/WidgetMac.mm b/Source/WebCore/platform/mac/WidgetMac.mm
index e8bb81d..f3c951a 100644
--- a/Source/WebCore/platform/mac/WidgetMac.mm
+++ b/Source/WebCore/platform/mac/WidgetMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2008, 2010, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#import "Chrome.h"
#import "Cursor.h"
#import "Document.h"
+#import "FloatConversion.h"
#import "Font.h"
#import "Frame.h"
#import "GraphicsContext.h"
@@ -170,25 +171,48 @@ void Widget::setFrameRect(const IntRect& rect)
m_frame = rect;
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSView *v = getOuterView();
- if (!v)
+ NSView *outerView = getOuterView();
+ if (!outerView)
return;
- NSRect visibleRect = [v visibleRect];
+ // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary
+ // code, which can deref it.
+ RefPtr<Widget> protectedThis(this);
+
+ NSRect visibleRect = [outerView visibleRect];
NSRect f = rect;
- if (!NSEqualRects(f, [v frame])) {
- [v setFrame:f];
- [v setNeedsDisplay:NO];
- } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [v respondsToSelector:@selector(visibleRectDidChange)])
- [v visibleRectDidChange];
+ if (!NSEqualRects(f, [outerView frame])) {
+ [outerView setFrame:f];
+ [outerView setNeedsDisplay:NO];
+ } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [outerView respondsToSelector:@selector(visibleRectDidChange)])
+ [outerView visibleRectDidChange];
m_data->previousVisibleRect = visibleRect;
END_BLOCK_OBJC_EXCEPTIONS;
}
-NSView* Widget::getOuterView() const
+void Widget::setBoundsSize(const IntSize& size)
{
- NSView* view = platformWidget();
+ NSSize nsSize = size;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ NSView *outerView = getOuterView();
+ if (!outerView)
+ return;
+
+ // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary
+ // code, which can deref it.
+ RefPtr<Widget> protectedThis(this);
+ if (!NSEqualSizes(nsSize, [outerView bounds].size)) {
+ [outerView setBoundsSize:nsSize];
+ [outerView setNeedsDisplay:NO];
+ }
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+NSView *Widget::getOuterView() const
+{
+ NSView *view = platformWidget();
// If this widget's view is a WebCoreFrameScrollView then we
// resize its containing view, a WebFrameView.
@@ -205,11 +229,35 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
if (p->paintingDisabled())
return;
NSView *view = getOuterView();
+
+ // Take a reference to this Widget, because sending messages to the views can invoke arbitrary
+ // code, which can deref it.
+ RefPtr<Widget> protectedThis(this);
+
+ IntPoint transformOrigin = frameRect().location();
+ AffineTransform widgetToViewTranform = makeMapBetweenRects(IntRect(IntPoint(), frameRect().size()), [view bounds]);
+
NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) {
// This is the common case of drawing into a window or printing.
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]];
+
+ CGContextRef context = (CGContextRef)[currentContext graphicsPort];
+
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, transformOrigin.x(), transformOrigin.y());
+ CGContextScaleCTM(context, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale()));
+ CGContextTranslateCTM(context, -transformOrigin.x(), -transformOrigin.y());
+
+ IntRect dirtyRect = r;
+ dirtyRect.move(-transformOrigin.x(), -transformOrigin.y());
+ if (![view isFlipped])
+ dirtyRect.setY([view bounds].size.height - dirtyRect.bottom());
+
+ [view displayRectIgnoringOpacity:dirtyRect];
+
+ CGContextRestoreGState(context);
+
END_BLOCK_OBJC_EXCEPTIONS;
} else {
// This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath
@@ -234,6 +282,10 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
ASSERT(cgContext == [currentContext graphicsPort]);
CGContextSaveGState(cgContext);
+ CGContextTranslateCTM(cgContext, transformOrigin.x(), transformOrigin.y());
+ CGContextScaleCTM(cgContext, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale()));
+ CGContextTranslateCTM(cgContext, -transformOrigin.x(), -transformOrigin.y());
+
NSRect viewFrame = [view frame];
NSRect viewBounds = [view bounds];
// Set up the translation and (flipped) orientation of the graphics context. In normal drawing, AppKit does it as it descends down
@@ -241,13 +293,18 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y + viewFrame.size.height + viewBounds.origin.y);
CGContextScaleCTM(cgContext, 1, -1);
+ IntRect dirtyRect = r;
+ dirtyRect.move(-transformOrigin.x(), -transformOrigin.y());
+ if (![view isFlipped])
+ dirtyRect.setY([view bounds].size.height - dirtyRect.bottom());
+
BEGIN_BLOCK_OBJC_EXCEPTIONS;
{
#ifdef BUILDING_ON_TIGER
AutodrainedPool pool;
#endif
NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES];
- [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext];
+ [view displayRectIgnoringOpacity:dirtyRect inContext:nsContext];
}
END_BLOCK_OBJC_EXCEPTIONS;
@@ -261,6 +318,7 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
void Widget::setIsSelected(bool isSelected)
{
NSView *view = platformWidget();
+
BEGIN_BLOCK_OBJC_EXCEPTIONS;
if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)])
[view webPlugInSetIsSelected:isSelected];