Modified: branches/safari-534.54-branch/Source/WebKit2/ChangeLog (105095 => 105096)
--- branches/safari-534.54-branch/Source/WebKit2/ChangeLog 2012-01-16 23:38:12 UTC (rev 105095)
+++ branches/safari-534.54-branch/Source/WebKit2/ChangeLog 2012-01-16 23:38:30 UTC (rev 105096)
@@ -1,3 +1,35 @@
+2012-01-16 Mark Rowe <[email protected]>
+
+ Merge r104377.
+
+ 2012-01-06 Mark Rowe <[email protected]>
+
+ REGRESSION (WebKit2): Save as PDF no longer generates links to URLs
+ <http://webkit.org/b/65076> / <rdar://problem/9606246>
+
+ WebKit2 printing works by having the web process render the page content to a PDF. The PDF
+ data is then shipped to the UI process which will render it in to the printing graphics context.
+ Links were being lost because the API used to do the rendering of the PDF in to the printing
+ graphics context, CGContextDrawPDFPage, did not preserve the links that were present in the
+ PDF content received from the web process.
+
+ To fix this we switch to using PDFKit for drawing the PDF in to the printing graphics context.
+ PDFKit provides the ability for us to iterate over the links in the PDF content ourselves and
+ add links in to the printing graphics context.
+
+ Reviewed by Alexey Proskuryakov.
+
+ * UIProcess/API/mac/WKPrintingView.h:
+ * UIProcess/API/mac/WKPrintingView.mm:
+ (pdfAnnotationLinkClass): Look up the PDFAnnotationLink class from PDFKit as WebKit2 loads PDFKit lazily.
+ (pdfDocumentClass): Ditto.
+ (-[WKPrintingView _drawPDFDocument:page:atPoint:]): Switch to using the PDFKit equivalents of several types.
+ Iterate over the annotations present in the PDFPage, calling CGPDFContextSetURLForRect for each PDFAnnotationLink
+ that we find.
+ (-[WKPrintingView _drawPreview:]): Create an NSData to feed to PDFDocument.
+ (-[WKPrintingView drawRect:]): Ditto.
+ * WebKit2Prefix.h: Add the usual workaround to make Objective-C exceptions compile when C++ exception handling is disabled.
+
2011-1-13 Lucas Forschler <[email protected]>
Merge 104269
Modified: branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h (105095 => 105096)
--- branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h 2012-01-16 23:38:12 UTC (rev 105095)
+++ branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h 2012-01-16 23:38:30 UTC (rev 105096)
@@ -27,6 +27,7 @@
#import <wtf/RetainPtr.h>
@class WKPrintingViewData;
+@class PDFDocument;
namespace WebKit {
class WebFrameProxy;
@@ -43,7 +44,7 @@
HashMap<WebCore::IntRect, Vector<uint8_t> > _pagePreviews;
Vector<uint8_t> _printedPagesData;
- RetainPtr<CGPDFDocumentRef> _printedPagesPDFDocument;
+ RetainPtr<PDFDocument> _printedPagesPDFDocument;
uint64_t _expectedComputedPagesCallback;
HashMap<uint64_t, WebCore::IntRect> _expectedPreviewCallbacks;
Modified: branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm (105095 => 105096)
--- branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm 2012-01-16 23:38:12 UTC (rev 105095)
+++ branches/safari-534.54-branch/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm 2012-01-16 23:38:30 UTC (rev 105096)
@@ -30,6 +30,7 @@
#import "PrintInfo.h"
#import "WebData.h"
#import "WebPageProxy.h"
+#import <PDFKit/PDFKit.h>
using namespace WebKit;
using namespace WebCore;
@@ -397,16 +398,30 @@
return 0; // Invalid page number.
}
-- (void)_drawPDFDocument:(CGPDFDocumentRef)pdfDocument page:(unsigned)page atPoint:(NSPoint)point
+static Class pdfAnnotationLinkClass()
{
+ static Class pdfAnnotationLinkClass = NSClassFromString(@"PDFAnnotationLink");
+ return pdfAnnotationLinkClass;
+}
+
+static Class pdfDocumentClass()
+{
+ static Class pdfDocumentClass = NSClassFromString(@"PDFDocument");
+ return pdfDocumentClass;
+}
+
+- (void)_drawPDFDocument:(PDFDocument *)pdfDocument page:(unsigned)page atPoint:(NSPoint)point
+{
if (!pdfDocument) {
LOG_ERROR("Couldn't create a PDF document with data passed for preview");
return;
}
- CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument, page);
- if (!pdfPage) {
- LOG_ERROR("Preview data doesn't have page %d", page);
+ PDFPage *pdfPage;
+ @try {
+ pdfPage = [pdfDocument pageAtIndex:page];
+ } @catch (id exception) {
+ LOG_ERROR("Preview data doesn't have page %d: %@", page, exception);
return;
}
@@ -416,8 +431,25 @@
CGContextSaveGState(context);
CGContextTranslateCTM(context, point.x, point.y);
CGContextScaleCTM(context, _totalScaleFactorForPrinting, -_totalScaleFactorForPrinting);
- CGContextTranslateCTM(context, 0, -CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox).size.height);
- CGContextDrawPDFPage(context, pdfPage);
+ CGContextTranslateCTM(context, 0, -[pdfPage boundsForBox:kPDFDisplayBoxMediaBox].size.height);
+ [pdfPage drawWithBox:kPDFDisplayBoxMediaBox];
+
+ CGAffineTransform transform = CGContextGetCTM(context);
+
+ for (PDFAnnotation *annotation in [pdfPage annotations]) {
+ if (![annotation isKindOfClass:pdfAnnotationLinkClass()])
+ continue;
+
+ PDFAnnotationLink *linkAnnotation = (PDFAnnotationLink *)annotation;
+ NSURL *url = "" URL];
+ if (!url)
+ continue;
+
+ CGRect urlRect = NSRectToCGRect([linkAnnotation bounds]);
+ CGRect transformedRect = CGRectApplyAffineTransform(urlRect, transform);
+ CGPDFContextSetURLForRect(context, (CFURLRef)url, transformedRect);
+ }
+
CGContextRestoreGState(context);
}
@@ -460,11 +492,11 @@
return;
}
- const Vector<uint8_t>& pdfData = pagePreviewIterator->second;
- RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithData(0, pdfData.data(), pdfData.size(), 0));
- RetainPtr<CGPDFDocumentRef> pdfDocument(AdoptCF, CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
+ const Vector<uint8_t>& pdfDataBytes = pagePreviewIterator->second;
+ RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:pdfDataBytes.data() length:pdfDataBytes.size()]);
+ RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:pdfData.get()]);
- [self _drawPDFDocument:pdfDocument.get() page:1 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)];
+ [self _drawPDFDocument:pdfDocument.get() page:0 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)];
}
- (void)drawRect:(NSRect)nsRect
@@ -485,11 +517,11 @@
ASSERT(!_printedPagesData.isEmpty()); // Prepared by knowsPageRange:
if (!_printedPagesPDFDocument) {
- RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithData(0, _printedPagesData.data(), _printedPagesData.size(), 0));
- _printedPagesPDFDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
+ RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:_printedPagesData.data() length:_printedPagesData.size()]);
+ _printedPagesPDFDocument.adoptNS([[pdfDocumentClass() alloc] initWithData:pdfData.get()]);
}
- unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber] + 1;
+ unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber];
[self _drawPDFDocument:_printedPagesPDFDocument.get() page:printedPageNumber atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)];
}
Modified: branches/safari-534.54-branch/Source/WebKit2/WebKit2Prefix.h (105095 => 105096)
--- branches/safari-534.54-branch/Source/WebKit2/WebKit2Prefix.h 2012-01-16 23:38:12 UTC (rev 105095)
+++ branches/safari-534.54-branch/Source/WebKit2/WebKit2Prefix.h 2012-01-16 23:38:30 UTC (rev 105096)
@@ -28,7 +28,21 @@
#import <Cocoa/Cocoa.h>
#endif
+/* When C++ exceptions are disabled, the C++ library defines |try| and |catch|
+* to allow C++ code that expects exceptions to build. These definitions
+* interfere with Objective-C++ uses of Objective-C exception handlers, which
+* use |@try| and |@catch|. As a workaround, undefine these macros. */
+
#ifdef __cplusplus
+#include <algorithm> // needed for exception_defines.h
+#endif
+
+#ifdef __OBJC__
+#undef try
+#undef catch
+#endif
+
+#ifdef __cplusplus
#define new ("if you use new/delete make sure to include config.h at the top of the file"())
#define delete ("if you use new/delete make sure to include config.h at the top of the file"())
#endif