Title: [161580] branches/safari-537.74-branch/Source/WebCore

Diff

Modified: branches/safari-537.74-branch/Source/WebCore/ChangeLog (161579 => 161580)


--- branches/safari-537.74-branch/Source/WebCore/ChangeLog	2014-01-09 21:26:54 UTC (rev 161579)
+++ branches/safari-537.74-branch/Source/WebCore/ChangeLog	2014-01-09 21:31:38 UTC (rev 161580)
@@ -1,3 +1,35 @@
+2014-01-09  Matthew Hanson  <[email protected]>
+
+        Merge r161568: <rdar://problem/15784802>
+
+    2014-01-09  Tim Horton  <[email protected]>
+
+            PDFDocumentImage can be very slow to do the initial paint
+            https://bugs.webkit.org/show_bug.cgi?id=126633
+            <rdar://problem/15770980>
+
+            Reviewed by Simon Fraser.
+
+            * platform/graphics/cg/PDFDocumentImage.cpp:
+            (WebCore::PDFDocumentImage::PDFDocumentImage):
+            (WebCore::PDFDocumentImage::size):
+            (WebCore::transformContextForPainting):
+            (WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
+            (WebCore::applyRotationForPainting):
+            (WebCore::PDFDocumentImage::drawPDFPage):
+            * platform/graphics/cg/PDFDocumentImage.h:
+            * platform/graphics/mac/PDFDocumentImageMac.mm:
+            (WebCore::PDFDocumentImage::computeBoundsForCurrentPage):
+            Store rotation from the PDF in degrees, since it can
+            only be 0, 90, 180, or 270, and don't do any trig to
+            perform the rotation, to avoid introducing minor rounding
+            issues in the size.
+
+            Once we're going to paint, if the difference between the
+            computed scale for each axis is due only to integer rounding
+            of the image size, use the same scale for both axes, to avoid
+            a CG slow-path which occurs whenever the scale is nonuniform.
+
 2014-01-07  Lucas Forschler  <[email protected]>
 
         Merge r160479

Modified: branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp (161579 => 161580)


--- branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2014-01-09 21:26:54 UTC (rev 161579)
+++ branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp	2014-01-09 21:31:38 UTC (rev 161580)
@@ -48,7 +48,7 @@
 PDFDocumentImage::PDFDocumentImage(ImageObserver* observer)
     : Image(observer)
     , m_cachedBytes(0)
-    , m_rotation(0.0f)
+    , m_rotationDegrees(0)
     , m_hasPage(false)
 {
 }
@@ -64,14 +64,11 @@
 
 IntSize PDFDocumentImage::size() const
 {
-    const float sina = sinf(-m_rotation);
-    const float cosa = cosf(-m_rotation);
-    const float width = m_mediaBox.size().width();
-    const float height = m_mediaBox.size().height();
-    const float rotWidth = fabsf(width * cosa - height * sina);
-    const float rotHeight = fabsf(width * sina + height * cosa);
-    
-    return expandedIntSize(FloatSize(rotWidth, rotHeight));
+    IntSize expandedCropBoxSize = expandedIntSize(m_cropBox.size());
+
+    if (m_rotationDegrees == 90 || m_rotationDegrees == 270)
+        return expandedCropBoxSize.transposedSize();
+    return expandedCropBoxSize;
 }
 
 void PDFDocumentImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
@@ -95,26 +92,6 @@
     return m_document; // Return true if size is available.
 }
 
-void PDFDocumentImage::applyRotationForPainting(GraphicsContext* context) const
-{
-    // Rotate the crop box and calculate bounding box.
-    float sina = sinf(-m_rotation);
-    float cosa = cosf(-m_rotation);
-    float width = m_cropBox.width();
-    float height = m_cropBox.height();
-
-    // 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;
-    context->translate(floorf(-std::min(zero, std::min(rx.x, ry.x))), floorf(-std::min(zero, std::min(rx.y, ry.y))));
-
-    context->rotate(-m_rotation);
-}
-
 bool PDFDocumentImage::cacheParametersMatch(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect) const
 {
     if (dstRect.size() != m_cachedDestinationSize)
@@ -138,6 +115,17 @@
 {
     float hScale = dstRect.width() / srcRect.width();
     float vScale = dstRect.height() / srcRect.height();
+
+    float minimumScale = std::max((dstRect.width() - 0.5) / srcRect.width(), (dstRect.height() - 0.5) / srcRect.height());
+    float maximumScale = std::min((dstRect.width() + 0.5) / srcRect.width(), (dstRect.height() + 0.5) / srcRect.height());
+
+    // If the difference between the two scales is due to integer rounding of image sizes,
+    // use the average scale for both axes.
+    if (minimumScale <= maximumScale) {
+        hScale = (maximumScale + minimumScale) / 2;
+        vScale = hScale;
+    }
+
     context->translate(srcRect.x() * hScale, srcRect.y() * vScale);
     context->scale(FloatSize(hScale, -vScale));
     context->translate(0, -srcRect.height());
@@ -238,7 +226,7 @@
     else
         m_cropBox = m_mediaBox;
 
-    m_rotation = deg2rad(static_cast<float>(CGPDFPageGetRotationAngle(cgPage)));
+    m_rotationDegrees = CGPDFPageGetRotationAngle(cgPage);
 }
 
 unsigned PDFDocumentImage::pageCount() const
@@ -246,9 +234,21 @@
     return CGPDFDocumentGetNumberOfPages(m_document.get());
 }
 
+static void applyRotationForPainting(GraphicsContext* context, IntSize size, int rotationDegrees) 
+{
+    if (rotationDegrees == 90)
+        context->translate(0, size.height());
+    else if (rotationDegrees == 180)
+        context->translate(size.width(), size.height());
+    else if (rotationDegrees == 270)
+        context->translate(size.width(), 0);
+
+    context->rotate(-deg2rad(static_cast<float>(rotationDegrees)));
+}
+
 void PDFDocumentImage::drawPDFPage(GraphicsContext* context)
 {
-    applyRotationForPainting(context);
+    applyRotationForPainting(context, size(), m_rotationDegrees);
 
     context->translate(-m_cropBox.x(), -m_cropBox.y());
 

Modified: branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h (161579 => 161580)


--- branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h	2014-01-09 21:26:54 UTC (rev 161579)
+++ branches/safari-537.74-branch/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h	2014-01-09 21:31:38 UTC (rev 161580)
@@ -75,8 +75,6 @@
     // FIXME: Implement this to be less conservative.
     virtual bool currentFrameKnownToBeOpaque() OVERRIDE { return false; }
 
-    void applyRotationForPainting(GraphicsContext*) const;
-
     void createPDFDocument();
     void computeBoundsForCurrentPage();
     unsigned pageCount() const;
@@ -99,7 +97,7 @@
 
     FloatRect m_mediaBox;
     FloatRect m_cropBox;
-    float m_rotation;
+    int m_rotationDegrees; // Can only be 0, 90, 180, or 270 degrees.
     bool m_hasPage;
 };
 

Modified: branches/safari-537.74-branch/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm (161579 => 161580)


--- branches/safari-537.74-branch/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm	2014-01-09 21:26:54 UTC (rev 161579)
+++ branches/safari-537.74-branch/Source/WebCore/platform/graphics/mac/PDFDocumentImageMac.mm	2014-01-09 21:31:38 UTC (rev 161580)
@@ -63,7 +63,7 @@
     m_mediaBox = [pdfPage boundsForBox:kPDFDisplayBoxMediaBox];
     m_cropBox = [pdfPage boundsForBox:kPDFDisplayBoxCropBox];
 
-    m_rotation = deg2rad(static_cast<float>([pdfPage rotation]));
+    m_rotationDegrees = [pdfPage rotation];
 }
 
 unsigned PDFDocumentImage::pageCount() const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to