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
This commit is contained in:
mike@reedtribe.org 2011-04-08 02:41:54 +00:00
parent bd36ebe294
commit 0e2810be95
2 changed files with 95 additions and 10 deletions

View File

@ -9,17 +9,38 @@ class SkLayerDrawLooper : public SkDrawLooper {
public: public:
SkLayerDrawLooper(); SkLayerDrawLooper();
virtual ~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 * Call for each layer you want to add (from top to bottom).
the next call made to this object. * 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() { SkPaint* addLayer(BitFlags bits = kEntirePaint_Bits) {
return this->addLayer(0, 0); return this->addLayer(0, 0, bits);
} }
// overrides from SkDrawLooper // overrides from SkDrawLooper
@ -43,6 +64,7 @@ private:
Rec* fNext; Rec* fNext;
SkPaint fPaint; SkPaint fPaint;
SkPoint fOffset; SkPoint fOffset;
uint32_t fBits;
static Rec* Reverse(Rec*); static Rec* Reverse(Rec*);
}; };
@ -51,7 +73,9 @@ private:
// state-machine during the init/next cycle // state-machine during the init/next cycle
Rec* fCurrRec; Rec* fCurrRec;
static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags bits);
class MyRegistrar : public SkFlattenable::Registrar { class MyRegistrar : public SkFlattenable::Registrar {
public: public:
MyRegistrar(); MyRegistrar();

View File

@ -16,12 +16,13 @@ SkLayerDrawLooper::~SkLayerDrawLooper() {
} }
} }
SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) { SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy, BitFlags bits) {
fCount += 1; fCount += 1;
Rec* rec = SkNEW(Rec); Rec* rec = SkNEW(Rec);
rec->fNext = fRecs; rec->fNext = fRecs;
rec->fOffset.set(dx, dy); rec->fOffset.set(dx, dy);
rec->fBits = bits;
fRecs = rec; fRecs = rec;
return &rec->fPaint; return &rec->fPaint;
@ -32,13 +33,73 @@ void SkLayerDrawLooper::init(SkCanvas* canvas) {
canvas->save(SkCanvas::kMatrix_SaveFlag); 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) { bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
canvas->restore(); canvas->restore();
if (NULL == fCurrRec) { if (NULL == fCurrRec) {
return false; return false;
} }
*paint = fCurrRec->fPaint; ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fBits);
canvas->save(SkCanvas::kMatrix_SaveFlag); canvas->save(SkCanvas::kMatrix_SaveFlag);
canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY); canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
fCurrRec = fCurrRec->fNext; fCurrRec = fCurrRec->fNext;