perform quickReject in drawPoints (which is called by drawLine) just like we
already did in drawRect and drawPath



git-svn-id: http://skia.googlecode.com/svn/trunk@3968 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/DashBench.cpp b/bench/DashBench.cpp
index 40fffe6..3f2cfa7 100644
--- a/bench/DashBench.cpp
+++ b/bench/DashBench.cpp
@@ -34,7 +34,8 @@
     SkString            fName;
     SkTDArray<SkScalar> fIntervals;
     int                 fWidth;
-    bool fDoClip;
+    SkPoint             fPts[2];
+    bool                fDoClip;
 
     enum {
         N = SkBENCHLOOP(100)
@@ -49,6 +50,9 @@
         fWidth = width;
         fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip");
         fDoClip = doClip;
+        
+        fPts[0].set(SkIntToScalar(10), SkIntToScalar(10));
+        fPts[1].set(SkIntToScalar(600), SkIntToScalar(10));
     }
 
     virtual void makePath(SkPath* path) {
@@ -87,6 +91,7 @@
     virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                             const SkPaint& paint, int N) {
         for (int i = 0; i < N; ++i) {
+//            canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, paint);
             canvas->drawPath(path, paint);
         }
     }
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index c5f7c9c..8fcfda2 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -434,52 +434,6 @@
     */
     bool getFillPath(const SkPath& src, SkPath* dst) const;
 
-    /** Returns true if the current paint settings allow for fast computation of
-        bounds (i.e. there is nothing complex like a patheffect that would make
-        the bounds computation expensive.
-    */
-    bool canComputeFastBounds() const {
-        if (this->getLooper()) {
-            return this->getLooper()->canComputeFastBounds(*this);
-        }
-        return !this->getRasterizer();
-    }
-
-    /** Only call this if canComputeFastBounds() returned true. This takes a
-        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
-        effects in the paint (e.g. stroking). If needed, it uses the storage
-        rect parameter. It returns the adjusted bounds that can then be used
-        for quickReject tests.
-
-        The returned rect will either be orig or storage, thus the caller
-        should not rely on storage being set to the result, but should always
-        use the retured value. It is legal for orig and storage to be the same
-        rect.
-
-        e.g.
-        if (paint.canComputeFastBounds()) {
-            SkRect r, storage;
-            path.computeBounds(&r, SkPath::kFast_BoundsType);
-            const SkRect& fastR = paint.computeFastBounds(r, &storage);
-            if (canvas->quickReject(fastR, ...)) {
-                // don't draw the path
-            }
-        }
-    */
-    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
-        // ultra fast-case: filling with no effects that affect geometry
-        if (this->getStyle() == kFill_Style) {
-            uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
-            effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
-            effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
-            if (!effects) {
-                return orig;
-            }
-        }
-
-        return this->doComputeFastBounds(orig, storage);
-    }
-
     /** Get the paint's shader object.
         <p />
       The shader's reference count is not affected.
@@ -914,7 +868,66 @@
                         void (*proc)(const SkDescriptor*, void*),
                         void* context, bool ignoreGamma = false) const;
 
-    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage) const;
+    ///////////////////////////////////////////////////////////////////////////
+    
+    /** Returns true if the current paint settings allow for fast computation of
+     bounds (i.e. there is nothing complex like a patheffect that would make
+     the bounds computation expensive.
+     */
+    bool canComputeFastBounds() const {
+        if (this->getLooper()) {
+            return this->getLooper()->canComputeFastBounds(*this);
+        }
+        return !this->getRasterizer();
+    }
+    
+    /** Only call this if canComputeFastBounds() returned true. This takes a
+     raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
+     effects in the paint (e.g. stroking). If needed, it uses the storage
+     rect parameter. It returns the adjusted bounds that can then be used
+     for quickReject tests.
+     
+     The returned rect will either be orig or storage, thus the caller
+     should not rely on storage being set to the result, but should always
+     use the retured value. It is legal for orig and storage to be the same
+     rect.
+     
+     e.g.
+     if (paint.canComputeFastBounds()) {
+     SkRect r, storage;
+     path.computeBounds(&r, SkPath::kFast_BoundsType);
+     const SkRect& fastR = paint.computeFastBounds(r, &storage);
+     if (canvas->quickReject(fastR, ...)) {
+     // don't draw the path
+     }
+     }
+     */
+    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
+        SkPaint::Style style = this->getStyle();
+        // ultra fast-case: filling with no effects that affect geometry
+        if (kFill_Style == style) {
+            uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
+            effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
+            effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
+            if (!effects) {
+                return orig;
+            }
+        }
+        
+        return this->doComputeFastBounds(orig, storage, style);
+    }
+    
+    const SkRect& computeFastStrokeBounds(const SkRect& orig,
+                                          SkRect* storage) const {
+        return this->doComputeFastBounds(orig, storage, kFill_Style);
+    }
+    
+    // Take the style explicitly, so the caller can force us to be stroked
+    // without having to make a copy of the paint just to change that field.
+    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
+                                      Style) const;
+
+    ///////////////////////////////////////////////////////////////////////////
 
     enum {
         kCanonicalTextSizeForPaths = 64
@@ -922,6 +935,8 @@
     friend class SkAutoGlyphCache;
     friend class SkCanvas;
     friend class SkDraw;
+    friend class SkDrawLooper;      // computeFastBounds
+    friend class SkPictureRecord;   // computeFastBounds
     friend class SkPDFDevice;
     friend class SkTextToPathIter;
 
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 90de54a..3687d1e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1452,6 +1452,21 @@
         return;
     }
 
+    if (paint.canComputeFastBounds()) {
+        SkRect r;
+        // special-case 2 points (common for drawing a single line)
+        if (2 == count) {
+            r.set(pts[0], pts[1]);
+        } else {
+            r.set(pts, count);
+        }
+        SkRect storage;
+        if (this->quickReject(paint.computeFastStrokeBounds(r, &storage),
+                              paint2EdgeType(&paint))) {
+            return;
+        }
+    }    
+
     SkASSERT(pts != NULL);
 
     LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type)
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 66fa0df..1b74fa1 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -2045,7 +2045,8 @@
 }
 
 const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
-                                                 SkRect* storage) const {
+                                           SkRect* storage,
+                                           Style style) const {
     SkASSERT(storage);
 
     const SkRect* src = &origSrc;
@@ -2062,7 +2063,7 @@
         src = &tmpSrc;
     }
 
-    if (this->getStyle() != SkPaint::kFill_Style) {
+    if (kFill_Style != style) {
         // since we're stroked, outset the rect by the radius (and join type)
         SkScalar radius = SkScalarHalf(this->getStrokeWidth());
         if (0 == radius) {  // hairline