Reviewed by John Sullivan.
authortomernic <tomernic@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Apr 2006 20:32:05 +0000 (20:32 +0000)
committertomernic <tomernic@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Apr 2006 20:32:05 +0000 (20:32 +0000)
        <rdar://problem/4476875> Support printing for embedded Netscape plugins

        NOTE: This only works with the Flash plugin right now.  It appears that the other
        major plugins either have awful printing support, or no printing support.  If someone
        can find an example of any other embedded Netscape plugin printing in any browser on
        the Mac, I will be happy to eat my own words!

        * Plugins/WebBaseNetscapePluginView.m:
        (-[WebBaseNetscapePluginView drawRect:]):
        When printing, get the printed bitmap via -_printedPluginBitmap, and draw it into the
        plugin view.
        (-[WebBaseNetscapePluginView _printedPluginBitmap]):
        Call NPP_Print on the plugin to render it into a GWorld.  This GWorld has the same
        underlying buffer as an NSBitmapImageRep, which is returned to the caller.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14001 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/Plugins/WebBaseNetscapePluginView.m

index 0307ff3045cc5210a3d116f8f7f97a34f5bb4841..4a3e9cbe874f63d5d7885f25a76b205e30bc1ac3 100644 (file)
@@ -1,3 +1,22 @@
+2006-04-20  Tim Omernick  <timo@apple.com>
+
+        Reviewed by John Sullivan.
+
+        <rdar://problem/4476875> Support printing for embedded Netscape plugins
+
+        NOTE: This only works with the Flash plugin right now.  It appears that the other
+        major plugins either have awful printing support, or no printing support.  If someone
+        can find an example of any other embedded Netscape plugin printing in any browser on
+        the Mac, I will be happy to eat my own words!
+
+        * Plugins/WebBaseNetscapePluginView.m:
+        (-[WebBaseNetscapePluginView drawRect:]):
+        When printing, get the printed bitmap via -_printedPluginBitmap, and draw it into the
+        plugin view.
+        (-[WebBaseNetscapePluginView _printedPluginBitmap]):
+        Call NPP_Print on the plugin to render it into a GWorld.  This GWorld has the same
+        underlying buffer as an NSBitmapImageRep, which is returned to the caller.
+
 2006-04-20 Mitz Pettel  <opendarwin.org@mitzpettel.com>
 
         Reviewed by Darin.
index 6528e73fb297c8fddc1df495f7a256e002611038..ea6e40469c9d2506861fda138210785bfaddaff2 100644 (file)
@@ -62,6 +62,9 @@
 #define LoginWindowDidSwitchFromUserNotification    @"WebLoginWindowDidSwitchFromUserNotification"
 #define LoginWindowDidSwitchToUserNotification      @"WebLoginWindowDidSwitchToUserNotification"
 
+@interface WebBaseNetscapePluginView (Internal)
+- (NSBitmapImageRep *)_printedPluginBitmap;
+@end
 
 static WebBaseNetscapePluginView *currentPluginView = nil;
 
@@ -1237,10 +1240,21 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
         return;
     }
     
-    if ([NSGraphicsContext currentContextDrawingToScreen]) {
+    if ([NSGraphicsContext currentContextDrawingToScreen])
         [self sendUpdateEvent];
-    } else {
-        // Printing 2862383
+    else {
+        NSBitmapImageRep *printedPluginBitmap = [self _printedPluginBitmap];
+        if (printedPluginBitmap) {
+            // Flip the bitmap before drawing because the QuickDraw port is flipped relative
+            // to this view.
+            CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort];
+            CGContextSaveGState(cgContext);
+            NSRect bounds = [self bounds];
+            CGContextTranslateCTM(cgContext, 0.0, NSHeight(bounds));
+            CGContextScaleCTM(cgContext, 1.0, -1.0);
+            [printedPluginBitmap drawInRect:bounds];
+            CGContextRestoreGState(cgContext);
+        }
     }
 }
 
@@ -1887,6 +1901,75 @@ static OSStatus TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEve
 
 @end
 
+@implementation WebBaseNetscapePluginView (Internal)
+
+- (NSBitmapImageRep *)_printedPluginBitmap
+{
+    // Cannot print plugins that do not implement NPP_Print
+    if (!NPP_Print)
+        return nil;
+
+    // This NSBitmapImageRep will share its bitmap buffer with a GWorld that the plugin will draw into.
+    // The bitmap is created in 32-bits-per-pixel ARGB format, which is the default GWorld pixel format.
+    NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+                                                         pixelsWide:window.width
+                                                         pixelsHigh:window.height
+                                                         bitsPerSample:8
+                                                         samplesPerPixel:4
+                                                         hasAlpha:YES
+                                                         isPlanar:NO
+                                                         colorSpaceName:NSDeviceRGBColorSpace
+                                                         bitmapFormat:NSAlphaFirstBitmapFormat
+                                                         bytesPerRow:0
+                                                         bitsPerPixel:0] autorelease];
+    ASSERT(bitmap);
+    
+    // Create a GWorld with the same underlying buffer into which the plugin can draw
+    Rect printGWorldBounds;
+    SetRect(&printGWorldBounds, 0, 0, window.width, window.height);
+    GWorldPtr printGWorld;
+    if (NewGWorldFromPtr(&printGWorld,
+                         k32ARGBPixelFormat,
+                         &printGWorldBounds,
+                         NULL,
+                         NULL,
+                         0,
+                         (Ptr)[bitmap bitmapData],
+                         [bitmap bytesPerRow]) != noErr) {
+        ERROR("Could not create GWorld for printing");
+        return nil;
+    }
+    
+    /// Create NPWindow for the GWorld
+    NPWindow printNPWindow;
+    printNPWindow.window = &printGWorld; // Normally this is an NP_Port, but when printing it is the actual CGrafPtr
+    printNPWindow.x = 0;
+    printNPWindow.y = 0;
+    printNPWindow.width = window.width;
+    printNPWindow.height = window.height;
+    printNPWindow.clipRect.top = 0;
+    printNPWindow.clipRect.left = 0;
+    printNPWindow.clipRect.right = window.width;
+    printNPWindow.clipRect.bottom = window.height;
+    printNPWindow.type = NPWindowTypeDrawable; // Offscreen graphics port as opposed to a proper window
+    
+    // Create embed-mode NPPrint
+    NPPrint npPrint;
+    npPrint.mode = NP_EMBED;
+    npPrint.print.embedPrint.window = printNPWindow;
+    npPrint.print.embedPrint.platformPrint = printGWorld;
+    
+    // Tell the plugin to print into the GWorld
+    NPP_Print(instance, &npPrint);
+
+    // Don't need the GWorld anymore
+    DisposeGWorld(printGWorld);
+        
+    return bitmap;
+}
+
+@end
+
 @implementation NSData (PluginExtras)
 
 - (BOOL)_web_startsWithBlankLine