Title: [214406] trunk/Source/WebKit2
Revision
214406
Author
aes...@apple.com
Date
2017-03-25 17:53:24 -0700 (Sat, 25 Mar 2017)

Log Message

[iOS] Use snapshotting instead of printing to draw single-page PDFs
https://bugs.webkit.org/show_bug.cgi?id=170103
<rdar://problem/30542960>

Reviewed by Tim Horton.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::paintSnapshotAtSize): Moved the painting logic from WebPage::snapshotAtSize() to here.
(WebKit::WebPage::snapshotAtSize): Changed to call paintSnapshotAtSize() with the
WebImage's graphics context.
(WebKit::WebPage::pdfSnapshotAtSize): Created a CGPDFGraphicsContext, passed it to
paintSnapshotAtSize(), and returned the context's data.
* WebProcess/WebPage/WebPage.h: Made snapshotAtSize() and snapshotNode() private, changed
their return values from PassRefPtr to RefPtr, and declared pdfSnapshotAtSize().
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::computePagesForPrintingAndDrawToPDF): If snapshotting the first page,
returned a page count of 1 and created a PDF using pdfSnapshotAtSize().

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (214405 => 214406)


--- trunk/Source/WebKit2/ChangeLog	2017-03-25 23:08:37 UTC (rev 214405)
+++ trunk/Source/WebKit2/ChangeLog	2017-03-26 00:53:24 UTC (rev 214406)
@@ -1,3 +1,23 @@
+2017-03-25  Andy Estes  <aes...@apple.com>
+
+        [iOS] Use snapshotting instead of printing to draw single-page PDFs
+        https://bugs.webkit.org/show_bug.cgi?id=170103
+        <rdar://problem/30542960>
+
+        Reviewed by Tim Horton.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::paintSnapshotAtSize): Moved the painting logic from WebPage::snapshotAtSize() to here.
+        (WebKit::WebPage::snapshotAtSize): Changed to call paintSnapshotAtSize() with the
+        WebImage's graphics context.
+        (WebKit::WebPage::pdfSnapshotAtSize): Created a CGPDFGraphicsContext, passed it to
+        paintSnapshotAtSize(), and returned the context's data.
+        * WebProcess/WebPage/WebPage.h: Made snapshotAtSize() and snapshotNode() private, changed
+        their return values from PassRefPtr to RefPtr, and declared pdfSnapshotAtSize().
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::computePagesForPrintingAndDrawToPDF): If snapshotting the first page,
+        returned a page count of 1 and created a PDF using pdfSnapshotAtSize().
+
 2017-03-25  John Wilander  <wilan...@apple.com>
 
         Re-enable the web process' keychain access to fix client certificate authentication

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (214405 => 214406)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-03-25 23:08:37 UTC (rev 214405)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2017-03-26 00:53:24 UTC (rev 214406)
@@ -1945,42 +1945,30 @@
     return snapshotAtSize(rect, bitmapSize, options);
 }
 
-PassRefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
+static void paintSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, Frame& frame, FrameView& frameView, GraphicsContext& graphicsContext)
 {
-    Frame* coreFrame = m_mainFrame->coreFrame();
-    if (!coreFrame)
-        return nullptr;
-
-    FrameView* frameView = coreFrame->view();
-    if (!frameView)
-        return nullptr;
-
     IntRect snapshotRect = rect;
     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
 
-    auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
-
-    auto graphicsContext = snapshot->bitmap().createGraphicsContext();
-
     if (options & SnapshotOptionsPrinting) {
-        PrintContext::spoolAllPagesWithBoundaries(*coreFrame, *graphicsContext, snapshotRect.size());
-        return snapshot;
+        PrintContext::spoolAllPagesWithBoundaries(frame, graphicsContext, snapshotRect.size());
+        return;
     }
 
-    Color documentBackgroundColor = frameView->documentBackgroundColor();
-    Color backgroundColor = (coreFrame->settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView->baseBackgroundColor();
-    graphicsContext->fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
+    Color documentBackgroundColor = frameView.documentBackgroundColor();
+    Color backgroundColor = (frame.settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView.baseBackgroundColor();
+    graphicsContext.fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
 
     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
-        double deviceScaleFactor = corePage()->deviceScaleFactor();
-        graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
+        double deviceScaleFactor = frame.page()->deviceScaleFactor();
+        graphicsContext.applyDeviceScaleFactor(deviceScaleFactor);
         scaleFactor /= deviceScaleFactor;
     }
 
-    graphicsContext->scale(scaleFactor);
-    graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
+    graphicsContext.scale(scaleFactor);
+    graphicsContext.translate(-snapshotRect.x(), -snapshotRect.y());
 
     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
     if (options & SnapshotOptionsExcludeSelectionHighlighting)
@@ -1990,18 +1978,35 @@
     if (options & SnapshotOptionsInViewCoordinates)
         coordinateSpace = FrameView::ViewCoordinates;
 
-    frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
+    frameView.paintContentsForSnapshot(graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
 
     if (options & SnapshotOptionsPaintSelectionRectangle) {
-        FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection().selectionBounds();
-        graphicsContext->setStrokeColor(Color(0xFF, 0, 0));
-        graphicsContext->strokeRect(selectionRectangle, 1);
+        FloatRect selectionRectangle = frame.selection().selectionBounds();
+        graphicsContext.setStrokeColor(Color(0xFF, 0, 0));
+        graphicsContext.strokeRect(selectionRectangle, 1);
     }
-    
+}
+
+RefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
+{
+    Frame* coreFrame = m_mainFrame->coreFrame();
+    if (!coreFrame)
+        return nullptr;
+
+    FrameView* frameView = coreFrame->view();
+    if (!frameView)
+        return nullptr;
+
+    auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
+    auto graphicsContext = snapshot->bitmap().createGraphicsContext();
+
+    paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, *graphicsContext);
+
     return snapshot;
 }
 
-PassRefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
+#if USE(CF)
+RetainPtr<CFDataRef> WebPage::pdfSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
 {
     Frame* coreFrame = m_mainFrame->coreFrame();
     if (!coreFrame)
@@ -2011,6 +2016,38 @@
     if (!frameView)
         return nullptr;
 
+    auto data = "" 0));
+
+#if USE(CG)
+    auto dataConsumer = adoptCF(CGDataConsumerCreateWithCFData(data.get()));
+    auto mediaBox = CGRectMake(0, 0, bitmapSize.width(), bitmapSize.height());
+    auto pdfContext = adoptCF(CGPDFContextCreate(dataConsumer.get(), &mediaBox, nullptr));
+
+    CGPDFContextBeginPage(pdfContext.get(), nullptr);
+
+    GraphicsContext graphicsContext { pdfContext.get() };
+    graphicsContext.scale({ 1, -1 });
+    graphicsContext.translate(0, -bitmapSize.height());
+    paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, graphicsContext);
+
+    CGPDFContextEndPage(pdfContext.get());
+    CGPDFContextClose(pdfContext.get());
+#endif
+
+    return WTFMove(data);
+}
+#endif
+
+RefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
+{
+    Frame* coreFrame = m_mainFrame->coreFrame();
+    if (!coreFrame)
+        return nullptr;
+
+    FrameView* frameView = coreFrame->view();
+    if (!frameView)
+        return nullptr;
+
     if (!node.renderer())
         return nullptr;
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (214405 => 214406)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-03-25 23:08:37 UTC (rev 214405)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-03-26 00:53:24 UTC (rev 214406)
@@ -490,8 +490,6 @@
 #endif
     
     PassRefPtr<WebImage> scaledSnapshotWithOptions(const WebCore::IntRect&, double additionalScaleFactor, SnapshotOptions);
-    PassRefPtr<WebImage> snapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize& bitmapSize, SnapshotOptions);
-    PassRefPtr<WebImage> snapshotNode(WebCore::Node&, SnapshotOptions, unsigned maximumPixelCount = std::numeric_limits<unsigned>::max());
 
     static const WebEvent* currentEvent();
 
@@ -1274,6 +1272,12 @@
     void urlSchemeHandlerTaskDidReceiveData(uint64_t handlerIdentifier, uint64_t taskIdentifier, const IPC::DataReference&);
     void urlSchemeHandlerTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceError&);
 
+    RefPtr<WebImage> snapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize& bitmapSize, SnapshotOptions);
+    RefPtr<WebImage> snapshotNode(WebCore::Node&, SnapshotOptions, unsigned maximumPixelCount = std::numeric_limits<unsigned>::max());
+#if USE(CF)
+    RetainPtr<CFDataRef> pdfSnapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize& bitmapSize, SnapshotOptions);
+#endif
+
     uint64_t m_pageID;
 
     std::unique_ptr<WebCore::Page> m_page;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (214405 => 214406)


--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2017-03-25 23:08:37 UTC (rev 214405)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm	2017-03-26 00:53:24 UTC (rev 214406)
@@ -3252,12 +3252,21 @@
 
 void WebPage::computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndDrawToPDF::DelayedReply> reply)
 {
+    if (printInfo.snapshotFirstPage) {
+        reply->send(1);
+        IntSize snapshotSize { FloatSize { printInfo.availablePaperWidth, printInfo.availablePaperHeight } };
+        IntRect snapshotRect { {0, 0}, snapshotSize };
+        auto pdfData = pdfSnapshotAtSize(snapshotRect, snapshotSize, 0);
+        send(Messages::WebPageProxy::DrawToPDFCallback(IPC::DataReference(CFDataGetBytePtr(pdfData.get()), CFDataGetLength(pdfData.get())), callbackID));
+        return;
+    }
+
     Vector<WebCore::IntRect> pageRects;
     double totalScaleFactor;
     computePagesForPrintingImpl(frameID, printInfo, pageRects, totalScaleFactor);
 
     ASSERT(pageRects.size() >= 1);
-    std::size_t pageCount = printInfo.snapshotFirstPage ? 1 : pageRects.size();
+    std::size_t pageCount = pageRects.size();
     ASSERT(pageCount <= std::numeric_limits<uint32_t>::max());
     reply->send(pageCount);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to