[PDF] Fix Chrome crash - don't assume that SkDraw.fClipStack != NULL.

Chrome bug is crbug.com/82198.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@1306 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index bef0dba..9ab0ae5 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -165,12 +165,12 @@
 
     // If the paint or clip is such that we shouldn't draw anything, these
     // return false and do not create a content entry.
-    bool setUpContentEntry(const SkClipStack& clipStack,
+    bool setUpContentEntry(const SkClipStack* clipStack,
                            const SkRegion& clipRegion,
                            const SkMatrix& matrix,
                            const SkPaint& paint,
                            bool hasText = false);
-    bool setUpContentEntryForText(const SkClipStack& clipStack,
+    bool setUpContentEntryForText(const SkClipStack* clipStack,
                                   const SkRegion& clipRegion,
                                   const SkMatrix& matrix,
                                   const SkPaint& paint);
@@ -187,7 +187,7 @@
 
     void internalDrawPaint(const SkPaint& paint);
     void internalDrawBitmap(const SkMatrix& matrix,
-                            const SkClipStack& clipStack,
+                            const SkClipStack* clipStack,
                             const SkRegion& clipRegion,
                             const SkBitmap& bitmap,
                             const SkIRect* srcRect,
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 2d4f0fb..1a3324a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -550,7 +550,7 @@
     paint.setStyle(SkPaint::kFill_Style);
     SkMatrix identity;
     identity.reset();
-    if (!setUpContentEntry(fExistingClipStack, fExistingClipRegion, identity,
+    if (!setUpContentEntry(&fExistingClipStack, fExistingClipRegion, identity,
                            paint)) {
         return;
     }
@@ -561,7 +561,7 @@
 void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
     SkPaint newPaint = paint;
     newPaint.setStyle(SkPaint::kFill_Style);
-    if (!setUpContentEntry(*d.fClipStack, *d.fClip, *d.fMatrix, newPaint)) {
+    if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, newPaint)) {
         return;
     }
 
@@ -615,7 +615,7 @@
     }
 
 
-    if (!setUpContentEntry(*d.fClipStack, *d.fClip, *d.fMatrix, *paint)) {
+    if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, *paint)) {
         return;
     }
 
@@ -669,7 +669,7 @@
         drawPath(d, path, noEffectPaint, NULL, true);
         return;
     }
-    if (!setUpContentEntry(*d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
+    if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
         return;
     }
 
@@ -696,7 +696,7 @@
         drawPath(d, noEffectPath, noEffectPaint, NULL, true);
         return;
     }
-    if (!setUpContentEntry(*d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
+    if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
         return;
     }
 
@@ -714,7 +714,7 @@
 
     SkMatrix transform = matrix;
     transform.postConcat(*d.fMatrix);
-    internalDrawBitmap(transform, *d.fClipStack, *d.fClip, bitmap, srcRect,
+    internalDrawBitmap(transform, d.fClipStack, *d.fClip, bitmap, srcRect,
                        paint);
 }
 
@@ -726,13 +726,13 @@
 
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
-    internalDrawBitmap(matrix, *d.fClipStack, *d.fClip, bitmap, NULL, paint);
+    internalDrawBitmap(matrix, d.fClipStack, *d.fClip, bitmap, NULL, paint);
 }
 
 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
                            SkScalar x, SkScalar y, const SkPaint& paint) {
     SkPaint textPaint = calculate_text_paint(paint);
-    if (!setUpContentEntryForText(*d.fClipStack, *d.fClip, *d.fMatrix,
+    if (!setUpContentEntryForText(d.fClipStack, *d.fClip, *d.fMatrix,
                                   textPaint)) {
         return;
     }
@@ -805,7 +805,7 @@
                               int scalarsPerPos, const SkPaint& paint) {
     SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos);
     SkPaint textPaint = calculate_text_paint(paint);
-    if (!setUpContentEntryForText(*d.fClipStack, *d.fClip, *d.fMatrix,
+    if (!setUpContentEntryForText(d.fClipStack, *d.fClip, *d.fMatrix,
                                   textPaint)) {
         return;
     }
@@ -881,7 +881,7 @@
 
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
-    if (!setUpContentEntry(*d.fClipStack, *d.fClip, matrix, paint)) {
+    if (!setUpContentEntry(d.fClipStack, *d.fClip, matrix, paint)) {
         return;
     }
 
@@ -1038,7 +1038,7 @@
     return result;
 }
 
-bool SkPDFDevice::setUpContentEntry(const SkClipStack& clipStack,
+bool SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack,
                                     const SkRegion& clipRegion,
                                     const SkMatrix& matrix,
                                     const SkPaint& paint,
@@ -1047,6 +1047,23 @@
         return false;
     }
 
+    // The clip stack can come from an SkDraw where it is technically optional.
+    SkClipStack synthesizedClipStack;
+    if (clipStack == NULL) {
+        if (clipRegion == fExistingClipRegion) {
+            clipStack = &fExistingClipStack;
+        } else {
+            // GraphicStackState::updateClip expects the clip stack to have
+            // fExistingClip as a prefix, so start there, then set the clip
+            // to the passed region.
+            synthesizedClipStack = fExistingClipStack;
+            SkPath clipPath;
+            clipRegion.getBoundaryPath(&clipPath);
+            synthesizedClipStack.clipDevPath(clipPath, SkRegion::kReplace_Op);
+            clipStack = &synthesizedClipStack;
+        }
+    }
+
     SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode;
     if (paint.getXfermode()) {
         paint.getXfermode()->asMode(&xfermode);
@@ -1056,7 +1073,7 @@
     // current clip.
     if (xfermode == SkXfermode::kClear_Mode ||
             xfermode == SkXfermode::kSrc_Mode) {
-        apply_inverse_clip_to_content_entries(clipStack, clipRegion,
+        apply_inverse_clip_to_content_entries(*clipStack, clipRegion,
                                               &fContentEntries);
         // apply_inverse_clip_to_content_entries may have removed entries
         // from fContentEntries and this may have invalidated
@@ -1091,7 +1108,7 @@
         entry = newEntry.get();
     }
 
-    populateGraphicStateEntryFromPaint(matrix, clipStack, clipRegion, paint,
+    populateGraphicStateEntryFromPaint(matrix, *clipStack, clipRegion, paint,
                                        hasText, &entry->fState);
     if (fCurrentContentEntry && xfermode != SkXfermode::kDstOver_Mode &&
             entry->fState.compareInitialState(fCurrentContentEntry->fState)) {
@@ -1111,7 +1128,7 @@
     return true;
 }
 
-bool SkPDFDevice::setUpContentEntryForText(const SkClipStack& clipStack,
+bool SkPDFDevice::setUpContentEntryForText(const SkClipStack* clipStack,
                                            const SkRegion& clipRegion,
                                            const SkMatrix& matrix,
                                            const SkPaint& paint) {
@@ -1254,7 +1271,7 @@
 }
 
 void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix,
-                                     const SkClipStack& clipStack,
+                                     const SkClipStack* clipStack,
                                      const SkRegion& clipRegion,
                                      const SkBitmap& bitmap,
                                      const SkIRect* srcRect,