[PDF] Reuse the invert function object for xform object masks.

Review URL: http://codereview.appspot.com/4557046

git-svn-id: http://skia.googlecode.com/svn/trunk@1417 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp
index 48203f6..b08bf24 100644
--- a/src/pdf/SkPDFGraphicState.cpp
+++ b/src/pdf/SkPDFGraphicState.cpp
@@ -117,6 +117,32 @@
 }
 
 // static
+SkPDFObject* SkPDFGraphicState::GetInvertFunction() {
+    // This assumes that canonicalPaintsMutex is held.
+    static SkPDFStream* invertFunction = NULL;
+    if (!invertFunction) {
+        // Acrobat crashes if we use a type 0 function, kpdf crashes if we use
+        // a type 2 function, so we use a type 4 function.
+        SkRefPtr<SkPDFArray> domainAndRange = new SkPDFArray;
+        domainAndRange->unref();  // SkRefPtr and new both took a reference.
+        domainAndRange->reserve(2);
+        domainAndRange->append(new SkPDFInt(0))->unref();
+        domainAndRange->append(new SkPDFInt(1))->unref();
+
+        static const char psInvert[] = "{1 exch sub}";
+        SkRefPtr<SkMemoryStream> psInvertStream =
+            new SkMemoryStream(&psInvert, strlen(psInvert), true);
+        psInvertStream->unref();  // SkRefPtr and new both took a reference.
+
+        invertFunction = new SkPDFStream(psInvertStream.get());
+        invertFunction->insert("FunctionType", new SkPDFInt(4))->unref();
+        invertFunction->insert("Domain", domainAndRange.get());
+        invertFunction->insert("Range", domainAndRange.get());
+    }
+    return invertFunction;
+}
+
+// static
 SkPDFGraphicState* SkPDFGraphicState::getSMaskGraphicState(
         SkPDFFormXObject* sMask, bool invert) {
     // The practical chances of using the same mask more than once are unlikely
@@ -137,27 +163,10 @@
     sMask->ref();
 
     if (invert) {
-        // Acrobat crashes if we use a type 0 function, kpdf crashes if we use
-        // a type 2 function, so we use a type 4 function.
-        SkRefPtr<SkPDFArray> domainAndRange = new SkPDFArray;
-        domainAndRange->unref();  // SkRefPtr and new both took a reference.
-        domainAndRange->reserve(2);
-        domainAndRange->append(new SkPDFInt(0))->unref();
-        domainAndRange->append(new SkPDFInt(1))->unref();
-
-        static const char psInvert[] = "{1 exch sub}";
-        SkRefPtr<SkMemoryStream> psInvertStream =
-            new SkMemoryStream(&psInvert, strlen(psInvert), true);
-        psInvertStream->unref();  // SkRefPtr and new both took a reference.
-
-        SkRefPtr<SkPDFStream> invertFunc =
-            new SkPDFStream(psInvertStream.get());
-        result->fResources.push(invertFunc.get());  // Pass the ref from new.
-        invertFunc->insert("FunctionType", new SkPDFInt(4))->unref();
-        invertFunc->insert("Domain", domainAndRange.get());
-        invertFunc->insert("Range", domainAndRange.get());
-
-        sMaskDict->insert("TR", new SkPDFObjRef(invertFunc.get()))->unref();
+        SkPDFObject* invertFunction = GetInvertFunction();
+        result->fResources.push(invertFunction);
+        invertFunction->ref();
+        sMaskDict->insert("TR", new SkPDFObjRef(invertFunction))->unref();
     }
 
     return result;