Patch by Mike Lawther (mikelawther@chromium.org).
The HTML5 canvas client of BlurDrawLooper needs the option to not apply the canvas transform to the blur offset. see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-elemen... - "The shadowOffsetX and shadowOffsetY attributes specify the distance that the shadow will be offset in the positive horizontal and positive vertical distance respectively. Their values are in coordinate space units. They are not affected by the current transformation matrix." This patch is part of fixing http://code.google.com/p/chromium/issues/detail?id=64647. Review URL: http://codereview.appspot.com/3391041/ git-svn-id: http://skia.googlecode.com/svn/trunk@631 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
8cfdf01ff9
commit
038aff623d
@ -29,7 +29,19 @@ class SkMaskFilter;
|
|||||||
*/
|
*/
|
||||||
class SkBlurDrawLooper : public SkDrawLooper {
|
class SkBlurDrawLooper : public SkDrawLooper {
|
||||||
public:
|
public:
|
||||||
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color);
|
enum BlurFlags {
|
||||||
|
kNone_BlurFlag = 0x00,
|
||||||
|
/**
|
||||||
|
The blur layer's dx/dy/radius aren't affected by the canvas
|
||||||
|
transform.
|
||||||
|
*/
|
||||||
|
kIgnoreTransform_BlurFlag = 0x01,
|
||||||
|
/** mask for all blur flags */
|
||||||
|
kAll_BlurFlag = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color,
|
||||||
|
uint32_t flags = kNone_BlurFlag);
|
||||||
virtual ~SkBlurDrawLooper();
|
virtual ~SkBlurDrawLooper();
|
||||||
|
|
||||||
// overrides from SkDrawLooper
|
// overrides from SkDrawLooper
|
||||||
@ -41,6 +53,7 @@ public:
|
|||||||
return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
|
return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkBlurDrawLooper(SkFlattenableReadBuffer&);
|
SkBlurDrawLooper(SkFlattenableReadBuffer&);
|
||||||
// overrides from SkFlattenable
|
// overrides from SkFlattenable
|
||||||
@ -55,6 +68,7 @@ private:
|
|||||||
SkColor fBlurColor;
|
SkColor fBlurColor;
|
||||||
SkColor fSavedColor; // remember the original
|
SkColor fSavedColor; // remember the original
|
||||||
int fSaveCount;
|
int fSaveCount;
|
||||||
|
uint32_t fBlurFlags;
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
kBeforeEdge,
|
kBeforeEdge,
|
||||||
|
@ -32,12 +32,22 @@ public:
|
|||||||
kBlurStyleCount
|
kBlurStyleCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BlurFlags {
|
||||||
|
kNone_BlurFlag = 0x00,
|
||||||
|
/** The blur layer's radius is not affected by transforms */
|
||||||
|
kIgnoreTransform_BlurFlag = 0x01,
|
||||||
|
/** mask for all blur flags */
|
||||||
|
kAll_BlurFlag = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
/** Create a blur maskfilter.
|
/** Create a blur maskfilter.
|
||||||
@param radius The radius to extend the blur from the original mask. Must be > 0.
|
@param radius The radius to extend the blur from the original mask. Must be > 0.
|
||||||
@param style The BlurStyle to use
|
@param style The BlurStyle to use
|
||||||
|
@param flags Flags to use - defaults to none
|
||||||
@return The new blur maskfilter
|
@return The new blur maskfilter
|
||||||
*/
|
*/
|
||||||
static SkMaskFilter* Create(SkScalar radius, BlurStyle style);
|
static SkMaskFilter* Create(SkScalar radius, BlurStyle style,
|
||||||
|
uint32_t flags = kNone_BlurFlag);
|
||||||
|
|
||||||
/** Create an emboss maskfilter
|
/** Create an emboss maskfilter
|
||||||
@param direction array of 3 scalars [x, y, z] specifying the direction of the light source
|
@param direction array of 3 scalars [x, y, z] specifying the direction of the light source
|
||||||
|
@ -5,12 +5,20 @@
|
|||||||
#include "SkMaskFilter.h"
|
#include "SkMaskFilter.h"
|
||||||
|
|
||||||
SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
|
SkBlurDrawLooper::SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy,
|
||||||
SkColor color)
|
SkColor color, uint32_t flags)
|
||||||
: fDx(dx), fDy(dy), fBlurColor(color)
|
: 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;
|
||||||
|
|
||||||
fBlur = SkBlurMaskFilter::Create(radius,
|
fBlur = SkBlurMaskFilter::Create(radius,
|
||||||
SkBlurMaskFilter::kNormal_BlurStyle);
|
SkBlurMaskFilter::kNormal_BlurStyle,
|
||||||
|
blurFlags);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fBlur = NULL;
|
fBlur = NULL;
|
||||||
}
|
}
|
||||||
@ -21,6 +29,7 @@ SkBlurDrawLooper::SkBlurDrawLooper(SkFlattenableReadBuffer& buffer)
|
|||||||
fDy = buffer.readScalar();
|
fDy = buffer.readScalar();
|
||||||
fBlurColor = buffer.readU32();
|
fBlurColor = buffer.readU32();
|
||||||
fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
|
fBlur = static_cast<SkMaskFilter*>(buffer.readFlattenable());
|
||||||
|
fBlurFlags = buffer.readU32() & kAll_BlurFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkBlurDrawLooper::~SkBlurDrawLooper()
|
SkBlurDrawLooper::~SkBlurDrawLooper()
|
||||||
@ -34,6 +43,7 @@ void SkBlurDrawLooper::flatten(SkFlattenableWriteBuffer& buffer)
|
|||||||
buffer.writeScalar(fDy);
|
buffer.writeScalar(fDy);
|
||||||
buffer.write32(fBlurColor);
|
buffer.write32(fBlurColor);
|
||||||
buffer.writeFlattenable(fBlur);
|
buffer.writeFlattenable(fBlur);
|
||||||
|
buffer.write32(fBlurFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
|
void SkBlurDrawLooper::init(SkCanvas* canvas, SkPaint* paint)
|
||||||
@ -58,7 +68,16 @@ bool SkBlurDrawLooper::next()
|
|||||||
fPaint->setColor(fBlurColor);
|
fPaint->setColor(fBlurColor);
|
||||||
fPaint->setMaskFilter(fBlur);
|
fPaint->setMaskFilter(fBlur);
|
||||||
fCanvas->save(SkCanvas::kMatrix_SaveFlag);
|
fCanvas->save(SkCanvas::kMatrix_SaveFlag);
|
||||||
fCanvas->translate(fDx, fDy);
|
if (fBlurFlags & kIgnoreTransform_BlurFlag)
|
||||||
|
{
|
||||||
|
SkMatrix transform(fCanvas->getTotalMatrix());
|
||||||
|
transform.postTranslate(fDx, fDy);
|
||||||
|
fCanvas->setMatrix(transform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fCanvas->translate(fDx, fDy);
|
||||||
|
}
|
||||||
fState = kAfterEdge;
|
fState = kAfterEdge;
|
||||||
return true;
|
return true;
|
||||||
case kAfterEdge:
|
case kAfterEdge:
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
class SkBlurMaskFilterImpl : public SkMaskFilter {
|
class SkBlurMaskFilterImpl : public SkMaskFilter {
|
||||||
public:
|
public:
|
||||||
SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style);
|
SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style, uint32_t flags);
|
||||||
|
|
||||||
// overrides from SkMaskFilter
|
// overrides from SkMaskFilter
|
||||||
virtual SkMask::Format getFormat();
|
virtual SkMask::Format getFormat();
|
||||||
@ -39,24 +39,28 @@ public:
|
|||||||
private:
|
private:
|
||||||
SkScalar fRadius;
|
SkScalar fRadius;
|
||||||
SkBlurMaskFilter::BlurStyle fBlurStyle;
|
SkBlurMaskFilter::BlurStyle fBlurStyle;
|
||||||
|
uint32_t fBlurFlags;
|
||||||
|
|
||||||
SkBlurMaskFilterImpl(SkFlattenableReadBuffer&);
|
SkBlurMaskFilterImpl(SkFlattenableReadBuffer&);
|
||||||
|
|
||||||
typedef SkMaskFilter INHERITED;
|
typedef SkMaskFilter INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style)
|
SkMaskFilter* SkBlurMaskFilter::Create(SkScalar radius, SkBlurMaskFilter::BlurStyle style,
|
||||||
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount)
|
if (radius <= 0 || (unsigned)style >= SkBlurMaskFilter::kBlurStyleCount
|
||||||
|
|| flags > SkBlurMaskFilter::kAll_BlurFlag)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style));
|
return SkNEW_ARGS(SkBlurMaskFilterImpl, (radius, style, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style)
|
SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::BlurStyle style,
|
||||||
: fRadius(radius), fBlurStyle(style)
|
uint32_t flags)
|
||||||
|
: fRadius(radius), fBlurStyle(style), fBlurFlags(flags)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
fGamma = NULL;
|
fGamma = NULL;
|
||||||
@ -71,6 +75,7 @@ SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkScalar radius, SkBlurMaskFilter::Bl
|
|||||||
#endif
|
#endif
|
||||||
SkASSERT(radius >= 0);
|
SkASSERT(radius >= 0);
|
||||||
SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount);
|
SkASSERT((unsigned)style < SkBlurMaskFilter::kBlurStyleCount);
|
||||||
|
SkASSERT(flags <= SkBlurMaskFilter::kAll_BlurFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkMask::Format SkBlurMaskFilterImpl::getFormat()
|
SkMask::Format SkBlurMaskFilterImpl::getFormat()
|
||||||
@ -80,7 +85,12 @@ SkMask::Format SkBlurMaskFilterImpl::getFormat()
|
|||||||
|
|
||||||
bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin)
|
bool SkBlurMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& matrix, SkIPoint* margin)
|
||||||
{
|
{
|
||||||
SkScalar radius = matrix.mapRadius(fRadius);
|
SkScalar radius;
|
||||||
|
if (fBlurFlags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag)
|
||||||
|
radius = fRadius;
|
||||||
|
else
|
||||||
|
radius = matrix.mapRadius(fRadius);
|
||||||
|
|
||||||
// To avoid unseemly allocation requests (esp. for finite platforms like
|
// To avoid unseemly allocation requests (esp. for finite platforms like
|
||||||
// handset) we limit the radius so something manageable. (as opposed to
|
// handset) we limit the radius so something manageable. (as opposed to
|
||||||
// a request like 10,000)
|
// a request like 10,000)
|
||||||
@ -113,6 +123,7 @@ SkBlurMaskFilterImpl::SkBlurMaskFilterImpl(SkFlattenableReadBuffer& buffer) : Sk
|
|||||||
{
|
{
|
||||||
fRadius = buffer.readScalar();
|
fRadius = buffer.readScalar();
|
||||||
fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32();
|
fBlurStyle = (SkBlurMaskFilter::BlurStyle)buffer.readS32();
|
||||||
|
fBlurFlags = buffer.readU32() & SkBlurMaskFilter::kAll_BlurFlag;
|
||||||
SkASSERT(fRadius >= 0);
|
SkASSERT(fRadius >= 0);
|
||||||
SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
|
SkASSERT((unsigned)fBlurStyle < SkBlurMaskFilter::kBlurStyleCount);
|
||||||
}
|
}
|
||||||
@ -122,6 +133,7 @@ void SkBlurMaskFilterImpl::flatten(SkFlattenableWriteBuffer& buffer)
|
|||||||
this->INHERITED::flatten(buffer);
|
this->INHERITED::flatten(buffer);
|
||||||
buffer.writeScalar(fRadius);
|
buffer.writeScalar(fRadius);
|
||||||
buffer.write32(fBlurStyle);
|
buffer.write32(fBlurStyle);
|
||||||
|
buffer.write32(fBlurFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user