/**
* 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
* 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;
/**
* 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*);
// 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:
#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) {}
enum Style {
kRect_Style,
kOval_Style,
- kRRect_Style
+ kRRect_Style,
+ kFrame_Style
};
RDraw(const SkRect& r, Style s) : fRect(r), fStyle(s) {}
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;
+ }
}
}
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;
}
virtual void onDraw(SkCanvas* canvas) {
this->drawBG(canvas);
+ // test_strokerect(canvas);
+ // return;
for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
(*iter)->draw(canvas);
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);
this->drawBG(canvas);
SkPaint paint;
+ paint.setTextSize(SkIntToScalar(72));
paint.setLooper(fLooper);
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
#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;
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) {
}
}
-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;
}
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) {