Bug 781731 - Fix shadow surface extents so they aren't double padded. r=joe

This commit is contained in:
Anthony Jones 2012-09-02 19:07:05 -04:00
Родитель b25ba9999a
Коммит 15b4ca998d
3 изменённых файлов: 46 добавлений и 29 удалений

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

@ -330,7 +330,8 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
const Rect* aSkipRect) const Rect* aSkipRect)
: mSpreadRadius(aSpreadRadius), : mSpreadRadius(aSpreadRadius),
mBlurRadius(aBlurRadius), mBlurRadius(aBlurRadius),
mData(nullptr) mData(nullptr),
mFreeData(true)
{ {
Rect rect(aRect); Rect rect(aRect);
rect.Inflate(Size(aBlurRadius + aSpreadRadius)); rect.Inflate(Size(aBlurRadius + aSpreadRadius));
@ -384,9 +385,25 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
} }
} }
AlphaBoxBlur::AlphaBoxBlur(uint8_t* aData,
const Rect& aRect,
int32_t aStride,
float aSigma)
: mSpreadRadius(),
mBlurRadius(CalculateBlurRadius(Point(aSigma, aSigma))),
mData(aData),
mFreeData(false),
mStride(aStride),
mRect(aRect.x, aRect.y, aRect.width, aRect.height)
{
}
AlphaBoxBlur::~AlphaBoxBlur() AlphaBoxBlur::~AlphaBoxBlur()
{ {
free(mData); if (mFreeData) {
delete mData;
}
} }
unsigned char* unsigned char*

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

@ -57,6 +57,11 @@ public:
const Rect* aDirtyRect, const Rect* aDirtyRect,
const Rect* aSkipRect); const Rect* aSkipRect);
AlphaBoxBlur(uint8_t* aData,
const Rect& aRect,
int32_t aStride,
float aSigma);
~AlphaBoxBlur(); ~AlphaBoxBlur();
/** /**
@ -135,7 +140,12 @@ private:
/** /**
* A pointer to the backing 8-bit alpha surface. * A pointer to the backing 8-bit alpha surface.
*/ */
unsigned char* mData; uint8_t* mData;
/**
* True if we need to dispose the data.
*/
bool mFreeData;
/** /**
* The stride of the data contained in mData. * The stride of the data contained in mData.

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

@ -387,43 +387,33 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
return; return;
} }
WillChange();
Float width = aSurface->GetSize().width; Float width = aSurface->GetSize().width;
Float height = aSurface->GetSize().height; Float height = aSurface->GetSize().height;
Rect extents(0, 0, width, height);
AlphaBoxBlur blur(extents, IntSize(0, 0),
AlphaBoxBlur::CalculateBlurRadius(Point(aSigma, aSigma)),
nullptr, nullptr);
if (!blur.GetData()) {
return;
}
IntSize blursize = blur.GetSize();
cairo_surface_t* blursurf = cairo_image_surface_create_for_data(blur.GetData(),
CAIRO_FORMAT_A8,
blursize.width,
blursize.height,
blur.GetStride());
ClearSurfaceForUnboundedSource(aOperator);
// Draw the source surface into the surface we're going to blur.
SourceSurfaceCairo* source = static_cast<SourceSurfaceCairo*>(aSurface); SourceSurfaceCairo* source = static_cast<SourceSurfaceCairo*>(aSurface);
cairo_surface_t* surf = source->GetSurface(); cairo_surface_t* surf = source->GetSurface();
cairo_surface_t* blursurf = cairo_image_surface_create(CAIRO_FORMAT_A8,
width,
height);
cairo_t* ctx = cairo_create(blursurf); cairo_t* ctx = cairo_create(blursurf);
cairo_set_source_surface(ctx, surf, 0, 0); cairo_set_source_surface(ctx, surf, 0, 0);
IntRect blurrect = blur.GetRect();
cairo_new_path(ctx); cairo_new_path(ctx);
cairo_rectangle(ctx, blurrect.x, blurrect.y, blurrect.width, blurrect.height); cairo_rectangle(ctx, 0, 0, width, height);
cairo_fill(ctx); cairo_fill(ctx);
cairo_destroy(ctx); cairo_destroy(ctx);
// Blur the result, then use that blurred result as a mask to draw the shadow Rect extents(0, 0, width, height);
// colour to the surface. AlphaBoxBlur blur(cairo_image_surface_get_data(blursurf),
extents,
cairo_image_surface_get_stride(blursurf),
aSigma);
blur.Blur(); blur.Blur();
WillChange();
ClearSurfaceForUnboundedSource(aOperator);
cairo_save(mContext); cairo_save(mContext);
cairo_set_operator(mContext, GfxOpToCairoOp(aOperator)); cairo_set_operator(mContext, GfxOpToCairoOp(aOperator));
cairo_identity_matrix(mContext); cairo_identity_matrix(mContext);