Title: [105096] branches/safari-534.54-branch/Source/WebKit2

Diff

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
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to