diff --git a/gn/pdf.gni b/gn/pdf.gni
index f7de23d..6b140e0 100644
--- a/gn/pdf.gni
+++ b/gn/pdf.gni
@@ -28,6 +28,8 @@
   "$_src/pdf/SkPDFFont.h",
   "$_src/pdf/SkPDFFormXObject.cpp",
   "$_src/pdf/SkPDFFormXObject.h",
+  "$_src/pdf/SkPDFGradientShader.cpp",
+  "$_src/pdf/SkPDFGradientShader.h",
   "$_src/pdf/SkPDFGraphicState.cpp",
   "$_src/pdf/SkPDFGraphicState.h",
   "$_src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp",
diff --git a/src/pdf/SkPDFCanon.cpp b/src/pdf/SkPDFCanon.cpp
index 3ecd474..53a0044 100644
--- a/src/pdf/SkPDFCanon.cpp
+++ b/src/pdf/SkPDFCanon.cpp
@@ -10,47 +10,7 @@
 #include "SkPDFCanon.h"
 #include "SkPDFFont.h"
 
-////////////////////////////////////////////////////////////////////////////////
-
 SkPDFCanon::~SkPDFCanon() {}
+SkPDFCanon::SkPDFCanon() {}
 
-////////////////////////////////////////////////////////////////////////////////
 
-template <typename T>
-sk_sp<SkPDFObject> find_shader(const SkTArray<T>& records,
-                               const SkPDFShader::State& state) {
-    for (const T& record : records) {
-        if (record.fShaderState == state) {
-            return record.fShaderObject;
-        }
-    }
-    return nullptr;
-}
-
-sk_sp<SkPDFObject> SkPDFCanon::findFunctionShader(
-        const SkPDFShader::State& state) const {
-    return find_shader(fFunctionShaderRecords, state);
-}
-void SkPDFCanon::addFunctionShader(sk_sp<SkPDFObject> pdfShader,
-                                   SkPDFShader::State state) {
-    fFunctionShaderRecords.emplace_back(ShaderRec{std::move(state), std::move(pdfShader)});
-}
-
-sk_sp<SkPDFObject> SkPDFCanon::findAlphaShader(
-        const SkPDFShader::State& state) const {
-    return find_shader(fAlphaShaderRecords, state);
-}
-void SkPDFCanon::addAlphaShader(sk_sp<SkPDFObject> pdfShader,
-                                SkPDFShader::State state) {
-    fAlphaShaderRecords.emplace_back(ShaderRec{std::move(state), std::move(pdfShader)});
-}
-
-sk_sp<SkPDFObject> SkPDFCanon::findImageShader(
-        const SkPDFShader::State& state) const {
-    return find_shader(fImageShaderRecords, state);
-}
-
-void SkPDFCanon::addImageShader(sk_sp<SkPDFObject> pdfShader,
-                                SkPDFShader::State state) {
-    fImageShaderRecords.emplace_back(ShaderRec{std::move(state), std::move(pdfShader)});
-}
diff --git a/src/pdf/SkPDFCanon.h b/src/pdf/SkPDFCanon.h
index d876443..1085387 100644
--- a/src/pdf/SkPDFCanon.h
+++ b/src/pdf/SkPDFCanon.h
@@ -9,6 +9,7 @@
 
 #include "SkPDFGraphicState.h"
 #include "SkPDFShader.h"
+#include "SkPDFGradientShader.h"
 #include "SkPixelSerializer.h"
 #include "SkTDArray.h"
 #include "SkTHash.h"
@@ -21,18 +22,17 @@
  *  The SkPDFCanon canonicalizes objects across PDF pages
  *  (SkPDFDevices) and across draw calls.
  */
-class SkPDFCanon : SkNoncopyable {
+class SkPDFCanon {
 public:
     ~SkPDFCanon();
+    SkPDFCanon();
+    SkPDFCanon(const SkPDFCanon&) = delete;
+    SkPDFCanon& operator=(const SkPDFCanon&) = delete;
 
-    sk_sp<SkPDFObject> findFunctionShader(const SkPDFShader::State&) const;
-    void addFunctionShader(sk_sp<SkPDFObject>, SkPDFShader::State);
+    SkTHashMap<SkPDFShader::State, sk_sp<SkPDFObject>> fImageShaderMap;
 
-    sk_sp<SkPDFObject> findAlphaShader(const SkPDFShader::State&) const;
-    void addAlphaShader(sk_sp<SkPDFObject>, SkPDFShader::State);
-
-    sk_sp<SkPDFObject> findImageShader(const SkPDFShader::State&) const;
-    void addImageShader(sk_sp<SkPDFObject>, SkPDFShader::State);
+    SkPDFGradientShader::HashMap fAlphaGradientMap;
+    SkPDFGradientShader::HashMap fOpaqueGradientMap;
 
     SkTHashMap<SkBitmapKey, sk_sp<SkPDFObject>> fPDFBitmapMap;
 
@@ -47,14 +47,5 @@
     sk_sp<SkPDFStream> fInvertFunction;
     sk_sp<SkPDFDict> fNoSmaskGraphicState;
     sk_sp<SkPDFArray> fRangeObject;
-
-private:
-    struct ShaderRec {
-        SkPDFShader::State fShaderState;
-        sk_sp<SkPDFObject> fShaderObject;
-    };
-    SkTArray<ShaderRec> fFunctionShaderRecords;
-    SkTArray<ShaderRec> fAlphaShaderRecords;
-    SkTArray<ShaderRec> fImageShaderRecords;
 };
 #endif  // SkPDFCanon_DEFINED
diff --git a/src/pdf/SkPDFGradientShader.cpp b/src/pdf/SkPDFGradientShader.cpp
new file mode 100644
index 0000000..0287678
--- /dev/null
+++ b/src/pdf/SkPDFGradientShader.cpp
@@ -0,0 +1,955 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkPDFGradientShader.h"
+
+#include "SkOpts.h"
+#include "SkPDFDocument.h"
+#include "SkPDFFormXObject.h"
+#include "SkPDFResourceDict.h"
+#include "SkPDFUtils.h"
+
+static uint32_t hash(const SkShader::GradientInfo& v) {
+    uint32_t buffer[] = {
+        (uint32_t)v.fColorCount,
+        SkOpts::hash(v.fColors, v.fColorCount * sizeof(SkColor)),
+        SkOpts::hash(v.fColorOffsets, v.fColorCount * sizeof(SkScalar)),
+        SkOpts::hash(v.fPoint, 2 * sizeof(SkPoint)),
+        SkOpts::hash(v.fRadius, 2 * sizeof(SkScalar)),
+        (uint32_t)v.fTileMode,
+        v.fGradientFlags,
+    };
+    return SkOpts::hash(buffer, sizeof(buffer));
+}
+
+static uint32_t hash(const SkPDFGradientShader::Key& k) {
+    uint32_t buffer[] = {
+        (uint32_t)k.fType,
+        hash(k.fInfo),
+        SkOpts::hash(&k.fCanvasTransform, sizeof(SkMatrix)),
+        SkOpts::hash(&k.fShaderTransform, sizeof(SkMatrix)),
+        SkOpts::hash(&k.fBBox, sizeof(SkIRect))
+    };
+    return SkOpts::hash(buffer, sizeof(buffer));
+}
+
+static void unit_to_points_matrix(const SkPoint pts[2], SkMatrix* matrix) {
+    SkVector    vec = pts[1] - pts[0];
+    SkScalar    mag = vec.length();
+    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;
+
+    vec.scale(inv);
+    matrix->setSinCos(vec.fY, vec.fX);
+    matrix->preScale(mag, mag);
+    matrix->postTranslate(pts[0].fX, pts[0].fY);
+}
+
+static const int kColorComponents = 3;
+typedef uint8_t ColorTuple[kColorComponents];
+
+/* Assumes t + startOffset is on the stack and does a linear interpolation on t
+   between startOffset and endOffset from prevColor to curColor (for each color
+   component), leaving the result in component order on the stack. It assumes
+   there are always 3 components per color.
+   @param range                  endOffset - startOffset
+   @param curColor[components]   The current color components.
+   @param prevColor[components]  The previous color components.
+   @param result                 The result ps function.
+ */
+static void interpolate_color_code(SkScalar range, const ColorTuple& curColor,
+                                   const ColorTuple& prevColor,
+                                   SkDynamicMemoryWStream* result) {
+    SkASSERT(range != SkIntToScalar(0));
+
+    // Figure out how to scale each color component.
+    SkScalar multiplier[kColorComponents];
+    for (int i = 0; i < kColorComponents; i++) {
+        static const SkScalar kColorScale = SkScalarInvert(255);
+        multiplier[i] = kColorScale * (curColor[i] - prevColor[i]) / range;
+    }
+
+    // Calculate when we no longer need to keep a copy of the input parameter t.
+    // If the last component to use t is i, then dupInput[0..i - 1] = true
+    // and dupInput[i .. components] = false.
+    bool dupInput[kColorComponents];
+    dupInput[kColorComponents - 1] = false;
+    for (int i = kColorComponents - 2; i >= 0; i--) {
+        dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0;
+    }
+
+    if (!dupInput[0] && multiplier[0] == 0) {
+        result->writeText("pop ");
+    }
+
+    for (int i = 0; i < kColorComponents; i++) {
+        // If the next components needs t and this component will consume a
+        // copy, make another copy.
+        if (dupInput[i] && multiplier[i] != 0) {
+            result->writeText("dup ");
+        }
+
+        if (multiplier[i] == 0) {
+            SkPDFUtils::AppendColorComponent(prevColor[i], result);
+            result->writeText(" ");
+        } else {
+            if (multiplier[i] != 1) {
+                SkPDFUtils::AppendScalar(multiplier[i], result);
+                result->writeText(" mul ");
+            }
+            if (prevColor[i] != 0) {
+                SkPDFUtils::AppendColorComponent(prevColor[i], result);
+                result->writeText(" add ");
+            }
+        }
+
+        if (dupInput[i]) {
+            result->writeText("exch\n");
+        }
+    }
+}
+
+/* Generate Type 4 function code to map t=[0,1) to the passed gradient,
+   clamping at the edges of the range.  The generated code will be of the form:
+       if (t < 0) {
+           return colorData[0][r,g,b];
+       } else {
+           if (t < info.fColorOffsets[1]) {
+               return linearinterpolation(colorData[0][r,g,b],
+                                          colorData[1][r,g,b]);
+           } else {
+               if (t < info.fColorOffsets[2]) {
+                   return linearinterpolation(colorData[1][r,g,b],
+                                              colorData[2][r,g,b]);
+               } else {
+
+                ...    } else {
+                           return colorData[info.fColorCount - 1][r,g,b];
+                       }
+                ...
+           }
+       }
+ */
+static void gradient_function_code(const SkShader::GradientInfo& info,
+                                 SkDynamicMemoryWStream* result) {
+    /* We want to linearly interpolate from the previous color to the next.
+       Scale the colors from 0..255 to 0..1 and determine the multipliers
+       for interpolation.
+       C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}.
+     */
+
+    SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount);
+    ColorTuple *colorData = colorDataAlloc.get();
+    for (int i = 0; i < info.fColorCount; i++) {
+        colorData[i][0] = SkColorGetR(info.fColors[i]);
+        colorData[i][1] = SkColorGetG(info.fColors[i]);
+        colorData[i][2] = SkColorGetB(info.fColors[i]);
+    }
+
+    // Clamp the initial color.
+    result->writeText("dup 0 le {pop ");
+    SkPDFUtils::AppendColorComponent(colorData[0][0], result);
+    result->writeText(" ");
+    SkPDFUtils::AppendColorComponent(colorData[0][1], result);
+    result->writeText(" ");
+    SkPDFUtils::AppendColorComponent(colorData[0][2], result);
+    result->writeText(" }\n");
+
+    // The gradient colors.
+    int gradients = 0;
+    for (int i = 1 ; i < info.fColorCount; i++) {
+        if (info.fColorOffsets[i] == info.fColorOffsets[i - 1]) {
+            continue;
+        }
+        gradients++;
+
+        result->writeText("{dup ");
+        SkPDFUtils::AppendScalar(info.fColorOffsets[i], result);
+        result->writeText(" le {");
+        if (info.fColorOffsets[i - 1] != 0) {
+            SkPDFUtils::AppendScalar(info.fColorOffsets[i - 1], result);
+            result->writeText(" sub\n");
+        }
+
+        interpolate_color_code(info.fColorOffsets[i] - info.fColorOffsets[i - 1],
+                             colorData[i], colorData[i - 1], result);
+        result->writeText("}\n");
+    }
+
+    // Clamp the final color.
+    result->writeText("{pop ");
+    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][0], result);
+    result->writeText(" ");
+    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][1], result);
+    result->writeText(" ");
+    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][2], result);
+
+    for (int i = 0 ; i < gradients + 1; i++) {
+        result->writeText("} ifelse\n");
+    }
+}
+
+static sk_sp<SkPDFDict> createInterpolationFunction(const ColorTuple& color1,
+                                                    const ColorTuple& color2) {
+    auto retval = sk_make_sp<SkPDFDict>();
+
+    auto c0 = sk_make_sp<SkPDFArray>();
+    c0->appendColorComponent(color1[0]);
+    c0->appendColorComponent(color1[1]);
+    c0->appendColorComponent(color1[2]);
+    retval->insertObject("C0", std::move(c0));
+
+    auto c1 = sk_make_sp<SkPDFArray>();
+    c1->appendColorComponent(color2[0]);
+    c1->appendColorComponent(color2[1]);
+    c1->appendColorComponent(color2[2]);
+    retval->insertObject("C1", std::move(c1));
+
+    auto domain = sk_make_sp<SkPDFArray>();
+    domain->appendScalar(0);
+    domain->appendScalar(1.0f);
+    retval->insertObject("Domain", std::move(domain));
+
+    retval->insertInt("FunctionType", 2);
+    retval->insertScalar("N", 1.0f);
+
+    return retval;
+}
+
+static sk_sp<SkPDFDict> gradientStitchCode(const SkShader::GradientInfo& info) {
+    auto retval = sk_make_sp<SkPDFDict>();
+
+    // normalize color stops
+    int colorCount = info.fColorCount;
+    SkTDArray<SkColor>    colors(info.fColors, colorCount);
+    SkTDArray<SkScalar>   colorOffsets(info.fColorOffsets, colorCount);
+
+    int i = 1;
+    while (i < colorCount - 1) {
+        // ensure stops are in order
+        if (colorOffsets[i - 1] > colorOffsets[i]) {
+            colorOffsets[i] = colorOffsets[i - 1];
+        }
+
+        // remove points that are between 2 coincident points
+        if ((colorOffsets[i - 1] == colorOffsets[i]) && (colorOffsets[i] == colorOffsets[i + 1])) {
+            colorCount -= 1;
+            colors.remove(i);
+            colorOffsets.remove(i);
+        } else {
+            i++;
+        }
+    }
+    // find coincident points and slightly move them over
+    for (i = 1; i < colorCount - 1; i++) {
+        if (colorOffsets[i - 1] == colorOffsets[i]) {
+            colorOffsets[i] += 0.00001f;
+        }
+    }
+    // check if last 2 stops coincide
+    if (colorOffsets[i - 1] == colorOffsets[i]) {
+        colorOffsets[i - 1] -= 0.00001f;
+    }
+
+    SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(colorCount);
+    ColorTuple *colorData = colorDataAlloc.get();
+    for (int i = 0; i < colorCount; i++) {
+        colorData[i][0] = SkColorGetR(colors[i]);
+        colorData[i][1] = SkColorGetG(colors[i]);
+        colorData[i][2] = SkColorGetB(colors[i]);
+    }
+
+    // no need for a stitch function if there are only 2 stops.
+    if (colorCount == 2)
+        return createInterpolationFunction(colorData[0], colorData[1]);
+
+    auto encode = sk_make_sp<SkPDFArray>();
+    auto bounds = sk_make_sp<SkPDFArray>();
+    auto functions = sk_make_sp<SkPDFArray>();
+
+    auto domain = sk_make_sp<SkPDFArray>();
+    domain->appendScalar(0);
+    domain->appendScalar(1.0f);
+    retval->insertObject("Domain", std::move(domain));
+    retval->insertInt("FunctionType", 3);
+
+    for (int i = 1; i < colorCount; i++) {
+        if (i > 1) {
+            bounds->appendScalar(colorOffsets[i-1]);
+        }
+
+        encode->appendScalar(0);
+        encode->appendScalar(1.0f);
+
+        functions->appendObject(createInterpolationFunction(colorData[i-1], colorData[i]));
+    }
+
+    retval->insertObject("Encode", std::move(encode));
+    retval->insertObject("Bounds", std::move(bounds));
+    retval->insertObject("Functions", std::move(functions));
+
+    return retval;
+}
+
+/* Map a value of t on the stack into [0, 1) for Repeat or Mirror tile mode. */
+static void tileModeCode(SkShader::TileMode mode,
+                         SkDynamicMemoryWStream* result) {
+    if (mode == SkShader::kRepeat_TileMode) {
+        result->writeText("dup truncate sub\n");  // Get the fractional part.
+        result->writeText("dup 0 le {1 add} if\n");  // Map (-1,0) => (0,1)
+        return;
+    }
+
+    if (mode == SkShader::kMirror_TileMode) {
+        // Map t mod 2 into [0, 1, 1, 0].
+        //               Code                     Stack
+        result->writeText("abs "                 // Map negative to positive.
+                          "dup "                 // t.s t.s
+                          "truncate "            // t.s t
+                          "dup "                 // t.s t t
+                          "cvi "                 // t.s t T
+                          "2 mod "               // t.s t (i mod 2)
+                          "1 eq "                // t.s t true|false
+                          "3 1 roll "            // true|false t.s t
+                          "sub "                 // true|false 0.s
+                          "exch "                // 0.s true|false
+                          "{1 exch sub} if\n");  // 1 - 0.s|0.s
+    }
+}
+
+/**
+ *  Returns PS function code that applies inverse perspective
+ *  to a x, y point.
+ *  The function assumes that the stack has at least two elements,
+ *  and that the top 2 elements are numeric values.
+ *  After executing this code on a PS stack, the last 2 elements are updated
+ *  while the rest of the stack is preserved intact.
+ *  inversePerspectiveMatrix is the inverse perspective matrix.
+ */
+static void apply_perspective_to_coordinates(const SkMatrix& inversePerspectiveMatrix,
+                                             SkDynamicMemoryWStream* code) {
+    if (!inversePerspectiveMatrix.hasPerspective()) {
+        return;
+    }
+
+    // Perspective matrix should be:
+    // 1   0  0
+    // 0   1  0
+    // p0 p1 p2
+
+    const SkScalar p0 = inversePerspectiveMatrix[SkMatrix::kMPersp0];
+    const SkScalar p1 = inversePerspectiveMatrix[SkMatrix::kMPersp1];
+    const SkScalar p2 = inversePerspectiveMatrix[SkMatrix::kMPersp2];
+
+    // y = y / (p2 + p0 x + p1 y)
+    // x = x / (p2 + p0 x + p1 y)
+
+    // Input on stack: x y
+    code->writeText(" dup ");             // x y y
+    SkPDFUtils::AppendScalar(p1, code);   // x y y p1
+    code->writeText(" mul "               // x y y*p1
+                    " 2 index ");         // x y y*p1 x
+    SkPDFUtils::AppendScalar(p0, code);   // x y y p1 x p0
+    code->writeText(" mul ");             // x y y*p1 x*p0
+    SkPDFUtils::AppendScalar(p2, code);   // x y y p1 x*p0 p2
+    code->writeText(" add "               // x y y*p1 x*p0+p2
+                    "add "                // x y y*p1+x*p0+p2
+                    "3 1 roll "           // y*p1+x*p0+p2 x y
+                    "2 index "            // z x y y*p1+x*p0+p2
+                    "div "                // y*p1+x*p0+p2 x y/(y*p1+x*p0+p2)
+                    "3 1 roll "           // y/(y*p1+x*p0+p2) y*p1+x*p0+p2 x
+                    "exch "               // y/(y*p1+x*p0+p2) x y*p1+x*p0+p2
+                    "div "                // y/(y*p1+x*p0+p2) x/(y*p1+x*p0+p2)
+                    "exch\n");            // x/(y*p1+x*p0+p2) y/(y*p1+x*p0+p2)
+}
+
+static void linearCode(const SkShader::GradientInfo& info,
+                       const SkMatrix& perspectiveRemover,
+                       SkDynamicMemoryWStream* function) {
+    function->writeText("{");
+
+    apply_perspective_to_coordinates(perspectiveRemover, function);
+
+    function->writeText("pop\n");  // Just ditch the y value.
+    tileModeCode(info.fTileMode, function);
+    gradient_function_code(info, function);
+    function->writeText("}");
+}
+
+static void radialCode(const SkShader::GradientInfo& info,
+                       const SkMatrix& perspectiveRemover,
+                       SkDynamicMemoryWStream* function) {
+    function->writeText("{");
+
+    apply_perspective_to_coordinates(perspectiveRemover, function);
+
+    // Find the distance from the origin.
+    function->writeText("dup "      // x y y
+                    "mul "      // x y^2
+                    "exch "     // y^2 x
+                    "dup "      // y^2 x x
+                    "mul "      // y^2 x^2
+                    "add "      // y^2+x^2
+                    "sqrt\n");  // sqrt(y^2+x^2)
+
+    tileModeCode(info.fTileMode, function);
+    gradient_function_code(info, function);
+    function->writeText("}");
+}
+
+/* Conical gradient shader, based on the Canvas spec for radial gradients
+   See: http://www.w3.org/TR/2dcontext/#dom-context-2d-createradialgradient
+ */
+static void twoPointConicalCode(const SkShader::GradientInfo& info,
+                                const SkMatrix& perspectiveRemover,
+                                SkDynamicMemoryWStream* function) {
+    SkScalar dx = info.fPoint[1].fX - info.fPoint[0].fX;
+    SkScalar dy = info.fPoint[1].fY - info.fPoint[0].fY;
+    SkScalar r0 = info.fRadius[0];
+    SkScalar dr = info.fRadius[1] - info.fRadius[0];
+    SkScalar a = dx * dx + dy * dy - dr * dr;
+
+    // First compute t, if the pixel falls outside the cone, then we'll end
+    // with 'false' on the stack, otherwise we'll push 'true' with t below it
+
+    // We start with a stack of (x y), copy it and then consume one copy in
+    // order to calculate b and the other to calculate c.
+    function->writeText("{");
+
+    apply_perspective_to_coordinates(perspectiveRemover, function);
+
+    function->writeText("2 copy ");
+
+    // Calculate b and b^2; b = -2 * (y * dy + x * dx + r0 * dr).
+    SkPDFUtils::AppendScalar(dy, function);
+    function->writeText(" mul exch ");
+    SkPDFUtils::AppendScalar(dx, function);
+    function->writeText(" mul add ");
+    SkPDFUtils::AppendScalar(r0 * dr, function);
+    function->writeText(" add -2 mul dup dup mul\n");
+
+    // c = x^2 + y^2 + radius0^2
+    function->writeText("4 2 roll dup mul exch dup mul add ");
+    SkPDFUtils::AppendScalar(r0 * r0, function);
+    function->writeText(" sub dup 4 1 roll\n");
+
+    // Contents of the stack at this point: c, b, b^2, c
+
+    // if a = 0, then we collapse to a simpler linear case
+    if (a == 0) {
+
+        // t = -c/b
+        function->writeText("pop pop div neg dup ");
+
+        // compute radius(t)
+        SkPDFUtils::AppendScalar(dr, function);
+        function->writeText(" mul ");
+        SkPDFUtils::AppendScalar(r0, function);
+        function->writeText(" add\n");
+
+        // if r(t) < 0, then it's outside the cone
+        function->writeText("0 lt {pop false} {true} ifelse\n");
+
+    } else {
+
+        // quadratic case: the Canvas spec wants the largest
+        // root t for which radius(t) > 0
+
+        // compute the discriminant (b^2 - 4ac)
+        SkPDFUtils::AppendScalar(a * 4, function);
+        function->writeText(" mul sub dup\n");
+
+        // if d >= 0, proceed
+        function->writeText("0 ge {\n");
+
+        // an intermediate value we'll use to compute the roots:
+        // q = -0.5 * (b +/- sqrt(d))
+        function->writeText("sqrt exch dup 0 lt {exch -1 mul} if");
+        function->writeText(" add -0.5 mul dup\n");
+
+        // first root = q / a
+        SkPDFUtils::AppendScalar(a, function);
+        function->writeText(" div\n");
+
+        // second root = c / q
+        function->writeText("3 1 roll div\n");
+
+        // put the larger root on top of the stack
+        function->writeText("2 copy gt {exch} if\n");
+
+        // compute radius(t) for larger root
+        function->writeText("dup ");
+        SkPDFUtils::AppendScalar(dr, function);
+        function->writeText(" mul ");
+        SkPDFUtils::AppendScalar(r0, function);
+        function->writeText(" add\n");
+
+        // if r(t) > 0, we have our t, pop off the smaller root and we're done
+        function->writeText(" 0 gt {exch pop true}\n");
+
+        // otherwise, throw out the larger one and try the smaller root
+        function->writeText("{pop dup\n");
+        SkPDFUtils::AppendScalar(dr, function);
+        function->writeText(" mul ");
+        SkPDFUtils::AppendScalar(r0, function);
+        function->writeText(" add\n");
+
+        // if r(t) < 0, push false, otherwise the smaller root is our t
+        function->writeText("0 le {pop false} {true} ifelse\n");
+        function->writeText("} ifelse\n");
+
+        // d < 0, clear the stack and push false
+        function->writeText("} {pop pop pop false} ifelse\n");
+    }
+
+    // if the pixel is in the cone, proceed to compute a color
+    function->writeText("{");
+    tileModeCode(info.fTileMode, function);
+    gradient_function_code(info, function);
+
+    // otherwise, just write black
+    function->writeText("} {0 0 0} ifelse }");
+}
+
+static void sweepCode(const SkShader::GradientInfo& info,
+                          const SkMatrix& perspectiveRemover,
+                          SkDynamicMemoryWStream* function) {
+    function->writeText("{exch atan 360 div\n");
+    tileModeCode(info.fTileMode, function);
+    gradient_function_code(info, function);
+    function->writeText("}");
+}
+
+
+// catch cases where the inner just touches the outer circle
+// and make the inner circle just inside the outer one to match raster
+static void FixUpRadius(const SkPoint& p1, SkScalar& r1, const SkPoint& p2, SkScalar& r2) {
+    // detect touching circles
+    SkScalar distance = SkPoint::Distance(p1, p2);
+    SkScalar subtractRadii = fabs(r1 - r2);
+    if (fabs(distance - subtractRadii) < 0.002f) {
+        if (r1 > r2) {
+            r1 += 0.002f;
+        } else {
+            r2 += 0.002f;
+        }
+    }
+}
+
+// Finds affine and persp such that in = affine * persp.
+// but it returns the inverse of perspective matrix.
+static bool split_perspective(const SkMatrix in, SkMatrix* affine,
+                              SkMatrix* perspectiveInverse) {
+    const SkScalar p2 = in[SkMatrix::kMPersp2];
+
+    if (SkScalarNearlyZero(p2)) {
+        return false;
+    }
+
+    const SkScalar zero = SkIntToScalar(0);
+    const SkScalar one = SkIntToScalar(1);
+
+    const SkScalar sx = in[SkMatrix::kMScaleX];
+    const SkScalar kx = in[SkMatrix::kMSkewX];
+    const SkScalar tx = in[SkMatrix::kMTransX];
+    const SkScalar ky = in[SkMatrix::kMSkewY];
+    const SkScalar sy = in[SkMatrix::kMScaleY];
+    const SkScalar ty = in[SkMatrix::kMTransY];
+    const SkScalar p0 = in[SkMatrix::kMPersp0];
+    const SkScalar p1 = in[SkMatrix::kMPersp1];
+
+    // Perspective matrix would be:
+    // 1  0  0
+    // 0  1  0
+    // p0 p1 p2
+    // But we need the inverse of persp.
+    perspectiveInverse->setAll(one,          zero,       zero,
+                               zero,         one,        zero,
+                               -p0/p2,     -p1/p2,     1/p2);
+
+    affine->setAll(sx - p0 * tx / p2,       kx - p1 * tx / p2,      tx / p2,
+                   ky - p0 * ty / p2,       sy - p1 * ty / p2,      ty / p2,
+                   zero,                    zero,                   one);
+
+    return true;
+}
+
+static sk_sp<SkPDFArray> make_range_object() {
+    auto range = sk_make_sp<SkPDFArray>();
+    range->reserve(6);
+    range->appendInt(0);
+    range->appendInt(1);
+    range->appendInt(0);
+    range->appendInt(1);
+    range->appendInt(0);
+    range->appendInt(1);
+    return range;
+}
+
+static sk_sp<SkPDFStream> make_ps_function(
+        std::unique_ptr<SkStreamAsset> psCode,
+        sk_sp<SkPDFArray> domain,
+        sk_sp<SkPDFObject> range) {
+    auto result = sk_make_sp<SkPDFStream>(std::move(psCode));
+    result->dict()->insertInt("FunctionType", 4);
+    result->dict()->insertObject("Domain", std::move(domain));
+    result->dict()->insertObject("Range", std::move(range));
+    return result;
+}
+
+
+static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
+                                             const SkPDFGradientShader::Key& state) {
+    SkPoint transformPoints[2];
+    const SkShader::GradientInfo& info = state.fInfo;
+    SkMatrix finalMatrix = state.fCanvasTransform;
+    finalMatrix.preConcat(state.fShaderTransform);
+
+    bool doStitchFunctions = (state.fType == SkShader::kLinear_GradientType ||
+                              state.fType == SkShader::kRadial_GradientType ||
+                              state.fType == SkShader::kConical_GradientType) &&
+                             info.fTileMode == SkShader::kClamp_TileMode &&
+                             !finalMatrix.hasPerspective();
+
+    auto domain = sk_make_sp<SkPDFArray>();
+
+    int32_t shadingType = 1;
+    auto pdfShader = sk_make_sp<SkPDFDict>();
+    // The two point radial gradient further references
+    // state.fInfo
+    // in translating from x, y coordinates to the t parameter. So, we have
+    // to transform the points and radii according to the calculated matrix.
+    if (doStitchFunctions) {
+        pdfShader->insertObject("Function", gradientStitchCode(info));
+        shadingType = (state.fType == SkShader::kLinear_GradientType) ? 2 : 3;
+
+        auto extend = sk_make_sp<SkPDFArray>();
+        extend->reserve(2);
+        extend->appendBool(true);
+        extend->appendBool(true);
+        pdfShader->insertObject("Extend", std::move(extend));
+
+        auto coords = sk_make_sp<SkPDFArray>();
+        if (state.fType == SkShader::kConical_GradientType) {
+            coords->reserve(6);
+            SkScalar r1 = info.fRadius[0];
+            SkScalar r2 = info.fRadius[1];
+            SkPoint pt1 = info.fPoint[0];
+            SkPoint pt2 = info.fPoint[1];
+            FixUpRadius(pt1, r1, pt2, r2);
+
+            coords->appendScalar(pt1.fX);
+            coords->appendScalar(pt1.fY);
+            coords->appendScalar(r1);
+
+            coords->appendScalar(pt2.fX);
+            coords->appendScalar(pt2.fY);
+            coords->appendScalar(r2);
+        } else if (state.fType == SkShader::kRadial_GradientType) {
+            coords->reserve(6);
+            const SkPoint& pt1 = info.fPoint[0];
+
+            coords->appendScalar(pt1.fX);
+            coords->appendScalar(pt1.fY);
+            coords->appendScalar(0);
+
+            coords->appendScalar(pt1.fX);
+            coords->appendScalar(pt1.fY);
+            coords->appendScalar(info.fRadius[0]);
+        } else {
+            coords->reserve(4);
+            const SkPoint& pt1 = info.fPoint[0];
+            const SkPoint& pt2 = info.fPoint[1];
+
+            coords->appendScalar(pt1.fX);
+            coords->appendScalar(pt1.fY);
+
+            coords->appendScalar(pt2.fX);
+            coords->appendScalar(pt2.fY);
+        }
+
+        pdfShader->insertObject("Coords", std::move(coords));
+    } else {
+        // Depending on the type of the gradient, we want to transform the
+        // coordinate space in different ways.
+        transformPoints[0] = info.fPoint[0];
+        transformPoints[1] = info.fPoint[1];
+        switch (state.fType) {
+            case SkShader::kLinear_GradientType:
+                break;
+            case SkShader::kRadial_GradientType:
+                transformPoints[1] = transformPoints[0];
+                transformPoints[1].fX += info.fRadius[0];
+                break;
+            case SkShader::kConical_GradientType: {
+                transformPoints[1] = transformPoints[0];
+                transformPoints[1].fX += SK_Scalar1;
+                break;
+            }
+            case SkShader::kSweep_GradientType:
+                transformPoints[1] = transformPoints[0];
+                transformPoints[1].fX += SK_Scalar1;
+                break;
+            case SkShader::kColor_GradientType:
+            case SkShader::kNone_GradientType:
+            default:
+                return nullptr;
+        }
+
+        // Move any scaling (assuming a unit gradient) or translation
+        // (and rotation for linear gradient), of the final gradient from
+        // info.fPoints to the matrix (updating bbox appropriately).  Now
+        // the gradient can be drawn on on the unit segment.
+        SkMatrix mapperMatrix;
+        unit_to_points_matrix(transformPoints, &mapperMatrix);
+
+        finalMatrix.preConcat(mapperMatrix);
+
+        // Preserves as much as posible in the final matrix, and only removes
+        // the perspective. The inverse of the perspective is stored in
+        // perspectiveInverseOnly matrix and has 3 useful numbers
+        // (p0, p1, p2), while everything else is either 0 or 1.
+        // In this way the shader will handle it eficiently, with minimal code.
+        SkMatrix perspectiveInverseOnly = SkMatrix::I();
+        if (finalMatrix.hasPerspective()) {
+            if (!split_perspective(finalMatrix,
+                                   &finalMatrix, &perspectiveInverseOnly)) {
+                return nullptr;
+            }
+        }
+
+        SkRect bbox;
+        bbox.set(state.fBBox);
+        if (!SkPDFUtils::InverseTransformBBox(finalMatrix, &bbox)) {
+            return nullptr;
+        }
+        domain->reserve(4);
+        domain->appendScalar(bbox.fLeft);
+        domain->appendScalar(bbox.fRight);
+        domain->appendScalar(bbox.fTop);
+        domain->appendScalar(bbox.fBottom);
+
+        SkDynamicMemoryWStream functionCode;
+
+        SkShader::GradientInfo infoCopy = info;
+
+        if (state.fType == SkShader::kConical_GradientType) {
+            SkMatrix inverseMapperMatrix;
+            if (!mapperMatrix.invert(&inverseMapperMatrix)) {
+                return nullptr;
+            }
+            inverseMapperMatrix.mapPoints(infoCopy.fPoint, 2);
+            infoCopy.fRadius[0] = inverseMapperMatrix.mapRadius(info.fRadius[0]);
+            infoCopy.fRadius[1] = inverseMapperMatrix.mapRadius(info.fRadius[1]);
+        }
+        switch (state.fType) {
+            case SkShader::kLinear_GradientType:
+                linearCode(infoCopy, perspectiveInverseOnly, &functionCode);
+                break;
+            case SkShader::kRadial_GradientType:
+                radialCode(infoCopy, perspectiveInverseOnly, &functionCode);
+                break;
+            case SkShader::kConical_GradientType:
+                twoPointConicalCode(infoCopy, perspectiveInverseOnly, &functionCode);
+                break;
+            case SkShader::kSweep_GradientType:
+                sweepCode(infoCopy, perspectiveInverseOnly, &functionCode);
+                break;
+            default:
+                SkASSERT(false);
+        }
+        pdfShader->insertObject("Domain", domain);
+
+        sk_sp<SkPDFArray>& rangeObject = canon->fRangeObject;
+        if (!rangeObject) {
+            rangeObject = make_range_object();
+        }
+        pdfShader->insertObjRef("Function",
+                                make_ps_function(functionCode.detachAsStream(), std::move(domain),
+                                                 rangeObject));
+    }
+
+    pdfShader->insertInt("ShadingType", shadingType);
+    pdfShader->insertName("ColorSpace", "DeviceRGB");
+
+    auto pdfFunctionShader = sk_make_sp<SkPDFDict>("Pattern");
+    pdfFunctionShader->insertInt("PatternType", 2);
+    pdfFunctionShader->insertObject("Matrix", SkPDFUtils::MatrixToArray(finalMatrix));
+    pdfFunctionShader->insertObject("Shading", std::move(pdfShader));
+
+    return pdfFunctionShader;
+}
+
+
+static sk_sp<SkPDFObject> find_function_shader(SkPDFDocument* doc,
+                                               SkPDFGradientShader::Key key) {
+    SkPDFCanon* canon = doc->canon();
+    if (sk_sp<SkPDFObject>* ptr = canon->fOpaqueGradientMap.find(key)) {
+        return *ptr;
+    }
+    sk_sp<SkPDFObject> pdfShader = make_function_shader(doc->canon(), key);
+    canon->fOpaqueGradientMap.set(std::move(key), pdfShader);
+    return pdfShader;
+}
+
+static sk_sp<SkPDFDict> get_gradient_resource_dict(SkPDFObject* functionShader,
+                                                   SkPDFObject* gState) {
+    SkTDArray<SkPDFObject*> patterns;
+    if (functionShader) {
+        patterns.push(functionShader);
+    }
+    SkTDArray<SkPDFObject*> graphicStates;
+    if (gState) {
+        graphicStates.push(gState);
+    }
+    return SkPDFResourceDict::Make(&graphicStates, &patterns, nullptr, nullptr);
+}
+
+// Creates a content stream which fills the pattern P0 across bounds.
+// @param gsIndex A graphics state resource index to apply, or <0 if no
+// graphics state to apply.
+static std::unique_ptr<SkStreamAsset> create_pattern_fill_content(int gsIndex, SkRect& bounds) {
+    SkDynamicMemoryWStream content;
+    if (gsIndex >= 0) {
+        SkPDFUtils::ApplyGraphicState(gsIndex, &content);
+    }
+    SkPDFUtils::ApplyPattern(0, &content);
+    SkPDFUtils::AppendRectangle(bounds, &content);
+    SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kEvenOdd_FillType, &content);
+    return content.detachAsStream();
+}
+
+static bool gradient_has_alpha(const SkPDFGradientShader::Key& key) {
+    SkASSERT(key.fType != SkShader::kNone_GradientType);
+    for (int i = 0; i < key.fInfo.fColorCount; i++) {
+        if ((SkAlpha)SkColorGetA(key.fInfo.fColors[i]) != SK_AlphaOPAQUE) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// warning: does not set fHash on new key.  (Both callers need to change fields.)
+static SkPDFGradientShader::Key clone_key(const SkPDFGradientShader::Key& k) {
+    SkPDFGradientShader::Key clone = {
+        k.fType,
+        k.fInfo,  // change pointers later.
+        std::unique_ptr<SkColor[]>(new SkColor[k.fInfo.fColorCount]),
+        std::unique_ptr<SkScalar[]>(new SkScalar[k.fInfo.fColorCount]),
+        k.fCanvasTransform,
+        k.fShaderTransform,
+        k.fBBox, 0};
+    clone.fInfo.fColors = clone.fColors.get();
+    clone.fInfo.fColorOffsets = clone.fStops.get();
+    for (int i = 0; i < clone.fInfo.fColorCount; i++) {
+        clone.fInfo.fColorOffsets[i] = k.fInfo.fColorOffsets[i];
+        clone.fInfo.fColors[i] = k.fInfo.fColors[i];
+    }
+    return clone;
+}
+
+static sk_sp<SkPDFObject> create_smask_graphic_state(SkPDFDocument* doc,
+                                                     const SkPDFGradientShader::Key& state) {
+    SkASSERT(state.fType != SkShader::kNone_GradientType);
+    SkPDFGradientShader::Key luminosityState = clone_key(state);
+    for (int i = 0; i < luminosityState.fInfo.fColorCount; i++) {
+        SkAlpha alpha = SkColorGetA(luminosityState.fInfo.fColors[i]);
+        luminosityState.fInfo.fColors[i] = SkColorSetARGB(255, alpha, alpha, alpha);
+    }
+    luminosityState.fHash = hash(luminosityState);
+
+    SkASSERT(!gradient_has_alpha(luminosityState));
+    sk_sp<SkPDFObject> luminosityShader = find_function_shader(doc, std::move(luminosityState));
+    sk_sp<SkPDFDict> resources = get_gradient_resource_dict(luminosityShader.get(), nullptr);
+    SkRect bbox = SkRect::Make(state.fBBox);
+    sk_sp<SkPDFObject> alphaMask = SkPDFMakeFormXObject(create_pattern_fill_content(-1, bbox),
+                                                        SkPDFUtils::RectToArray(bbox),
+                                                        std::move(resources),
+                                                        SkMatrix::I(),
+                                                        "DeviceRGB");
+    return SkPDFGraphicState::GetSMaskGraphicState(
+            std::move(alphaMask), false,
+            SkPDFGraphicState::kLuminosity_SMaskMode, doc->canon());
+}
+
+static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
+                                                     const SkPDFGradientShader::Key& state) {
+    SkASSERT(state.fType != SkShader::kNone_GradientType);
+    SkPDFGradientShader::Key opaqueState = clone_key(state);
+    for (int i = 0; i < opaqueState.fInfo.fColorCount; i++) {
+        opaqueState.fInfo.fColors[i] = SkColorSetA(opaqueState.fInfo.fColors[i], SK_AlphaOPAQUE);
+    }
+    opaqueState.fHash = hash(opaqueState);
+
+    SkASSERT(!gradient_has_alpha(opaqueState));
+    SkRect bbox = SkRect::Make(state.fBBox);
+    sk_sp<SkPDFObject> colorShader = find_function_shader(doc, std::move(opaqueState));
+    if (!colorShader) {
+        return nullptr;
+    }
+
+    // Create resource dict with alpha graphics state as G0 and
+    // pattern shader as P0, then write content stream.
+    sk_sp<SkPDFObject> alphaGs = create_smask_graphic_state(doc, state);
+
+    sk_sp<SkPDFDict> resourceDict =
+            get_gradient_resource_dict(colorShader.get(), alphaGs.get());
+
+    std::unique_ptr<SkStreamAsset> colorStream(create_pattern_fill_content(0, bbox));
+    auto alphaFunctionShader = sk_make_sp<SkPDFStream>(std::move(colorStream));
+
+    SkPDFUtils::PopulateTilingPatternDict(alphaFunctionShader->dict(), bbox,
+                                 std::move(resourceDict), SkMatrix::I());
+    return alphaFunctionShader;
+}
+
+
+
+static SkPDFGradientShader::Key make_key(const SkShader* shader,
+                                         const SkMatrix& canvasTransform,
+                                         const SkIRect& bbox) {
+    SkPDFGradientShader::Key key = {
+         SkShader::kNone_GradientType,
+         {0, nullptr, nullptr, {{0, 0}, {0, 0}}, {0, 0}, SkShader::kClamp_TileMode, 0},
+         nullptr,
+         nullptr,
+         canvasTransform,
+         SkPDFUtils::GetShaderLocalMatrix(shader),
+         bbox, 0};
+    key.fType = shader->asAGradient(&key.fInfo);
+    SkASSERT(SkShader::kNone_GradientType != key.fType);
+    SkASSERT(key.fInfo.fColorCount > 0);
+    key.fColors.reset(new SkColor[key.fInfo.fColorCount]);
+    key.fStops.reset(new SkScalar[key.fInfo.fColorCount]);
+    key.fInfo.fColors = key.fColors.get();
+    key.fInfo.fColorOffsets = key.fStops.get();
+    (void)shader->asAGradient(&key.fInfo);
+    key.fHash = hash(key);
+    return key;
+}
+
+sk_sp<SkPDFObject> SkPDFGradientShader::Make(SkPDFDocument* doc,
+                                             SkShader* shader,
+                                             const SkMatrix& canvasTransform,
+                                             const SkIRect& bbox) {
+    SkASSERT(shader);
+    SkASSERT(SkShader::kNone_GradientType != shader->asAGradient(nullptr));
+    SkPDFGradientShader::Key key = make_key(shader, canvasTransform, bbox);
+    // TODO(halcanary): measure to see if one hashmap is as fast as two.
+    if (gradient_has_alpha(key)) {
+        SkPDFCanon* canon = doc->canon();
+        if (sk_sp<SkPDFObject>* ptr = canon->fAlphaGradientMap.find(key)) {
+            return *ptr;
+        }
+        sk_sp<SkPDFObject> pdfShader = make_alpha_function_shader(doc, key);
+        canon->fAlphaGradientMap.set(std::move(key), pdfShader);
+        return pdfShader;
+    } else {
+        return find_function_shader(doc, std::move(key));
+    }
+}
+
+
diff --git a/src/pdf/SkPDFGradientShader.h b/src/pdf/SkPDFGradientShader.h
new file mode 100644
index 0000000..0cc059c
--- /dev/null
+++ b/src/pdf/SkPDFGradientShader.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPDFGradientShader_DEFINED
+#define SkPDFGradientShader_DEFINED
+
+#include "SkPDFTypes.h"
+#include "SkPDFUtils.h"
+#include "SkShader.h"
+
+class SkMatrix;
+class SkPDFDocument;
+struct SkIRect;
+
+namespace SkPDFGradientShader {
+
+sk_sp<SkPDFObject> Make(SkPDFDocument* doc,
+                        SkShader* shader,
+                        const SkMatrix& matrix,
+                        const SkIRect& surfaceBBox);
+
+struct Key {
+    SkShader::GradientType fType;
+    SkShader::GradientInfo fInfo;
+    std::unique_ptr<SkColor[]> fColors;
+    std::unique_ptr<SkScalar[]> fStops;
+    SkMatrix fCanvasTransform;
+    SkMatrix fShaderTransform;
+    SkIRect fBBox;
+    uint32_t fHash;
+};
+
+struct KeyHash {
+    uint32_t operator()(const Key& k) const { return k.fHash; }
+};
+
+using HashMap = SkTHashMap<Key, sk_sp<SkPDFObject>, KeyHash>;
+
+inline bool operator==(const SkShader::GradientInfo& u, const SkShader::GradientInfo& v) {
+    return u.fColorCount    == v.fColorCount
+        && u.fPoint[0]      == v.fPoint[0]
+        && u.fPoint[1]      == v.fPoint[1]
+        && u.fRadius[0]     == v.fRadius[0]
+        && u.fRadius[1]     == v.fRadius[1]
+        && u.fTileMode      == v.fTileMode
+        && u.fGradientFlags == v.fGradientFlags
+        && SkPackedArrayEqual(u.fColors, v.fColors, u.fColorCount)
+        && SkPackedArrayEqual(u.fColorOffsets, v.fColorOffsets, u.fColorCount);
+}
+
+inline bool operator==(const Key& u, const Key& v) {
+    SkASSERT(u.fInfo.fColors       == u.fColors.get());
+    SkASSERT(u.fInfo.fColorOffsets == u.fStops.get());
+    SkASSERT(v.fInfo.fColors       == v.fColors.get());
+    SkASSERT(v.fInfo.fColorOffsets == v.fStops.get());
+    return u.fType            == v.fType
+        && u.fInfo            == v.fInfo
+        && u.fCanvasTransform == v.fCanvasTransform
+        && u.fShaderTransform == v.fShaderTransform
+        && u.fBBox            == v.fBBox;
+}
+inline bool operator!=(const Key& u, const Key& v) { return !(u == v); }
+
+}  // namespace SkPDFGradientShader
+#endif  // SkPDFGradientShader_DEFINED
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 7369abf..44cc27b 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -13,6 +13,7 @@
 #include "SkPDFDevice.h"
 #include "SkPDFDocument.h"
 #include "SkPDFFormXObject.h"
+#include "SkPDFGradientShader.h"
 #include "SkPDFGraphicState.h"
 #include "SkPDFResourceDict.h"
 #include "SkPDFUtils.h"
@@ -20,936 +21,13 @@
 #include "SkStream.h"
 #include "SkTemplates.h"
 
-static bool inverse_transform_bbox(const SkMatrix& matrix, SkRect* bbox) {
-    SkMatrix inverse;
-    if (!matrix.invert(&inverse)) {
-        return false;
-    }
-    inverse.mapRect(bbox);
-    return true;
-}
 
-static void unitToPointsMatrix(const SkPoint pts[2], SkMatrix* matrix) {
-    SkVector    vec = pts[1] - pts[0];
-    SkScalar    mag = vec.length();
-    SkScalar    inv = mag ? SkScalarInvert(mag) : 0;
-
-    vec.scale(inv);
-    matrix->setSinCos(vec.fY, vec.fX);
-    matrix->preScale(mag, mag);
-    matrix->postTranslate(pts[0].fX, pts[0].fY);
-}
-
-static const int kColorComponents = 3;
-typedef uint8_t ColorTuple[kColorComponents];
-
-/* Assumes t + startOffset is on the stack and does a linear interpolation on t
-   between startOffset and endOffset from prevColor to curColor (for each color
-   component), leaving the result in component order on the stack. It assumes
-   there are always 3 components per color.
-   @param range                  endOffset - startOffset
-   @param curColor[components]   The current color components.
-   @param prevColor[components]  The previous color components.
-   @param result                 The result ps function.
- */
-static void interpolateColorCode(SkScalar range, const ColorTuple& curColor,
-                                 const ColorTuple& prevColor,
-                                 SkDynamicMemoryWStream* result) {
-    SkASSERT(range != SkIntToScalar(0));
-
-    // Figure out how to scale each color component.
-    SkScalar multiplier[kColorComponents];
-    for (int i = 0; i < kColorComponents; i++) {
-        static const SkScalar kColorScale = SkScalarInvert(255);
-        multiplier[i] = kColorScale * (curColor[i] - prevColor[i]) / range;
-    }
-
-    // Calculate when we no longer need to keep a copy of the input parameter t.
-    // If the last component to use t is i, then dupInput[0..i - 1] = true
-    // and dupInput[i .. components] = false.
-    bool dupInput[kColorComponents];
-    dupInput[kColorComponents - 1] = false;
-    for (int i = kColorComponents - 2; i >= 0; i--) {
-        dupInput[i] = dupInput[i + 1] || multiplier[i + 1] != 0;
-    }
-
-    if (!dupInput[0] && multiplier[0] == 0) {
-        result->writeText("pop ");
-    }
-
-    for (int i = 0; i < kColorComponents; i++) {
-        // If the next components needs t and this component will consume a
-        // copy, make another copy.
-        if (dupInput[i] && multiplier[i] != 0) {
-            result->writeText("dup ");
-        }
-
-        if (multiplier[i] == 0) {
-            SkPDFUtils::AppendColorComponent(prevColor[i], result);
-            result->writeText(" ");
-        } else {
-            if (multiplier[i] != 1) {
-                SkPDFUtils::AppendScalar(multiplier[i], result);
-                result->writeText(" mul ");
-            }
-            if (prevColor[i] != 0) {
-                SkPDFUtils::AppendColorComponent(prevColor[i], result);
-                result->writeText(" add ");
-            }
-        }
-
-        if (dupInput[i]) {
-            result->writeText("exch\n");
-        }
-    }
-}
-
-/* Generate Type 4 function code to map t=[0,1) to the passed gradient,
-   clamping at the edges of the range.  The generated code will be of the form:
-       if (t < 0) {
-           return colorData[0][r,g,b];
-       } else {
-           if (t < info.fColorOffsets[1]) {
-               return linearinterpolation(colorData[0][r,g,b],
-                                          colorData[1][r,g,b]);
-           } else {
-               if (t < info.fColorOffsets[2]) {
-                   return linearinterpolation(colorData[1][r,g,b],
-                                              colorData[2][r,g,b]);
-               } else {
-
-                ...    } else {
-                           return colorData[info.fColorCount - 1][r,g,b];
-                       }
-                ...
-           }
-       }
- */
-static void gradientFunctionCode(const SkShader::GradientInfo& info,
-                                 SkDynamicMemoryWStream* result) {
-    /* We want to linearly interpolate from the previous color to the next.
-       Scale the colors from 0..255 to 0..1 and determine the multipliers
-       for interpolation.
-       C{r,g,b}(t, section) = t - offset_(section-1) + t * Multiplier{r,g,b}.
-     */
-
-    SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(info.fColorCount);
-    ColorTuple *colorData = colorDataAlloc.get();
-    for (int i = 0; i < info.fColorCount; i++) {
-        colorData[i][0] = SkColorGetR(info.fColors[i]);
-        colorData[i][1] = SkColorGetG(info.fColors[i]);
-        colorData[i][2] = SkColorGetB(info.fColors[i]);
-    }
-
-    // Clamp the initial color.
-    result->writeText("dup 0 le {pop ");
-    SkPDFUtils::AppendColorComponent(colorData[0][0], result);
-    result->writeText(" ");
-    SkPDFUtils::AppendColorComponent(colorData[0][1], result);
-    result->writeText(" ");
-    SkPDFUtils::AppendColorComponent(colorData[0][2], result);
-    result->writeText(" }\n");
-
-    // The gradient colors.
-    int gradients = 0;
-    for (int i = 1 ; i < info.fColorCount; i++) {
-        if (info.fColorOffsets[i] == info.fColorOffsets[i - 1]) {
-            continue;
-        }
-        gradients++;
-
-        result->writeText("{dup ");
-        SkPDFUtils::AppendScalar(info.fColorOffsets[i], result);
-        result->writeText(" le {");
-        if (info.fColorOffsets[i - 1] != 0) {
-            SkPDFUtils::AppendScalar(info.fColorOffsets[i - 1], result);
-            result->writeText(" sub\n");
-        }
-
-        interpolateColorCode(info.fColorOffsets[i] - info.fColorOffsets[i - 1],
-                             colorData[i], colorData[i - 1], result);
-        result->writeText("}\n");
-    }
-
-    // Clamp the final color.
-    result->writeText("{pop ");
-    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][0], result);
-    result->writeText(" ");
-    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][1], result);
-    result->writeText(" ");
-    SkPDFUtils::AppendColorComponent(colorData[info.fColorCount - 1][2], result);
-
-    for (int i = 0 ; i < gradients + 1; i++) {
-        result->writeText("} ifelse\n");
-    }
-}
-
-static sk_sp<SkPDFDict> createInterpolationFunction(const ColorTuple& color1,
-                                                    const ColorTuple& color2) {
-    auto retval = sk_make_sp<SkPDFDict>();
-
-    auto c0 = sk_make_sp<SkPDFArray>();
-    c0->appendColorComponent(color1[0]);
-    c0->appendColorComponent(color1[1]);
-    c0->appendColorComponent(color1[2]);
-    retval->insertObject("C0", std::move(c0));
-
-    auto c1 = sk_make_sp<SkPDFArray>();
-    c1->appendColorComponent(color2[0]);
-    c1->appendColorComponent(color2[1]);
-    c1->appendColorComponent(color2[2]);
-    retval->insertObject("C1", std::move(c1));
-
-    auto domain = sk_make_sp<SkPDFArray>();
-    domain->appendScalar(0);
-    domain->appendScalar(1.0f);
-    retval->insertObject("Domain", std::move(domain));
-
-    retval->insertInt("FunctionType", 2);
-    retval->insertScalar("N", 1.0f);
-
-    return retval;
-}
-
-static sk_sp<SkPDFDict> gradientStitchCode(const SkShader::GradientInfo& info) {
-    auto retval = sk_make_sp<SkPDFDict>();
-
-    // normalize color stops
-    int colorCount = info.fColorCount;
-    SkTDArray<SkColor>    colors(info.fColors, colorCount);
-    SkTDArray<SkScalar>   colorOffsets(info.fColorOffsets, colorCount);
-
-    int i = 1;
-    while (i < colorCount - 1) {
-        // ensure stops are in order
-        if (colorOffsets[i - 1] > colorOffsets[i]) {
-            colorOffsets[i] = colorOffsets[i - 1];
-        }
-
-        // remove points that are between 2 coincident points
-        if ((colorOffsets[i - 1] == colorOffsets[i]) && (colorOffsets[i] == colorOffsets[i + 1])) {
-            colorCount -= 1;
-            colors.remove(i);
-            colorOffsets.remove(i);
-        } else {
-            i++;
-        }
-    }
-    // find coincident points and slightly move them over
-    for (i = 1; i < colorCount - 1; i++) {
-        if (colorOffsets[i - 1] == colorOffsets[i]) {
-            colorOffsets[i] += 0.00001f;
-        }
-    }
-    // check if last 2 stops coincide
-    if (colorOffsets[i - 1] == colorOffsets[i]) {
-        colorOffsets[i - 1] -= 0.00001f;
-    }
-
-    SkAutoSTMalloc<4, ColorTuple> colorDataAlloc(colorCount);
-    ColorTuple *colorData = colorDataAlloc.get();
-    for (int i = 0; i < colorCount; i++) {
-        colorData[i][0] = SkColorGetR(colors[i]);
-        colorData[i][1] = SkColorGetG(colors[i]);
-        colorData[i][2] = SkColorGetB(colors[i]);
-    }
-
-    // no need for a stitch function if there are only 2 stops.
-    if (colorCount == 2)
-        return createInterpolationFunction(colorData[0], colorData[1]);
-
-    auto encode = sk_make_sp<SkPDFArray>();
-    auto bounds = sk_make_sp<SkPDFArray>();
-    auto functions = sk_make_sp<SkPDFArray>();
-
-    auto domain = sk_make_sp<SkPDFArray>();
-    domain->appendScalar(0);
-    domain->appendScalar(1.0f);
-    retval->insertObject("Domain", std::move(domain));
-    retval->insertInt("FunctionType", 3);
-
-    for (int i = 1; i < colorCount; i++) {
-        if (i > 1) {
-            bounds->appendScalar(colorOffsets[i-1]);
-        }
-
-        encode->appendScalar(0);
-        encode->appendScalar(1.0f);
-
-        functions->appendObject(createInterpolationFunction(colorData[i-1], colorData[i]));
-    }
-
-    retval->insertObject("Encode", std::move(encode));
-    retval->insertObject("Bounds", std::move(bounds));
-    retval->insertObject("Functions", std::move(functions));
-
-    return retval;
-}
-
-/* Map a value of t on the stack into [0, 1) for Repeat or Mirror tile mode. */
-static void tileModeCode(SkShader::TileMode mode,
-                         SkDynamicMemoryWStream* result) {
-    if (mode == SkShader::kRepeat_TileMode) {
-        result->writeText("dup truncate sub\n");  // Get the fractional part.
-        result->writeText("dup 0 le {1 add} if\n");  // Map (-1,0) => (0,1)
-        return;
-    }
-
-    if (mode == SkShader::kMirror_TileMode) {
-        // Map t mod 2 into [0, 1, 1, 0].
-        //               Code                     Stack
-        result->writeText("abs "                 // Map negative to positive.
-                          "dup "                 // t.s t.s
-                          "truncate "            // t.s t
-                          "dup "                 // t.s t t
-                          "cvi "                 // t.s t T
-                          "2 mod "               // t.s t (i mod 2)
-                          "1 eq "                // t.s t true|false
-                          "3 1 roll "            // true|false t.s t
-                          "sub "                 // true|false 0.s
-                          "exch "                // 0.s true|false
-                          "{1 exch sub} if\n");  // 1 - 0.s|0.s
-    }
-}
-
-/**
- *  Returns PS function code that applies inverse perspective
- *  to a x, y point.
- *  The function assumes that the stack has at least two elements,
- *  and that the top 2 elements are numeric values.
- *  After executing this code on a PS stack, the last 2 elements are updated
- *  while the rest of the stack is preserved intact.
- *  inversePerspectiveMatrix is the inverse perspective matrix.
- */
-static void apply_perspective_to_coordinates(
-        const SkMatrix& inversePerspectiveMatrix,
-        SkDynamicMemoryWStream* code) {
-    if (!inversePerspectiveMatrix.hasPerspective()) {
-        return;
-    }
-
-    // Perspective matrix should be:
-    // 1   0  0
-    // 0   1  0
-    // p0 p1 p2
-
-    const SkScalar p0 = inversePerspectiveMatrix[SkMatrix::kMPersp0];
-    const SkScalar p1 = inversePerspectiveMatrix[SkMatrix::kMPersp1];
-    const SkScalar p2 = inversePerspectiveMatrix[SkMatrix::kMPersp2];
-
-    // y = y / (p2 + p0 x + p1 y)
-    // x = x / (p2 + p0 x + p1 y)
-
-    // Input on stack: x y
-    code->writeText(" dup ");             // x y y
-    SkPDFUtils::AppendScalar(p1, code);   // x y y p1
-    code->writeText(" mul "               // x y y*p1
-                    " 2 index ");         // x y y*p1 x
-    SkPDFUtils::AppendScalar(p0, code);   // x y y p1 x p0
-    code->writeText(" mul ");             // x y y*p1 x*p0
-    SkPDFUtils::AppendScalar(p2, code);   // x y y p1 x*p0 p2
-    code->writeText(" add "               // x y y*p1 x*p0+p2
-                    "add "                // x y y*p1+x*p0+p2
-                    "3 1 roll "           // y*p1+x*p0+p2 x y
-                    "2 index "            // z x y y*p1+x*p0+p2
-                    "div "                // y*p1+x*p0+p2 x y/(y*p1+x*p0+p2)
-                    "3 1 roll "           // y/(y*p1+x*p0+p2) y*p1+x*p0+p2 x
-                    "exch "               // y/(y*p1+x*p0+p2) x y*p1+x*p0+p2
-                    "div "                // y/(y*p1+x*p0+p2) x/(y*p1+x*p0+p2)
-                    "exch\n");            // x/(y*p1+x*p0+p2) y/(y*p1+x*p0+p2)
-}
-
-static void linearCode(const SkShader::GradientInfo& info,
-                       const SkMatrix& perspectiveRemover,
-                       SkDynamicMemoryWStream* function) {
-    function->writeText("{");
-
-    apply_perspective_to_coordinates(perspectiveRemover, function);
-
-    function->writeText("pop\n");  // Just ditch the y value.
-    tileModeCode(info.fTileMode, function);
-    gradientFunctionCode(info, function);
-    function->writeText("}");
-}
-
-static void radialCode(const SkShader::GradientInfo& info,
-                       const SkMatrix& perspectiveRemover,
-                       SkDynamicMemoryWStream* function) {
-    function->writeText("{");
-
-    apply_perspective_to_coordinates(perspectiveRemover, function);
-
-    // Find the distance from the origin.
-    function->writeText("dup "      // x y y
-                    "mul "      // x y^2
-                    "exch "     // y^2 x
-                    "dup "      // y^2 x x
-                    "mul "      // y^2 x^2
-                    "add "      // y^2+x^2
-                    "sqrt\n");  // sqrt(y^2+x^2)
-
-    tileModeCode(info.fTileMode, function);
-    gradientFunctionCode(info, function);
-    function->writeText("}");
-}
-
-/* Conical gradient shader, based on the Canvas spec for radial gradients
-   See: http://www.w3.org/TR/2dcontext/#dom-context-2d-createradialgradient
- */
-static void twoPointConicalCode(const SkShader::GradientInfo& info,
-                                const SkMatrix& perspectiveRemover,
-                                SkDynamicMemoryWStream* function) {
-    SkScalar dx = info.fPoint[1].fX - info.fPoint[0].fX;
-    SkScalar dy = info.fPoint[1].fY - info.fPoint[0].fY;
-    SkScalar r0 = info.fRadius[0];
-    SkScalar dr = info.fRadius[1] - info.fRadius[0];
-    SkScalar a = dx * dx + dy * dy - dr * dr;
-
-    // First compute t, if the pixel falls outside the cone, then we'll end
-    // with 'false' on the stack, otherwise we'll push 'true' with t below it
-
-    // We start with a stack of (x y), copy it and then consume one copy in
-    // order to calculate b and the other to calculate c.
-    function->writeText("{");
-
-    apply_perspective_to_coordinates(perspectiveRemover, function);
-
-    function->writeText("2 copy ");
-
-    // Calculate b and b^2; b = -2 * (y * dy + x * dx + r0 * dr).
-    SkPDFUtils::AppendScalar(dy, function);
-    function->writeText(" mul exch ");
-    SkPDFUtils::AppendScalar(dx, function);
-    function->writeText(" mul add ");
-    SkPDFUtils::AppendScalar(r0 * dr, function);
-    function->writeText(" add -2 mul dup dup mul\n");
-
-    // c = x^2 + y^2 + radius0^2
-    function->writeText("4 2 roll dup mul exch dup mul add ");
-    SkPDFUtils::AppendScalar(r0 * r0, function);
-    function->writeText(" sub dup 4 1 roll\n");
-
-    // Contents of the stack at this point: c, b, b^2, c
-
-    // if a = 0, then we collapse to a simpler linear case
-    if (a == 0) {
-
-        // t = -c/b
-        function->writeText("pop pop div neg dup ");
-
-        // compute radius(t)
-        SkPDFUtils::AppendScalar(dr, function);
-        function->writeText(" mul ");
-        SkPDFUtils::AppendScalar(r0, function);
-        function->writeText(" add\n");
-
-        // if r(t) < 0, then it's outside the cone
-        function->writeText("0 lt {pop false} {true} ifelse\n");
-
-    } else {
-
-        // quadratic case: the Canvas spec wants the largest
-        // root t for which radius(t) > 0
-
-        // compute the discriminant (b^2 - 4ac)
-        SkPDFUtils::AppendScalar(a * 4, function);
-        function->writeText(" mul sub dup\n");
-
-        // if d >= 0, proceed
-        function->writeText("0 ge {\n");
-
-        // an intermediate value we'll use to compute the roots:
-        // q = -0.5 * (b +/- sqrt(d))
-        function->writeText("sqrt exch dup 0 lt {exch -1 mul} if");
-        function->writeText(" add -0.5 mul dup\n");
-
-        // first root = q / a
-        SkPDFUtils::AppendScalar(a, function);
-        function->writeText(" div\n");
-
-        // second root = c / q
-        function->writeText("3 1 roll div\n");
-
-        // put the larger root on top of the stack
-        function->writeText("2 copy gt {exch} if\n");
-
-        // compute radius(t) for larger root
-        function->writeText("dup ");
-        SkPDFUtils::AppendScalar(dr, function);
-        function->writeText(" mul ");
-        SkPDFUtils::AppendScalar(r0, function);
-        function->writeText(" add\n");
-
-        // if r(t) > 0, we have our t, pop off the smaller root and we're done
-        function->writeText(" 0 gt {exch pop true}\n");
-
-        // otherwise, throw out the larger one and try the smaller root
-        function->writeText("{pop dup\n");
-        SkPDFUtils::AppendScalar(dr, function);
-        function->writeText(" mul ");
-        SkPDFUtils::AppendScalar(r0, function);
-        function->writeText(" add\n");
-
-        // if r(t) < 0, push false, otherwise the smaller root is our t
-        function->writeText("0 le {pop false} {true} ifelse\n");
-        function->writeText("} ifelse\n");
-
-        // d < 0, clear the stack and push false
-        function->writeText("} {pop pop pop false} ifelse\n");
-    }
-
-    // if the pixel is in the cone, proceed to compute a color
-    function->writeText("{");
-    tileModeCode(info.fTileMode, function);
-    gradientFunctionCode(info, function);
-
-    // otherwise, just write black
-    function->writeText("} {0 0 0} ifelse }");
-}
-
-static void sweepCode(const SkShader::GradientInfo& info,
-                          const SkMatrix& perspectiveRemover,
-                          SkDynamicMemoryWStream* function) {
-    function->writeText("{exch atan 360 div\n");
-    tileModeCode(info.fTileMode, function);
-    gradientFunctionCode(info, function);
-    function->writeText("}");
-}
-
-static void drawBitmapMatrix(SkCanvas* canvas, const SkBitmap& bm, const SkMatrix& matrix) {
+static void draw_bitmap_matrix(SkCanvas* canvas, const SkBitmap& bm, const SkMatrix& matrix) {
     SkAutoCanvasRestore acr(canvas, true);
     canvas->concat(matrix);
     canvas->drawBitmap(bm, 0, 0);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-
-static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
-                                                     const SkPDFShader::State& state);
-static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
-                                             const SkPDFShader::State& state);
-
-static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc,
-                                            const SkPDFShader::State& state,
-                                            SkBitmap image);
-
-static sk_sp<SkPDFObject> get_pdf_shader_by_state(
-        SkPDFDocument* doc,
-        SkPDFShader::State state,
-        SkBitmap image) {
-    SkPDFCanon* canon = doc->canon();
-    if (state.fType == SkShader::kNone_GradientType && image.isNull()) {
-        // TODO(vandebo) This drops SKComposeShader on the floor.  We could
-        // handle compose shader by pulling things up to a layer, drawing with
-        // the first shader, applying the xfer mode and drawing again with the
-        // second shader, then applying the layer to the original drawing.
-        return nullptr;
-    } else if (state.fType == SkShader::kNone_GradientType) {
-        sk_sp<SkPDFObject> shader = canon->findImageShader(state);
-        if (!shader) {
-            shader = make_image_shader(doc, state, std::move(image));
-            canon->addImageShader(shader, std::move(state));
-        }
-        return shader;
-    } else if (state.GradientHasAlpha()) {
-        sk_sp<SkPDFObject> shader = canon->findAlphaShader(state);
-        if (!shader) {
-            shader = make_alpha_function_shader(doc, state);
-            canon->addAlphaShader(shader, std::move(state));
-        }
-        return shader;
-    } else {
-        sk_sp<SkPDFObject> shader = canon->findFunctionShader(state);
-        if (!shader) {
-            shader = make_function_shader(canon, state);
-            canon->addFunctionShader(shader, std::move(state));
-        }
-        return shader;
-    }
-}
-
-sk_sp<SkPDFObject> SkPDFShader::GetPDFShader(SkPDFDocument* doc,
-                                             SkShader* shader,
-                                             const SkMatrix& matrix,
-                                             const SkIRect& surfaceBBox) {
-    if (surfaceBBox.isEmpty()) {
-        return nullptr;
-    }
-    SkScalar rasterDpi = doc->rasterDpi();
-    SkScalar rasterScale = SkIntToScalar(rasterDpi) / SkPDFUtils::kDpiForRasterScaleOne;
-    SkBitmap image;
-    State state(shader, matrix, surfaceBBox, rasterScale, &image);
-    return get_pdf_shader_by_state(doc, std::move(state), std::move(image));
-}
-
-static sk_sp<SkPDFDict> get_gradient_resource_dict(
-        SkPDFObject* functionShader,
-        SkPDFObject* gState) {
-    SkTDArray<SkPDFObject*> patterns;
-    if (functionShader) {
-        patterns.push(functionShader);
-    }
-    SkTDArray<SkPDFObject*> graphicStates;
-    if (gState) {
-        graphicStates.push(gState);
-    }
-    return SkPDFResourceDict::Make(&graphicStates, &patterns, nullptr, nullptr);
-}
-
-static void populate_tiling_pattern_dict(SkPDFDict* pattern,
-                                         SkRect& bbox,
-                                         sk_sp<SkPDFDict> resources,
-                                         const SkMatrix& matrix) {
-    const int kTiling_PatternType = 1;
-    const int kColoredTilingPattern_PaintType = 1;
-    const int kConstantSpacing_TilingType = 1;
-
-    pattern->insertName("Type", "Pattern");
-    pattern->insertInt("PatternType", kTiling_PatternType);
-    pattern->insertInt("PaintType", kColoredTilingPattern_PaintType);
-    pattern->insertInt("TilingType", kConstantSpacing_TilingType);
-    pattern->insertObject("BBox", SkPDFUtils::RectToArray(bbox));
-    pattern->insertScalar("XStep", bbox.width());
-    pattern->insertScalar("YStep", bbox.height());
-    pattern->insertObject("Resources", std::move(resources));
-    if (!matrix.isIdentity()) {
-        pattern->insertObject("Matrix", SkPDFUtils::MatrixToArray(matrix));
-    }
-}
-
-/**
- * Creates a content stream which fills the pattern P0 across bounds.
- * @param gsIndex A graphics state resource index to apply, or <0 if no
- * graphics state to apply.
- */
-static std::unique_ptr<SkStreamAsset> create_pattern_fill_content(
-        int gsIndex, SkRect& bounds) {
-    SkDynamicMemoryWStream content;
-    if (gsIndex >= 0) {
-        SkPDFUtils::ApplyGraphicState(gsIndex, &content);
-    }
-    SkPDFUtils::ApplyPattern(0, &content);
-    SkPDFUtils::AppendRectangle(bounds, &content);
-    SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kEvenOdd_FillType,
-                          &content);
-
-    return std::unique_ptr<SkStreamAsset>(content.detachAsStream());
-}
-
-/**
- * Creates a ExtGState with the SMask set to the luminosityShader in
- * luminosity mode. The shader pattern extends to the bbox.
- */
-static sk_sp<SkPDFObject> create_smask_graphic_state(SkPDFDocument* doc,
-                                                     const SkPDFShader::State& state) {
-    SkRect bbox;
-    bbox.set(state.fBBox);
-
-    sk_sp<SkPDFObject> luminosityShader(
-            get_pdf_shader_by_state(doc, state.MakeAlphaToLuminosityState(), SkBitmap()));
-
-    std::unique_ptr<SkStreamAsset> alphaStream(create_pattern_fill_content(-1, bbox));
-
-    sk_sp<SkPDFDict> resources =
-        get_gradient_resource_dict(luminosityShader.get(), nullptr);
-
-    sk_sp<SkPDFObject> alphaMask =
-        SkPDFMakeFormXObject(std::move(alphaStream),
-                             SkPDFUtils::RectToArray(bbox),
-                             std::move(resources),
-                             SkMatrix::I(),
-                             "DeviceRGB");
-    return SkPDFGraphicState::GetSMaskGraphicState(
-            std::move(alphaMask), false,
-            SkPDFGraphicState::kLuminosity_SMaskMode, doc->canon());
-}
-
-static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
-                                                     const SkPDFShader::State& state) {
-    SkRect bbox;
-    bbox.set(state.fBBox);
-
-    SkPDFShader::State opaqueState(state.MakeOpaqueState());
-
-    sk_sp<SkPDFObject> colorShader(
-            get_pdf_shader_by_state(doc, std::move(opaqueState), SkBitmap()));
-    if (!colorShader) {
-        return nullptr;
-    }
-
-    // Create resource dict with alpha graphics state as G0 and
-    // pattern shader as P0, then write content stream.
-    sk_sp<SkPDFObject> alphaGs = create_smask_graphic_state(doc, state);
-
-    sk_sp<SkPDFDict> resourceDict =
-            get_gradient_resource_dict(colorShader.get(), alphaGs.get());
-
-    std::unique_ptr<SkStreamAsset> colorStream(
-            create_pattern_fill_content(0, bbox));
-    auto alphaFunctionShader = sk_make_sp<SkPDFStream>(std::move(colorStream));
-
-    populate_tiling_pattern_dict(alphaFunctionShader->dict(), bbox,
-                                 std::move(resourceDict), SkMatrix::I());
-    return alphaFunctionShader;
-}
-
-// Finds affine and persp such that in = affine * persp.
-// but it returns the inverse of perspective matrix.
-static bool split_perspective(const SkMatrix in, SkMatrix* affine,
-                              SkMatrix* perspectiveInverse) {
-    const SkScalar p2 = in[SkMatrix::kMPersp2];
-
-    if (SkScalarNearlyZero(p2)) {
-        return false;
-    }
-
-    const SkScalar zero = SkIntToScalar(0);
-    const SkScalar one = SkIntToScalar(1);
-
-    const SkScalar sx = in[SkMatrix::kMScaleX];
-    const SkScalar kx = in[SkMatrix::kMSkewX];
-    const SkScalar tx = in[SkMatrix::kMTransX];
-    const SkScalar ky = in[SkMatrix::kMSkewY];
-    const SkScalar sy = in[SkMatrix::kMScaleY];
-    const SkScalar ty = in[SkMatrix::kMTransY];
-    const SkScalar p0 = in[SkMatrix::kMPersp0];
-    const SkScalar p1 = in[SkMatrix::kMPersp1];
-
-    // Perspective matrix would be:
-    // 1  0  0
-    // 0  1  0
-    // p0 p1 p2
-    // But we need the inverse of persp.
-    perspectiveInverse->setAll(one,          zero,       zero,
-                               zero,         one,        zero,
-                               -p0/p2,     -p1/p2,     1/p2);
-
-    affine->setAll(sx - p0 * tx / p2,       kx - p1 * tx / p2,      tx / p2,
-                   ky - p0 * ty / p2,       sy - p1 * ty / p2,      ty / p2,
-                   zero,                    zero,                   one);
-
-    return true;
-}
-
-static sk_sp<SkPDFArray> make_range_object() {
-    auto range = sk_make_sp<SkPDFArray>();
-    range->reserve(6);
-    range->appendInt(0);
-    range->appendInt(1);
-    range->appendInt(0);
-    range->appendInt(1);
-    range->appendInt(0);
-    range->appendInt(1);
-    return range;
-}
-
-static sk_sp<SkPDFStream> make_ps_function(
-        std::unique_ptr<SkStreamAsset> psCode,
-        sk_sp<SkPDFArray> domain,
-        sk_sp<SkPDFObject> range) {
-    auto result = sk_make_sp<SkPDFStream>(std::move(psCode));
-    result->dict()->insertInt("FunctionType", 4);
-    result->dict()->insertObject("Domain", std::move(domain));
-    result->dict()->insertObject("Range", std::move(range));
-    return result;
-}
-
-// catch cases where the inner just touches the outer circle
-// and make the inner circle just inside the outer one to match raster
-static void FixUpRadius(const SkPoint& p1, SkScalar& r1, const SkPoint& p2, SkScalar& r2) {
-    // detect touching circles
-    SkScalar distance = SkPoint::Distance(p1, p2);
-    SkScalar subtractRadii = fabs(r1 - r2);
-    if (fabs(distance - subtractRadii) < 0.002f) {
-        if (r1 > r2) {
-            r1 += 0.002f;
-        } else {
-            r2 += 0.002f;
-        }
-    }
-}
-
-static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
-                                             const SkPDFShader::State& state) {
-    void (*codeFunction)(const SkShader::GradientInfo& info,
-                         const SkMatrix& perspectiveRemover,
-                         SkDynamicMemoryWStream* function) = nullptr;
-    SkPoint transformPoints[2];
-    const SkShader::GradientInfo* info = &state.fInfo;
-    SkMatrix finalMatrix = state.fCanvasTransform;
-    finalMatrix.preConcat(state.fShaderTransform);
-
-    bool doStitchFunctions = (state.fType == SkShader::kLinear_GradientType ||
-                              state.fType == SkShader::kRadial_GradientType ||
-                              state.fType == SkShader::kConical_GradientType) &&
-                             info->fTileMode == SkShader::kClamp_TileMode &&
-                             !finalMatrix.hasPerspective();
-
-    auto domain = sk_make_sp<SkPDFArray>();
-
-    int32_t shadingType = 1;
-    auto pdfShader = sk_make_sp<SkPDFDict>();
-    // The two point radial gradient further references
-    // state.fInfo
-    // in translating from x, y coordinates to the t parameter. So, we have
-    // to transform the points and radii according to the calculated matrix.
-    if (doStitchFunctions) {
-        pdfShader->insertObject("Function", gradientStitchCode(*info));
-        shadingType = (state.fType == SkShader::kLinear_GradientType) ? 2 : 3;
-
-        auto extend = sk_make_sp<SkPDFArray>();
-        extend->reserve(2);
-        extend->appendBool(true);
-        extend->appendBool(true);
-        pdfShader->insertObject("Extend", std::move(extend));
-
-        auto coords = sk_make_sp<SkPDFArray>();
-        if (state.fType == SkShader::kConical_GradientType) {
-            coords->reserve(6);
-            SkScalar r1 = info->fRadius[0];
-            SkScalar r2 = info->fRadius[1];
-            SkPoint pt1 = info->fPoint[0];
-            SkPoint pt2 = info->fPoint[1];
-            FixUpRadius(pt1, r1, pt2, r2);
-
-            coords->appendScalar(pt1.fX);
-            coords->appendScalar(pt1.fY);
-            coords->appendScalar(r1);
-
-            coords->appendScalar(pt2.fX);
-            coords->appendScalar(pt2.fY);
-            coords->appendScalar(r2);
-        } else if (state.fType == SkShader::kRadial_GradientType) {
-            coords->reserve(6);
-            const SkPoint& pt1 = info->fPoint[0];
-
-            coords->appendScalar(pt1.fX);
-            coords->appendScalar(pt1.fY);
-            coords->appendScalar(0);
-
-            coords->appendScalar(pt1.fX);
-            coords->appendScalar(pt1.fY);
-            coords->appendScalar(info->fRadius[0]);
-        } else {
-            coords->reserve(4);
-            const SkPoint& pt1 = info->fPoint[0];
-            const SkPoint& pt2 = info->fPoint[1];
-
-            coords->appendScalar(pt1.fX);
-            coords->appendScalar(pt1.fY);
-
-            coords->appendScalar(pt2.fX);
-            coords->appendScalar(pt2.fY);
-        }
-
-        pdfShader->insertObject("Coords", std::move(coords));
-    } else {
-        // Depending on the type of the gradient, we want to transform the
-        // coordinate space in different ways.
-        transformPoints[0] = info->fPoint[0];
-        transformPoints[1] = info->fPoint[1];
-        switch (state.fType) {
-            case SkShader::kLinear_GradientType:
-                codeFunction = &linearCode;
-                break;
-            case SkShader::kRadial_GradientType:
-                transformPoints[1] = transformPoints[0];
-                transformPoints[1].fX += info->fRadius[0];
-                codeFunction = &radialCode;
-                break;
-            case SkShader::kConical_GradientType: {
-                transformPoints[1] = transformPoints[0];
-                transformPoints[1].fX += SK_Scalar1;
-                codeFunction = &twoPointConicalCode;
-                break;
-            }
-            case SkShader::kSweep_GradientType:
-                transformPoints[1] = transformPoints[0];
-                transformPoints[1].fX += SK_Scalar1;
-                codeFunction = &sweepCode;
-                break;
-            case SkShader::kColor_GradientType:
-            case SkShader::kNone_GradientType:
-            default:
-                return nullptr;
-        }
-
-        // Move any scaling (assuming a unit gradient) or translation
-        // (and rotation for linear gradient), of the final gradient from
-        // info->fPoints to the matrix (updating bbox appropriately).  Now
-        // the gradient can be drawn on on the unit segment.
-        SkMatrix mapperMatrix;
-        unitToPointsMatrix(transformPoints, &mapperMatrix);
-
-        finalMatrix.preConcat(mapperMatrix);
-
-        // Preserves as much as posible in the final matrix, and only removes
-        // the perspective. The inverse of the perspective is stored in
-        // perspectiveInverseOnly matrix and has 3 useful numbers
-        // (p0, p1, p2), while everything else is either 0 or 1.
-        // In this way the shader will handle it eficiently, with minimal code.
-        SkMatrix perspectiveInverseOnly = SkMatrix::I();
-        if (finalMatrix.hasPerspective()) {
-            if (!split_perspective(finalMatrix,
-                                   &finalMatrix, &perspectiveInverseOnly)) {
-                return nullptr;
-            }
-        }
-
-        SkRect bbox;
-        bbox.set(state.fBBox);
-        if (!inverse_transform_bbox(finalMatrix, &bbox)) {
-            return nullptr;
-        }
-        domain->reserve(4);
-        domain->appendScalar(bbox.fLeft);
-        domain->appendScalar(bbox.fRight);
-        domain->appendScalar(bbox.fTop);
-        domain->appendScalar(bbox.fBottom);
-
-        SkDynamicMemoryWStream functionCode;
-
-        if (state.fType == SkShader::kConical_GradientType) {
-            SkShader::GradientInfo twoPointRadialInfo = *info;
-            SkMatrix inverseMapperMatrix;
-            if (!mapperMatrix.invert(&inverseMapperMatrix)) {
-                return nullptr;
-            }
-            inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2);
-            twoPointRadialInfo.fRadius[0] =
-                inverseMapperMatrix.mapRadius(info->fRadius[0]);
-            twoPointRadialInfo.fRadius[1] =
-                inverseMapperMatrix.mapRadius(info->fRadius[1]);
-            codeFunction(twoPointRadialInfo, perspectiveInverseOnly, &functionCode);
-        } else {
-            codeFunction(*info, perspectiveInverseOnly, &functionCode);
-        }
-
-        pdfShader->insertObject("Domain", domain);
-
-        std::unique_ptr<SkStreamAsset> functionStream(functionCode.detachAsStream());
-
-        sk_sp<SkPDFArray>& rangeObject = canon->fRangeObject;
-        if (!rangeObject) {
-            rangeObject = make_range_object();
-        }
-        sk_sp<SkPDFStream> function = make_ps_function(std::move(functionStream), std::move(domain),
-                                                       rangeObject);
-        pdfShader->insertObjRef("Function", std::move(function));
-    }
-
-    pdfShader->insertInt("ShadingType", shadingType);
-    pdfShader->insertName("ColorSpace", "DeviceRGB");
-
-    auto pdfFunctionShader = sk_make_sp<SkPDFDict>("Pattern");
-    pdfFunctionShader->insertInt("PatternType", 2);
-    pdfFunctionShader->insertObject("Matrix",
-                                    SkPDFUtils::MatrixToArray(finalMatrix));
-    pdfFunctionShader->insertObject("Shading", std::move(pdfShader));
-
-    return pdfFunctionShader;
-}
-
 static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc,
                                             const SkPDFShader::State& state,
                                             SkBitmap image) {
@@ -966,7 +44,7 @@
     finalMatrix.preConcat(state.fShaderTransform);
     SkRect deviceBounds;
     deviceBounds.set(state.fBBox);
-    if (!inverse_transform_bbox(finalMatrix, &deviceBounds)) {
+    if (!SkPDFUtils::InverseTransformBBox(finalMatrix, &deviceBounds)) {
         return nullptr;
     }
 
@@ -1012,14 +90,14 @@
         SkMatrix xMirror;
         xMirror.setScale(-1, 1);
         xMirror.postTranslate(2 * width, 0);
-        drawBitmapMatrix(&canvas, image, xMirror);
+        draw_bitmap_matrix(&canvas, image, xMirror);
         patternBBox.fRight += width;
     }
     if (tileModes[1] == SkShader::kMirror_TileMode) {
         SkMatrix yMirror;
         yMirror.setScale(SK_Scalar1, -SK_Scalar1);
         yMirror.postTranslate(0, 2 * height);
-        drawBitmapMatrix(&canvas, image, yMirror);
+        draw_bitmap_matrix(&canvas, image, yMirror);
         patternBBox.fBottom += height;
     }
     if (tileModes[0] == SkShader::kMirror_TileMode &&
@@ -1027,7 +105,7 @@
         SkMatrix mirror;
         mirror.setScale(-1, -1);
         mirror.postTranslate(2 * width, 2 * height);
-        drawBitmapMatrix(&canvas, image, mirror);
+        draw_bitmap_matrix(&canvas, image, mirror);
     }
 
     // Then handle Clamping, which requires expanding the pattern canvas to
@@ -1078,12 +156,12 @@
             SkMatrix leftMatrix;
             leftMatrix.setScale(-deviceBounds.left(), 1);
             leftMatrix.postTranslate(deviceBounds.left(), 0);
-            drawBitmapMatrix(&canvas, left, leftMatrix);
+            draw_bitmap_matrix(&canvas, left, leftMatrix);
 
             if (tileModes[1] == SkShader::kMirror_TileMode) {
                 leftMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                 leftMatrix.postTranslate(0, 2 * height);
-                drawBitmapMatrix(&canvas, left, leftMatrix);
+                draw_bitmap_matrix(&canvas, left, leftMatrix);
             }
             patternBBox.fLeft = 0;
         }
@@ -1096,12 +174,12 @@
             SkMatrix rightMatrix;
             rightMatrix.setScale(deviceBounds.right() - width, 1);
             rightMatrix.postTranslate(width, 0);
-            drawBitmapMatrix(&canvas, right, rightMatrix);
+            draw_bitmap_matrix(&canvas, right, rightMatrix);
 
             if (tileModes[1] == SkShader::kMirror_TileMode) {
                 rightMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                 rightMatrix.postTranslate(0, 2 * height);
-                drawBitmapMatrix(&canvas, right, rightMatrix);
+                draw_bitmap_matrix(&canvas, right, rightMatrix);
             }
             patternBBox.fRight = deviceBounds.width();
         }
@@ -1116,12 +194,12 @@
             SkMatrix topMatrix;
             topMatrix.setScale(SK_Scalar1, -deviceBounds.top());
             topMatrix.postTranslate(0, deviceBounds.top());
-            drawBitmapMatrix(&canvas, top, topMatrix);
+            draw_bitmap_matrix(&canvas, top, topMatrix);
 
             if (tileModes[0] == SkShader::kMirror_TileMode) {
                 topMatrix.postScale(-1, 1);
                 topMatrix.postTranslate(2 * width, 0);
-                drawBitmapMatrix(&canvas, top, topMatrix);
+                draw_bitmap_matrix(&canvas, top, topMatrix);
             }
             patternBBox.fTop = 0;
         }
@@ -1134,229 +212,122 @@
             SkMatrix bottomMatrix;
             bottomMatrix.setScale(SK_Scalar1, deviceBounds.bottom() - height);
             bottomMatrix.postTranslate(0, height);
-            drawBitmapMatrix(&canvas, bottom, bottomMatrix);
+            draw_bitmap_matrix(&canvas, bottom, bottomMatrix);
 
             if (tileModes[0] == SkShader::kMirror_TileMode) {
                 bottomMatrix.postScale(-1, 1);
                 bottomMatrix.postTranslate(2 * width, 0);
-                drawBitmapMatrix(&canvas, bottom, bottomMatrix);
+                draw_bitmap_matrix(&canvas, bottom, bottomMatrix);
             }
             patternBBox.fBottom = deviceBounds.height();
         }
     }
 
     auto imageShader = sk_make_sp<SkPDFStream>(patternDevice->content());
-    populate_tiling_pattern_dict(imageShader->dict(), patternBBox,
+    SkPDFUtils::PopulateTilingPatternDict(imageShader->dict(), patternBBox,
                                  patternDevice->makeResourceDict(), finalMatrix);
     return imageShader;
 }
 
-bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
-    if (fType != b.fType ||
-            fCanvasTransform != b.fCanvasTransform ||
-            fShaderTransform != b.fShaderTransform ||
-            fBBox != b.fBBox) {
-        return false;
-    }
+// Generic fallback for unsupported shaders:
+//  * allocate a surfaceBBox-sized bitmap
+//  * shade the whole area
+//  * use the result as a bitmap shader
+static sk_sp<SkPDFObject> make_fallback_shader(SkPDFDocument* doc,
+                                               SkShader* shader,
+                                               const SkMatrix& canvasTransform,
+                                               const SkIRect& surfaceBBox) {
+    // TODO(vandebo) This drops SKComposeShader on the floor.  We could
+    // handle compose shader by pulling things up to a layer, drawing with
+    // the first shader, applying the xfer mode and drawing again with the
+    // second shader, then applying the layer to the original drawing.
+    SkPDFShader::State state = {
+        canvasTransform,
+        SkMatrix::I(),
+        surfaceBBox,
+        {{0, 0, 0, 0}, 0},
+        {SkShader::kClamp_TileMode, SkShader::kClamp_TileMode}};
 
-    if (fType == SkShader::kNone_GradientType) {
-        if (fBitmapKey != b.fBitmapKey ||
-                fBitmapKey.fID == 0 ||
-                fImageTileModes[0] != b.fImageTileModes[0] ||
-                fImageTileModes[1] != b.fImageTileModes[1]) {
-            return false;
-        }
-    } else {
-        if (fInfo.fColorCount != b.fInfo.fColorCount ||
-                memcmp(fInfo.fColors, b.fInfo.fColors,
-                       sizeof(SkColor) * fInfo.fColorCount) != 0 ||
-                memcmp(fInfo.fColorOffsets, b.fInfo.fColorOffsets,
-                       sizeof(SkScalar) * fInfo.fColorCount) != 0 ||
-                fInfo.fPoint[0] != b.fInfo.fPoint[0] ||
-                fInfo.fTileMode != b.fInfo.fTileMode) {
-            return false;
-        }
+    state.fShaderTransform = shader->getLocalMatrix();
 
-        switch (fType) {
-            case SkShader::kLinear_GradientType:
-                if (fInfo.fPoint[1] != b.fInfo.fPoint[1]) {
-                    return false;
-                }
-                break;
-            case SkShader::kRadial_GradientType:
-                if (fInfo.fRadius[0] != b.fInfo.fRadius[0]) {
-                    return false;
-                }
-                break;
-            case SkShader::kConical_GradientType:
-                if (fInfo.fPoint[1] != b.fInfo.fPoint[1] ||
-                        fInfo.fRadius[0] != b.fInfo.fRadius[0] ||
-                        fInfo.fRadius[1] != b.fInfo.fRadius[1]) {
-                    return false;
-                }
-                break;
-            case SkShader::kSweep_GradientType:
-            case SkShader::kNone_GradientType:
-            case SkShader::kColor_GradientType:
-                break;
-        }
-    }
-    return true;
-}
-
-SkPDFShader::State::State(SkShader* shader, const SkMatrix& canvasTransform,
-                          const SkIRect& bbox, SkScalar rasterScale,
-                          SkBitmap* imageDst)
-        : fType(SkShader::kNone_GradientType)
-        , fInfo{0, nullptr, nullptr, {{0.0f, 0.0f}, {0.0f, 0.0f}},
-                {0.0f, 0.0f}, SkShader::kClamp_TileMode, 0}
-        , fCanvasTransform(canvasTransform)
-        , fShaderTransform{SkMatrix::I()}
-        , fBBox(bbox)
-        , fBitmapKey{{0, 0, 0, 0}, 0}
-        , fImageTileModes{SkShader::kClamp_TileMode,
-                          SkShader::kClamp_TileMode} {
-    SkASSERT(imageDst);
-    fInfo.fColorCount = 0;
-    fInfo.fColors = nullptr;
-    fInfo.fColorOffsets = nullptr;
-    fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;
-    fType = shader->asAGradient(&fInfo);
-
-    if (fType != SkShader::kNone_GradientType) {
-        fBitmapKey = SkBitmapKey{{0, 0, 0, 0}, 0};
-        fShaderTransform = SkPDFUtils::GetShaderLocalMatrix(shader);
-        this->allocateGradientInfoStorage();
-        shader->asAGradient(&fInfo);
-        return;
-    }
-    if (SkImage* skimg = shader->isAImage(&fShaderTransform, fImageTileModes)) {
-        // TODO(halcanary): delay converting to bitmap.
-        if (skimg->asLegacyBitmap(imageDst, SkImage::kRO_LegacyBitmapMode)) {
-            fBitmapKey = SkBitmapKey{imageDst->getSubset(), imageDst->getGenerationID()};
-            return;
-        }
-    }
-    fShaderTransform = shader->getLocalMatrix();
-    // Generic fallback for unsupported shaders:
-    //  * allocate a bbox-sized bitmap
-    //  * shade the whole area
-    //  * use the result as a bitmap shader
-
-    // bbox is in device space. While that's exactly what we
+    // surfaceBBox 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
     // MakeImageShader's behavior).
-    SkRect shaderRect = SkRect::Make(bbox);
-    if (!inverse_transform_bbox(canvasTransform, &shaderRect)) {
-        imageDst->reset();
-        return;
+    SkRect shaderRect = SkRect::Make(surfaceBBox);
+    if (!SkPDFUtils::InverseTransformBBox(canvasTransform, &shaderRect)) {
+        return nullptr;
     }
-
     // Clamp the bitmap size to about 1M pixels
     static const SkScalar kMaxBitmapArea = 1024 * 1024;
-    SkScalar bitmapArea = rasterScale * bbox.width() * rasterScale * bbox.height();
+    SkScalar rasterScale = SkIntToScalar(doc->rasterDpi()) / SkPDFUtils::kDpiForRasterScaleOne;
+    SkScalar bitmapArea = rasterScale * surfaceBBox.width() * rasterScale * surfaceBBox.height();
     if (bitmapArea > kMaxBitmapArea) {
         rasterScale *= SkScalarSqrt(kMaxBitmapArea / bitmapArea);
     }
 
-    SkISize size = {SkScalarRoundToInt(rasterScale * bbox.width()),
-                    SkScalarRoundToInt(rasterScale * bbox.height())};
+    SkISize size = {SkScalarRoundToInt(rasterScale * surfaceBBox.width()),
+                    SkScalarRoundToInt(rasterScale * surfaceBBox.height())};
     SkSize scale = {SkIntToScalar(size.width()) / shaderRect.width(),
                     SkIntToScalar(size.height()) / shaderRect.height()};
 
-    imageDst->allocN32Pixels(size.width(), size.height());
-    imageDst->eraseColor(SK_ColorTRANSPARENT);
+    SkBitmap image;
+    image.allocN32Pixels(size.width(), size.height());
+    image.eraseColor(SK_ColorTRANSPARENT);
 
     SkPaint p;
     p.setShader(sk_ref_sp(shader));
 
-    SkCanvas canvas(*imageDst);
+    SkCanvas canvas(image);
     canvas.scale(scale.width(), scale.height());
     canvas.translate(-shaderRect.x(), -shaderRect.y());
     canvas.drawPaint(p);
 
-    fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
-    fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
-    fBitmapKey = SkBitmapKey{imageDst->getSubset(), imageDst->getGenerationID()};
+    state.fShaderTransform.setTranslate(shaderRect.x(), shaderRect.y());
+    state.fShaderTransform.preScale(1 / scale.width(), 1 / scale.height());
+    state.fBitmapKey = SkBitmapKey{image.getSubset(), image.getGenerationID()};
+    SkASSERT (!image.isNull());
+    return make_image_shader(doc, state, std::move(image));
 }
 
-SkPDFShader::State::State(const SkPDFShader::State& other)
-  : fType(other.fType),
-    fCanvasTransform(other.fCanvasTransform),
-    fShaderTransform(other.fShaderTransform),
-    fBBox(other.fBBox)
-{
-    // Only gradients supported for now, since that is all that is used.
-    // If needed, image state copy constructor can be added here later.
-    SkASSERT(fType != SkShader::kNone_GradientType);
+sk_sp<SkPDFObject> SkPDFShader::GetPDFShader(SkPDFDocument* doc,
+                                             SkShader* shader,
+                                             const SkMatrix& canvasTransform,
+                                             const SkIRect& surfaceBBox) {
+    SkASSERT(shader);
+    SkASSERT(doc);
+    if (SkShader::kNone_GradientType != shader->asAGradient(nullptr)) {
+        return SkPDFGradientShader::Make(doc, shader, canvasTransform, surfaceBBox);
+    }
+    if (surfaceBBox.isEmpty()) {
+        return nullptr;
+    }
+    SkBitmap image;
+    SkPDFShader::State state = {
+        canvasTransform,
+        SkMatrix::I(),
+        surfaceBBox,
+        {{0, 0, 0, 0}, 0},
+        {SkShader::kClamp_TileMode, SkShader::kClamp_TileMode}};
 
-    if (fType != SkShader::kNone_GradientType) {
-        fInfo = other.fInfo;
-
-        this->allocateGradientInfoStorage();
-        for (int i = 0; i < fInfo.fColorCount; i++) {
-            fInfo.fColors[i] = other.fInfo.fColors[i];
-            fInfo.fColorOffsets[i] = other.fInfo.fColorOffsets[i];
+    SkASSERT(shader->asAGradient(nullptr) == SkShader::kNone_GradientType) ;
+    SkImage* skimg;
+    if ((skimg = shader->isAImage(&state.fShaderTransform, state.fImageTileModes))
+            && skimg->asLegacyBitmap(&image, SkImage::kRO_LegacyBitmapMode)) {
+        // TODO(halcanary): delay converting to bitmap.
+        state.fBitmapKey = SkBitmapKey{image.getSubset(), image.getGenerationID()};
+        if (image.isNull()) {
+            return nullptr;
         }
-    }
-}
-
-/**
- * Create a copy of this gradient state with alpha assigned to RGB luminousity.
- * Only valid for gradient states.
- */
-SkPDFShader::State SkPDFShader::State::MakeAlphaToLuminosityState() const {
-    SkASSERT(fBitmapKey == (SkBitmapKey{{0, 0, 0, 0}, 0}));
-    SkASSERT(fType != SkShader::kNone_GradientType);
-
-    SkPDFShader::State newState(*this);
-
-    for (int i = 0; i < fInfo.fColorCount; i++) {
-        SkAlpha alpha = SkColorGetA(fInfo.fColors[i]);
-        newState.fInfo.fColors[i] = SkColorSetARGB(255, alpha, alpha, alpha);
-    }
-
-    return newState;
-}
-
-/**
- * Create a copy of this gradient state with alpha set to fully opaque
- * Only valid for gradient states.
- */
-SkPDFShader::State SkPDFShader::State::MakeOpaqueState() const {
-    SkASSERT(fBitmapKey == (SkBitmapKey{{0, 0, 0, 0}, 0}));
-    SkASSERT(fType != SkShader::kNone_GradientType);
-
-    SkPDFShader::State newState(*this);
-    for (int i = 0; i < fInfo.fColorCount; i++) {
-        newState.fInfo.fColors[i] = SkColorSetA(fInfo.fColors[i],
-                                                 SK_AlphaOPAQUE);
-    }
-
-    return newState;
-}
-
-/**
- * Returns true if state is a gradient and the gradient has alpha.
- */
-bool SkPDFShader::State::GradientHasAlpha() const {
-    if (fType == SkShader::kNone_GradientType) {
-        return false;
-    }
-
-    for (int i = 0; i < fInfo.fColorCount; i++) {
-        SkAlpha alpha = SkColorGetA(fInfo.fColors[i]);
-        if (alpha != SK_AlphaOPAQUE) {
-            return true;
+        SkPDFCanon* canon = doc->canon();
+        sk_sp<SkPDFObject>* shaderPtr = canon->fImageShaderMap.find(state);
+        if (shaderPtr) {
+            return *shaderPtr;
         }
+        sk_sp<SkPDFObject> pdfShader = make_image_shader(doc, state, std::move(image));
+        canon->fImageShaderMap.set(std::move(state), pdfShader);
+        return pdfShader;
     }
-    return false;
-}
-
-void SkPDFShader::State::allocateGradientInfoStorage() {
-    fColors.reset(new SkColor[fInfo.fColorCount]);
-    fStops.reset(new SkScalar[fInfo.fColorCount]);
-    fInfo.fColors = fColors.get();
-    fInfo.fColorOffsets = fStops.get();
+    // Don't bother to de-dup fallback shader.
+    return make_fallback_shader(doc, shader, canvasTransform, surfaceBBox);
 }
diff --git a/src/pdf/SkPDFShader.h b/src/pdf/SkPDFShader.h
index fe561b6..062aaa6 100644
--- a/src/pdf/SkPDFShader.h
+++ b/src/pdf/SkPDFShader.h
@@ -45,38 +45,26 @@
 
     static sk_sp<SkPDFArray> MakeRangeObject();
 
-    class State {
-    public:
-        SkShader::GradientType fType;
-        SkShader::GradientInfo fInfo;
-        std::unique_ptr<SkColor[]> fColors;
-        std::unique_ptr<SkScalar[]> fStops;
+    SK_BEGIN_REQUIRE_DENSE
+    struct State {
         SkMatrix fCanvasTransform;
         SkMatrix fShaderTransform;
         SkIRect fBBox;
-
         SkBitmapKey fBitmapKey;
         SkShader::TileMode fImageTileModes[2];
-
-        State(SkShader* shader, const SkMatrix& canvasTransform,
-              const SkIRect& bbox, SkScalar rasterScale,
-              SkBitmap* dstImage);
-
-        bool operator==(const State& b) const;
-
-        State MakeAlphaToLuminosityState() const;
-        State MakeOpaqueState() const;
-
-        bool GradientHasAlpha() const;
-
-        State(State&&) = default;
-        State& operator=(State&&) = default;
-
-    private:
-        State(const State& other);
-        State& operator=(const State& rhs);
-        void allocateGradientInfoStorage();
     };
+    SK_END_REQUIRE_DENSE
 };
 
+inline bool operator==(const SkPDFShader::State& a, const SkPDFShader::State& b) {
+    SkASSERT(a.fBitmapKey.fID != 0);
+    SkASSERT(b.fBitmapKey.fID != 0);
+    return a.fCanvasTransform   == b.fCanvasTransform
+        && a.fShaderTransform   == b.fShaderTransform
+        && a.fBBox              == b.fBBox
+        && a.fBitmapKey         == b.fBitmapKey
+        && a.fImageTileModes[0] == b.fImageTileModes[0]
+        && a.fImageTileModes[1] == b.fImageTileModes[1];
+}
+
 #endif
diff --git a/src/pdf/SkPDFUtils.cpp b/src/pdf/SkPDFUtils.cpp
index 3cbf038..510be6c 100644
--- a/src/pdf/SkPDFUtils.cpp
+++ b/src/pdf/SkPDFUtils.cpp
@@ -486,3 +486,33 @@
         wStream->writeText(">");
     }
 }
+
+bool SkPDFUtils::InverseTransformBBox(const SkMatrix& matrix, SkRect* bbox) {
+    SkMatrix inverse;
+    if (!matrix.invert(&inverse)) {
+        return false;
+    }
+    inverse.mapRect(bbox);
+    return true;
+}
+
+void SkPDFUtils::PopulateTilingPatternDict(SkPDFDict* pattern,
+                                           SkRect& bbox,
+                                           sk_sp<SkPDFDict> resources,
+                                           const SkMatrix& matrix) {
+    const int kTiling_PatternType = 1;
+    const int kColoredTilingPattern_PaintType = 1;
+    const int kConstantSpacing_TilingType = 1;
+
+    pattern->insertName("Type", "Pattern");
+    pattern->insertInt("PatternType", kTiling_PatternType);
+    pattern->insertInt("PaintType", kColoredTilingPattern_PaintType);
+    pattern->insertInt("TilingType", kConstantSpacing_TilingType);
+    pattern->insertObject("BBox", SkPDFUtils::RectToArray(bbox));
+    pattern->insertScalar("XStep", bbox.width());
+    pattern->insertScalar("YStep", bbox.height());
+    pattern->insertObject("Resources", std::move(resources));
+    if (!matrix.isIdentity()) {
+        pattern->insertObject("Matrix", SkPDFUtils::MatrixToArray(matrix));
+    }
+}
diff --git a/src/pdf/SkPDFUtils.h b/src/pdf/SkPDFUtils.h
index dfc10b3..93509fe 100644
--- a/src/pdf/SkPDFUtils.h
+++ b/src/pdf/SkPDFUtils.h
@@ -19,6 +19,13 @@
 class SkPDFArray;
 struct SkRect;
 
+template <typename T>
+bool SkPackedArrayEqual(T* u, T* v, size_t n) {
+    SkASSERT(u);
+    SkASSERT(v);
+    return 0 == memcmp(u, v, n * sizeof(T));
+}
+
 #if 0
 #define PRINT_NOT_IMPL(str) fprintf(stderr, str)
 #else
@@ -112,6 +119,11 @@
     }
     return shader->getLocalMatrix();
 }
+bool InverseTransformBBox(const SkMatrix& matrix, SkRect* bbox);
+void PopulateTilingPatternDict(SkPDFDict* pattern,
+                               SkRect& bbox,
+                               sk_sp<SkPDFDict> resources,
+                               const SkMatrix& matrix);
 }  // namespace SkPDFUtils
 
 #endif
