Add SkCanvas::getClipDescription() and getClipDeviceBounds() so clients don't
authortomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 13 Sep 2011 15:07:58 +0000 (15:07 +0000)
committertomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 13 Sep 2011 15:07:58 +0000 (15:07 +0000)
need to explicitly get the exact clip & compute those values themselves. (We
may be able to provide description/bounds more cheaply than the exact clip.)

git-svn-id: http://skia.googlecode.com/svn/trunk@2255 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkCanvas.h
src/core/SkCanvas.cpp

index a22f54f..a6c9528 100644 (file)
@@ -336,6 +336,13 @@ public:
     */
     bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
 
+    /** Return the bounds of the current clip, in device coordinates; returns
+        true if non-empty. Maybe faster than getting the clip explicitly and
+        then taking its bounds.
+    */
+    bool getClipDeviceBounds(SkIRect* bounds) const;
+       
+
     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
         specified ARGB color, using the specified mode.
         @param a    the alpha component (0..255) of the color to fill the canvas
@@ -743,6 +750,17 @@ public:
     */
     const SkMatrix& getTotalMatrix() const;
 
+    enum ClipType {
+        kEmpty_ClipType = 0,
+        kRect_ClipType,
+        kComplex_ClipType
+    };
+
+    /** Returns a description of the total clip; may be cheaper than
+        getting the clip and querying it directly.
+    */
+    ClipType getClipType() const;
+
     /** Return the current device clip (concatenation of all clip calls).
         This does not account for the translate in any of the devices.
         @return the current device clip (concatenation of all clip calls).
index 1f75aa9..3ee29ce 100644 (file)
@@ -678,12 +678,12 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
 
     fDeviceCMDirty = true;
 
-    SkIRect         ir;
-    const SkIRect&  clipBounds = this->getTotalClip().getBounds();
-    if (clipBounds.isEmpty()) {
+    SkIRect clipBounds;
+    if (!this->getClipDeviceBounds(&clipBounds)) {
         return count;
     }
 
+    SkIRect ir;
     if (NULL != bounds) {
         SkRect r;
 
@@ -691,8 +691,9 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
         r.roundOut(&ir);
         // early exit if the layer's bounds are clipped out
         if (!ir.intersect(clipBounds)) {
-            if (bounds_affects_clip(flags))
+            if (bounds_affects_clip(flags)) {
                 fMCRec->fRegion->setEmpty();
+            }
             return count;
         }
     } else {    // no user bounds, so just use the clip
@@ -1095,11 +1096,8 @@ bool SkCanvas::quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
 }
 
 bool SkCanvas::getClipBounds(SkRect* bounds, EdgeType et) const {
-    const SkRegion& clip = *fMCRec->fRegion;
-    if (clip.isEmpty()) {
-        if (bounds) {
-            bounds->setEmpty();
-        }
+    SkIRect ibounds;
+    if (!getClipDeviceBounds(&ibounds)) {
         return false;
     }
 
@@ -1113,24 +1111,41 @@ bool SkCanvas::getClipBounds(SkRect* bounds, EdgeType et) const {
     }
 
     if (NULL != bounds) {
-        SkRect   r;
-        // get the clip's bounds
-        const SkIRect& ibounds = clip.getBounds();
+        SkRect r;
         // adjust it outwards if we are antialiasing
         int inset = (kAA_EdgeType == et);
         r.iset(ibounds.fLeft - inset,  ibounds.fTop - inset,
                ibounds.fRight + inset, ibounds.fBottom + inset);
-
-        // invert into local coordinates
         inverse.mapRect(bounds, r);
     }
     return true;
 }
 
+bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const {
+    const SkRegion& clip = *fMCRec->fRegion;
+    if (clip.isEmpty()) {
+        if (bounds) {
+            bounds->setEmpty();
+        }
+        return false;
+    }
+
+    if (NULL != bounds) {
+        *bounds = clip.getBounds();
+    }
+    return true;
+}
+
 const SkMatrix& SkCanvas::getTotalMatrix() const {
     return *fMCRec->fMatrix;
 }
 
+SkCanvas::ClipType SkCanvas::getClipType() const {
+    if (fMCRec->fRegion->isEmpty()) return kEmpty_ClipType;
+    if (fMCRec->fRegion->isRect()) return kRect_ClipType;
+    return kComplex_ClipType;
+}
+
 const SkRegion& SkCanvas::getTotalClip() const {
     return *fMCRec->fRegion;
 }