Add a WebViewDidMoveToWindowObserver for WKWebView
[WebKit-https.git] / Source / WebKit / UIProcess / _WKWebViewPrintFormatter.mm
1 /*
2  * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "_WKWebViewPrintFormatterInternal.h"
28
29 #if PLATFORM(IOS_FAMILY) && !PLATFORM(IOSMAC)
30
31 #import "WKWebViewInternal.h"
32 #import "_WKFrameHandle.h"
33 #import <wtf/RetainPtr.h>
34 #import <wtf/SetForScope.h>
35
36 @interface UIPrintPageRenderer ()
37 @property (nonatomic) CGRect paperRect;
38 @property (nonatomic) CGRect printableRect;
39 @end
40
41 @implementation _WKWebViewPrintFormatter {
42     RetainPtr<_WKFrameHandle> _frameToPrint;
43     RetainPtr<CGPDFDocumentRef> _printedDocument;
44     BOOL _suppressPageCountRecalc;
45 }
46
47 - (_WKFrameHandle *)frameToPrint
48 {
49     return _frameToPrint.get();
50 }
51
52 - (void)setFrameToPrint:(_WKFrameHandle *)frameToPrint
53 {
54     _frameToPrint = frameToPrint;
55 }
56
57 - (WKWebView *)_webView
58 {
59     UIView *view = self.view;
60     ASSERT([view isKindOfClass:[WKWebView class]]);
61     return static_cast<WKWebView *>(view);
62 }
63
64 - (void)_setSnapshotPaperRect:(CGRect)paperRect
65 {
66     SetForScope<BOOL> suppressPageCountRecalc(_suppressPageCountRecalc, YES);
67     UIPrintPageRenderer *printPageRenderer = self.printPageRenderer;
68     printPageRenderer.paperRect = paperRect;
69     printPageRenderer.printableRect = paperRect;
70 }
71
72 - (NSInteger)_recalcPageCount
73 {
74     _printedDocument = nullptr;
75     NSUInteger pageCount = [self._webView._printProvider _wk_pageCountForPrintFormatter:self];
76     return std::min<NSUInteger>(pageCount, NSIntegerMax);
77 }
78
79 - (void)_setNeedsRecalc
80 {
81     if (!_suppressPageCountRecalc)
82         [super _setNeedsRecalc];
83 }
84
85 - (CGRect)rectForPageAtIndex:(NSInteger)pageIndex
86 {
87     if (self.snapshotFirstPage)
88         return self.printPageRenderer.paperRect;
89     return [self _pageContentRect:pageIndex == self.startPage];
90 }
91
92 - (void)drawInRect:(CGRect)rect forPageAtIndex:(NSInteger)pageIndex
93 {
94     if (!_printedDocument)
95         _printedDocument = self._webView._printProvider._wk_printedDocument;
96
97     NSInteger offsetFromStartPage = pageIndex - self.startPage;
98     if (offsetFromStartPage < 0)
99         return;
100
101     CGPDFPageRef page = CGPDFDocumentGetPage(_printedDocument.get(), offsetFromStartPage + 1);
102     if (!page)
103         return;
104
105     CGContextRef context = UIGraphicsGetCurrentContext();
106     CGContextSaveGState(context);
107
108     CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMaxY(rect));
109     CGContextScaleCTM(context, 1, -1);
110     CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect)), 0, true));
111     CGContextClipToRect(context, CGPDFPageGetBoxRect(page, kCGPDFCropBox));
112     CGContextDrawPDFPage(context, page);
113
114     CGContextRestoreGState(context);
115 }
116
117 @end
118
119 #endif // PLATFORM(IOS_FAMILY) && !PLATFORM(IOSMAC)