From 0e2810be95d3f1aa95c341521d3f514eb9e9ebde Mon Sep 17 00:00:00 2001 From: "mike@reedtribe.org" Date: Fri, 8 Apr 2011 02:41:54 +0000 Subject: [PATCH] add optional bitflags to control which aspect of each layer's paint is applied git-svn-id: http://skia.googlecode.com/svn/trunk@1083 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/effects/SkLayerDrawLooper.h | 40 ++++++++++++++---- src/effects/SkLayerDrawLooper.cpp | 65 ++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 10 deletions(-) diff --git a/include/effects/SkLayerDrawLooper.h b/include/effects/SkLayerDrawLooper.h index d35d70d7dd..682a9dc119 100644 --- a/include/effects/SkLayerDrawLooper.h +++ b/include/effects/SkLayerDrawLooper.h @@ -9,17 +9,38 @@ class SkLayerDrawLooper : public SkDrawLooper { public: SkLayerDrawLooper(); virtual ~SkLayerDrawLooper(); + + enum Bits { + kAlpha_Bit = 1 << 0, //!< use this layer's alpha + kColor_Bit = 1 << 1, //!< use this layer's color + kStyle_Bit = 1 << 2, //!< use this layer's Style/stroke settings + kTextSkewX_Bit = 1 << 3, //!< use this layer's textskewx + kPathEffect_Bit = 1 << 4, //!< use this layer's patheffect + kMaskFilter_Bit = 1 << 5, //!< use this layer's maskfilter + kShader_Bit = 1 << 6, //!< use this layer's shader + kColorFilter_Bit = 1 << 7, //!< use this layer's colorfilter + kXfermode_Bit = 1 << 8, //!< use this layer's xfermode + + kEntirePaint_Bits = -1, //!< use this layer's paint entirely + }; + typedef int32_t BitFlags; - /** Call for each layer you want to add (from top to bottom). - This returns a paint you can modify, but that ptr is only valid until - the next call made to this object. + /** + * Call for each layer you want to add (from top to bottom). + * This returns a paint you can modify, but that ptr is only valid until + * the next call made to this object. + * + * The optional bits parameter specifies which aspects of this paint + * should replace the paint that is passed to the draw call. If 0 is + * specified, then this layer's paint will be ignored. */ - SkPaint* addLayer(SkScalar dx, SkScalar dy); + SkPaint* addLayer(SkScalar dx, SkScalar dy, BitFlags = kEntirePaint_Bits); - /** Helper for addLayer() which passes (0, 0) for the offset parameters + /** + * Helper for addLayer() which passes (0, 0) for the offset parameters */ - SkPaint* addLayer() { - return this->addLayer(0, 0); + SkPaint* addLayer(BitFlags bits = kEntirePaint_Bits) { + return this->addLayer(0, 0, bits); } // overrides from SkDrawLooper @@ -43,6 +64,7 @@ private: Rec* fNext; SkPaint fPaint; SkPoint fOffset; + uint32_t fBits; static Rec* Reverse(Rec*); }; @@ -51,7 +73,9 @@ private: // state-machine during the init/next cycle Rec* fCurrRec; - + + static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags bits); + class MyRegistrar : public SkFlattenable::Registrar { public: MyRegistrar(); diff --git a/src/effects/SkLayerDrawLooper.cpp b/src/effects/SkLayerDrawLooper.cpp index 32b56d6948..ee0fc985cc 100644 --- a/src/effects/SkLayerDrawLooper.cpp +++ b/src/effects/SkLayerDrawLooper.cpp @@ -16,12 +16,13 @@ SkLayerDrawLooper::~SkLayerDrawLooper() { } } -SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) { +SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) { fCount += 1; Rec* rec = SkNEW(Rec); rec->fNext = fRecs; rec->fOffset.set(dx, dy); + rec->fBits = bits; fRecs = rec; return &rec->fPaint; @@ -32,13 +33,73 @@ void SkLayerDrawLooper::init(SkCanvas* canvas) { canvas->save(SkCanvas::kMatrix_SaveFlag); } +void SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src, + BitFlags bits) { + if (kEntirePaint_Bits == bits) { + *dst = src; + return; + } + + SkColor c = dst->getColor(); + if (bits & kAlpha_Bit) { + c &= 0x00FFFFFF; + c |= src.getColor() & 0xFF000000; + } + if (bits & kColor_Bit) { + c &= 0xFF000000; + c |= src.getColor() & 0x00FFFFFF; + } + dst->setColor(c); + + if (bits & kStyle_Bit) { + dst->setStyle(src.getStyle()); + dst->setStrokeWidth(src.getStrokeWidth()); + dst->setStrokeMiter(src.getStrokeMiter()); + dst->setStrokeCap(src.getStrokeCap()); + dst->setStrokeJoin(src.getStrokeJoin()); + } + + if (bits & kTextSkewX_Bit) { + dst->setTextSkewX(src.getTextSkewX()); + } + + if (bits & kPathEffect_Bit) { + dst->setPathEffect(src.getPathEffect()); + } + if (bits & kMaskFilter_Bit) { + dst->setMaskFilter(src.getMaskFilter()); + } + if (bits & kShader_Bit) { + dst->setShader(src.getShader()); + } + if (bits & kColorFilter_Bit) { + dst->setColorFilter(src.getColorFilter()); + } + if (bits & kXfermode_Bit) { + dst->setXfermode(src.getXfermode()); + } + + // we never copy these +#if 0 + dst->setFlags(src.getFlags()); + dst->setTypeface(src.getTypeface()); + dst->setTextSize(src.getTextSize()); + dst->setTextScaleX(src.getTextScaleX()); + dst->setTextSkewX(src.getTextSkewX()); + dst->setRasterizer(src.getRasterizer()); + dst->setLooper(src.getLooper()); + dst->setTextEncoding(src.getTextEncoding()); + dst->setHinting(src.getHinting()); +#endif +} + bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { canvas->restore(); if (NULL == fCurrRec) { return false; } - *paint = fCurrRec->fPaint; + ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits); canvas->save(SkCanvas::kMatrix_SaveFlag); canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY); fCurrRec = fCurrRec->fNext;