[PDF] Fix shader fallback mapping when clipped

The bounding box used for our pattern sizing is in device coordinates,
but SkPDFImageShader::Create() runs it through the inverse CTM to map
into shader space (with a notable effect of vertical flipping).

In order not to implode, the fallback shader path needs to compute its
adjustments in a consistent space.

BUG=skia:3398, chromium:454591, chromium:455052
R=halcanary@google.com

Review URL: https://codereview.chromium.org/901303003
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index b20be99..e9283bc 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -24,7 +24,7 @@
 #include "SkTSet.h"
 #include "SkTypes.h"
 
-static bool inverseTransformBBox(const SkMatrix& matrix, SkRect* bbox) {
+static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) {
     SkMatrix inverse;
     if (!matrix.invert(&inverse)) {
         return false;
@@ -849,7 +849,7 @@
 
     SkRect bbox;
     bbox.set(state.fBBox);
-    if (!inverseTransformBBox(finalMatrix, &bbox)) {
+    if (!inverse_transform_bbox(finalMatrix, &bbox)) {
         return NULL;
     }
 
@@ -922,7 +922,7 @@
     finalMatrix.preConcat(state.fShaderTransform);
     SkRect deviceBounds;
     deviceBounds.set(state.fBBox);
-    if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
+    if (!inverse_transform_bbox(finalMatrix, &deviceBounds)) {
         return NULL;
     }
 
@@ -1200,6 +1200,15 @@
             //  * shade the whole area
             //  * use the result as a bitmap shader
 
+            // bbox is in device space. While that's exactly what we want for sizing our bitmap,
+            // we need to map it into shader space for adjustments (to match
+            // SkPDFImageShader::Create's behavior).
+            SkRect shaderRect = SkRect::Make(bbox);
+            if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
+                fImage.reset();
+                return;
+            }
+
             // Clamp the bitmap size to about 1M pixels
             static const SkScalar kMaxBitmapArea = 1024 * 1024;
             SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
@@ -1209,8 +1218,8 @@
 
             SkISize size = SkISize::Make(SkScalarRoundToInt(rasterScale * bbox.width()),
                                          SkScalarRoundToInt(rasterScale * bbox.height()));
-            SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / SkIntToScalar(bbox.width()),
-                                        SkIntToScalar(size.height()) / SkIntToScalar(bbox.height()));
+            SkSize scale = SkSize::Make(SkIntToScalar(size.width()) / shaderRect.width(),
+                                        SkIntToScalar(size.height()) / shaderRect.height());
 
             fImage.allocN32Pixels(size.width(), size.height());
             fImage.eraseColor(SK_ColorTRANSPARENT);
@@ -1220,10 +1229,10 @@
 
             SkCanvas canvas(fImage);
             canvas.scale(scale.width(), scale.height());
-            canvas.translate(-SkIntToScalar(bbox.x()), -SkIntToScalar(bbox.y()));
+            canvas.translate(-shaderRect.x(), -shaderRect.y());
             canvas.drawPaint(p);
 
-            fShaderTransform.setTranslate(SkIntToScalar(bbox.x()), SkIntToScalar(bbox.y()));
+            fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
             fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
         } else {
             SkASSERT(matrix.isIdentity());