Changeset 75897 in webkit


Ignore:
Timestamp:
Jan 16, 2011, 5:07:24 PM (15 years ago)
Author:
Simon Fraser
Message:

2011-01-16 Simon Fraser <Simon Fraser>

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:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/Source/WebCore/ChangeLog

    r75894 r75897  
    88        * plugins/qt/PluginViewQt.cpp:
    99        (WebCore::setXKeyEventSpecificFields): map event text to keycode
     10
     112011-01-16  Simon Fraser  <simon.fraser@apple.com>
     12
     13        Reviewed by Dan Bernstein.
     14
     15        Issues with iframes and plugins when the WebView is scaled.
     16        <rdar://problem/6213380>
     17       
     18        When _scaleWebView has been called on a WebView, iframes
     19        in WebKit1 render and hit-test incorrectly, and plug-ins don't scale up.
     20        This is caused by AppKit NSViews not playing nicely with the scale
     21        applied through style.
     22       
     23        Work around most of these issues by adjusting the bounds size
     24        of widgets to allow iframe contents to paint with the correct scale,
     25        and fix various places in the code where we relied on coordinate
     26        transforms via NSViews (which ignore CSS transforms).
     27
     28        * WebCore.exp.in:
     29        * platform/Widget.cpp:
     30        (WebCore::Widget::setBoundsSize):
     31        * platform/Widget.h:
     32        * platform/mac/WidgetMac.mm:
     33        (WebCore::Widget::setBoundsSize):
     34        (WebCore::Widget::paint):
     35        * rendering/RenderLayerCompositor.cpp:
     36        (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingIFrame):
     37        * rendering/RenderWidget.cpp:
     38        (WebCore::RenderWidget::setWidgetGeometry):
     39        (WebCore::RenderWidget::setWidget):
     40        (WebCore::RenderWidget::updateWidgetPosition):
     41        * rendering/RenderWidget.h:
    1042
    11432011-01-16  Simon Fraser  <simon.fraser@apple.com>
  • TabularUnified trunk/Source/WebCore/WebCore.exp.in

    r75857 r75897  
    11601160__ZNK7WebCore6Editor8canPasteEv
    11611161__ZNK7WebCore6Editor9canDeleteEv
     1162__ZN7WebCore6Widget13setBoundsSizeERKNS_7IntSizeE
    11621163__ZNK7WebCore6Widget14platformWidgetEv
    11631164__ZNK7WebCore6Widget23convertToContainingViewERKNS_7IntRectE
  • TabularUnified trunk/Source/WebCore/platform/Widget.cpp

    r68054 r75897  
    107107
    108108#if !PLATFORM(MAC)
     109void Widget::setBoundsSize(const IntSize&)
     110{
     111}
     112
    109113IntRect Widget::convertFromRootToContainingWindow(const Widget*, const IntRect& rect)
    110114{
  • TabularUnified trunk/Source/WebCore/platform/Widget.h

    r75031 r75897  
    154154
    155155    virtual void setFrameRect(const IntRect&);
     156    virtual void setBoundsSize(const IntSize&);
    156157    virtual IntRect frameRect() const;
    157158    IntRect boundsRect() const { return IntRect(0, 0, width(),  height()); }
  • TabularUnified trunk/Source/WebCore/platform/mac/WidgetMac.mm

    r75720 r75897  
    3535#import "Cursor.h"
    3636#import "Document.h"
     37#import "FloatConversion.h"
    3738#import "Font.h"
    3839#import "Frame.h"
     
    191192}
    192193
     194void Widget::setBoundsSize(const IntSize& size)
     195{
     196    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     197    NSView *outerView = getOuterView();
     198    if (!outerView)
     199        return;
     200
     201    // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary
     202    // code, which can deref it.
     203    RefPtr<Widget> protectedThis(this);
     204
     205    NSSize nsSize = size;
     206    if (!NSEqualSizes(nsSize, [outerView bounds].size)) {
     207        [outerView setBoundsSize:nsSize];
     208        [outerView setNeedsDisplay:NO];
     209    }
     210    END_BLOCK_OBJC_EXCEPTIONS;
     211}
     212
    193213NSView *Widget::getOuterView() const
    194214{
     
    215235    RefPtr<Widget> protectedThis(this);
    216236
     237    IntPoint transformOrigin = frameRect().location();
     238    AffineTransform widgetToViewTranform = makeMapBetweenRects(IntRect(IntPoint(), frameRect().size()), [view bounds]);
     239
    217240    NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
    218241    if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) {
    219242        // This is the common case of drawing into a window or printing.
    220243        BEGIN_BLOCK_OBJC_EXCEPTIONS;
    221         [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]];
     244       
     245        CGContextRef context = (CGContextRef)[currentContext graphicsPort];
     246
     247        CGContextSaveGState(context);
     248        CGContextTranslateCTM(context, transformOrigin.x(), transformOrigin.y());
     249        CGContextScaleCTM(context, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale()));
     250        CGContextTranslateCTM(context, -transformOrigin.x(), -transformOrigin.y());
     251
     252        IntRect dirtyRect = r;
     253        dirtyRect.move(-transformOrigin.x(), -transformOrigin.y());
     254        if (![view isFlipped])
     255            dirtyRect.setY([view bounds].size.height - dirtyRect.bottom());
     256
     257        [view displayRectIgnoringOpacity:dirtyRect];
     258
     259        CGContextRestoreGState(context);
     260
    222261        END_BLOCK_OBJC_EXCEPTIONS;
    223262    } else {
     
    244283        CGContextSaveGState(cgContext);
    245284
     285        CGContextTranslateCTM(cgContext, transformOrigin.x(), transformOrigin.y());
     286        CGContextScaleCTM(cgContext, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale()));
     287        CGContextTranslateCTM(cgContext, -transformOrigin.x(), -transformOrigin.y());
     288
    246289        NSRect viewFrame = [view frame];
    247290        NSRect viewBounds = [view bounds];
     
    251294        CGContextScaleCTM(cgContext, 1, -1);
    252295
     296        IntRect dirtyRect = r;
     297        dirtyRect.move(-transformOrigin.x(), -transformOrigin.y());
     298        if (![view isFlipped])
     299            dirtyRect.setY([view bounds].size.height - dirtyRect.bottom());
     300
    253301        BEGIN_BLOCK_OBJC_EXCEPTIONS;
    254302        {
     
    257305#endif
    258306            NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES];
    259             [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext];
     307            [view displayRectIgnoringOpacity:dirtyRect inContext:nsContext];
    260308        }
    261309        END_BLOCK_OBJC_EXCEPTIONS;
  • TabularUnified trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r75832 r75897  
    11191119
    11201120    // On Mac, only propagate compositing if the iframe is overlapped in the parent
    1121     // document, or the parent is already compositing.
     1121    // document, or the parent is already compositing, or the main frame is scaled.
     1122    Frame* frame = m_renderView->frameView()->frame();
     1123    Page* page = frame ? frame->page() : 0;
     1124    if (page->mainFrame()->pageScaleFactor() != 1)
     1125        return true;
     1126   
    11221127    RenderIFrame* iframeRenderer = toRenderIFrame(renderer);
    11231128    if (iframeRenderer->widget()) {
  • TabularUnified trunk/Source/WebCore/rendering/RenderWidget.cpp

    r75851 r75897  
    158158}
    159159
    160 bool RenderWidget::setWidgetGeometry(const IntRect& frame)
     160bool RenderWidget::setWidgetGeometry(const IntRect& frame, const IntSize& boundsSize)
    161161{
    162162    if (!node())
     
    175175    RefPtr<Node> protectedNode(node());
    176176    m_widget->setFrameRect(frame);
     177    m_widget->setBoundsSize(boundsSize);
    177178   
    178179#if USE(ACCELERATED_COMPOSITING)
     
    202203        if (style()) {
    203204            if (!needsLayout())
    204                 setWidgetGeometry(absoluteContentBox());
     205                setWidgetGeometry(localToAbsoluteQuad(FloatQuad(contentBoxRect())).enclosingBoundingBox(), contentBoxRect().size());
    205206            if (style()->visibility() != VISIBLE)
    206207                m_widget->hide();
     
    342343        return;
    343344
    344     // FIXME: This doesn't work correctly with transforms.
    345     FloatPoint absPos = localToAbsolute();
    346     absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
    347 
    348     int w = width() - borderAndPaddingWidth();
    349     int h = height() - borderAndPaddingHeight();
    350 
    351     bool boundsChanged = setWidgetGeometry(IntRect(absPos.x(), absPos.y(), w, h));
     345    IntRect contentBox = contentBoxRect();
     346    IntRect absoluteContentBox = localToAbsoluteQuad(FloatQuad(contentBoxRect())).enclosingBoundingBox();
     347    bool boundsChanged = setWidgetGeometry(absoluteContentBox, contentBoxRect().size());
    352348
    353349    // if the frame bounds got changed, or if view needs layout (possibly indicating
  • TabularUnified trunk/Source/WebCore/rendering/RenderWidget.h

    r74524 r75897  
    7171    virtual void setOverlapTestResult(bool);
    7272
    73     bool setWidgetGeometry(const IntRect&);
     73    bool setWidgetGeometry(const IntRect&, const IntSize&);
    7474
    7575    RefPtr<Widget> m_widget;
  • TabularUnified trunk/WebKit/mac/ChangeLog

    r75893 r75897  
     12011-01-16  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        Issues with iframes and plugins when the WebView is scaled.
     6        <rdar://problem/6213380>
     7       
     8        When _scaleWebView has been called on a WebView, iframes
     9        in WebKit1 render and hit-test incorrectly, and plug-ins don't scale up.
     10        This is caused by AppKit NSViews not playing nicely with the scale
     11        applied through style.
     12       
     13        Work around most of these issues by adjusting the bounds size
     14        of widgets to allow iframe contents to paint with the correct scale,
     15        and fix various places in the code where we relied on coordinate
     16        transforms via NSViews (which ignore CSS transforms).
     17
     18        * Plugins/Hosted/WebHostedNetscapePluginView.mm:
     19        (-[WebHostedNetscapePluginView updateAndSetWindow]):
     20        * WebView/WebFrameView.mm:
     21        (-[WebFrameView setBoundsSize:]):
     22
    1232011-01-16  Beth Dakin  <bdakin@apple.com>
    224
  • TabularUnified trunk/WebKit/mac/Plugins/Hosted/WebHostedNetscapePluginView.mm

    r75873 r75897  
    209209   
    210210    _proxy->resize(boundsInWindow, visibleRectInWindow);
     211
     212    CGRect layerBounds = NSRectToCGRect(boundsInWindow);
     213    CGRect bounds = NSRectToCGRect([self bounds]);
     214    CGRect frame = NSRectToCGRect([self frame]);
     215   
     216    // We're not scaled, or in a subframe
     217    CATransform3D scaleTransform = CATransform3DIdentity;
     218    if (CGSizeEqualToSize(bounds.size, frame.size)) {
     219        // We're in a subframe. Backing store is boundsInWindow.size.
     220        if (boundsInWindow.size.width && boundsInWindow.size.height)
     221            scaleTransform = CATransform3DMakeScale(frame.size.width / boundsInWindow.size.width, frame.size.height / boundsInWindow.size.height, 1);
     222    } else {
     223        // We're in the main frame with scaling. Need to mimic the frame/bounds scaling on Widgets.
     224        if (frame.size.width && frame.size.height)
     225            scaleTransform = CATransform3DMakeScale(bounds.size.width / frame.size.width, bounds.size.height / frame.size.height, 1);
     226    }
     227
     228    _pluginLayer.get().sublayerTransform = scaleTransform;
    211229}
    212230
  • TabularUnified trunk/WebKit/mac/WebView/WebFrameView.mm

    r73645 r75897  
    510510}
    511511
     512- (void)setBoundsSize:(NSSize)size
     513{
     514    [super setBoundsSize:size];
     515    [[self _scrollView] setFrameSize:size];
     516}
     517
    512518- (void)viewDidMoveToWindow
    513519{
Note: See TracChangeset for help on using the changeset viewer.