[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

simon.fraser at apple.com simon.fraser at apple.com
Sun Feb 20 23:04:15 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 448c931f6d9fc828515a8ba489335af221a2622b
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jan 17 01:07:24 2011 +0000

    2011-01-16  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            Issues with iframes and plugins when the WebView is scaled.
            <rdar://problem/6213380>
    
            When _scaleWebView has been called on a WebView, iframes
            in WebKit1 render and hit-test incorrectly, and plug-ins don't scale up.
            This is caused by AppKit NSViews not playing nicely with the scale
            applied through style.
    
            Work around most of these issues by adjusting the bounds size
            of widgets to allow iframe contents to paint with the correct scale,
            and fix various places in the code where we relied on coordinate
            transforms via NSViews (which ignore CSS transforms).
    
            * WebCore.exp.in:
            * platform/Widget.cpp:
            (WebCore::Widget::setBoundsSize):
            * platform/Widget.h:
            * platform/mac/WidgetMac.mm:
            (WebCore::Widget::setBoundsSize):
            (WebCore::Widget::paint):
            * rendering/RenderLayerCompositor.cpp:
            (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame):
            * rendering/RenderWidget.cpp:
            (WebCore::RenderWidget::setWidgetGeometry):
            (WebCore::RenderWidget::setWidget):
            (WebCore::RenderWidget::updateWidgetPosition):
            * rendering/RenderWidget.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75897 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 240424d..1a6c804 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -12,6 +12,38 @@
 
         Reviewed by Dan Bernstein.
 
+        Issues with iframes and plugins when the WebView is scaled.
+        <rdar://problem/6213380>
+        
+        When _scaleWebView has been called on a WebView, iframes
+        in WebKit1 render and hit-test incorrectly, and plug-ins don't scale up.
+        This is caused by AppKit NSViews not playing nicely with the scale
+        applied through style.
+        
+        Work around most of these issues by adjusting the bounds size
+        of widgets to allow iframe contents to paint with the correct scale,
+        and fix various places in the code where we relied on coordinate
+        transforms via NSViews (which ignore CSS transforms).
+
+        * WebCore.exp.in:
+        * platform/Widget.cpp:
+        (WebCore::Widget::setBoundsSize):
+        * platform/Widget.h:
+        * platform/mac/WidgetMac.mm:
+        (WebCore::Widget::setBoundsSize):
+        (WebCore::Widget::paint):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame):
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::setWidgetGeometry):
+        (WebCore::RenderWidget::setWidget):
+        (WebCore::RenderWidget::updateWidgetPosition):
+        * rendering/RenderWidget.h:
+
+2011-01-16  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
         RenderView needs to take transforms on its layer into account
         https://bugs.webkit.org/show_bug.cgi?id=52536
         
diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in
index 46ad8a8..a77730e 100644
--- a/Source/WebCore/WebCore.exp.in
+++ b/Source/WebCore/WebCore.exp.in
@@ -1159,6 +1159,7 @@ __ZNK7WebCore6Editor7canCopyEv
 __ZNK7WebCore6Editor7canEditEv
 __ZNK7WebCore6Editor8canPasteEv
 __ZNK7WebCore6Editor9canDeleteEv
+__ZN7WebCore6Widget13setBoundsSizeERKNS_7IntSizeE
 __ZNK7WebCore6Widget14platformWidgetEv
 __ZNK7WebCore6Widget23convertToContainingViewERKNS_7IntRectE
 __ZNK7WebCore6Widget23convertToContainingViewERKNS_8IntPointE
diff --git a/Source/WebCore/platform/Widget.cpp b/Source/WebCore/platform/Widget.cpp
index 77560ff..9a980c0 100644
--- a/Source/WebCore/platform/Widget.cpp
+++ b/Source/WebCore/platform/Widget.cpp
@@ -106,6 +106,10 @@ IntPoint Widget::convertToContainingWindow(const IntPoint& localPoint) const
 }
 
 #if !PLATFORM(MAC)
+void Widget::setBoundsSize(const IntSize&)
+{
+}
+
 IntRect Widget::convertFromRootToContainingWindow(const Widget*, const IntRect& rect)
 {
     return rect;
diff --git a/Source/WebCore/platform/Widget.h b/Source/WebCore/platform/Widget.h
index b13ed2b..6d12365 100644
--- a/Source/WebCore/platform/Widget.h
+++ b/Source/WebCore/platform/Widget.h
@@ -153,6 +153,7 @@ public:
     IntPoint pos() const { return frameRect().location(); }
 
     virtual void setFrameRect(const IntRect&);
+    virtual void setBoundsSize(const IntSize&);
     virtual IntRect frameRect() const;
     IntRect boundsRect() const { return IntRect(0, 0, width(),  height()); }
 
diff --git a/Source/WebCore/platform/mac/WidgetMac.mm b/Source/WebCore/platform/mac/WidgetMac.mm
index 2c1b52f..0d12ebc 100644
--- a/Source/WebCore/platform/mac/WidgetMac.mm
+++ b/Source/WebCore/platform/mac/WidgetMac.mm
@@ -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"
@@ -190,6 +191,25 @@ void Widget::setFrameRect(const IntRect& rect)
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
+void Widget::setBoundsSize(const IntSize& 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);
+
+    NSSize nsSize = size;
+    if (!NSEqualSizes(nsSize, [outerView bounds].size)) {
+        [outerView setBoundsSize:nsSize];
+        [outerView setNeedsDisplay:NO];
+    }
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
 NSView *Widget::getOuterView() const
 {
     NSView *view = platformWidget();
@@ -214,11 +234,30 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
     // 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
@@ -243,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
@@ -250,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;
 
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 2155b35..17f16c3 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1118,7 +1118,12 @@ bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame() const
         return true;
 
     // On Mac, only propagate compositing if the iframe is overlapped in the parent
-    // document, or the parent is already compositing.
+    // document, or the parent is already compositing, or the main frame is scaled.
+    Frame* frame = m_renderView->frameView()->frame();
+    Page* page = frame ? frame->page() : 0;
+    if (page->mainFrame()->pageScaleFactor() != 1)
+        return true;
+    
     RenderIFrame* iframeRenderer = toRenderIFrame(renderer);
     if (iframeRenderer->widget()) {
         ASSERT(iframeRenderer->widget()->isFrameView());
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp
index 74faf00..5387306 100644
--- a/Source/WebCore/rendering/RenderWidget.cpp
+++ b/Source/WebCore/rendering/RenderWidget.cpp
@@ -157,7 +157,7 @@ RenderWidget::~RenderWidget()
     clearWidget();
 }
 
-bool RenderWidget::setWidgetGeometry(const IntRect& frame)
+bool RenderWidget::setWidgetGeometry(const IntRect& frame, const IntSize& boundsSize)
 {
     if (!node())
         return false;
@@ -174,6 +174,7 @@ bool RenderWidget::setWidgetGeometry(const IntRect& frame)
     RenderWidgetProtector protector(this);
     RefPtr<Node> protectedNode(node());
     m_widget->setFrameRect(frame);
+    m_widget->setBoundsSize(boundsSize);
     
 #if USE(ACCELERATED_COMPOSITING)
     if (hasLayer() && layer()->isComposited())
@@ -201,7 +202,7 @@ void RenderWidget::setWidget(PassRefPtr<Widget> widget)
         // style pointer).
         if (style()) {
             if (!needsLayout())
-                setWidgetGeometry(absoluteContentBox());
+                setWidgetGeometry(localToAbsoluteQuad(FloatQuad(contentBoxRect())).enclosingBoundingBox(), contentBoxRect().size());
             if (style()->visibility() != VISIBLE)
                 m_widget->hide();
             else
@@ -341,14 +342,9 @@ void RenderWidget::updateWidgetPosition()
     if (!m_widget || !node()) // Check the node in case destroy() has been called.
         return;
 
-    // FIXME: This doesn't work correctly with transforms.
-    FloatPoint absPos = localToAbsolute();
-    absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
-
-    int w = width() - borderAndPaddingWidth();
-    int h = height() - borderAndPaddingHeight();
-
-    bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h));
+    IntRect contentBox = contentBoxRect();
+    IntRect absoluteContentBox = localToAbsoluteQuad(FloatQuad(contentBoxRect())).enclosingBoundingBox();
+    bool boundsChanged = setWidgetGeometry(absoluteContentBox, contentBoxRect().size());
 
     // if the frame bounds got changed, or if view needs layout (possibly indicating
     // content size is wrong) we have to do a layout to set the right widget size
diff --git a/Source/WebCore/rendering/RenderWidget.h b/Source/WebCore/rendering/RenderWidget.h
index d2ec096..5cbdfaf 100644
--- a/Source/WebCore/rendering/RenderWidget.h
+++ b/Source/WebCore/rendering/RenderWidget.h
@@ -70,7 +70,7 @@ private:
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
     virtual void setOverlapTestResult(bool);
 
-    bool setWidgetGeometry(const IntRect&);
+    bool setWidgetGeometry(const IntRect&, const IntSize&);
 
     RefPtr<Widget> m_widget;
     RefPtr<Image> m_substituteImage;
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 458bdaa..6274a01 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,25 @@
+2011-01-16  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Issues with iframes and plugins when the WebView is scaled.
+        <rdar://problem/6213380>
+        
+        When _scaleWebView has been called on a WebView, iframes
+        in WebKit1 render and hit-test incorrectly, and plug-ins don't scale up.
+        This is caused by AppKit NSViews not playing nicely with the scale
+        applied through style.
+        
+        Work around most of these issues by adjusting the bounds size
+        of widgets to allow iframe contents to paint with the correct scale,
+        and fix various places in the code where we relied on coordinate
+        transforms via NSViews (which ignore CSS transforms).
+
+        * Plugins/Hosted/WebHostedNetscapePluginView.mm:
+        (-[WebHostedNetscapePluginView updateAndSetWindow]):
+        * WebView/WebFrameView.mm:
+        (-[WebFrameView setBoundsSize:]):
+
 2011-01-16  Beth Dakin  <bdakin at apple.com>
 
         Reviewed by Kevin Decker.
diff --git a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
index ed53b0a..5593050 100644
--- a/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm
@@ -208,6 +208,24 @@ extern "C" {
     _previousSize = boundsInWindow.size;
     
     _proxy->resize(boundsInWindow, visibleRectInWindow);
+
+    CGRect layerBounds = NSRectToCGRect(boundsInWindow);
+    CGRect bounds = NSRectToCGRect([self bounds]);
+    CGRect frame = NSRectToCGRect([self frame]);
+    
+    // We're not scaled, or in a subframe
+    CATransform3D scaleTransform = CATransform3DIdentity;
+    if (CGSizeEqualToSize(bounds.size, frame.size)) {
+        // We're in a subframe. Backing store is boundsInWindow.size.
+        if (boundsInWindow.size.width && boundsInWindow.size.height)
+            scaleTransform = CATransform3DMakeScale(frame.size.width / boundsInWindow.size.width, frame.size.height / boundsInWindow.size.height, 1);
+    } else {
+        // We're in the main frame with scaling. Need to mimic the frame/bounds scaling on Widgets.
+        if (frame.size.width && frame.size.height)
+            scaleTransform = CATransform3DMakeScale(bounds.size.width / frame.size.width, bounds.size.height / frame.size.height, 1);
+    }
+
+    _pluginLayer.get().sublayerTransform = scaleTransform;
 }
 
 - (void)windowFocusChanged:(BOOL)hasFocus
diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm
index 82efa6d..801c1f4 100644
--- a/WebKit/mac/WebView/WebFrameView.mm
+++ b/WebKit/mac/WebView/WebFrameView.mm
@@ -509,6 +509,12 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl
     [super setFrameSize:size];
 }
 
+- (void)setBoundsSize:(NSSize)size
+{
+    [super setBoundsSize:size];
+    [[self _scrollView] setFrameSize:size];
+}
+
 - (void)viewDidMoveToWindow
 {
     // See WebFrameLoaderClient::provisionalLoadStarted.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list