add mask for paint-bits to layerdrawlooper

change addLayer variants that don't respect paint changes to return void



git-svn-id: http://skia.googlecode.com/svn/trunk@1123 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
mike@reedtribe.org 2011-04-14 01:22:45 +00:00
Родитель 399d454be9
Коммит a8282ef8f9
4 изменённых файлов: 102 добавлений и 31 удалений

Просмотреть файл

@ -33,6 +33,12 @@ public:
/**
* Info for how to apply the layer's paint and offset.
*
* fFlagsMask selects which flags in the layer's paint should be applied.
* result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask)
* In the extreme:
* If fFlagsMask is 0, we ignore all of the layer's flags
* If fFlagsMask is -1, we use all of the layer's flags
*
* fColorMode controls how we compute the final color for the layer:
* The layer's paint's color is treated as the SRC
* The draw's paint's color is treated as the DST
@ -42,6 +48,7 @@ public:
* kDst_Mode: to just keep the draw's color, ignoring the layer's
*/
struct LayerInfo {
uint32_t fFlagsMask; // SkPaint::Flags
BitFlags fPaintBits;
SkXfermode::Mode fColorMode;
SkVector fOffset;
@ -60,29 +67,19 @@ public:
/**
* 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 next call made to addLayer().
*/
SkPaint* addLayer(const LayerInfo&);
/**
* 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 returned paint will be ignored, and only the offset will be applied
*
* DEPRECATED: call addLayer(const LayerInfo&)
* This layer will draw with the original paint, ad the specified offset
*/
SkPaint* addLayer(SkScalar dx, SkScalar dy);
void addLayer(SkScalar dx, SkScalar dy);
/**
* Helper for addLayer() which passes (0, 0) for the offset parameters.
* This layer will not affect the drawing in any way.
*
* DEPRECATED: call addLayer(const LayerInfo&)
* This layer will with the original paint and no offset.
*/
SkPaint* addLayer() {
return this->addLayer(0, 0);
}
void addLayer() { this->addLayer(0, 0); }
// overrides from SkDrawLooper
virtual void init(SkCanvas*);
@ -114,8 +111,7 @@ private:
// state-machine during the init/next cycle
Rec* fCurrRec;
static void ApplyBits(SkPaint* dst, const SkPaint& src, BitFlags,
SkXfermode::Mode);
static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&);
class MyRegistrar : public SkFlattenable::Registrar {
public:

Просмотреть файл

@ -4,6 +4,55 @@
#include "SkGraphics.h"
#include "SkRandom.h"
static void test_strokerect(SkCanvas* canvas, const SkRect& r) {
SkPaint p;
p.setAntiAlias(true);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(4);
canvas->drawRect(r, p);
SkPath path;
SkRect r2(r);
r2.offset(18, 0);
path.addRect(r2);
canvas->drawPath(path, p);
}
static void test_strokerect(SkCanvas* canvas) {
canvas->drawColor(SK_ColorWHITE);
SkRect r;
r.set(10, 10, 14, 14);
r.offset(0.25, 0.3333);
test_strokerect(canvas, r);
canvas->translate(0, 20);
r.set(10, 10, 14.5f, 14.5f);
r.offset(0.25, 0.3333);
test_strokerect(canvas, r);
canvas->translate(0, 20);
r.set(10, 10, 14.5f, 20);
r.offset(0.25, 0.3333);
test_strokerect(canvas, r);
canvas->translate(0, 20);
r.set(10, 10, 20, 14.5f);
r.offset(0.25, 0.3333);
test_strokerect(canvas, r);
canvas->translate(0, 20);
r.set(10, 10, 20, 20);
r.offset(0.25, 0.3333);
test_strokerect(canvas, r);
canvas->translate(0, 20);
}
class Draw : public SkRefCnt {
public:
Draw() : fFlags(0) {}
@ -83,7 +132,8 @@ public:
enum Style {
kRect_Style,
kOval_Style,
kRRect_Style
kRRect_Style,
kFrame_Style
};
RDraw(const SkRect& r, Style s) : fRect(r), fStyle(s) {}
@ -116,6 +166,15 @@ protected:
canvas->drawRoundRect(fRect, rx, ry, fPaint);
break;
}
case kFrame_Style: {
SkPath path;
path.addOval(fRect, SkPath::kCW_Direction);
SkRect r = fRect;
r.inset(fRect.width()/6, 0);
path.addOval(r, SkPath::kCCW_Direction);
canvas->drawPath(path, fPaint);
break;
}
}
}
@ -158,7 +217,8 @@ public:
r.set(p0.x(), p0.y(), p1.x(), p1.y());
r.sort();
RDraw* d = new RDraw(r, RDraw::kRRect_Style);
// RDraw* d = new RDraw(r, RDraw::kRRect_Style);
RDraw* d = new RDraw(r, RDraw::kFrame_Style);
d->setPaint(this->getPaint());
return d;
}
@ -217,6 +277,8 @@ protected:
virtual void onDraw(SkCanvas* canvas) {
this->drawBG(canvas);
// test_strokerect(canvas);
// return;
for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
(*iter)->draw(canvas);

Просмотреть файл

@ -30,14 +30,18 @@ public:
fLooper = new SkLayerDrawLooper;
SkLayerDrawLooper::LayerInfo info;
info.fFlagsMask = SkPaint::kAntiAlias_Flag;
info.fPaintBits = SkLayerDrawLooper::kStyle_Bit | SkLayerDrawLooper::kMaskFilter_Bit;
info.fColorMode = SkXfermode::kSrc_Mode;
for (int i = 0; i < SK_ARRAY_COUNT(gParams); i++) {
SkPaint* paint = fLooper->addLayer(gParams[i].fOffset,
gParams[i].fOffset);
info.fOffset.set(gParams[i].fOffset, gParams[i].fOffset);
SkPaint* paint = fLooper->addLayer(info);
paint->setAntiAlias(true);
paint->setColor(gParams[i].fColor);
paint->setStyle(gParams[i].fStyle);
paint->setStrokeWidth(gParams[i].fWidth);
paint->setTextSize(SkIntToScalar(72));
if (gParams[i].fBlur > 0) {
SkMaskFilter* mf = SkBlurMaskFilter::Create(SkIntToScalar(gParams[i].fBlur),
SkBlurMaskFilter::kNormal_BlurStyle);
@ -69,6 +73,7 @@ protected:
this->drawBG(canvas);
SkPaint paint;
paint.setTextSize(SkIntToScalar(72));
paint.setLooper(fLooper);
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),

Просмотреть файл

@ -5,7 +5,8 @@
#include "SkUnPreMultiply.h"
SkLayerDrawLooper::LayerInfo::LayerInfo() {
fPaintBits = 0; // ignore out paint
fFlagsMask = 0; // ignore our paint flags
fPaintBits = 0; // ignore our paint fields
fColorMode = SkXfermode::kDst_Mode; // ignore our color
fOffset.set(0, 0);
fPostTranslate = false;
@ -36,11 +37,11 @@ SkPaint* SkLayerDrawLooper::addLayer(const LayerInfo& info) {
return &rec->fPaint;
}
SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
void SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
LayerInfo info;
info.fOffset.set(dx, dy);
return this->addLayer(info);
(void)this->addLayer(info);
}
void SkLayerDrawLooper::init(SkCanvas* canvas) {
@ -63,17 +64,25 @@ static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
}
}
void SkLayerDrawLooper::ApplyBits(SkPaint* dst, const SkPaint& src,
BitFlags bits, SkXfermode::Mode colorMode) {
dst->setColor(xferColor(src.getColor(), dst->getColor(), colorMode));
void SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src,
const LayerInfo& info) {
uint32_t mask = info.fFlagsMask;
dst->setFlags((dst->getFlags() & ~mask) | (src.getFlags() & mask));
dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode));
BitFlags bits = info.fPaintBits;
if (0 == bits) {
return;
}
if (kEntirePaint_Bits == bits) {
// we've already compute the color, so save it from the assignment
// we've already computed these, so save it from the assignment
uint32_t f = dst->getFlags();
SkColor c = dst->getColor();
*dst = src;
dst->setFlags(f);
dst->setColor(c);
return;
}
@ -133,8 +142,7 @@ bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
return false;
}
ApplyBits(paint, fCurrRec->fPaint, fCurrRec->fInfo.fPaintBits,
fCurrRec->fInfo.fColorMode);
ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo);
canvas->save(SkCanvas::kMatrix_SaveFlag);
if (fCurrRec->fInfo.fPostTranslate) {