check-point for aaclip
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 6 Oct 2011 13:11:25 +0000 (13:11 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 6 Oct 2011 13:11:25 +0000 (13:11 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@2419 2bbb7eff-a529-9590-31e7-b0007b416f81

samplecode/SampleAAClip2.cpp [new file with mode: 0644]
src/core/SkAAClip.cpp
src/core/SkAAClip.h

diff --git a/samplecode/SampleAAClip2.cpp b/samplecode/SampleAAClip2.cpp
new file mode 100644 (file)
index 0000000..bdb3741
--- /dev/null
@@ -0,0 +1,175 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkAAClip.h"
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+#include "SkUtils.h"
+#include "SkImageDecoder.h"
+
+#ifdef SK_BUILD_FOR_WIN
+// windows doesn't have roundf
+inline float roundf(float x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); }
+#endif
+
+static void drawClip(SkCanvas* canvas, const SkAAClip& clip) {
+    SkMask mask;
+    SkBitmap bm;
+    
+    clip.copyToMask(&mask);
+    bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
+                 mask.fBounds.height(), mask.fRowBytes);
+    bm.setPixels(mask.fImage);
+    
+    SkPaint paint;
+    canvas->drawBitmap(bm, mask.fBounds.fLeft, mask.fBounds.fTop, &paint);
+}
+
+static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
+                      const SkPaint& paint) {
+    SkMask mask;
+    SkBitmap bm;
+    
+    clip.copyToMask(&mask);
+    bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
+                 mask.fBounds.height(), mask.fRowBytes);
+    bm.setPixels(mask.fImage);
+    
+    canvas->drawBitmap(bm, mask.fBounds.fLeft, mask.fBounds.fTop, &paint);
+}
+
+class AAClipView2 : public SampleView {
+public:
+       AAClipView2() {
+        fBase.set(100, 100, 150, 150);
+        fRect = fBase;
+        fRect.inset(5, 5);
+        fRect.offset(25, 25);
+        this->setBGColor(0xFFDDDDDD);
+    }
+
+    void build_rgn(SkAAClip* clip, SkRegion::Op op) {
+        clip->setRect(fBase);
+#if 0
+        SkIRect r = fBase;
+        r.offset(75, 20);
+        rgn->op(r, SkRegion::kUnion_Op);
+#endif
+
+        SkRect r;
+        r.set(fRect);
+        SkPath path;
+        path.addOval(r);
+        SkAAClip clip2;
+        clip2.setPath(path);
+        // hack
+        op = SkRegion::kIntersect_Op;
+        clip->op(clip2, op);
+    }
+
+
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "AAClips");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+    
+    void drawOrig(SkCanvas* canvas, bool bg) {
+        SkRect      r;
+        SkPaint     paint;
+        
+        paint.setStyle(SkPaint::kStroke_Style);
+        if (bg)
+            paint.setColor(0xFFBBBBBB);
+        
+        r.set(fBase);
+        canvas->drawRect(r, paint);
+        r.set(fRect);
+        canvas->drawRect(r, paint);
+    }
+    
+    void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
+        SkAAClip clip;
+
+        this->build_rgn(&clip, op);
+        
+        this->drawOrig(canvas, true);
+
+        SkPaint paint;
+        paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24));
+        paint_rgn(canvas, clip, paint);
+
+        paint.setStyle(SkPaint::kStroke_Style);
+        paint.setColor(color);
+        paint_rgn(canvas, clip, paint);
+    }
+    
+    virtual void onDrawContent(SkCanvas* canvas) {
+
+        static const struct {
+            SkColor         fColor;
+            const char*     fName;
+            SkRegion::Op    fOp;
+        } gOps[] = {
+            { SK_ColorBLACK,    "Difference",   SkRegion::kDifference_Op    },
+            { SK_ColorRED,      "Intersect",    SkRegion::kIntersect_Op     },
+            { 0xFF008800,       "Union",        SkRegion::kUnion_Op         },
+            { SK_ColorBLUE,     "XOR",          SkRegion::kXOR_Op           }
+        };
+
+        SkPaint textPaint;
+        textPaint.setAntiAlias(true);
+        textPaint.setTextSize(SK_Scalar1*24);
+
+        this->drawOrig(canvas, false);
+        canvas->save();
+            canvas->translate(SkIntToScalar(200), 0);
+            this->drawRgnOped(canvas, SkRegion::kUnion_Op, SK_ColorBLACK);
+        canvas->restore();
+        
+        canvas->translate(0, SkIntToScalar(200));
+
+        for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
+            canvas->drawText(gOps[op].fName, strlen(gOps[op].fName), SkIntToScalar(75), SkIntToScalar(50), textPaint);
+
+            this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
+            
+            canvas->translate(SkIntToScalar(200), 0);
+        }
+    }
+    
+    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
+        return fRect.contains(SkScalarRound(x), SkScalarRound(y)) ? new Click(this) : NULL;
+    }
+    
+    virtual bool onClick(Click* click) {
+        fRect.offset(click->fICurr.fX - click->fIPrev.fX,
+                     click->fICurr.fY - click->fIPrev.fY);
+        this->inval(NULL);
+        return true;
+    }
+    
+private:
+    SkIRect    fBase, fRect;
+    
+    typedef SampleView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new AAClipView2; }
+static SkViewRegister reg(MyFactory);
+
index a79cca1..ff5715e 100644 (file)
@@ -112,7 +112,7 @@ void SkAAClip::Iter::next() {
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkAAClip::freeRuns() {
-    if (this->isComplex()) {
+    if (fRunHead) {
         SkASSERT(fRunHead->fRefCnt >= 1);
         if (1 == sk_atomic_dec(&fRunHead->fRefCnt)) {
             sk_free(fRunHead);
@@ -122,11 +122,11 @@ void SkAAClip::freeRuns() {
 
 SkAAClip::SkAAClip() {
     fBounds.setEmpty();
-    fRunHead = SkAAClip_gEmptyPtr;
+    fRunHead = NULL;
 }
 
 SkAAClip::SkAAClip(const SkAAClip& src) {
-    fRunHead = SkAAClip_gEmptyPtr;
+    fRunHead = NULL;
     *this = src;
 }
 
@@ -139,7 +139,7 @@ SkAAClip& SkAAClip::operator=(const SkAAClip& src) {
         this->freeRuns();
         fBounds = src.fBounds;
         fRunHead = src.fRunHead;
-        if (this->isComplex()) {
+        if (fRunHead) {
             sk_atomic_inc(&fRunHead->fRefCnt);
         }
     }
@@ -163,7 +163,7 @@ bool operator==(const SkAAClip& a, const SkAAClip& b) {
     }
 
     // now we insist that both are complex (but different ptrs)
-    if (!a.isComplex() || !b.isComplex()) {
+    if (!a.fRunHead || !b.fRunHead) {
         return false;
     }
 
@@ -185,7 +185,7 @@ bool SkAAClip::set(const SkAAClip& src) {
 bool SkAAClip::setEmpty() {
     this->freeRuns();
     fBounds.setEmpty();
-    fRunHead = SkAAClip_gEmptyPtr;
+    fRunHead = NULL;
     return false;
 }
 
@@ -193,10 +193,14 @@ bool SkAAClip::setRect(const SkIRect& bounds) {
     if (bounds.isEmpty()) {
         return this->setEmpty();
     }
-    this->freeRuns();
-    fBounds = bounds;
-    fRunHead = SkAAClip_gRectPtr;
-    return true;
+
+    // TODO: special case this
+
+    SkRect r;
+    r.set(bounds);
+    SkPath path;
+    path.addRect(r);
+    return this->setPath(path);
 }
 
 bool SkAAClip::setRect(const SkRect& r) {
@@ -212,7 +216,7 @@ bool SkAAClip::setRect(const SkRect& r) {
 ///////////////////////////////////////////////////////////////////////////////
 
 const uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const {
-    SkASSERT(this->isComplex());
+    SkASSERT(fRunHead);
 
     if (!y_in_rect(y, fBounds)) {
         return NULL;
@@ -894,6 +898,22 @@ bool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig,
     return !this->isEmpty();
 }
 
+bool SkAAClip::op(const SkIRect& r, SkRegion::Op op) {
+    SkAAClip clip;
+    clip.setRect(r);
+    return this->op(*this, clip, op);
+}
+
+bool SkAAClip::op(const SkRect& r, SkRegion::Op op) {
+    SkAAClip clip;
+    clip.setRect(r);
+    return this->op(*this, clip, op);
+}
+
+bool SkAAClip::op(const SkAAClip& clip, SkRegion::Op op) {
+    return this->op(*this, clip, op);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
index 98df3a6..cebe97c 100644 (file)
@@ -12,9 +12,6 @@
 #include "SkBlitter.h"
 #include "SkRegion.h"
 
-#define SkAAClip_gEmptyPtr   ((SkAAClip::RunHead*)-1)
-#define SkAAClip_gRectPtr    NULL
-
 class SkAAClip {
 public:
     SkAAClip();
@@ -29,9 +26,7 @@ public:
 
     void swap(SkAAClip&);
 
-    bool isEmpty() const { return SkAAClip_gEmptyPtr == fRunHead; }
-//    bool isRect() const { return SkAAClip_gRectPtr == fRunHead; }
-    bool isComplex() const { return !this->isEmpty() /*&& !this->isRect()*/; }
+    bool isEmpty() const { return NULL == fRunHead; }
     const SkIRect& getBounds() const { return fBounds; }
 
     bool setEmpty();
@@ -42,6 +37,11 @@ public:
 
     bool op(const SkAAClip&, const SkAAClip&, SkRegion::Op);
 
+    // Helpers for op()
+    bool op(const SkIRect&, SkRegion::Op);
+    bool op(const SkRect&, SkRegion::Op);
+    bool op(const SkAAClip&, SkRegion::Op);
+
     /**
      *  Allocates a mask the size of the aaclip, and expands its data into
      *  the mask, using kA8_Format