https://bugs.webkit.org/show_bug.cgi?id=134269
<rdar://problem/
17272825>
Reviewed by Dan Bernstein.
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _currentContentView]):
(contentZoomScale):
Factor _currentContentView out of contentZoomScale.
(-[WKWebView _zoomToRect:WebCore::atScale:origin:WebCore::]):
(-[WKWebView _scrollToRect:WebCore::origin:WebCore::minimumScrollDistance:]):
(-[WKWebView _contentRectForUserInteraction]):
Use it in a bunch more places so we query the right view when zooming/scrolling for smart magnification.
* UIProcess/ios/WKPDFView.h:
* UIProcess/ios/WKPDFView.mm:
(-[WKPDFView scrollViewDidScroll:]):
(-[WKPDFView _revalidateViews]):
(-[WKPDFView zoom:to:atPoint:kind:]):
(-[WKPDFView resetZoom:]):
Implement zoom:to:atPoint:kind: and resetZoom: UIPDFPageViewDelegate methods.
Convert the rects/points and forward them on to the WKWebView to do the zoom.
resetZoom: doesn't provide the gesture origin, so we zoom out using the view center as our origin.
Avoid parenting new UIPDFPageViews while starting a zoom; they'll end up with a bizarre
animation on them and go flying across the screen (even before _isAnimatingZoom is set).
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170515
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-06-26 Timothy Horton <timothy_horton@apple.com>
+
+ [iOS][WK2] Implement WKPDFView smart magnification
+ https://bugs.webkit.org/show_bug.cgi?id=134269
+ <rdar://problem/17272825>
+
+ Reviewed by Dan Bernstein.
+
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _currentContentView]):
+ (contentZoomScale):
+ Factor _currentContentView out of contentZoomScale.
+
+ (-[WKWebView _zoomToRect:WebCore::atScale:origin:WebCore::]):
+ (-[WKWebView _scrollToRect:WebCore::origin:WebCore::minimumScrollDistance:]):
+ (-[WKWebView _contentRectForUserInteraction]):
+ Use it in a bunch more places so we query the right view when zooming/scrolling for smart magnification.
+
+ * UIProcess/ios/WKPDFView.h:
+ * UIProcess/ios/WKPDFView.mm:
+ (-[WKPDFView scrollViewDidScroll:]):
+ (-[WKPDFView _revalidateViews]):
+ (-[WKPDFView zoom:to:atPoint:kind:]):
+ (-[WKPDFView resetZoom:]):
+ Implement zoom:to:atPoint:kind: and resetZoom: UIPDFPageViewDelegate methods.
+ Convert the rects/points and forward them on to the WKWebView to do the zoom.
+ resetZoom: doesn't provide the gesture origin, so we zoom out using the view center as our origin.
+ Avoid parenting new UIPDFPageViews while starting a zoom; they'll end up with a bizarre
+ animation on them and go flying across the screen (even before _isAnimatingZoom is set).
+
2014-06-26 Tim Horton <timothy_horton@apple.com>
[WK2] Pinch-zoom shadows can overlap headers and footers
return CGSizeMake(floorToDevicePixel(contentSize.width, deviceScaleFactor), floorToDevicePixel(contentSize.height, deviceScaleFactor));
}
+- (UIView *)_currentContentView
+{
+ return _customContentView ? _customContentView.get() : _contentView.get();
+}
+
- (void)_setHasCustomContentView:(BOOL)pageHasCustomContentView loadedMIMEType:(const WTF::String&)mimeType
{
if (pageHasCustomContentView) {
static CGFloat contentZoomScale(WKWebView* webView)
{
- UIView *zoomView;
- if (webView->_customContentView)
- zoomView = webView->_customContentView.get();
- else
- zoomView = webView->_contentView.get();
-
- CGFloat scale = [[zoomView layer] affineTransform].a;
+ CGFloat scale = [[webView._currentContentView layer] affineTransform].a;
ASSERT(scale == [webView->_scrollView zoomScale]);
return scale;
}
{
// FIMXE: Some of this could be shared with _scrollToRect.
const double visibleRectScaleChange = contentZoomScale(self) / scale;
- const WebCore::FloatRect visibleRect([self convertRect:self.bounds toView:_contentView.get()]);
+ const WebCore::FloatRect visibleRect([self convertRect:self.bounds toView:self._currentContentView]);
const WebCore::FloatRect unobscuredRect([self _contentRectForUserInteraction]);
const WebCore::FloatSize topLeftObscuredInsetAfterZoom((unobscuredRect.minXMinYCorner() - visibleRect.minXMinYCorner()) * visibleRectScaleChange);
{
WebCore::FloatRect unobscuredContentRect([self _contentRectForUserInteraction]);
WebCore::FloatPoint unobscuredContentOffset = unobscuredContentRect.location();
- WebCore::FloatSize contentSize([_contentView bounds].size);
+ WebCore::FloatSize contentSize([self._currentContentView bounds].size);
// Center the target rect in the scroll view.
// If the target doesn't fit in the scroll view, center on the gesture location instead.
UIEdgeInsets obscuredInsets = _obscuredInsets;
obscuredInsets.bottom = std::max(_obscuredInsets.bottom, _inputViewBounds.size.height);
CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, obscuredInsets);
- return [self convertRect:unobscuredRect toView:_contentView.get()];
+ return [self convertRect:unobscuredRect toView:self._currentContentView];
}
- (void)_updateVisibleContentRects
#if PLATFORM(IOS)
#import "WKWebViewContentProvider.h"
+#import <CorePDF/UIPDFPageView.h>
#import <UIKit/UIView.h>
-@interface WKPDFView : UIView <WKWebViewContentProvider>
+@interface WKPDFView : UIView <WKWebViewContentProvider, UIPDFPageViewDelegate>
@property (nonatomic, readonly) NSString *suggestedFilename;
@property (nonatomic, readonly) CGPDFDocumentRef pdfDocument;
#import <CorePDF/UIPDFDocument.h>
#import <CorePDF/UIPDFPage.h>
#import <CorePDF/UIPDFPageView.h>
+#import <UIKit/UIScrollView_Private.h>
#import <WebCore/FloatRect.h>
#import <wtf/RetainPtr.h>
#import <wtf/Vector.h>
const float overdrawHeightMultiplier = 1.5;
+static const CGFloat smartMagnificationElementPadding = 0.05;
+
typedef struct {
CGRect frame;
RetainPtr<UIPDFPageView> view;
WKWebView *_webView;
UIScrollView *_scrollView;
UIView *_fixedOverlayView;
+
+ BOOL _isStartingZoom;
}
- (instancetype)web_initWithFrame:(CGRect)frame webView:(WKWebView *)webView
- (void)dealloc
{
+ [self _clearPages];
[_pageNumberIndicator removeFromSuperview];
[super dealloc];
}
return [_pdfDocument CGDocument];
}
+- (void)_clearPages
+{
+ for (auto& page : _pages) {
+ [page.view removeFromSuperview];
+ [page.view setDelegate:nil];
+ }
+
+ _pages.clear();
+}
+
- (void)web_setContentProviderData:(NSData *)data suggestedFilename:(NSString *)filename
{
_suggestedFilename = adoptNS([filename copy]);
- for (auto& page : _pages)
- [page.view removeFromSuperview];
-
- _pages.clear();
+ [self _clearPages];
RetainPtr<CGDataProvider> dataProvider = adoptCF(CGDataProviderCreateWithCFData((CFDataRef)data));
RetainPtr<CGPDFDocumentRef> cgPDFDocument = adoptCF(CGPDFDocumentCreateWithProvider(dataProvider.get()));
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
- if (scrollView.isZoomBouncing)
+ if (scrollView.isZoomBouncing || scrollView._isAnimatingZoom)
return;
[self _revalidateViews];
- (void)_revalidateViews
{
+ if (_isStartingZoom)
+ return;
+
CGRect targetRect = [_scrollView convertRect:_scrollView.bounds toView:self];
// We apply overdraw after applying scale in order to avoid excessive
pageInfo.view = adoptNS([[UIPDFPageView alloc] initWithPage:pageInfo.page.get() tiledContent:YES]);
[pageInfo.view setUseBackingLayer:YES];
+ [pageInfo.view setDelegate:self];
[self addSubview:pageInfo.view.get()];
[pageInfo.view setFrame:pageInfo.frame];
{
NSUInteger pageCount = [_pdfDocument numberOfPages];
[_pageNumberIndicator setPageCount:pageCount];
+
+ [self _clearPages];
- for (auto& pageInfo : _pages)
- [pageInfo.view removeFromSuperview];
-
- _pages.clear();
_pages.reserveCapacity(pageCount);
CGRect pageFrame = CGRectMake(0, 0, _minimumSize.width, _minimumSize.height);
[_scrollView setContentSize:newFrame.size];
}
+
+- (void)zoom:(UIPDFPageView *)pageView to:(CGRect)targetRect atPoint:(CGPoint)origin kind:(UIPDFObjectKind)kind
+{
+ _isStartingZoom = YES;
+
+ BOOL isImage = kind == kUIPDFObjectKindGraphic;
+
+ if (!isImage)
+ targetRect = CGRectInset(targetRect, smartMagnificationElementPadding * targetRect.size.width, smartMagnificationElementPadding * targetRect.size.height);
+
+ CGRect rectInDocumentCoordinates = [pageView convertRect:targetRect toView:self];
+ CGPoint originInDocumentCoordinates = [pageView convertPoint:origin toView:self];
+
+ [_webView _zoomToRect:rectInDocumentCoordinates withOrigin:originInDocumentCoordinates fitEntireRect:isImage minimumScale:pdfMinimumZoomScale maximumScale:pdfMaximumZoomScale minimumScrollDistance:0];
+
+ _isStartingZoom = NO;
+}
+
+- (void)resetZoom:(UIPDFPageView *)pageView
+{
+ _isStartingZoom = YES;
+
+ CGRect scrollViewBounds = _scrollView.bounds;
+ CGPoint centerOfPageInDocumentCoordinates = [_scrollView convertPoint:CGPointMake(CGRectGetMidX(scrollViewBounds), CGRectGetMidY(scrollViewBounds)) toView:self];
+ [_webView _zoomOutWithOrigin:centerOfPageInDocumentCoordinates];
+
+ _isStartingZoom = NO;
+}
+
@end
#endif /* PLATFORM(IOS) */