Changeset 20042 in webkit


Ignore:
Timestamp:
Mar 7, 2007 5:34:23 PM (17 years ago)
Author:
bdash
Message:

2007-03-07 Bruce Q Hammond <bruceq@apple.om>

Reviewed by Darin.

This fixes a problem with Netscape-style Plug-ins which draw through the Quickdraw APIs
being unable to render into offscreen bitmap contexts.

This patches both saveAndSetNewPortStateForUpdate: and restorePortState:
These methods now check the current context and see if appropriate setup/cleanup needs to be done
for offscreen rendering.

  • Plugins/WebBaseNetscapePluginView.mm: (QDPixelFormatFromCGBitmapInfo): (-[WebBaseNetscapePluginView saveAndSetNewPortStateForUpdate:]): (-[WebBaseNetscapePluginView restorePortState:]):
Location:
trunk/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit/ChangeLog

    r20040 r20042  
     12007-03-07  Bruce Q Hammond  <bruceq@apple.om>
     2
     3        Reviewed by Darin.
     4
     5        This fixes a problem with Netscape-style Plug-ins which draw through the Quickdraw APIs
     6        being unable to render into offscreen bitmap contexts.
     7
     8        This patches both saveAndSetNewPortStateForUpdate: and restorePortState:
     9        These methods now check the current context and see if appropriate setup/cleanup needs to be done
     10        for offscreen rendering.
     11
     12        * Plugins/WebBaseNetscapePluginView.mm:
     13        (QDPixelFormatFromCGBitmapInfo):
     14        (-[WebBaseNetscapePluginView saveAndSetNewPortStateForUpdate:]):
     15        (-[WebBaseNetscapePluginView restorePortState:]):
     16
    1172007-03-07  Anders Carlsson  <acarlsson@apple.com>
    218
  • trunk/WebKit/Plugins/WebBaseNetscapePluginView.mm

    r19966 r20042  
    3737#import "WebKitLogging.h"
    3838#import "WebKitNSStringExtras.h"
     39#import "WebKitSystemInterface.h"
    3940#import "WebNSDataExtras.h"
    4041#import "WebNSDictionaryExtras.h"
     
    5758#import <WebCore/FrameTree.h>
    5859#import <WebCore/Page.h>
    59 #import <WebCore/WebCoreObjCExtras.h>
    6060#import <WebKit/DOMPrivate.h>
    6161#import <WebKit/WebUIDelegate.h>
    62 #import <WebKitSystemInterface.h>
    6362#import <objc/objc-runtime.h>
    6463
     
    263262#endif
    264263
     264#ifndef NP_NO_QUICKDRAW
     265static UInt32 QDPixelFormatFromCGBitmapInfo(CGBitmapInfo bitmapInfo)
     266{
     267    UInt32 cgByteOrder = bitmapInfo & kCGBitmapByteOrderMask;
     268    switch (cgByteOrder) {
     269    case kCGBitmapByteOrderDefault:
     270        return 0;
     271    case kCGBitmapByteOrder16Little:
     272        return k16LE555PixelFormat;
     273    case kCGBitmapByteOrder32Little:
     274        return k32BGRAPixelFormat;
     275    case kCGBitmapByteOrder16Big:
     276        return k16BE555PixelFormat;
     277    case kCGBitmapByteOrder32Big:
     278        return k32ARGBPixelFormat;
     279    default:
     280        ASSERT_NOT_REACHED();
     281        return 0;
     282    }
     283}
     284#endif
     285
    265286- (PortState)saveAndSetNewPortStateForUpdate:(BOOL)forUpdate
    266287{
     
    373394            RgnHandle clipRegion = NewRgn();
    374395            qdPortState->clipRegion = clipRegion;
    375            
     396
     397            CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
     398            // If the current context is an offscreen bitmap, then we create a GWorld for it
     399            bool offScreenContext = WKCGContextIsBitmapContext(currentContext);
     400            if (offScreenContext) {
     401                CGBitmapInfo contextBitmapInfo = CGBitmapContextGetBitmapInfo(currentContext);
     402                GWorldPtr pOffScreenGWorld;
     403                Rect offscreenBounds;
     404                int rowBytes = CGBitmapContextGetBytesPerRow(currentContext);
     405                offscreenBounds.top = 0;
     406                offscreenBounds.left = 0;
     407                offscreenBounds.right = CGBitmapContextGetWidth(currentContext);
     408                offscreenBounds.bottom = CGBitmapContextGetHeight(currentContext);
     409                UInt32 pixelFormat = QDPixelFormatFromCGBitmapInfo(contextBitmapInfo);
     410                if (pixelFormat == 0) {
     411                    // Not a valid pixel format - don't render at all.
     412                    offscreenBounds.top = 0;
     413                    offscreenBounds.left = 0;
     414                    offscreenBounds.right = 0;
     415                    offscreenBounds.bottom = 0;
     416                    rowBytes = 0;
     417                    pixelFormat = k32BGRAPixelFormat;
     418                }
     419                void* bits = CGBitmapContextGetData(currentContext);
     420                QDErr err = NewGWorldFromPtr(&pOffScreenGWorld, pixelFormat, &offscreenBounds, 0, 0, 0, static_cast<char*>(bits), rowBytes);
     421                ASSERT(pOffScreenGWorld && !err);
     422                if (!err) {
     423                    SetGWorld(pOffScreenGWorld, NULL);
     424                    nPort.qdPort.port = pOffScreenGWorld;
     425                    NSRect boundsInWindow = [self bounds];
     426                    nPort.qdPort.portx = ((int32)-boundsInWindow.origin.x);
     427                    nPort.qdPort.porty = ((int32)-boundsInWindow.origin.y);
     428                    window.x = 0;
     429                    window.y = 0;
     430                    window.window = &nPort;
     431
     432                    // Get the clip bounds for the existing context and use that for the plug-in's window.clipRect.
     433                    // The plug-in will intersect this clip rect with the port's dirty region clip constructed below.
     434                    CGRect contextClip = CGContextGetClipBoundingBox(currentContext);
     435                    window.clipRect.top = contextClip.origin.y;
     436                    window.clipRect.left = contextClip.origin.x;
     437                    window.clipRect.right = window.clipRect.left + contextClip.size.width;
     438                    window.clipRect.bottom = window.clipRect.top + contextClip.size.height;
     439                }
     440            }
    376441            MacSetRectRgn(clipRegion,
    377442                window.clipRect.left + nPort.qdPort.portx, window.clipRect.top + nPort.qdPort.porty,
     
    380445            // Clip to dirty region so plug-in does not draw over already-drawn regions of the window that are
    381446            // not going to be redrawn this update.  This forces plug-ins to play nice with z-index ordering.
     447            Rect clipBounds;
    382448            if (forUpdate) {
    383449                RgnHandle viewClipRegion = NewRgn();
     
    407473                SectRgn(clipRegion, viewClipRegion, clipRegion);
    408474                DisposeRgn(viewClipRegion);
     475                if (offScreenContext) {
     476                    GetRegionBounds(clipRegion, &clipBounds);
     477                    OffsetRgn(clipRegion, -clipBounds.left, -clipBounds.top);
     478                    port = nPort.qdPort.port;
     479                }
    409480            }
    410            
    411             qdPortState->forUpdate = forUpdate;
    412            
     481   
    413482            // Switch to the port and set it up.
    414483            SetPort(port);
    415 
    416484            PenNormal();
    417485            ForeColor(blackColor);
    418486            BackColor(whiteColor);
    419            
    420487            SetOrigin(nPort.qdPort.portx, nPort.qdPort.porty);
    421 
    422488            SetPortClipRegion(nPort.qdPort.port, clipRegion);
    423489
     
    430496                // Some plugins do their own BeginUpdate/EndUpdate.
    431497                // For those, we must make sure that the update region contains the area we want to draw.
     498                if (offScreenContext)
     499                    OffsetRgn(clipRegion, clipBounds.left, clipBounds.top);
    432500                InvalWindowRgn(windowRef, clipRegion);
    433501            }
     502           
     503            qdPortState->forUpdate = forUpdate;
     504
    434505        }
    435506        break;
     
    527598        case NPDrawingModelQuickDraw:
    528599        {
     600            CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
     601           
     602            // If the current context is an offscreen bitmap, then we need to
     603            // dispose its GWorld and restore the Window's GWorld
     604            if (WKCGContextIsBitmapContext(currentContext)) {
     605                GWorldPtr curGWorld;
     606                GetGWorld(&curGWorld, NULL);
     607                DisposeGWorld(curGWorld);
     608                WindowRef windowRef = (WindowRef)[[self currentWindow] windowRef];
     609                CGrafPtr port = GetWindowPort(windowRef);
     610                SetGWorld(port, NULL);
     611            }
     612
    529613            PortState_QD *qdPortState = (PortState_QD *)portState;
    530614            WindowRef windowRef = (WindowRef)[[self currentWindow] windowRef];
     
    543627            DisposeRgn(qdPortState->clipRegion);
    544628
    545             SetPort(qdPortState->oldPort);
     629            SetGWorld(qdPortState->oldPort, NULL);
    546630        }
    547631        break;
Note: See TracChangeset for help on using the changeset viewer.