update dox for SkAvoidXfermode (as best I could)
authorreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 9 Nov 2009 16:01:36 +0000 (16:01 +0000)
committerreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 9 Nov 2009 16:01:36 +0000 (16:01 +0000)
fix 565 and 4444 implementations

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

include/effects/SkAvoidXfermode.h
samplecode/SampleAvoid.cpp [new file with mode: 0644]
src/effects/SkAvoidXfermode.cpp

index 32bc049..2803c07 100644 (file)
@@ -31,16 +31,21 @@ public:
         kTargetColor_Mode   //!< draw only on top of the opColor
     };
 
-    /** This xfermode will draw the src everywhere except on top of the opColor
-        or, depending on the Mode, draw only on top of the opColor.
-        @param opColor  the color to avoid (or to target depending on Mode).
-                        note: the alpha in opColor is ignored
-        @param tolerance    How closely we compare a pixel to the opColor.
-                            0 - only operate if exact match
-                            255 - maximum gradation (blending) based on how
-                            similar the pixel is to our opColor (max tolerance)
-        @param mode If we should avoid or target the opColor
-    */
+    /** This xfermode draws, or doesn't draw, based on the destination's
+        distance from an op-color.
+     
+        There are two modes, and each mode interprets a tolerance value.
+     
+        Avoid: In this mode, drawing is allowed only on destination pixels that
+               are different from the op-color.
+               Tolerance near 0: avoid anything close to the op-color
+               Tolerance near 255: avoid only colors very close to the op-color
+     
+        Target: In this mode, drawing only occurs on destination pixels that
+                are similar to the op-color
+                Tolerance near 0: draw on colors that are very close to op-color
+                Tolerance near 255: draw on colors that  to the op-color
+     */
     SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
 
     // overrides from SkXfermode
diff --git a/samplecode/SampleAvoid.cpp b/samplecode/SampleAvoid.cpp
new file mode 100644 (file)
index 0000000..faeee20
--- /dev/null
@@ -0,0 +1,101 @@
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkAvoidXfermode.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+class AvoidView : public SkView {
+    SkShader* fShader;
+
+    enum {
+        W = 480,
+        H = 320
+    };
+public:
+    AvoidView() {
+        SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorCYAN, SK_ColorBLUE };
+
+#if 0
+        SkPoint pts[] = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
+        fShader = SkGradientShader::CreateLinear(pts, colors, NULL,
+                                                 SK_ARRAY_COUNT(colors),
+                                                 SkShader::kMirror_TileMode);
+#else
+        SkPoint pts[] = { SkIntToScalar(W)/2, SkIntToScalar(H)/2 };
+        fShader = SkGradientShader::CreateRadial(pts[0], SkIntToScalar(H)/5,
+                                                 colors, NULL,
+                                                 SK_ARRAY_COUNT(colors),
+                                                 SkShader::kMirror_TileMode);
+#endif
+    }
+    
+    virtual ~AvoidView() {
+        fShader->unref();
+    }
+
+protected:
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "AvoidXfermode");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        canvas->drawColor(SK_ColorWHITE);
+        
+        SkPaint paint;
+        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
+        
+        canvas->translate(r.width() / 6, r.height() / 6);
+
+        paint.setShader(fShader);
+        canvas->drawRect(r, paint);
+
+        static const struct {
+            int                     fTolerance;
+            SkAvoidXfermode::Mode   fMode;
+            float                   fDX, fDY;
+        } gData[] = {
+            { 16,       SkAvoidXfermode::kAvoidColor_Mode, 0, 0 },
+            { 255-16,   SkAvoidXfermode::kAvoidColor_Mode, 1, 0 },
+            { 16,       SkAvoidXfermode::kTargetColor_Mode, 0, 1 },
+            { 255-16,   SkAvoidXfermode::kTargetColor_Mode, 1, 1 },
+        };
+
+        paint.setShader(NULL);
+        paint.setColor(SK_ColorMAGENTA);
+        
+        SkPaint frameP;
+        frameP.setStyle(SkPaint::kStroke_Style);
+
+        for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
+            SkAvoidXfermode mode(SK_ColorGREEN, gData[i].fTolerance,
+                                 gData[i].fMode);
+            paint.setXfermode(&mode);
+            int div = 3;
+            SkRect rr = { 0, 0, r.width()/div, r.height()/div };
+            rr.offset(r.width()/4 - rr.width()/2, r.height()/4 - rr.height()/2);
+            rr.offset(r.width() * gData[i].fDX/2, r.height() * gData[i].fDY/2);
+            canvas->drawRect(rr, paint);
+            paint.setXfermode(NULL);
+
+            canvas->drawRect(rr, frameP);
+        }
+    }
+    
+private:
+    typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() {
+    return new AvoidView;
+}
+
+static SkViewRegister reg(MyFactory);
+
index eed4012..d26039c 100644 (file)
@@ -174,7 +174,7 @@ void SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
     unsigned    opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
     unsigned    opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS);
     uint32_t    mul = fDistMul;
-    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
+    uint32_t    sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
 
     int MAX, mask;
     
@@ -193,7 +193,6 @@ void SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
         SkASSERT((unsigned)d <= 31);
         // convert from 0..31 to 0..32
         d += d >> 4;
-
         d = scale_dist_14(d, mul, sub);
         SkASSERT(d <= 32);
 
@@ -216,7 +215,7 @@ void SkAvoidXfermode::xfer4444(uint16_t dst[], const SkPMColor src[], int count,
     unsigned    opG = SkColorGetG(fOpColor) >> 4;
     unsigned    opB = SkColorGetB(fOpColor) >> 4;
     uint32_t    mul = fDistMul;
-    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
+    uint32_t    sub = (fDistMul - (1 << 14)) << 4;
     
     int MAX, mask;
     
@@ -233,8 +232,8 @@ void SkAvoidXfermode::xfer4444(uint16_t dst[], const SkPMColor src[], int count,
         // now reverse d if we need to
         d = MAX + (d ^ mask) - mask;
         SkASSERT((unsigned)d <= 15);
-        d = SkAlpha255To256(d);
-        
+        // convert from 0..15 to 0..16
+        d += d >> 3;
         d = scale_dist_14(d, mul, sub);
         SkASSERT(d <= 16);