From: reed@android.com Date: Mon, 9 Nov 2009 16:01:36 +0000 (+0000) Subject: update dox for SkAvoidXfermode (as best I could) X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~19337 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0db5a7fae596e4914250554402e4874c33fdf0d4;p=platform%2Fupstream%2FlibSkiaSharp.git update dox for SkAvoidXfermode (as best I could) fix 565 and 4444 implementations git-svn-id: http://skia.googlecode.com/svn/trunk@420 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/include/effects/SkAvoidXfermode.h b/include/effects/SkAvoidXfermode.h index 32bc049..2803c07 100644 --- a/include/effects/SkAvoidXfermode.h +++ b/include/effects/SkAvoidXfermode.h @@ -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 index 0000000..faeee20 --- /dev/null +++ b/samplecode/SampleAvoid.cpp @@ -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); + diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp index eed4012..d26039c 100644 --- a/src/effects/SkAvoidXfermode.cpp +++ b/src/effects/SkAvoidXfermode.cpp @@ -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);