Diff
Modified: trunk/Source/WebKit2/ChangeLog (201887 => 201888)
--- trunk/Source/WebKit2/ChangeLog 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/ChangeLog 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,3 +1,104 @@
+2016-06-09 Andy Estes <aes...@apple.com>
+
+ WKWebView does not render PDF pages in AirPrint
+ https://bugs.webkit.org/show_bug.cgi?id=151386
+ rdar://problem/22499157
+
+ Reviewed by Tim Horton.
+
+ _WKWebViewPrintFormatter originally attempted to handle PDFs, but the code path was never
+ properly tested since Safari prints PDFs by setting a printingItem on the
+ UIPrintInteractionController instead of going through a print formatter. The existing code
+ almost worked, if it weren't for CGContextScaleCTM() scaling each page into oblivion due to
+ _totalScaleFactor equaling 0.
+
+ This patch properly implements -[_WKWebViewPrintFormatter drawInRect:forPageAtIndex:] to
+ handle drawing both PDFs generated by WebKit and PDFs loaded in the main frame. It also
+ takes the opportunity to clean up a number of issues in the existing code:
+
+ - Handling of -[_WKWebViewPrintFormatter startPage] is now correct. I had previously assumed
+ this property represented the first page of output to print, but it actually represents
+ the first page in the overall print job that the print formatter renders. In other words,
+ regardless of -startPage, the print formatter should always print all its pages.
+ - Code specific to webpage and PDF printing was factored out into WKContentView and
+ WKPDFView, respectively. Each conforms to @protocol(_WKWebViewPrintProvider), and
+ _WKWebViewPrintFormatter accesses the provider via -[WKWebView _printProvider].
+ - Instead of piping the printed PDF data from WebPageProxy to WKWebView via PageClient, use
+ the GenericCallback mechanism to have WebPageProxy call a lambda specified by
+ WKContentView when the printed PDF is available.
+ - Removed _totalScaleFactor and used CGPDFPageGetDrawingTransform() to transform both
+ webpages and PDFs. For webpages, _totalScaleFactor will always equal the ratio of the
+ paper width to the PDF page width, so CGPDFPageGetDrawingTransform() will apply the same
+ scaling as CGContextScaleCTM(_totalScaleFactor, _totalScaleFactor) would.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _printProvider]): Added. Returns _currentContentView if it conforms to
+ @protocol(_WKWebViewPrintProvider).
+ (-[WKWebView _computePageCountAndStartDrawingToPDFForFrame:printInfo:firstPage:computedTotalScaleFactor:]):
+ Moved code to _wk_pageCountForPrintFormatter in WKContentView and WKPDFView.
+ (-[WKWebView _endPrinting]): Deleted.
+ (-[WKWebView _printedDocument]): Deleted.
+ (-[WKWebView _setPrintedDocument:]): Deleted.
+ * UIProcess/API/Cocoa/WKWebViewInternal.h: Declared the _printProvider property.
+ * UIProcess/PageClient.h: Removed didFinishDrawingPagesToPDF().
+ * UIProcess/WebPageProxy.h: Declared computePagesForPrintingAndDrawToPDF() and
+ drawToPDFCallback().
+ * UIProcess/WebPageProxy.messages.in: Renamed DidFinishDrawingPagesToPDF to
+ DrawToPDFCallback.
+ * UIProcess/_WKWebViewPrintFormatter.mm: Backed the frameToPrint property with a RetainPtr
+ ivar so that it doesn't need to be released manually in -dealloc; removed _totalScaleFactor
+ and _printInfo ivars and added a _printedDocument ivar; removed the property declaration for
+ webView.
+ (-[_WKWebViewPrintFormatter frameToPrint]): Added a custom getter for the frameToPrint
+ property.
+ (-[_WKWebViewPrintFormatter setFrameToPrint:]): Added a custom setter for the frameToPrint
+ property.
+ (-[_WKWebViewPrintFormatter _webView]): Renamed from webView; added an underscore since this
+ is a private method.
+ (-[_WKWebViewPrintFormatter _recalcPageCount]): Retrieved the page count from the print
+ provider and clamped its value to NSIntegerMax.
+ (-[_WKWebViewPrintFormatter drawInRect:forPageAtIndex:]): Retrieved the printed document
+ from the print provider if needed; modified the CTM transformations to work for both
+ webpages and PDFs.
+ (-[_WKWebViewPrintFormatter dealloc]): Deleted.
+ (-[_WKWebViewPrintFormatter webView]): Renamed to _webView.
+ (-[_WKWebViewPrintFormatter rectForPageAtIndex:]): Deleted.
+ * UIProcess/_WKWebViewPrintFormatterInternal.h: Added. Moved a UIPrintFormatter internal
+ method declaration to here and defined the _WKWebViewPrintProvider protocol.
+ * UIProcess/ios/PageClientImplIOS.h: Removed didFinishDrawingPagesToPDF().
+ * UIProcess/ios/PageClientImplIOS.mm: Ditto.
+ (WebKit::PageClientImpl::didFinishDrawingPagesToPDF): Deleted.
+ * UIProcess/ios/WKContentView.mm: Conformed to @protocol(_WKWebViewPrintProvider).
+ (-[WKContentView _wk_pageCountForPrintFormatter:]): Moved the code to compute page count
+ from WKWebView to here.
+ (-[WKContentView _wk_printedDocument]): Moved the code to get the printed document from
+ WKWebView to here.
+ * UIProcess/ios/WKPDFView.mm:
+ (-[WKPDFView _wk_pageCountForPrintFormatter:]): Moved the code to compute the page count
+ from WKWebView to here; added a call to CGPDFDocumentAllowsPrinting(), returning 0 if
+ printing is not allowed.
+ (-[WKPDFView _wk_printedDocument]): Moved the code to get the printed document from
+ WKWebView to here.
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::computePagesForPrintingAndDrawToPDF): Registered the callback with
+ m_callbacks and sent Messages::WebPage::ComputePagesForPrintingAndDrawToPDF; returned the
+ synchronously-returned page count.
+ (WebKit::WebPageProxy::drawToPDFCallback): Added to perform the callback when drawing to PDF
+ is complete.
+ (WebKit::WebPageProxy::didFinishDrawingPagesToPDF): Deleted.
+ * WebKit2.xcodeproj/project.pbxproj: Added _WKWebViewPrintFormatterInternal.h.
+ * WebProcess/WebPage/WebPage.h: Renamed computePagesForPrintingAndStartDrawingToPDF() to
+ computePagesForPrintingAndDrawToPDF().
+ * WebProcess/WebPage/WebPage.messages.in: Renamed
+ ComputePagesForPrintingAndStartDrawingToPDF to ComputePagesForPrintingAndDrawToPDF. Removed
+ the startPage parameter and added a callbackID.
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::computePagesForPrintingAndDrawToPDF): Renamed from
+ computePagesForPrintingAndStartDrawingToPDF(). Added a call to endPrinting() after sending
+ Messages::WebPageProxy::DrawToPDFCallback.
+ (WebKit::WebPage::computePagesForPrintingAndStartDrawingToPDF): Renamed to
+ computePagesForPrintingAndDrawToPDF.
+
2016-06-09 Alex Christensen <achristen...@webkit.org>
Clean up WebSocket code
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -99,7 +99,6 @@
#if PLATFORM(IOS)
#import "_WKWebViewPrintFormatter.h"
-#import "PrintInfo.h"
#import "ProcessThrottler.h"
#import "RemoteLayerTreeDrawingAreaProxy.h"
#import "RemoteScrollingCoordinatorProxy.h"
@@ -108,7 +107,6 @@
#import "WKPDFView.h"
#import "WKScrollView.h"
#import "WKWebViewContentProviderRegistry.h"
-#import "WebPageMessages.h"
#import "WebVideoFullscreenManagerProxy.h"
#import <UIKit/UIApplication.h>
#import <WebCore/CoreGraphicsSPI.h>
@@ -260,8 +258,6 @@
BOOL _delayUpdateVisibleContentRects;
BOOL _hadDelayedUpdateVisibleContentRects;
- BOOL _pageIsPrintingToPDF;
- RetainPtr<CGPDFDocumentRef> _printedDocument;
Vector<std::function<void ()>> _snapshotsDeferredDuringResize;
#endif
#if PLATFORM(MAC)
@@ -4533,52 +4529,14 @@
return [_WKWebViewPrintFormatter class];
}
-- (NSInteger)_computePageCountAndStartDrawingToPDFForFrame:(_WKFrameHandle *)frame printInfo:(const WebKit::PrintInfo&)printInfo firstPage:(uint32_t)firstPage computedTotalScaleFactor:(double&)totalScaleFactor
+- (id <_WKWebViewPrintProvider>)_printProvider
{
- if ([self _isDisplayingPDF])
- return CGPDFDocumentGetNumberOfPages([(WKPDFView *)_customContentView pdfDocument]);
-
- _pageIsPrintingToPDF = YES;
- Vector<WebCore::IntRect> pageRects;
- uint64_t frameID = frame ? frame._frameID : _page->mainFrame()->frameID();
- if (!_page->sendSync(Messages::WebPage::ComputePagesForPrintingAndStartDrawingToPDF(frameID, printInfo, firstPage), Messages::WebPage::ComputePagesForPrintingAndStartDrawingToPDF::Reply(pageRects, totalScaleFactor)))
- return 0;
- return pageRects.size();
+ id contentView = self._currentContentView;
+ if ([contentView conformsToProtocol:@protocol(_WKWebViewPrintProvider)])
+ return contentView;
+ return nil;
}
-- (void)_endPrinting
-{
- _pageIsPrintingToPDF = NO;
- _printedDocument = nullptr;
- _page->send(Messages::WebPage::EndPrinting());
-}
-
-- (CGPDFDocumentRef)_printedDocument
-{
- if ([self _isDisplayingPDF]) {
- ASSERT(!_pageIsPrintingToPDF);
- return [(WKPDFView *)_customContentView pdfDocument];
- }
-
- if (_pageIsPrintingToPDF) {
- if (!_page->process().connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DidFinishDrawingPagesToPDF>(_page->pageID(), std::chrono::milliseconds::max())) {
- ASSERT_NOT_REACHED();
- return nullptr;
- }
- ASSERT(!_pageIsPrintingToPDF);
- }
- return _printedDocument.get();
-}
-
-- (void)_setPrintedDocument:(CGPDFDocumentRef)printedDocument
-{
- if (!_pageIsPrintingToPDF)
- return;
- ASSERT(![self _isDisplayingPDF]);
- _printedDocument = printedDocument;
- _pageIsPrintingToPDF = NO;
-}
-
@end
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,6 +57,7 @@
@class WKWebViewContentProviderRegistry;
@class _WKFrameHandle;
+@protocol _WKWebViewPrintProvider;
@interface WKWebView () WK_WEB_VIEW_PROTOCOLS {
@@ -134,9 +135,7 @@
#if PLATFORM(IOS)
@interface WKWebView (_WKWebViewPrintFormatter)
-- (NSInteger)_computePageCountAndStartDrawingToPDFForFrame:(_WKFrameHandle *)frame printInfo:(const WebKit::PrintInfo&)printInfo firstPage:(uint32_t)firstPage computedTotalScaleFactor:(double&)totalScaleFactor;
-- (void)_endPrinting;
-@property (nonatomic, setter=_setPrintedDocument:) CGPDFDocumentRef _printedDocument;
+@property (nonatomic, readonly) id <_WKWebViewPrintProvider> _printProvider;
@end
#endif
Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/PageClient.h 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -305,7 +305,6 @@
virtual void overflowScrollViewDidScroll() = 0;
virtual void overflowScrollWillStartScroll() = 0;
virtual void overflowScrollDidEndScroll() = 0;
- virtual void didFinishDrawingPagesToPDF(const IPC::DataReference&) = 0;
virtual Vector<String> mimeTypesWithCustomContentProviders() = 0;
virtual void showInspectorHighlight(const WebCore::Highlight&) = 0;
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -256,6 +256,8 @@
bool m_blurPreviousNode;
RefPtr<API::Object> m_userData;
};
+
+using DrawToPDFCallback = GenericCallback<const IPC::DataReference&>;
#endif
#if PLATFORM(COCOA)
@@ -515,7 +517,6 @@
void commitPotentialTapFailed();
void didNotHandleTapAsClick(const WebCore::IntPoint&);
void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID);
- void didFinishDrawingPagesToPDF(const IPC::DataReference&);
void contentSizeCategoryDidChange(const String& contentSizeCategory);
void getSelectionContext(std::function<void(const String&, const String&, const String&, CallbackBase::Error)>);
void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, std::function<void(const String&, CallbackBase::Error)>);
@@ -905,6 +906,10 @@
#if PLATFORM(COCOA)
void drawRectToImage(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, const WebCore::IntSize&, PassRefPtr<ImageCallback>);
void drawPagesToPDF(WebFrameProxy*, const PrintInfo&, uint32_t first, uint32_t count, PassRefPtr<DataCallback>);
+#if PLATFORM(IOS)
+ uint32_t computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo&, DrawToPDFCallback::CallbackFunction&&);
+ void drawToPDFCallback(const IPC::DataReference& pdfData, uint64_t callbackID);
+#endif
#elif PLATFORM(GTK)
void drawPagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<PrintFinishedCallback>);
#endif
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,4 +1,4 @@
-# Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+# Copyright (C) 2010-2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -186,7 +186,7 @@
CommitPotentialTapFailed()
DidNotHandleTapAsClick(WebCore::IntPoint point)
DisableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
- DidFinishDrawingPagesToPDF(IPC::DataReference pdfData)
+ DrawToPDFCallback(IPC::DataReference pdfData, uint64_t callbackID)
#endif
#if ENABLE(DATA_DETECTION)
SetDataDetectionResult(struct WebKit::DataDetectionResult dataDetectionResult)
Modified: trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatter.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatter.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatter.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,81 +24,69 @@
*/
#import "config.h"
-#import "_WKWebViewPrintFormatter.h"
+#import "_WKWebViewPrintFormatterInternal.h"
#if PLATFORM(IOS)
-#import "PrintInfo.h"
#import "WKWebViewInternal.h"
+#import "_WKFrameHandle.h"
#import <wtf/RetainPtr.h>
-@interface UIPrintFormatter ()
-- (CGRect)_pageContentRect:(BOOL)firstPage;
-- (void)_recalcIfNecessary;
-@end
-
-@interface _WKWebViewPrintFormatter ()
-@property (nonatomic, readonly) WKWebView *webView;
-@end
-
@implementation _WKWebViewPrintFormatter {
- double _totalScaleFactor;
- WebKit::PrintInfo _printInfo;
+ RetainPtr<_WKFrameHandle> _frameToPrint;
+ RetainPtr<CGPDFDocumentRef> _printedDocument;
}
-- (void)dealloc
+- (_WKFrameHandle *)frameToPrint
{
- [self.webView _endPrinting];
- [_frameToPrint release];
- [super dealloc];
+ return _frameToPrint.get();
}
-- (WKWebView *)webView
+- (void)setFrameToPrint:(_WKFrameHandle *)frameToPrint
{
- ASSERT([self.view isKindOfClass:[WKWebView class]]);
- return static_cast<WKWebView *>(self.view);
+ _frameToPrint = frameToPrint;
}
-- (NSInteger)_recalcPageCount
+- (WKWebView *)_webView
{
- ASSERT([self respondsToSelector:@selector(_pageContentRect:)]);
+ UIView *view = self.view;
+ ASSERT([view isKindOfClass:[WKWebView class]]);
+ return static_cast<WKWebView *>(view);
+}
- CGRect firstRect = [self _pageContentRect:YES];
- CGRect nextRect = [self _pageContentRect:NO];
- if (CGRectIsEmpty(firstRect) || CGRectIsEmpty(nextRect))
- return 0;
-
- // The first page can have a smaller content rect than subsequent pages if a top content inset is specified. Since
- // WebKit requires a uniform content rect for each page during layout, use the first page rect for all pages if it's
- // smaller. This is what UIWebView's print formatter does.
- ASSERT(firstRect.size.width == nextRect.size.width);
- ASSERT(firstRect.origin.y >= nextRect.origin.y);
- _printInfo.pageSetupScaleFactor = 1;
- _printInfo.availablePaperWidth = nextRect.size.width;
- _printInfo.availablePaperHeight = nextRect.size.height - (firstRect.origin.y - nextRect.origin.y);
-
- return [self.webView _computePageCountAndStartDrawingToPDFForFrame:_frameToPrint printInfo:_printInfo firstPage:self.startPage computedTotalScaleFactor:_totalScaleFactor];
+- (NSInteger)_recalcPageCount
+{
+ _printedDocument = nullptr;
+ NSUInteger pageCount = [self._webView._printProvider _wk_pageCountForPrintFormatter:self];
+ return std::min<NSUInteger>(pageCount, NSIntegerMax);
}
- (CGRect)rectForPageAtIndex:(NSInteger)pageIndex
{
- ASSERT([self respondsToSelector:@selector(_recalcIfNecessary)]);
- [self _recalcIfNecessary];
return [self _pageContentRect:pageIndex == self.startPage];
}
- (void)drawInRect:(CGRect)rect forPageAtIndex:(NSInteger)pageIndex
{
- // CGPDFDocuments use 1-based page indexing.
- CGPDFPageRef pdfPage = CGPDFDocumentGetPage(self.webView._printedDocument, pageIndex - self.startPage + 1);
+ if (!_printedDocument)
+ _printedDocument = self._webView._printProvider._wk_printedDocument;
+ NSInteger offsetFromStartPage = pageIndex - self.startPage;
+ if (offsetFromStartPage < 0)
+ return;
+
+ CGPDFPageRef page = CGPDFDocumentGetPage(_printedDocument.get(), offsetFromStartPage + 1);
+ if (!page)
+ return;
+
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
- CGContextTranslateCTM(context, rect.origin.x, rect.origin.y);
- CGContextScaleCTM(context, _totalScaleFactor, -_totalScaleFactor);
- CGContextTranslateCTM(context, 0, -CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox).size.height);
- CGContextDrawPDFPage(context, pdfPage);
+ CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMaxY(rect));
+ CGContextScaleCTM(context, 1, -1);
+ CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect)), 0, true));
+ CGContextClipToRect(context, CGPDFPageGetBoxRect(page, kCGPDFCropBox));
+ CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
}
Added: trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h (0 => 201888)
--- trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "_WKWebViewPrintFormatter.h"
+
+#if PLATFORM(IOS)
+
+@interface UIPrintFormatter ()
+- (CGRect)_pageContentRect:(BOOL)firstPage;
+@end
+
+@protocol _WKWebViewPrintProvider <NSObject>
+- (NSUInteger)_wk_pageCountForPrintFormatter:(_WKWebViewPrintFormatter *)printFormatter;
+@property (nonatomic, readonly) CGPDFDocumentRef _wk_printedDocument;
+@end
+
+#endif // PLATFORM(IOS)
Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -152,8 +152,6 @@
void overflowScrollWillStartScroll() override;
void overflowScrollDidEndScroll() override;
- void didFinishDrawingPagesToPDF(const IPC::DataReference&) override;
-
// Auxiliary Client Creation
#if ENABLE(FULLSCREEN_API)
virual WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() override;
Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -663,13 +663,6 @@
[m_contentView _overflowScrollingDidEnd];
}
-void PageClientImpl::didFinishDrawingPagesToPDF(const IPC::DataReference& pdfData)
-{
- RetainPtr<CFDataRef> data = "" pdfData.data(), pdfData.size()));
- RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(data.get()));
- m_webView._printedDocument = adoptCF(CGPDFDocumentCreateWithProvider(dataProvider.get())).get();
-}
-
Vector<String> PageClientImpl::mimeTypesWithCustomContentProviders()
{
return m_webView._contentProviderRegistry._mimeTypesWithCustomContentProviders;
Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
#import "AccessibilityIOS.h"
#import "ApplicationStateTracker.h"
#import "PageClientImplIOS.h"
+#import "PrintInfo.h"
#import "RemoteLayerTreeDrawingAreaProxy.h"
#import "RemoteScrollingCoordinatorProxy.h"
#import "SmartMagnificationController.h"
@@ -48,6 +49,8 @@
#import "WebPageGroup.h"
#import "WebProcessPool.h"
#import "WebSystemInterface.h"
+#import "_WKFrameHandleInternal.h"
+#import "_WKWebViewPrintFormatterInternal.h"
#import <CoreGraphics/CoreGraphics.h>
#import <WebCore/FloatQuad.h>
#import <WebCore/FrameView.h>
@@ -181,6 +184,9 @@
RetainPtr<NSUndoManager> _undoManager;
std::unique_ptr<ApplicationStateTracker> _applicationStateTracker;
+
+ BOOL _isPrintingToPDF;
+ RetainPtr<CGPDFDocumentRef> _printedDocument;
}
- (instancetype)_commonInitializationWithProcessPool:(WebKit::WebProcessPool&)processPool configuration:(Ref<API::PageConfiguration>&&)configuration
@@ -610,4 +616,65 @@
@end
+#pragma mark Printing
+
+@interface WKContentView (_WKWebViewPrintFormatter) <_WKWebViewPrintProvider>
+@end
+
+@implementation WKContentView (_WKWebViewPrintFormatter)
+
+- (NSUInteger)_wk_pageCountForPrintFormatter:(_WKWebViewPrintFormatter *)printFormatter
+{
+ if (_isPrintingToPDF)
+ return 0;
+
+ uint64_t frameID;
+ if (_WKFrameHandle *handle = printFormatter.frameToPrint)
+ frameID = handle._frameID;
+ else if (auto mainFrame = _page->mainFrame())
+ frameID = mainFrame->frameID();
+ else
+ return 0;
+
+ // The first page can have a smaller content rect than subsequent pages if a top content inset
+ // is specified. Since WebKit requires a uniform content rect for each page during layout, use
+ // the intersection of the first and non-first page rects.
+ // FIXME: Teach WebCore::PrintContext to accept an initial content offset when paginating.
+ CGRect printingRect = CGRectIntersection([printFormatter _pageContentRect:YES], [printFormatter _pageContentRect:NO]);
+ if (CGRectIsEmpty(printingRect))
+ return 0;
+
+ PrintInfo printInfo;
+ printInfo.pageSetupScaleFactor = 1;
+ printInfo.availablePaperWidth = CGRectGetWidth(printingRect);
+ printInfo.availablePaperHeight = CGRectGetHeight(printingRect);
+
+ _isPrintingToPDF = YES;
+ auto retainedSelf = retainPtr(self);
+ return _page->computePagesForPrintingAndDrawToPDF(frameID, printInfo, [retainedSelf](const IPC::DataReference& pdfData, CallbackBase::Error error) {
+ retainedSelf->_isPrintingToPDF = NO;
+ if (error != CallbackBase::Error::None)
+ return;
+
+ auto data = "" pdfData.data(), pdfData.size()));
+ auto dataProvider = adoptCF(CGDataProviderCreateWithCFData(data.get()));
+ retainedSelf->_printedDocument = adoptCF(CGPDFDocumentCreateWithProvider(dataProvider.get()));
+ });
+}
+
+- (CGPDFDocumentRef)_wk_printedDocument
+{
+ if (_isPrintingToPDF) {
+ if (!_page->process().connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DrawToPDFCallback>(_page->pageID(), std::chrono::milliseconds::max())) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+ ASSERT(!_isPrintingToPDF);
+ }
+
+ return _printedDocument.autorelease();
+}
+
+@end
+
#endif // PLATFORM(IOS)
Modified: trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,6 +39,7 @@
#import "WeakObjCPtr.h"
#import "WebPageProxy.h"
#import "_WKFindDelegate.h"
+#import "_WKWebViewPrintFormatterInternal.h"
#import <MobileCoreServices/UTCoreTypes.h>
#import <WebCore/FloatRect.h>
#import <WebCore/LocalizedStrings.h>
@@ -890,4 +891,26 @@
@end
+#pragma mark Printing
+
+@interface WKPDFView (_WKWebViewPrintFormatter) <_WKWebViewPrintProvider>
+@end
+
+@implementation WKPDFView (_WKWebViewPrintFormatter)
+
+- (NSUInteger)_wk_pageCountForPrintFormatter:(_WKWebViewPrintFormatter *)printFormatter
+{
+ CGPDFDocumentRef document = _cgPDFDocument.get();
+ if (CGPDFDocumentAllowsPrinting(document))
+ return CGPDFDocumentGetNumberOfPages(document);
+ return 0;
+}
+
+- (CGPDFDocumentRef)_wk_printedDocument
+{
+ return _cgPDFDocument.get();
+}
+
+@end
+
#endif /* PLATFORM(IOS) */
Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (201887 => 201888)
--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#import "InteractionInformationAtPosition.h"
#import "NativeWebKeyboardEvent.h"
#import "PageClient.h"
+#import "PrintInfo.h"
#import "RemoteLayerTreeDrawingAreaProxy.h"
#import "RemoteLayerTreeDrawingAreaProxyMessages.h"
#import "RemoteLayerTreeTransaction.h"
@@ -962,11 +963,27 @@
m_pageClient.disableDoubleTapGesturesDuringTapIfNecessary(requestID);
}
-void WebPageProxy::didFinishDrawingPagesToPDF(const IPC::DataReference& pdfData)
+uint32_t WebPageProxy::computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo& printInfo, DrawToPDFCallback::CallbackFunction&& callback)
{
- m_pageClient.didFinishDrawingPagesToPDF(pdfData);
+ if (!isValid()) {
+ callback(IPC::DataReference(), CallbackBase::Error::OwnerWasInvalidated);
+ return 0;
+ }
+
+ uint32_t pageCount = 0;
+ uint64_t callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
+ using Message = Messages::WebPage::ComputePagesForPrintingAndDrawToPDF;
+ process().sendSync(Message(frameID, printInfo, callbackID), Message::Reply(pageCount), m_pageID);
+ return pageCount;
}
+void WebPageProxy::drawToPDFCallback(const IPC::DataReference& pdfData, uint64_t callbackID)
+{
+ auto callback = m_callbacks.take<DrawToPDFCallback>(callbackID);
+ RELEASE_ASSERT(callback);
+ callback->performCallbackWithReturnValue(pdfData);
+}
+
void WebPageProxy::contentSizeCategoryDidChange(const String& contentSizeCategory)
{
process().send(Messages::WebPage::ContentSizeCategoryDidChange(contentSizeCategory), m_pageID);
Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (201887 => 201888)
--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1261,6 +1261,7 @@
A118A9F31908B8EA00F7C92B /* _WKNSFileManagerExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = A118A9F11908B8EA00F7C92B /* _WKNSFileManagerExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
A182D5B41BE6BD250087A7CC /* AccessibilityIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = A182D5B21BE6BD250087A7CC /* AccessibilityIOS.mm */; };
A182D5B51BE6BD250087A7CC /* AccessibilityIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = A182D5B31BE6BD250087A7CC /* AccessibilityIOS.h */; };
+ A19DD3C01D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A19DD3BF1D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h */; };
A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */; settings = {ATTRIBUTES = (Private, ); }; };
A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */; };
A1A4FE5C18DCE9FA00B5EA8A /* _WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */; };
@@ -3312,6 +3313,7 @@
A118A9F11908B8EA00F7C92B /* _WKNSFileManagerExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKNSFileManagerExtras.h; sourceTree = "<group>"; };
A182D5B21BE6BD250087A7CC /* AccessibilityIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityIOS.mm; sourceTree = "<group>"; };
A182D5B31BE6BD250087A7CC /* AccessibilityIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityIOS.h; sourceTree = "<group>"; };
+ A19DD3BF1D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKWebViewPrintFormatterInternal.h; sourceTree = "<group>"; };
A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownload.h; sourceTree = "<group>"; };
A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKDownload.mm; sourceTree = "<group>"; };
A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDownloadInternal.h; sourceTree = "<group>"; };
@@ -4864,6 +4866,7 @@
children = (
C54256AE18BEC16100DE4179 /* forms */,
A115DC6E191D82AB00DA8072 /* _WKWebViewPrintFormatter.h */,
+ A19DD3BF1D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h */,
A115DC6D191D82AB00DA8072 /* _WKWebViewPrintFormatter.mm */,
1AD4C1911B39F33200ABC28E /* ApplicationStateTracker.h */,
1AD4C1901B39F33200ABC28E /* ApplicationStateTracker.mm */,
@@ -8068,6 +8071,7 @@
37948409150C4B9700E52CE9 /* WKRenderLayer.h in Headers */,
37608823150414F700FC82C7 /* WKRenderObject.h in Headers */,
3336763B130C99DC006C9DE2 /* WKResourceCacheManager.h in Headers */,
+ A19DD3C01D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h in Headers */,
BC8A501511765F5600757573 /* WKRetainPtr.h in Headers */,
1A7E377918E4A4FE003D0FFF /* WKScriptMessage.h in Headers */,
1A7E377518E4A33A003D0FFF /* WKScriptMessageHandler.h in Headers */,
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (201887 => 201888)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -743,7 +743,7 @@
void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID);
void drawPagesToPDFImpl(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, RetainPtr<CFMutableDataRef>& pdfPageData);
#if PLATFORM(IOS)
- void computePagesForPrintingAndStartDrawingToPDF(uint64_t frameID, const PrintInfo&, uint32_t firstPage, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndStartDrawingToPDF::DelayedReply>);
+ void computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo&, uint64_t callbackID, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndDrawToPDF::DelayedReply>);
#endif
#elif PLATFORM(GTK)
void drawPagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (201887 => 201888)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,4 +1,4 @@
-# Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+# Copyright (C) 2010-2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -301,7 +301,7 @@
DrawRectToImage(uint64_t frameID, struct WebKit::PrintInfo printInfo, WebCore::IntRect rect, WebCore::IntSize imageSize, uint64_t callbackID)
DrawPagesToPDF(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
#if PLATFORM(IOS)
- ComputePagesForPrintingAndStartDrawingToPDF(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint32_t firstPage) -> (Vector<WebCore::IntRect> pageRects, double totalScaleFactor) Delayed
+ ComputePagesForPrintingAndDrawToPDF(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint64_t callbackID) -> (uint32_t pageCount) Delayed
#endif
#endif
#if PLATFORM(GTK)
Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (201887 => 201888)
--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm 2016-06-09 22:03:53 UTC (rev 201887)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm 2016-06-09 22:05:04 UTC (rev 201888)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -3128,17 +3128,21 @@
}
#endif
-void WebPage::computePagesForPrintingAndStartDrawingToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t firstPage, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndStartDrawingToPDF::DelayedReply> reply)
+void WebPage::computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndDrawToPDF::DelayedReply> reply)
{
Vector<WebCore::IntRect> pageRects;
- double totalScaleFactor = 1;
+ double totalScaleFactor;
computePagesForPrintingImpl(frameID, printInfo, pageRects, totalScaleFactor);
+
std::size_t pageCount = pageRects.size();
- reply->send(WTFMove(pageRects), totalScaleFactor);
+ ASSERT(pageCount <= std::numeric_limits<uint32_t>::max());
+ reply->send(pageCount);
RetainPtr<CFMutableDataRef> pdfPageData;
- drawPagesToPDFImpl(frameID, printInfo, firstPage, pageCount - firstPage, pdfPageData);
- send(Messages::WebPageProxy::DidFinishDrawingPagesToPDF(IPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get()))));
+ drawPagesToPDFImpl(frameID, printInfo, 0, pageCount, pdfPageData);
+ send(Messages::WebPageProxy::DrawToPDFCallback(IPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
+
+ endPrinting();
}
void WebPage::contentSizeCategoryDidChange(const String& contentSizeCategory)