Title: [155069] trunk
Revision
155069
Author
[email protected]
Date
2013-09-04 15:08:26 -0700 (Wed, 04 Sep 2013)

Log Message

[mac] PDFDocumentImage should use PDFKit to draw
https://bugs.webkit.org/show_bug.cgi?id=120651
<rdar://problem/12810731>

Reviewed by Alexey Proskuryakov.

Use PDFKit to draw PDF-in-<img> on Mac, so that annotations in PDF are painted.

Test: fast/images/pdf-as-image-with-annotations.html

* WebCore.xcodeproj/project.pbxproj:
Add PDFDocumentImageMac.mm.

* platform/graphics/cg/PDFDocumentImage.cpp:
(WebCore::PDFDocumentImage::PDFDocumentImage):
We don't need to initialize m_document anymore because it's now a RetainPtr.
Initialize m_hasPage to false.

(WebCore::PDFDocumentImage::~PDFDocumentImage):
We don't need to manually release our CGPDFDocumentRef anymore because it's now a RetainPtr.

(WebCore::PDFDocumentImage::size):
Use expandedIntSize for explicitness.

(WebCore::PDFDocumentImage::applyRotationForPainting):
Rename adjustCTM to applyRotationForPainting, and move the one non-rotation related transformation out.
We need to do this because PDFKit applies the rotation transformation itself, so we don't need to.
Also, explicitly use std::min instead of importing the whole std namespace.

(WebCore::PDFDocumentImage::dataChanged):
Assert that we don't re-enter dataChanged after we've created a document,
because it seems like that shouldn't happen - we only create a document when
we've supposedly received all data, and it would be nice if we didn't have
all this varying code to deal with SharedBuffers changing out from under each other.
Factor the code to create a CGPDFDocumentRef out into createPDFDocument, so we can
replace it with a different implementation that creates a PDFDocument.

(WebCore::PDFDocumentImage::setCurrentPage):
Make all page-number-related things unsigned, since they are in CG and PDFKit,
and add m_hasPage to denote whether we've acquired a valid page yet.
Factor code to retrieve the PDF box bounds into computeBoundsForCurrentPage.
Remove setCurrentPage itself, as we never use a page other than the first page;
we will call computeBoundsForCurrentPage and set hasPage in dataChanged, now.

(WebCore::PDFDocumentImage::draw):
Fix a weird comment.
Factor code that actually draws the PDF out into drawPDFPage.

The rest of the functions in this file are only built for USE(CG) && !PLATFORM(MAC):

(WebCore::PDFDocumentImage::createPDFDocument):
Factored out of dataChanged(); I only kept the !PLATFORM(MAC) branch.

(WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
Factored out of setCurrentPage().
Use deg2rad since we have it.

(WebCore::PDFDocumentImage::pageCount):
(WebCore::PDFDocumentImage::drawPDFPage):
Factored out of draw().
Reduced an unnecessary transform (we were effectively doing mediaBox.origin - cropBox.origin - mediaBox.origin).

* platform/graphics/cg/PDFDocumentImage.h:
Unindent all the things, as we don't indent the first level inside a namespace scope.
Forward-declare PDFDocument.
Make m_currentPage unsigned as it should be.
Add m_hasPage.
Make m_document a PDFDocument on PLATFORM(MAC) and a CGPDFDocumentRef on other platforms.

* platform/graphics/mac/PDFDocumentImageMac.mm: Added.
Soft-link in PDFKit and specifically the PDFDocument class.

(WebCore::PDFDocumentImage::createPDFDocument):
Create our PDFDocument from the SharedBuffer's NSData directly. This shouldn't be a problem
(with respect to the SharedBuffer's data being appended to in secret), because we've waited
for the document to finish loading before getting here.

(WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
Ask PDFKit for the page's media and crop boxes; it automatically performs the correct fallback.
Ask PDFKit for the page's rotation.

(WebCore::PDFDocumentImage::pageCount):
Ask PDFKit for the page count.

(WebCore::PDFDocumentImage::drawPDFPage):
Paint the current page of the PDF. Note that we do not apply the rotation here
via applyRotationForPainting because PDFKit will do it itself.

* platform/mac/SoftLinking.h:
I couldn't find any clients of SOFT_LINK_FRAMEWORK_IN_CORESERVICES_UMBRELLA,
so I made it the more generic SOFT_LINK_FRAMEWORK_IN_UMBRELLA, taking the name
of the umbrella framework and the subframework, so I could use it to soft link
Quartz.framework's PDFKit.framework.

* fast/images/pdf-as-image-with-annotations-expected.html: Added.
* fast/images/pdf-as-image-with-annotations.html: Added.
* fast/images/resources/annotation.pdf: Added.
Add a test that ensures that PDF-in-<img> draws simple annotations.

* platform/mac/fast/images/pdf-as-image-landscape-expected.png:
* platform/mac/fast/images/pdf-as-image-landscape-expected.txt:
Extremely minor rebaselines probably due to PDFKit handling rotation in the new implementation.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (155068 => 155069)


--- trunk/LayoutTests/ChangeLog	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/LayoutTests/ChangeLog	2013-09-04 22:08:26 UTC (rev 155069)
@@ -1,3 +1,20 @@
+2013-09-04  Tim Horton  <[email protected]>
+
+        [mac] PDFDocumentImage should use PDFKit to draw
+        https://bugs.webkit.org/show_bug.cgi?id=120651
+        <rdar://problem/12810731>
+
+        Reviewed by Alexey Proskuryakov.
+
+        * fast/images/pdf-as-image-with-annotations-expected.html: Added.
+        * fast/images/pdf-as-image-with-annotations.html: Added.
+        * fast/images/resources/annotation.pdf: Added.
+        Add a test that ensures that PDF-in-<img> draws simple annotations.
+
+        * platform/mac/fast/images/pdf-as-image-landscape-expected.png:
+        * platform/mac/fast/images/pdf-as-image-landscape-expected.txt:
+        Extremely minor rebaselines probably due to PDFKit handling rotation in the new implementation.
+
 2013-09-04  Ryosuke Niwa  <[email protected]>
 
         Check that XMLHttpRequest.response returns null or a json object as specified in the spec according to readyState value.

Added: trunk/LayoutTests/fast/images/pdf-as-image-with-annotations-expected.html (0 => 155069)


--- trunk/LayoutTests/fast/images/pdf-as-image-with-annotations-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/pdf-as-image-with-annotations-expected.html	2013-09-04 22:08:26 UTC (rev 155069)
@@ -0,0 +1,6 @@
+<html>
+<body style='margin: 0px'>
+<div style='background: lime; height: 100px; width: 100px; overflow: hidden;'>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/images/pdf-as-image-with-annotations.html (0 => 155069)


--- trunk/LayoutTests/fast/images/pdf-as-image-with-annotations.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/pdf-as-image-with-annotations.html	2013-09-04 22:08:26 UTC (rev 155069)
@@ -0,0 +1,10 @@
+<html>
+<head>
+    <title>There should be a single 100x100 green square at 0x0.</title>
+</head>
+<body style='margin: 0px'>
+<div style='background: red; height: 100px; width: 100px; overflow: hidden;'>
+    <img src=''>
+</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/images/resources/annotation.pdf


(Binary files differ)
Property changes on: trunk/LayoutTests/fast/images/resources/annotation.pdf ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/LayoutTests/platform/mac/fast/images/pdf-as-image-landscape-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/platform/mac/fast/images/pdf-as-image-landscape-expected.txt (155068 => 155069)


--- trunk/LayoutTests/platform/mac/fast/images/pdf-as-image-landscape-expected.txt	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/LayoutTests/platform/mac/fast/images/pdf-as-image-landscape-expected.txt	2013-09-04 22:08:26 UTC (rev 155069)
@@ -1,12 +1,12 @@
-layer at (0,0) size 850x653
+layer at (0,0) size 850x654
   RenderView at (0,0) size 785x585
-layer at (0,0) size 785x653
-  RenderBlock {HTML} at (0,0) size 785x653
-    RenderBody {BODY} at (8,8) size 769x629
+layer at (0,0) size 785x654
+  RenderBlock {HTML} at (0,0) size 785x654
+    RenderBody {BODY} at (8,8) size 769x630
       RenderBlock (anonymous) at (0,0) size 769x18
         RenderText {#text} at (0,0) size 663x18
           text run at (0,0) width 349: "This test that we correctly orient landscape pdf images. "
           text run at (349,0) width 314: "The green rectangle should be wider than it is tall."
-      RenderBlock {P} at (0,34) size 769x595
-        RenderImage {IMG} at (0,0) size 842x595
+      RenderBlock {P} at (0,34) size 769x596
+        RenderImage {IMG} at (0,0) size 842x596
         RenderText {#text} at (0,0) size 0x0

Modified: trunk/Source/WebCore/ChangeLog (155068 => 155069)


--- trunk/Source/WebCore/ChangeLog	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/Source/WebCore/ChangeLog	2013-09-04 22:08:26 UTC (rev 155069)
@@ -1,3 +1,99 @@
+2013-09-04  Tim Horton  <[email protected]>
+
+        [mac] PDFDocumentImage should use PDFKit to draw
+        https://bugs.webkit.org/show_bug.cgi?id=120651
+        <rdar://problem/12810731>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Use PDFKit to draw PDF-in-<img> on Mac, so that annotations in PDF are painted.
+
+        Test: fast/images/pdf-as-image-with-annotations.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add PDFDocumentImageMac.mm.
+
+        * platform/graphics/cg/PDFDocumentImage.cpp:
+        (WebCore::PDFDocumentImage::PDFDocumentImage):
+        We don't need to initialize m_document anymore because it's now a RetainPtr.
+        Initialize m_hasPage to false.
+
+        (WebCore::PDFDocumentImage::~PDFDocumentImage):
+        We don't need to manually release our CGPDFDocumentRef anymore because it's now a RetainPtr.
+
+        (WebCore::PDFDocumentImage::size):
+        Use expandedIntSize for explicitness.
+
+        (WebCore::PDFDocumentImage::applyRotationForPainting):
+        Rename adjustCTM to applyRotationForPainting, and move the one non-rotation related transformation out.
+        We need to do this because PDFKit applies the rotation transformation itself, so we don't need to.
+        Also, explicitly use std::min instead of importing the whole std namespace.
+
+        (WebCore::PDFDocumentImage::dataChanged):
+        Assert that we don't re-enter dataChanged after we've created a document,
+        because it seems like that shouldn't happen - we only create a document when
+        we've supposedly received all data, and it would be nice if we didn't have
+        all this varying code to deal with SharedBuffers changing out from under each other.
+        Factor the code to create a CGPDFDocumentRef out into createPDFDocument, so we can
+        replace it with a different implementation that creates a PDFDocument.
+
+        (WebCore::PDFDocumentImage::setCurrentPage):
+        Make all page-number-related things unsigned, since they are in CG and PDFKit,
+        and add m_hasPage to denote whether we've acquired a valid page yet.
+        Factor code to retrieve the PDF box bounds into computeBoundsForCurrentPage.
+        Remove setCurrentPage itself, as we never use a page other than the first page;
+        we will call computeBoundsForCurrentPage and set hasPage in dataChanged, now.
+
+        (WebCore::PDFDocumentImage::draw):
+        Fix a weird comment.
+        Factor code that actually draws the PDF out into drawPDFPage.
+
+        The rest of the functions in this file are only built for USE(CG) && !PLATFORM(MAC):
+
+        (WebCore::PDFDocumentImage::createPDFDocument):
+        Factored out of dataChanged(); I only kept the !PLATFORM(MAC) branch.
+
+        (WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
+        Factored out of setCurrentPage().
+        Use deg2rad since we have it.
+
+        (WebCore::PDFDocumentImage::pageCount):
+        (WebCore::PDFDocumentImage::drawPDFPage):
+        Factored out of draw().
+        Reduced an unnecessary transform (we were effectively doing mediaBox.origin - cropBox.origin - mediaBox.origin).
+
+        * platform/graphics/cg/PDFDocumentImage.h:
+        Unindent all the things, as we don't indent the first level inside a namespace scope.
+        Forward-declare PDFDocument.
+        Make m_currentPage unsigned as it should be.
+        Add m_hasPage.
+        Make m_document a PDFDocument on PLATFORM(MAC) and a CGPDFDocumentRef on other platforms.
+
+        * platform/graphics/mac/PDFDocumentImageMac.mm: Added.
+        Soft-link in PDFKit and specifically the PDFDocument class.
+
+        (WebCore::PDFDocumentImage::createPDFDocument):
+        Create our PDFDocument from the SharedBuffer's NSData directly. This shouldn't be a problem
+        (with respect to the SharedBuffer's data being appended to in secret), because we've waited
+        for the document to finish loading before getting here.
+
+        (WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
+        Ask PDFKit for the page's media and crop boxes; it automatically performs the correct fallback.
+        Ask PDFKit for the page's rotation.
+
+        (WebCore::PDFDocumentImage::pageCount):
+        Ask PDFKit for the page count.
+
+        (WebCore::PDFDocumentImage::drawPDFPage):
+        Paint the current page of the PDF. Note that we do not apply the rotation here
+        via applyRotationForPainting because PDFKit will do it itself.
+
+        * platform/mac/SoftLinking.h:
+        I couldn't find any clients of SOFT_LINK_FRAMEWORK_IN_CORESERVICES_UMBRELLA,
+        so I made it the more generic SOFT_LINK_FRAMEWORK_IN_UMBRELLA, taking the name
+        of the umbrella framework and the subframework, so I could use it to soft link
+        Quartz.framework's PDFKit.framework.
+
 2013-09-04  Roger Fong  <[email protected]>
 
         Unreviewed Windows build fix.

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (155068 => 155069)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-09-04 22:08:26 UTC (rev 155069)
@@ -904,6 +904,7 @@
 		2D5A592F152525230036EE51 /* ImageOrientation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */; };
 		2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8748D6612CC3763001FBA41 /* ImageOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */; };
+		2D6E468417D660F500ECF8BB /* PDFDocumentImageMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */; };
 		2D8287F616E4A0380086BD00 /* HitTestLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */; };
 		2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8287F516E4A0380086BD00 /* HitTestLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2D8FEBDC143E3EF70072502B /* CSSCrossfadeValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */; };
@@ -7343,6 +7344,7 @@
 		2D46F04F17B96FD2005647F0 /* IntSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntSize.cpp; sourceTree = "<group>"; };
 		2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityPolicyViolationEvent.h; sourceTree = "<group>"; };
 		2D5BC42616F882BE007048D0 /* SecurityPolicyViolationEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SecurityPolicyViolationEvent.idl; sourceTree = "<group>"; };
+		2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PDFDocumentImageMac.mm; sourceTree = "<group>"; };
 		2D8287F416E4A0380086BD00 /* HitTestLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestLocation.cpp; sourceTree = "<group>"; };
 		2D8287F516E4A0380086BD00 /* HitTestLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HitTestLocation.h; sourceTree = "<group>"; };
 		2D8FEBDA143E3EF70072502B /* CSSCrossfadeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCrossfadeValue.cpp; sourceTree = "<group>"; };
@@ -18716,6 +18718,7 @@
 				E4B41E100CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.h */,
 				E4B41E110CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.mm */,
 				0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */,
+				2D6E468217D660F500ECF8BB /* PDFDocumentImageMac.mm */,
 				163E88F5118A39D200ED9231 /* SimpleFontDataCoreText.cpp */,
 				B2AFFC770D00A5C10030074D /* SimpleFontDataMac.mm */,
 				49FFBF3D11C93EE3006A7118 /* WebGLLayer.h */,
@@ -25991,6 +25994,7 @@
 				4ACBC0CA12713D0A0094F9B2 /* JSDOMSettableTokenList.cpp in Sources */,
 				C5137CF211A58378004ADB99 /* JSDOMStringList.cpp in Sources */,
 				9A1B6F97158869C80011A8C4 /* JSDOMStringListCustom.cpp in Sources */,
+				2D6E468417D660F500ECF8BB /* PDFDocumentImageMac.mm in Sources */,
 				BC64649711D82349006455B0 /* JSDOMStringMap.cpp in Sources */,
 				BC64649C11D8238C006455B0 /* JSDOMStringMapCustom.cpp in Sources */,
 				7694563C1214D97C0007CBAE /* JSDOMTokenList.cpp in Sources */,

Modified: trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp (155068 => 155069)


--- trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2013-09-04 22:08:26 UTC (rev 155069)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2013 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,21 +42,17 @@
 #include "ImageSourceCG.h"
 #endif
 
-using namespace std;
-
 namespace WebCore {
 
 PDFDocumentImage::PDFDocumentImage()
     : Image(0) // PDFs don't animate
-    , m_document(0)
     , m_rotation(0.0f)
-    , m_currentPage(-1)
+    , m_hasPage(false)
 {
 }
 
 PDFDocumentImage::~PDFDocumentImage()
 {
-    CGPDFDocumentRelease(m_document);
 }
 
 String PDFDocumentImage::filenameExtension() const
@@ -70,10 +66,10 @@
     const float cosa = cosf(-m_rotation);
     const float width = m_mediaBox.size().width();
     const float height = m_mediaBox.size().height();
-    const float rotWidth = width * cosa - height * sina;
-    const float rotHeight = width * sina + height * cosa;
+    const float rotWidth = fabsf(width * cosa - height * sina);
+    const float rotHeight = fabsf(width * sina + height * cosa);
     
-    return IntSize((int)(fabsf(rotWidth) + 0.5f), (int)(fabsf(rotHeight) + 0.5f));
+    return expandedIntSize(FloatSize(rotWidth, rotHeight));
 }
 
 void PDFDocumentImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
@@ -85,27 +81,19 @@
 
 bool PDFDocumentImage::dataChanged(bool allDataReceived)
 {
+    ASSERT(!m_document);
     if (allDataReceived && !m_document) {
-#if PLATFORM(MAC)
-        // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
-        // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
-        RetainPtr<CFDataRef> data = ""
-        RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateWithCFData(data.get()));
-#else
-        // Create a CGDataProvider to wrap the SharedBuffer.
-        // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
-        // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
-        // is a requirement for using the GetBytePointer callback.
-        CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 };
-        RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks));
-#endif
-        m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
-        setCurrentPage(0);
+        createPDFDocument();
+
+        if (pageCount()) {
+            m_hasPage = true;
+            computeBoundsForCurrentPage();
+        }
     }
-    return m_document; // return true if size is available
+    return m_document; // Return true if size is available.
 }
 
-void PDFDocumentImage::adjustCTM(GraphicsContext* context) const
+void PDFDocumentImage::applyRotationForPainting(GraphicsContext* context) const
 {
     // rotate the crop box and calculate bounding box
     float sina = sinf(-m_rotation);
@@ -113,59 +101,22 @@
     float width = m_cropBox.width();
     float height = m_cropBox.height();
 
-    // calculate rotated x and y edges of the corp box. if they're negative, it means part of the image has
+    // calculate rotated x and y edges of the crop box. if they're negative, it means part of the image has
     // been rotated outside of the bounds and we need to shift over the image so it lies inside the bounds again
     CGPoint rx = CGPointMake(width * cosa, width * sina);
     CGPoint ry = CGPointMake(-height * sina, height * cosa);
 
     // adjust so we are at the crop box origin
     const CGFloat zero = 0;
-    CGContextTranslateCTM(context->platformContext(), floorf(-min(zero, min(rx.x, ry.x))), floorf(-min(zero, min(rx.y, ry.y))));
+    CGContextTranslateCTM(context->platformContext(), floorf(-std::min(zero, std::min(rx.x, ry.x))), floorf(-std::min(zero, std::min(rx.y, ry.y))));
 
     // rotate -ve to remove rotation
     CGContextRotateCTM(context->platformContext(), -m_rotation);
-
-    // shift so we are completely within media box
-    CGContextTranslateCTM(context->platformContext(), m_mediaBox.x() - m_cropBox.x(), m_mediaBox.y() - m_cropBox.y());
 }
 
-void PDFDocumentImage::setCurrentPage(int page)
-{
-    if (!m_document)
-        return;
-
-    if (page == m_currentPage)
-        return;
-
-    if (!(page >= 0 && page < pageCount()))
-        return;
-
-    m_currentPage = page;
-
-    CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1);
-
-    // get media box (guaranteed)
-    m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);
-
-    // get crop box (not always there). if not, use media box
-    CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);
-    if (!CGRectIsEmpty(r))
-        m_cropBox = r;
-    else
-        m_cropBox = m_mediaBox;
-
-    // get page rotation angle
-    m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians
-}
-
-int PDFDocumentImage::pageCount() const
-{
-    return m_document ? CGPDFDocumentGetNumberOfPages(m_document) : 0;
-}
-
 void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator op, BlendMode)
 {
-    if (!m_document || m_currentPage == -1)
+    if (!m_document || !m_hasPage)
         return;
 
     {
@@ -177,25 +128,65 @@
         float vScale = dstRect.height() / srcRect.height();
 
         // Scale and translate so the document is rendered in the correct location,
-        // including accounting for the fact that a GraphicsContext is always flipped
-        // and doing appropriate flipping.
+        // accounting for the fact that the GraphicsContext is flipped.
         CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale);
         CGContextScaleCTM(context->platformContext(), hScale, vScale);
         CGContextScaleCTM(context->platformContext(), 1, -1);
         CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height());
         CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect));
 
-        // Rotate translate image into position according to doc properties.
-        adjustCTM(context);
-
-        CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y());
-        CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1));
+        drawPDFPage(context);
     }
 
     if (imageObserver())
         imageObserver()->didDraw(this);
 }
 
+#if !USE(PDFKIT_FOR_PDFDOCUMENTIMAGE)
+void PDFDocumentImage::createPDFDocument()
+{
+    // Create a CGDataProvider to wrap the SharedBuffer.
+    // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
+    // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
+    // is a requirement for using the GetBytePointer callback.
+
+    CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, 0 };
+    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(this->data(), this->data()->size(), &providerCallbacks));
+    m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
 }
 
+void PDFDocumentImage::computeBoundsForCurrentPage()
+{
+    CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document.get(), 1);
+
+    m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);
+
+    // Get crop box (not always there). If not, use media box.
+    CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);
+    if (!CGRectIsEmpty(r))
+        m_cropBox = r;
+    else
+        m_cropBox = m_mediaBox;
+
+    m_rotation = deg2rad(static_cast<float>(CGPDFPageGetRotationAngle(cgPage)));
+}
+
+unsigned PDFDocumentImage::pageCount() const
+{
+    return CGPDFDocumentGetNumberOfPages(m_document.get());
+}
+
+void PDFDocumentImage::drawPDFPage(GraphicsContext* context)
+{
+    applyRotationForPainting(context);
+
+    CGContextTranslateCTM(context->platformContext(), -m_cropBox.x(), -m_cropBox.y());
+
+    // CGPDF pages are indexed from 1.
+    CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document.get(), 1));
+}
+#endif // !USE(PDFKIT_FOR_PDFDOCUMENTIMAGE)
+
+}
+
 #endif // USE(CG)

Modified: trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h (155068 => 155069)


--- trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h	2013-09-04 22:08:26 UTC (rev 155069)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2013 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,53 +32,66 @@
 
 #if USE(CG)
 
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+#define WTF_USE_PDFKIT_FOR_PDFDOCUMENTIMAGE 1
+#endif
+
 typedef struct CGPDFDocument *CGPDFDocumentRef;
+OBJC_CLASS PDFDocument;
 
 namespace WebCore {
 
-    class GraphicsContext;
+class GraphicsContext;
 
-    class PDFDocumentImage : public Image {
-    public:
-        static PassRefPtr<PDFDocumentImage> create()
-        {
-            return adoptRef(new PDFDocumentImage);
-        }
+class PDFDocumentImage : public Image {
+public:
+    static PassRefPtr<PDFDocumentImage> create()
+    {
+        return adoptRef(new PDFDocumentImage);
+    }
 
-    private:
-        virtual ~PDFDocumentImage();
+private:
+    PDFDocumentImage();
+    virtual ~PDFDocumentImage();
 
-        virtual String filenameExtension() const;
+    virtual String filenameExtension() const OVERRIDE;
 
-        virtual bool hasSingleSecurityOrigin() const { return true; }
+    virtual bool hasSingleSecurityOrigin() const OVERRIDE { return true; }
 
-        virtual bool dataChanged(bool allDataReceived);
+    virtual bool dataChanged(bool allDataReceived) OVERRIDE;
 
-        // FIXME: PDF Images are underreporting decoded sizes and will be unable
-        // to prune because these functions are not implemented yet.
-        virtual void destroyDecodedData(bool /*destroyAll*/ = true) { }
-        virtual unsigned decodedSize() const { return 0; }
+    // FIXME: PDF Images are underreporting decoded sizes and will be unable
+    // to prune because these functions are not implemented yet.
+    virtual void destroyDecodedData(bool /*destroyAll*/ = true) OVERRIDE { }
+    virtual unsigned decodedSize() const OVERRIDE { return 0; }
 
-        virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
-        virtual IntSize size() const;
+    virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) OVERRIDE;
+    virtual IntSize size() const OVERRIDE;
 
-        PDFDocumentImage();
-        virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode);
+    virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode) OVERRIDE;
 
-        // FIXME: Implement this to be less conservative.
-        virtual bool currentFrameKnownToBeOpaque() OVERRIDE { return false; }
+    // FIXME: Implement this to be less conservative.
+    virtual bool currentFrameKnownToBeOpaque() OVERRIDE { return false; }
 
-        void setCurrentPage(int);
-        int pageCount() const;
-        void adjustCTM(GraphicsContext*) const;
+    void applyRotationForPainting(GraphicsContext*) const;
 
-        CGPDFDocumentRef m_document;
-        FloatRect m_mediaBox;
-        FloatRect m_cropBox;
-        float m_rotation;
-        int m_currentPage;
-    };
+    void createPDFDocument();
+    void computeBoundsForCurrentPage();
+    unsigned pageCount() const;
+    void drawPDFPage(GraphicsContext*);
 
+#if USE(PDFKIT_FOR_PDFDOCUMENTIMAGE)
+    RetainPtr<PDFDocument> m_document;
+#else
+    RetainPtr<CGPDFDocumentRef> m_document;
+#endif
+
+    FloatRect m_mediaBox;
+    FloatRect m_cropBox;
+    float m_rotation;
+    bool m_hasPage;
+};
+
 }
 
 #endif // USE(CG)

Added: trunk/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm (0 => 155069)


--- trunk/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm	2013-09-04 22:08:26 UTC (rev 155069)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 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. ``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
+ * 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 "config.h"
+#import "PDFDocumentImage.h"
+
+#if USE(PDFKIT_FOR_PDFDOCUMENTIMAGE)
+
+#import "LocalCurrentGraphicsContext.h"
+#import "SharedBuffer.h"
+#import "SoftLinking.h"
+#import <Quartz/Quartz.h>
+#import <objc/objc-class.h>
+#import <wtf/RetainPtr.h>
+
+SOFT_LINK_FRAMEWORK_IN_UMBRELLA(Quartz, PDFKit)
+SOFT_LINK_CLASS(PDFKit, PDFDocument)
+
+namespace WebCore {
+
+void PDFDocumentImage::createPDFDocument()
+{
+    m_document = adoptNS([[getPDFDocumentClass() alloc] initWithData:data()->createNSData()]);
+}
+
+void PDFDocumentImage::computeBoundsForCurrentPage()
+{
+    PDFPage *pdfPage = [m_document pageAtIndex:0];
+
+    m_mediaBox = [pdfPage boundsForBox:kPDFDisplayBoxMediaBox];
+    m_cropBox = [pdfPage boundsForBox:kPDFDisplayBoxCropBox];
+
+    m_rotation = deg2rad(static_cast<float>([pdfPage rotation]));
+}
+
+unsigned PDFDocumentImage::pageCount() const
+{
+    return [m_document pageCount];
+}
+
+void PDFDocumentImage::drawPDFPage(GraphicsContext* context)
+{
+    CGContextTranslateCTM(context->platformContext(), -m_cropBox.x(), -m_cropBox.y());
+
+    LocalCurrentGraphicsContext localCurrentContext(context);
+    [[m_document pageAtIndex:0] drawWithBox:kPDFDisplayBoxCropBox];
+}
+
+}
+
+#endif // USE(PDFKIT_FOR_PDFDOCUMENTIMAGE)

Modified: trunk/Source/WebCore/platform/mac/SoftLinking.h (155068 => 155069)


--- trunk/Source/WebCore/platform/mac/SoftLinking.h	2013-09-04 22:04:37 UTC (rev 155068)
+++ trunk/Source/WebCore/platform/mac/SoftLinking.h	2013-09-04 22:08:26 UTC (rev 155069)
@@ -65,10 +65,10 @@
         return frameworkLibrary; \
     }
 
-#define SOFT_LINK_FRAMEWORK_IN_CORESERVICES_UMBRELLA(framework) \
+#define SOFT_LINK_FRAMEWORK_IN_UMBRELLA(umbrella, framework) \
     static void* framework##Library() \
     { \
-        static void* frameworkLibrary = dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \
+        static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #umbrella ".framework/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \
         ASSERT_WITH_MESSAGE(frameworkLibrary, "%s", dlerror()); \
         return frameworkLibrary; \
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to