Simplify drawloopers and drawfilters. This allows the canvas to keep its
promise that const SkPaint& stay const (so we don't have bugs if a const paint is referenced from two threads in pictures) git-svn-id: http://skia.googlecode.com/svn/trunk@1074 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
591b6dadb0
commit
4e2b3d3fb1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -19,18 +19,15 @@
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
////////////////// EXPERIMENTAL //////////////////////////
|
||||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
/** Right before something is being draw, filter() is called with the
|
||||
current canvas and paint. If it returns true, then drawing proceeds
|
||||
with the (possibly modified) canvas/paint, and then restore() is called
|
||||
to restore the canvas/paint to their state before filter() was called.
|
||||
If filter returns false, canvas/paint should not have been changed, and
|
||||
restore() will not be called.
|
||||
*/
|
||||
/**
|
||||
* Right before something is being draw, filter() is called with the
|
||||
* paint. The filter may modify the paint as it wishes, which will then be
|
||||
* used for the actual drawing. Note: this modification only lasts for the
|
||||
* current draw, as a temporary copy of the paint is used.
|
||||
*/
|
||||
class SkDrawFilter : public SkRefCnt {
|
||||
public:
|
||||
enum Type {
|
||||
@ -43,14 +40,11 @@ public:
|
||||
kText_Type
|
||||
};
|
||||
|
||||
/** Return true to allow the draw to continue (with possibly modified
|
||||
canvas/paint). If true is returned, then restore() will be called.
|
||||
*/
|
||||
virtual bool filter(SkCanvas*, SkPaint*, Type) = 0;
|
||||
/** If filter() returned true, then restore() will be called to restore the
|
||||
canvas/paint to their previous states
|
||||
*/
|
||||
virtual void restore(SkCanvas*, SkPaint*, Type) = 0;
|
||||
/**
|
||||
* Called with the paint that will be used to draw the specified type.
|
||||
* The implementation may modify the paint as they wish.
|
||||
*/
|
||||
virtual void filter(SkPaint*, Type) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -19,8 +19,6 @@
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
////////////////// EXPERIMENTAL //////////////////////////
|
||||
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
@ -34,24 +32,25 @@ class SkPaint;
|
||||
*/
|
||||
class SK_API SkDrawLooper : public SkFlattenable {
|
||||
public:
|
||||
/** Called right before something is being drawn to the specified canvas
|
||||
with the specified paint. Subclass that want to modify either parameter
|
||||
can do so now.
|
||||
*/
|
||||
virtual void init(SkCanvas*, SkPaint*) {}
|
||||
/** Called in a loop (after init()). Each time true is returned, the object
|
||||
is drawn (possibly with a modified canvas and/or paint). When false is
|
||||
finally returned, drawing for the object stops.
|
||||
*/
|
||||
virtual bool next() { return false; }
|
||||
/** Called after the looper has finally returned false from next(), allowing
|
||||
the looper to restore the canvas/paint to their original states.
|
||||
is this required, since the subclass knows when it is done???
|
||||
should we pass the canvas/paint here, and/or to the next call
|
||||
so that subclasses don't need to retain pointers to them during the
|
||||
loop?
|
||||
*/
|
||||
virtual void restore() {}
|
||||
/**
|
||||
* Called right before something is being drawn. This will be followed by
|
||||
* calls to next() until next() returns false.
|
||||
*/
|
||||
virtual void init(SkCanvas*) = 0;
|
||||
|
||||
/**
|
||||
* Called in a loop (after init()). Each time true is returned, the object
|
||||
* is drawn (possibly with a modified canvas and/or paint). When false is
|
||||
* finally returned, drawing for the object stops.
|
||||
*
|
||||
* On each call, the paint will be in its original state, but the canvas
|
||||
* will be as it was following the previous call to next() or init().
|
||||
*
|
||||
* The implementation must ensure that, when next() finally returns false,
|
||||
* that the canvas has been restored to the state it was initially, before
|
||||
* init() was first called.
|
||||
*/
|
||||
virtual bool next(SkCanvas*, SkPaint* paint) = 0;
|
||||
|
||||
protected:
|
||||
SkDrawLooper() {}
|
||||
|
@ -48,9 +48,8 @@ public:
|
||||
virtual ~SkBlurDrawLooper();
|
||||
|
||||
// overrides from SkDrawLooper
|
||||
virtual void init(SkCanvas*, SkPaint*);
|
||||
virtual bool next();
|
||||
virtual void restore();
|
||||
virtual void init(SkCanvas*);
|
||||
virtual bool next(SkCanvas*, SkPaint* paint);
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
|
||||
@ -64,14 +63,10 @@ protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
SkPaint* fPaint;
|
||||
SkMaskFilter* fBlur;
|
||||
SkColorFilter* fColorFilter;
|
||||
SkScalar fDx, fDy;
|
||||
SkColor fBlurColor;
|
||||
SkColor fSavedColor; // remember the original
|
||||
int fSaveCount;
|
||||
uint32_t fBlurFlags;
|
||||
|
||||
enum State {
|
||||
|
@ -23,9 +23,8 @@ public:
|
||||
}
|
||||
|
||||
// overrides from SkDrawLooper
|
||||
virtual void init(SkCanvas*, SkPaint*);
|
||||
virtual bool next();
|
||||
virtual void restore();
|
||||
virtual void init(SkCanvas*);
|
||||
virtual bool next(SkCanvas*, SkPaint* paint);
|
||||
|
||||
// must be public for Registrar :(
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
@ -49,14 +48,9 @@ private:
|
||||
};
|
||||
Rec* fRecs;
|
||||
int fCount;
|
||||
|
||||
struct Iter {
|
||||
SkPaint fSavedPaint;
|
||||
SkPaint* fPaint;
|
||||
SkCanvas* fCanvas;
|
||||
Rec* fRec;
|
||||
};
|
||||
Iter fIter;
|
||||
|
||||
// state-machine during the init/next cycle
|
||||
Rec* fCurrRec;
|
||||
|
||||
class MyRegistrar : public SkFlattenable::Registrar {
|
||||
public:
|
||||
|
@ -24,8 +24,7 @@ public:
|
||||
SkPaintFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags);
|
||||
|
||||
// overrides
|
||||
virtual bool filter(SkCanvas*, SkPaint*, Type);
|
||||
virtual void restore(SkCanvas*, SkPaint*, Type);
|
||||
virtual void filter(SkPaint*, Type);
|
||||
|
||||
private:
|
||||
uint32_t fPrevFlags; // local cache for filter/restore
|
||||
|
@ -280,65 +280,65 @@ private:
|
||||
|
||||
class AutoDrawLooper {
|
||||
public:
|
||||
AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, SkDrawFilter::Type t)
|
||||
: fCanvas(canvas), fPaint((SkPaint*)&paint), fType(t) {
|
||||
if ((fLooper = paint.getLooper()) != NULL) {
|
||||
fLooper->init(canvas, (SkPaint*)&paint);
|
||||
} else {
|
||||
fOnce = true;
|
||||
}
|
||||
AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint) : fOrigPaint(paint) {
|
||||
fCanvas = canvas;
|
||||
fLooper = paint.getLooper();
|
||||
fFilter = canvas->getDrawFilter();
|
||||
fNeedFilterRestore = false;
|
||||
}
|
||||
fPaint = NULL;
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
fDone = false;
|
||||
|
||||
if (fLooper) {
|
||||
fLooper->init(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
~AutoDrawLooper() {
|
||||
if (fNeedFilterRestore) {
|
||||
SkASSERT(fFilter);
|
||||
fFilter->restore(fCanvas, fPaint, fType);
|
||||
}
|
||||
if (NULL != fLooper) {
|
||||
fLooper->restore();
|
||||
}
|
||||
SkASSERT(fCanvas->getSaveCount() == fSaveCount);
|
||||
}
|
||||
|
||||
bool next() {
|
||||
SkDrawFilter* filter = fFilter;
|
||||
|
||||
// if we drew earlier with a filter, then we need to restore first
|
||||
if (fNeedFilterRestore) {
|
||||
SkASSERT(filter);
|
||||
filter->restore(fCanvas, fPaint, fType);
|
||||
fNeedFilterRestore = false;
|
||||
}
|
||||
|
||||
bool result;
|
||||
|
||||
if (NULL != fLooper) {
|
||||
result = fLooper->next();
|
||||
} else {
|
||||
result = fOnce;
|
||||
fOnce = false;
|
||||
}
|
||||
|
||||
// if we're gonna draw, give the filter a chance to do its work
|
||||
if (result && NULL != filter) {
|
||||
fNeedFilterRestore = result = filter->filter(fCanvas, fPaint,
|
||||
fType);
|
||||
}
|
||||
return result;
|
||||
|
||||
const SkPaint& paint() const {
|
||||
SkASSERT(fPaint);
|
||||
return *fPaint;
|
||||
}
|
||||
|
||||
|
||||
bool next(SkDrawFilter::Type drawType);
|
||||
|
||||
private:
|
||||
SkDrawLooper* fLooper;
|
||||
SkDrawFilter* fFilter;
|
||||
SkCanvas* fCanvas;
|
||||
SkPaint* fPaint;
|
||||
SkDrawFilter::Type fType;
|
||||
bool fOnce;
|
||||
bool fNeedFilterRestore;
|
||||
|
||||
SkTLazy<SkPaint> fLazyPaint;
|
||||
SkCanvas* fCanvas;
|
||||
const SkPaint& fOrigPaint;
|
||||
SkDrawLooper* fLooper;
|
||||
SkDrawFilter* fFilter;
|
||||
const SkPaint* fPaint;
|
||||
int fSaveCount;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
bool AutoDrawLooper::next(SkDrawFilter::Type drawType) {
|
||||
if (fDone) {
|
||||
fPaint = NULL;
|
||||
return false;
|
||||
}
|
||||
if (!fLooper && !fFilter) {
|
||||
fDone = true;
|
||||
fPaint = &fOrigPaint;
|
||||
return true;
|
||||
}
|
||||
|
||||
SkPaint* paint = fLazyPaint.set(fOrigPaint);
|
||||
if (fLooper && !fLooper->next(fCanvas, paint)) {
|
||||
fDone = true;
|
||||
fPaint = NULL;
|
||||
return false;
|
||||
}
|
||||
if (fFilter) {
|
||||
fFilter->filter(paint, drawType);
|
||||
}
|
||||
fPaint = paint;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stack helper for managing a SkBounder. In the destructor, if we were
|
||||
given a bounder, we call its commit() method, signifying that we are
|
||||
done accumulating bounds for that draw.
|
||||
@ -380,14 +380,14 @@ private:
|
||||
|
||||
////////// macros to place around the internal draw calls //////////////////
|
||||
|
||||
#define ITER_BEGIN(paint, type) \
|
||||
#define LOOPER_BEGIN(paint, type) \
|
||||
/* AutoValidator validator(fMCRec->fTopLayer->fDevice); */ \
|
||||
AutoDrawLooper looper(this, paint, type); \
|
||||
while (looper.next()) { \
|
||||
AutoDrawLooper looper(this, paint); \
|
||||
while (looper.next(type)) { \
|
||||
SkAutoBounderCommit ac(fBounder); \
|
||||
SkDrawIter iter(this);
|
||||
|
||||
#define ITER_END }
|
||||
#define LOOPER_END }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -853,12 +853,12 @@ void SkCanvas::drawDevice(SkDevice* device, int x, int y,
|
||||
paint = &tmp;
|
||||
}
|
||||
|
||||
ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawDevice(iter, device, x - iter.getX(), y - iter.getY(),
|
||||
*paint);
|
||||
looper.paint());
|
||||
}
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@ -1190,13 +1190,13 @@ SkDevice* SkCanvas::createDevice(SkBitmap::Config config, int width, int height,
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkCanvas::drawPaint(const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kPaint_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPaint(iter, paint);
|
||||
iter.fDevice->drawPaint(iter, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
||||
@ -1207,13 +1207,13 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
||||
|
||||
SkASSERT(pts != NULL);
|
||||
|
||||
ITER_BEGIN(paint, SkDrawFilter::kPoint_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPoints(iter, mode, count, pts, paint);
|
||||
iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
@ -1225,13 +1225,13 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
}
|
||||
}
|
||||
|
||||
ITER_BEGIN(paint, SkDrawFilter::kRect_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRect(iter, r, paint);
|
||||
iter.fDevice->drawRect(iter, r, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
|
||||
@ -1244,13 +1244,13 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
|
||||
}
|
||||
}
|
||||
|
||||
ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPath(iter, path, paint);
|
||||
iter.fDevice->drawPath(iter, path, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
|
||||
@ -1328,13 +1328,13 @@ void SkCanvas::commonDrawBitmap(const SkBitmap& bitmap, const SkIRect* srcRect,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
SkDEBUGCODE(bitmap.validate();)
|
||||
|
||||
ITER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kBitmap_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, paint);
|
||||
iter.fDevice->drawBitmap(iter, bitmap, srcRect, matrix, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
@ -1350,13 +1350,13 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
paint = &tmp;
|
||||
}
|
||||
|
||||
ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawSprite(iter, bitmap, x - iter.getX(), y - iter.getY(),
|
||||
*paint);
|
||||
looper.paint());
|
||||
}
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
class SkDeviceFilteredPaint {
|
||||
@ -1382,54 +1382,54 @@ private:
|
||||
|
||||
void SkCanvas::drawText(const void* text, size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, paint);
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawPosText(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, paint);
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, paint);
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
|
||||
matrix, paint);
|
||||
matrix, looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
@ -1437,14 +1437,14 @@ void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint,
|
||||
const SkPath& path, const SkMatrix* matrix) {
|
||||
|
||||
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos,
|
||||
paint, path, matrix);
|
||||
looper.paint(), path, matrix);
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1453,14 +1453,15 @@ void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) {
|
||||
ITER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
|
||||
colors, xmode, indices, indexCount, paint);
|
||||
colors, xmode, indices, indexCount,
|
||||
looper.paint());
|
||||
}
|
||||
|
||||
ITER_END
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
void SkCanvas::drawData(const void* data, size_t length) {
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
|
||||
SkColor color, uint32_t flags)
|
||||
: fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags)
|
||||
{
|
||||
: fDx(dx), fDy(dy), fBlurColor(color), fBlurFlags(flags) {
|
||||
|
||||
SkASSERT(flags <= kAll_BlurFlag);
|
||||
if (radius > 0)
|
||||
{
|
||||
if (radius > 0) {
|
||||
uint32_t blurFlags = flags & kIgnoreTransform_BlurFlag ?
|
||||
SkBlurMaskFilter::kIgnoreTransform_BlurFlag :
|
||||
SkBlurMaskFilter::kNone_BlurFlag;
|
||||
@ -23,28 +22,23 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
|
||||
fBlur = SkBlurMaskFilter::Create(radius,
|
||||
SkBlurMaskFilter::kNormal_BlurStyle,
|
||||
blurFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fBlur = NULL;
|
||||
}
|
||||
|
||||
if (flags & kOverrideColor_BlurFlag)
|
||||
{
|
||||
if (flags & kOverrideColor_BlurFlag) {
|
||||
// Set alpha to 1 for the override since transparency will already
|
||||
// be baked into the blurred mask.
|
||||
SkColor opaqueColor = SkColorSetA(color, 255);
|
||||
//The SrcIn xfer mode will multiply 'color' by the incoming alpha
|
||||
fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor, SkXfermode::kSrcIn_Mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
fColorFilter = SkColorFilter::CreateModeFilter(opaqueColor,
|
||||
SkXfermode::kSrcIn_Mode);
|
||||
} else {
|
||||
fColorFilter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
|
||||
{
|
||||
SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer) {
|
||||
fDx = buffer.readScalar();
|
||||
fDy = buffer.readScalar();
|
||||
fBlurColor = buffer.readU32();
|
||||
@ -53,14 +47,12 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
|
||||
fBlurFlags = buffer.readU32() & kAll_BlurFlag;
|
||||
}
|
||||
|
||||
SkBlurDrawLooper::~SkBlurDrawLooper()
|
||||
{
|
||||
SkBlurDrawLooper::~SkBlurDrawLooper() {
|
||||
SkSafeUnref(fBlur);
|
||||
SkSafeUnref(fColorFilter);
|
||||
}
|
||||
|
||||
void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
|
||||
{
|
||||
void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer) {
|
||||
buffer.writeScalar(fDx);
|
||||
buffer.writeScalar(fDy);
|
||||
buffer.write32(fBlurColor);
|
||||
@ -69,63 +61,38 @@ void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
|
||||
buffer.write32(fBlurFlags);
|
||||
}
|
||||
|
||||
void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
|
||||
{
|
||||
// we do nothing if a maskfilter is already installed
|
||||
if (paint->getMaskFilter() != NULL)
|
||||
fState = kDone;
|
||||
else
|
||||
{
|
||||
fState = kBeforeEdge;
|
||||
fPaint = paint;
|
||||
fCanvas = canvas;
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
}
|
||||
void SkBlurDrawLooper::init(SkCanvas* canvas) {
|
||||
fState = kBeforeEdge;
|
||||
}
|
||||
|
||||
bool SkBlurDrawLooper::next()
|
||||
{
|
||||
bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
|
||||
switch (fState) {
|
||||
case kBeforeEdge:
|
||||
fSavedColor = fPaint->getColor();
|
||||
fPaint->setColor(fBlurColor);
|
||||
fPaint->setMaskFilter(fBlur);
|
||||
fPaint->setColorFilter(fColorFilter);
|
||||
fCanvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
if (fBlurFlags & kIgnoreTransform_BlurFlag)
|
||||
{
|
||||
SkMatrix transform(fCanvas->getTotalMatrix());
|
||||
transform.postTranslate(fDx, fDy);
|
||||
fCanvas->setMatrix(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
fCanvas->translate(fDx, fDy);
|
||||
}
|
||||
fState = kAfterEdge;
|
||||
return true;
|
||||
case kAfterEdge:
|
||||
fPaint->setColor(fSavedColor);
|
||||
fPaint->setMaskFilter(NULL);
|
||||
fPaint->setColorFilter(NULL);
|
||||
fCanvas->restore(); // to remove the translate we did earlier
|
||||
fState = kDone;
|
||||
return true;
|
||||
default:
|
||||
SkASSERT(kDone == fState);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SkBlurDrawLooper::restore()
|
||||
{
|
||||
if (kAfterEdge == fState)
|
||||
{
|
||||
fPaint->setColor(fSavedColor);
|
||||
fPaint->setMaskFilter(NULL);
|
||||
fPaint->setColorFilter(NULL);
|
||||
fCanvas->restore(); // to remove the translate we did earlier
|
||||
fState = kDone;
|
||||
case kBeforeEdge:
|
||||
// we do nothing if a maskfilter is already installed
|
||||
if (paint->getMaskFilter()) {
|
||||
fState = kDone;
|
||||
return false;
|
||||
}
|
||||
paint->setColor(fBlurColor);
|
||||
paint->setMaskFilter(fBlur);
|
||||
paint->setColorFilter(fColorFilter);
|
||||
canvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
if (fBlurFlags & kIgnoreTransform_BlurFlag) {
|
||||
SkMatrix transform(canvas->getTotalMatrix());
|
||||
transform.postTranslate(fDx, fDy);
|
||||
canvas->setMatrix(transform);
|
||||
} else {
|
||||
canvas->translate(fDx, fDy);
|
||||
}
|
||||
fState = kAfterEdge;
|
||||
return true;
|
||||
case kAfterEdge:
|
||||
canvas->restore();
|
||||
fState = kDone;
|
||||
return true;
|
||||
default:
|
||||
SkASSERT(kDone == fState);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,31 +27,21 @@ SkPaint* SkLayerDrawLooper::addLayer(SkScalar dx, SkScalar dy) {
|
||||
return &rec->fPaint;
|
||||
}
|
||||
|
||||
void SkLayerDrawLooper::init(SkCanvas* canvas, SkPaint* paint) {
|
||||
fIter.fSavedPaint = *paint;
|
||||
fIter.fPaint = paint;
|
||||
fIter.fCanvas = canvas;
|
||||
fIter.fRec = fRecs;
|
||||
void SkLayerDrawLooper::init(SkCanvas* canvas) {
|
||||
fCurrRec = fRecs;
|
||||
canvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
}
|
||||
|
||||
bool SkLayerDrawLooper::next() {
|
||||
Rec* rec = fIter.fRec;
|
||||
if (rec) {
|
||||
*fIter.fPaint = rec->fPaint;
|
||||
fIter.fCanvas->restore();
|
||||
fIter.fCanvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
fIter.fCanvas->translate(rec->fOffset.fX, rec->fOffset.fY);
|
||||
|
||||
fIter.fRec = rec->fNext;
|
||||
return true;
|
||||
bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) {
|
||||
canvas->restore();
|
||||
if (NULL == fCurrRec) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkLayerDrawLooper::restore() {
|
||||
fIter.fCanvas->restore();
|
||||
*fIter.fPaint = fIter.fSavedPaint;
|
||||
*paint = fCurrRec->fPaint;
|
||||
canvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||
canvas->translate(fCurrRec->fOffset.fX, fCurrRec->fOffset.fY);
|
||||
return true;
|
||||
}
|
||||
|
||||
SkLayerDrawLooper::Rec* SkLayerDrawLooper::Rec::Reverse(Rec* head) {
|
||||
|
@ -2,21 +2,12 @@
|
||||
#include "SkPaint.h"
|
||||
|
||||
SkPaintFlagsDrawFilter::SkPaintFlagsDrawFilter(uint32_t clearFlags,
|
||||
uint32_t setFlags)
|
||||
{
|
||||
uint32_t setFlags) {
|
||||
fClearFlags = SkToU16(clearFlags & SkPaint::kAllFlags);
|
||||
fSetFlags = SkToU16(setFlags & SkPaint::kAllFlags);
|
||||
}
|
||||
|
||||
bool SkPaintFlagsDrawFilter::filter(SkCanvas*, SkPaint* paint, Type)
|
||||
{
|
||||
fPrevFlags = paint->getFlags();
|
||||
paint->setFlags((fPrevFlags & ~fClearFlags) | fSetFlags);
|
||||
return true;
|
||||
void SkPaintFlagsDrawFilter::filter(SkPaint* paint, Type) {
|
||||
paint->setFlags((paint->getFlags() & ~fClearFlags) | fSetFlags);
|
||||
}
|
||||
|
||||
void SkPaintFlagsDrawFilter::restore(SkCanvas*, SkPaint* paint, Type)
|
||||
{
|
||||
paint->setFlags(fPrevFlags);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user