[WK2] Print preview should vend images to the UIProcess instead of PDFs
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Nov 2012 20:47:34 +0000 (20:47 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Nov 2012 20:47:34 +0000 (20:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=101382
<rdar://problem/9866766>

Reviewed by Alexey Proskuryakov.

In the interests of keeping PDF processing inside the WebProcess, we should
remove print preview's reliance on PDFs, by handing bitmaps back instead.

* Shared/ShareableBitmap.cpp:
(WebKit::ShareableBitmap::create): Add an optional SharedMemory::Protection argument, so we can make
ShareableBitmaps from read-only handles if desired. Defaults to read-write as previously.
(WebKit::ShareableBitmap::createHandle): Add an optional SharedMemory::Protection argument, so we can make
read-only handles if desired. Defaults to read-write as previously.
* Shared/ShareableBitmap.h:
* UIProcess/API/mac/WKPrintingView.h:
(WebImage): Store WebImages instead of raw PDF data for previews.
* UIProcess/API/mac/WKPrintingView.mm:
(pageDidDrawToImage): Add a callback for when a preview we've requested is done rendering into an image.
Cache the image in _pagePreviews if appropriate.
(pageDidDrawToPDF): Do not handle PDF data unless we are expecting a real print callback (not a preview).
(-[WKPrintingView _drawPreview:]): Request an image instead of PDF data when doing a print preview.
* UIProcess/GenericCallback.h:
(ImageCallback): Add a callback type with one argument: a ShareableBitmap::Handle.
I can't use the GenericCallback template because ShareableBitmap::Handle doesn't have a corresponding WK type.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::close): Add support for ImageCallback.
(WebKit::WebPageProxy::imageCallback): Add support for ImageCallback.
(WebKit::WebPageProxy::drawRectToImage): Rename drawRectToPDF to drawRectToImage.
* UIProcess/WebPageProxy.h:
(WebPageProxy): Rename drawRectToPDF to drawRectToImage, add support for ImageCallback.
* UIProcess/WebPageProxy.messages.in: Add support for ImageCallback.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::drawRectToImage): Rename drawRectToPDF to drawRectToImage.
Make drawRectToImage create a bitmap snapshot of the page (using the normal snapshotting code),
or, if the page is backed by a *PDFPlugin, draw the PDF document into a bitmap and use that.
* WebProcess/WebPage/WebPage.h:
(WebPage): Rename drawRectToPDF to drawRectToImage.
* WebProcess/WebPage/WebPage.messages.in: Rename drawRectToPDF to drawRectToImage.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::drawPDFDocument): Rename drawRectToPDFFromPDFDocument to drawPDFDocument,
because it's more like drawImage than anything else.

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

13 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/ShareableBitmap.cpp
Source/WebKit2/Shared/ShareableBitmap.h
Source/WebKit2/UIProcess/API/mac/WKPrintingView.h
Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm
Source/WebKit2/UIProcess/GenericCallback.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

index 3dc6fbc..5eb5490 100644 (file)
@@ -1,3 +1,48 @@
+2012-11-08  Tim Horton  <timothy_horton@apple.com>
+
+        [WK2] Print preview should vend images to the UIProcess instead of PDFs
+        https://bugs.webkit.org/show_bug.cgi?id=101382
+        <rdar://problem/9866766>
+
+        Reviewed by Alexey Proskuryakov.
+
+        In the interests of keeping PDF processing inside the WebProcess, we should
+        remove print preview's reliance on PDFs, by handing bitmaps back instead.
+
+        * Shared/ShareableBitmap.cpp:
+        (WebKit::ShareableBitmap::create): Add an optional SharedMemory::Protection argument, so we can make
+        ShareableBitmaps from read-only handles if desired. Defaults to read-write as previously.
+        (WebKit::ShareableBitmap::createHandle): Add an optional SharedMemory::Protection argument, so we can make
+        read-only handles if desired. Defaults to read-write as previously.
+        * Shared/ShareableBitmap.h:
+        * UIProcess/API/mac/WKPrintingView.h:
+        (WebImage): Store WebImages instead of raw PDF data for previews.
+        * UIProcess/API/mac/WKPrintingView.mm:
+        (pageDidDrawToImage): Add a callback for when a preview we've requested is done rendering into an image.
+        Cache the image in _pagePreviews if appropriate.
+        (pageDidDrawToPDF): Do not handle PDF data unless we are expecting a real print callback (not a preview).
+        (-[WKPrintingView _drawPreview:]): Request an image instead of PDF data when doing a print preview.
+        * UIProcess/GenericCallback.h:
+        (ImageCallback): Add a callback type with one argument: a ShareableBitmap::Handle.
+        I can't use the GenericCallback template because ShareableBitmap::Handle doesn't have a corresponding WK type.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::close): Add support for ImageCallback.
+        (WebKit::WebPageProxy::imageCallback): Add support for ImageCallback.
+        (WebKit::WebPageProxy::drawRectToImage): Rename drawRectToPDF to drawRectToImage.
+        * UIProcess/WebPageProxy.h:
+        (WebPageProxy): Rename drawRectToPDF to drawRectToImage, add support for ImageCallback.
+        * UIProcess/WebPageProxy.messages.in: Add support for ImageCallback.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::drawRectToImage): Rename drawRectToPDF to drawRectToImage.
+        Make drawRectToImage create a bitmap snapshot of the page (using the normal snapshotting code),
+        or, if the page is backed by a *PDFPlugin, draw the PDF document into a bitmap and use that.
+        * WebProcess/WebPage/WebPage.h:
+        (WebPage): Rename drawRectToPDF to drawRectToImage.
+        * WebProcess/WebPage/WebPage.messages.in: Rename drawRectToPDF to drawRectToImage.
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::drawPDFDocument): Rename drawRectToPDFFromPDFDocument to drawPDFDocument,
+        because it's more like drawImage than anything else.
+
 2012-11-08  Simon Hausmann  <simon.hausmann@digia.com>
 
         [Qt] Fix build without WebKit1
index acae74f..8c0deaf 100644 (file)
@@ -89,21 +89,21 @@ PassRefPtr<ShareableBitmap> ShareableBitmap::create(const IntSize& size, Flags f
     return adoptRef(new ShareableBitmap(size, flags, sharedMemory));
 }
 
-PassRefPtr<ShareableBitmap> ShareableBitmap::create(const Handle& handle)
+PassRefPtr<ShareableBitmap> ShareableBitmap::create(const Handle& handle, SharedMemory::Protection protection)
 {
     // Create the shared memory.
-    RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, SharedMemory::ReadWrite);
+    RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, protection);
     if (!sharedMemory)
         return 0;
 
     return create(handle.m_size, handle.m_flags, sharedMemory.release());
 }
 
-bool ShareableBitmap::createHandle(Handle& handle)
+bool ShareableBitmap::createHandle(Handle& handle, SharedMemory::Protection protection)
 {
     ASSERT(isBackedBySharedMemory());
 
-    if (!m_sharedMemory->createHandle(handle.m_handle, SharedMemory::ReadWrite))
+    if (!m_sharedMemory->createHandle(handle.m_handle, protection))
         return false;
     handle.m_size = m_size;
     handle.m_flags = m_flags;
index 8dbf1dd..6a575f2 100644 (file)
@@ -93,10 +93,10 @@ public:
     static PassRefPtr<ShareableBitmap> create(const WebCore::IntSize&, Flags, PassRefPtr<SharedMemory>);
 
     // Create a shareable bitmap from a handle.
-    static PassRefPtr<ShareableBitmap> create(const Handle&);
+    static PassRefPtr<ShareableBitmap> create(const Handle&, SharedMemory::Protection = SharedMemory::ReadWrite);
 
     // Create a handle.
-    bool createHandle(Handle&);
+    bool createHandle(Handle&, SharedMemory::Protection = SharedMemory::ReadWrite);
 
     ~ShareableBitmap();
 
index cd3b1f9..67bd4b1 100644 (file)
@@ -30,6 +30,7 @@
 @class PDFDocument;
 
 namespace WebKit {
+    class ShareableBitmap;
     class WebFrameProxy;
 }
 
@@ -41,7 +42,7 @@ namespace WebKit {
     RefPtr<WebKit::WebFrameProxy> _webFrame;
     Vector<WebCore::IntRect> _printingPageRects;
     double _totalScaleFactorForPrinting;
-    HashMap<WebCore::IntRect, Vector<uint8_t> > _pagePreviews;
+    HashMap<WebCore::IntRect, RefPtr<WebKit::ShareableBitmap> > _pagePreviews;
 
     Vector<uint8_t> _printedPagesData;
     RetainPtr<PDFDocument> _printedPagesPDFDocument;
index ca1cad5..0f53f99 100644 (file)
 #import "Logging.h"
 #import "PDFKitImports.h"
 #import "PrintInfo.h"
+#import "ShareableBitmap.h"
 #import "WebData.h"
 #import "WebPageProxy.h"
 #import <PDFKit/PDFKit.h>
+#import <WebCore/GraphicsContext.h>
 #import <WebCore/WebCoreObjCExtras.h>
 #import <wtf/MainThread.h>
 
@@ -205,6 +207,35 @@ struct IPCCallbackContext {
     uint64_t callbackID;
 };
 
+static void pageDidDrawToImage(const ShareableBitmap::Handle& imageHandle, WKErrorRef, void* untypedContext)
+{
+    ASSERT(isMainThread());
+
+    OwnPtr<IPCCallbackContext> context = adoptPtr(static_cast<IPCCallbackContext*>(untypedContext));
+    WKPrintingView *view = context->view.get();
+
+    // If the user has already changed print setup, then this response is obsolete. And if this callback is not in response to the latest request,
+    // then the user has already moved to another page - we'll cache the response, but won't draw it.
+    HashMap<uint64_t, WebCore::IntRect>::iterator iter = view->_expectedPreviewCallbacks.find(context->callbackID);
+    if (iter != view->_expectedPreviewCallbacks.end()) {
+        ASSERT([view _isPrintingPreview]);
+
+        if (!imageHandle.isNull()) {
+            RefPtr<ShareableBitmap> image = ShareableBitmap::create(imageHandle, SharedMemory::ReadOnly);
+
+            if (image)
+                view->_pagePreviews.add(iter->value, image);
+        }
+
+        view->_expectedPreviewCallbacks.remove(context->callbackID);
+        bool receivedResponseToLatestRequest = view->_latestExpectedPreviewCallback == context->callbackID;
+        if (receivedResponseToLatestRequest) {
+            view->_latestExpectedPreviewCallback = 0;
+            [view _updatePreview];
+        }
+    }
+}
+
 static void pageDidDrawToPDF(WKDataRef dataRef, WKErrorRef, void* untypedContext)
 {
     ASSERT(isMainThread());
@@ -221,24 +252,6 @@ static void pageDidDrawToPDF(WKDataRef dataRef, WKErrorRef, void* untypedContext
             view->_printedPagesData.append(data->bytes(), data->size());
         view->_expectedPrintCallback = 0;
         view->_printingCallbackCondition.signal();
-    } else {
-        // If the user has already changed print setup, then this response is obsolete. And this callback is not in response to the latest request,
-        // then the user has already moved to another page - we'll cache the response, but won't draw it.
-        HashMap<uint64_t, WebCore::IntRect>::iterator iter = view->_expectedPreviewCallbacks.find(context->callbackID);
-        if (iter != view->_expectedPreviewCallbacks.end()) {
-            ASSERT([view _isPrintingPreview]);
-
-            if (data) {
-                HashMap<WebCore::IntRect, Vector<uint8_t> >::AddResult entry = view->_pagePreviews.add(iter->value, Vector<uint8_t>());
-                entry.iterator->value.append(data->bytes(), data->size());
-            }
-            view->_expectedPreviewCallbacks.remove(context->callbackID);
-            bool receivedResponseToLatestRequest = view->_latestExpectedPreviewCallback == context->callbackID;
-            if (receivedResponseToLatestRequest) {
-                view->_latestExpectedPreviewCallback = 0;
-                [view _updatePreview];
-            }
-        }
     }
 }
 
@@ -461,7 +474,7 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext)
 
     IntRect rect(nsRect);
     rect.scale(1 / _totalScaleFactorForPrinting);
-    HashMap<WebCore::IntRect, Vector<uint8_t> >::iterator pagePreviewIterator = _pagePreviews.find(rect);
+    HashMap<WebCore::IntRect, RefPtr<ShareableBitmap> >::iterator pagePreviewIterator = _pagePreviews.find(rect);
     if (pagePreviewIterator == _pagePreviews.end())  {
         // It's too early to ask for page preview if we don't even know page size and scale.
         if ([self _hasPageRects]) {
@@ -478,14 +491,14 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext)
                 _webFrame->page()->beginPrinting(_webFrame.get(), PrintInfo([_printOperation printInfo]));
 
                 IPCCallbackContext* context = new IPCCallbackContext;
-                RefPtr<DataCallback> callback = DataCallback::create(context, pageDidDrawToPDF);
+                RefPtr<ImageCallback> callback = ImageCallback::create(context, pageDidDrawToImage);
                 _latestExpectedPreviewCallback = callback->callbackID();
                 _expectedPreviewCallbacks.add(_latestExpectedPreviewCallback, rect);
 
                 context->view = self;
                 context->callbackID = callback->callbackID();
 
-                _webFrame->page()->drawRectToPDF(_webFrame.get(), PrintInfo([_printOperation printInfo]), rect, callback.get());
+                _webFrame->page()->drawRectToImage(_webFrame.get(), PrintInfo([_printOperation printInfo]), rect, callback.get());
                 return;
             }
         }
@@ -494,11 +507,20 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext)
         return;
     }
 
-    const Vector<uint8_t>& pdfDataBytes = pagePreviewIterator->value;
-    RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:pdfDataBytes.data() length:pdfDataBytes.size()]);
-    RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:pdfData.get()]);
+    RefPtr<ShareableBitmap> bitmap = pagePreviewIterator->value;
+    CGContextRef cgContext = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
+
+    GraphicsContext context(cgContext);
+    GraphicsContextStateSaver stateSaver(context);
+
+    context.translate(nsRect.origin.x, nsRect.origin.y);
+    context.scale(FloatSize(_totalScaleFactorForPrinting, _totalScaleFactorForPrinting));
+
+    // FIXME: Should we get the WebPage's deviceScaleFactor from here instead?
+    const IntRect& imageBounds = bitmap->bounds();
+    float imageScaleFactor = imageBounds.width() / rect.width();
 
-    [self _drawPDFDocument:pdfDocument.get() page:0 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)];
+    bitmap->paint(context, imageScaleFactor, IntPoint(), imageBounds);
 }
 
 - (void)drawRect:(NSRect)nsRect
index 5b6a0f9..cda020f 100644 (file)
@@ -26,8 +26,8 @@
 #ifndef GenericCallback_h
 #define GenericCallback_h
 
+#include "ShareableBitmap.h"
 #include "WKAPICast.h"
-
 #include "WebError.h"
 #include <wtf/HashMap.h>
 #include <wtf/PassRefPtr.h>
@@ -195,6 +195,51 @@ private:
     CallbackFunction m_callback;
 };
 
+class ImageCallback : public CallbackBase {
+public:
+    typedef void (*CallbackFunction)(const ShareableBitmap::Handle&, WKErrorRef, void*);
+
+    static PassRefPtr<ImageCallback> create(void* context, CallbackFunction callback)
+    {
+        return adoptRef(new ImageCallback(context, callback));
+    }
+
+    virtual ~ImageCallback()
+    {
+        ASSERT(!m_callback);
+    }
+
+    void performCallbackWithReturnValue(const ShareableBitmap::Handle& returnValue1)
+    {
+        ASSERT(m_callback);
+
+        m_callback(returnValue1, 0, context());
+
+        m_callback = 0;
+    }
+
+    void invalidate()
+    {
+        ASSERT(m_callback);
+
+        RefPtr<WebError> error = WebError::create();
+        ShareableBitmap::Handle handle;
+        m_callback(handle, toAPI(error.get()), context());
+
+        m_callback = 0;
+    }
+
+private:
+
+    ImageCallback(void* context, CallbackFunction callback)
+        : CallbackBase(context)
+        , m_callback(callback)
+    {
+    }
+    
+    CallbackFunction m_callback;
+};
+
 template<typename T>
 void invalidateCallbackMap(HashMap<uint64_t, T>& map)
 {
index 14313e9..0704055 100644 (file)
@@ -496,6 +496,7 @@ void WebPageProxy::close()
 
     invalidateCallbackMap(m_voidCallbacks);
     invalidateCallbackMap(m_dataCallbacks);
+    invalidateCallbackMap(m_imageCallbacks);
     invalidateCallbackMap(m_stringCallbacks);
     m_loadDependentStringCallbackIDs.clear();
     invalidateCallbackMap(m_scriptValueCallbacks);
@@ -3475,6 +3476,17 @@ void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uin
     callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get());
 }
 
+void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID)
+{
+    RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID);
+    if (!callback) {
+        // FIXME: Log error or assert.
+        return;
+    }
+
+    callback->performCallbackWithReturnValue(bitmapHandle);
+}
+
 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
 {
     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
@@ -4009,17 +4021,17 @@ void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo
 }
 
 #if PLATFORM(MAC) || PLATFORM(WIN)
-void WebPageProxy::drawRectToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, PassRefPtr<DataCallback> prpCallback)
+void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, PassRefPtr<ImageCallback> prpCallback)
 {
-    RefPtr<DataCallback> callback = prpCallback;
+    RefPtr<ImageCallback> callback = prpCallback;
     if (!isValid()) {
         callback->invalidate();
         return;
     }
     
     uint64_t callbackID = callback->callbackID();
-    m_dataCallbacks.set(callbackID, callback.get());
-    m_process->send(Messages::WebPage::DrawRectToPDF(frame->frameID(), printInfo, rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
+    m_imageCallbacks.set(callbackID, callback.get());
+    m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
 }
 
 void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback)
index c954b52..39d716c 100644 (file)
@@ -697,7 +697,7 @@ public:
     void endPrinting();
     void computePagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<ComputedPagesCallback>);
 #if PLATFORM(MAC) || PLATFORM(WIN)
-    void drawRectToPDF(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, PassRefPtr<DataCallback>);
+    void drawRectToImage(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, PassRefPtr<ImageCallback>);
     void drawPagesToPDF(WebFrameProxy*, const PrintInfo&, uint32_t first, uint32_t count, PassRefPtr<DataCallback>);
 #elif PLATFORM(GTK)
     void drawPagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<PrintFinishedCallback>);
@@ -973,6 +973,7 @@ private:
 
     void voidCallback(uint64_t);
     void dataCallback(const CoreIPC::DataReference&, uint64_t);
+    void imageCallback(const ShareableBitmap::Handle&, uint64_t);
     void stringCallback(const String&, uint64_t);
     void scriptValueCallback(const CoreIPC::DataReference&, uint64_t);
     void computedPagesCallback(const Vector<WebCore::IntRect>&, double totalScaleFactorForPrinting, uint64_t);
@@ -1077,6 +1078,7 @@ private:
 
     HashMap<uint64_t, RefPtr<VoidCallback> > m_voidCallbacks;
     HashMap<uint64_t, RefPtr<DataCallback> > m_dataCallbacks;
+    HashMap<uint64_t, RefPtr<ImageCallback> > m_imageCallbacks;
     HashMap<uint64_t, RefPtr<StringCallback> > m_stringCallbacks;
     HashSet<uint64_t> m_loadDependentStringCallbackIDs;
     HashMap<uint64_t, RefPtr<ScriptValueCallback> > m_scriptValueCallbacks;
index 197f20d..b43c9c5 100644 (file)
@@ -165,6 +165,7 @@ messages -> WebPageProxy {
     # Callback messages
     VoidCallback(uint64_t callbackID)
     DataCallback(CoreIPC::DataReference resultData, uint64_t callbackID)
+    ImageCallback(WebKit::ShareableBitmap::Handle bitmapHandle, uint64_t callbackID)
     StringCallback(WTF::String resultString, uint64_t callbackID)
     ScriptValueCallback(CoreIPC::DataReference resultData, uint64_t callbackID)
     ComputedPagesCallback(Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
index 1d412b5..60ca678 100644 (file)
@@ -3175,12 +3175,12 @@ void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printIn
 }
 
 #if PLATFORM(MAC) || PLATFORM(WIN)
-void WebPage::drawRectToPDF(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID)
+void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID)
 {
     WebFrame* frame = WebProcess::shared().webFrame(frameID);
     Frame* coreFrame = frame ? frame->coreFrame() : 0;
 
-    RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
+    RefPtr<WebImage> image;
 
 #if USE(CG)
     if (coreFrame) {
@@ -3189,34 +3189,29 @@ void WebPage::drawRectToPDF(uint64_t frameID, const PrintInfo& printInfo, const
 #else
         ASSERT(coreFrame->document()->printing());
 #endif
-
-        // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
-        RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
-
-        CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
-        RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
-        RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-        CGPDFContextBeginPage(context.get(), pageInfo.get());
-
 #if PLATFORM(MAC)
         if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
             ASSERT(!m_printContext);
-            drawRectToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, rect);
+            RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(rect.size(), ShareableBitmap::SupportsAlpha);
+            OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
+            graphicsContext->scale(FloatSize(1, -1));
+            graphicsContext->translate(0, -rect.height());
+            drawPDFDocument(graphicsContext->platformContext(), pdfDocument.get(), printInfo, rect);
+            image = WebImage::create(bitmap.release());
         } else
 #endif
         {
-            GraphicsContext ctx(context.get());
-            ctx.scale(FloatSize(1, -1));
-            ctx.translate(0, -rect.height());
-            m_printContext->spoolRect(ctx, rect);
+            image = scaledSnapshotWithOptions(rect, 1, SnapshotOptionsShareable | SnapshotOptionsExcludeSelectionHighlighting);
         }
-
-        CGPDFContextEndPage(context.get());
-        CGPDFContextClose(context.get());
     }
 #endif
 
-    send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
+    ShareableBitmap::Handle handle;
+
+    if (image)
+        image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
+
+    send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
 }
 
 void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
index eafc871..606ada8 100644 (file)
@@ -518,7 +518,7 @@ public:
     void endPrinting();
     void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
 #if PLATFORM(MAC) || PLATFORM(WIN)
-    void drawRectToPDF(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID);
+    void drawRectToImage(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID);
     void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID);
 #elif PLATFORM(GTK)
     void drawPagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
@@ -724,7 +724,7 @@ private:
 
     RetainPtr<PDFDocument> pdfDocumentForPrintingFrame(WebCore::Frame*);
     void computePagesForPrintingPDFDocument(uint64_t frameID, const PrintInfo&, Vector<WebCore::IntRect>& resultPageRects);
-    void drawRectToPDFFromPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, const WebCore::IntRect&);
+    void drawPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, const WebCore::IntRect&);
     void drawPagesToPDFFromPDFDocument(CGContextRef, PDFDocument *, const PrintInfo&, uint32_t first, uint32_t count);
 #endif
 
index 0933aa1..bbf6a68 100644 (file)
@@ -217,7 +217,7 @@ messages -> WebPage {
     EndPrinting()
     ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID)
 #if PLATFORM(MAC) || PLATFORM(WIN)
-    DrawRectToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID)
+    DrawRectToImage(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID)
     DrawPagesToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
 #endif
 #if PLATFORM(GTK)
index b524daf..7b0c9ab 100644 (file)
@@ -837,7 +837,7 @@ static void drawPDFPage(PDFDocument *pdfDocument, CFIndex pageIndex, CGContextRe
     CGContextRestoreGState(context);
 }
 
-void WebPage::drawRectToPDFFromPDFDocument(CGContextRef context, PDFDocument *pdfDocument, const PrintInfo& printInfo, const WebCore::IntRect& rect)
+void WebPage::drawPDFDocument(CGContextRef context, PDFDocument *pdfDocument, const PrintInfo& printInfo, const WebCore::IntRect& rect)
 {
     NSUInteger pageCount = [pdfDocument pageCount];
     IntSize paperSize(ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight));