diff --git a/gfx/2d/Blur.cpp b/gfx/2d/Blur.cpp index 9fe879836307..6849d8b21769 100644 --- a/gfx/2d/Blur.cpp +++ b/gfx/2d/Blur.cpp @@ -330,7 +330,8 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect, const Rect* aSkipRect) : mSpreadRadius(aSpreadRadius), mBlurRadius(aBlurRadius), - mData(nullptr) + mData(nullptr), + mFreeData(true) { Rect rect(aRect); 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() { - free(mData); + if (mFreeData) { + delete mData; + } } unsigned char* diff --git a/gfx/2d/Blur.h b/gfx/2d/Blur.h index 30d84e296de5..68bb06d4a9f4 100644 --- a/gfx/2d/Blur.h +++ b/gfx/2d/Blur.h @@ -57,6 +57,11 @@ public: const Rect* aDirtyRect, const Rect* aSkipRect); + AlphaBoxBlur(uint8_t* aData, + const Rect& aRect, + int32_t aStride, + float aSigma); + ~AlphaBoxBlur(); /** @@ -135,7 +140,12 @@ private: /** * 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. diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp index 548ae14e12ad..edff4423ed0c 100644 --- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -387,43 +387,33 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface, return; } - WillChange(); - Float width = aSurface->GetSize().width; 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(aSurface); 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_set_source_surface(ctx, surf, 0, 0); - IntRect blurrect = blur.GetRect(); 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_destroy(ctx); - - // Blur the result, then use that blurred result as a mask to draw the shadow - // colour to the surface. + + Rect extents(0, 0, width, height); + AlphaBoxBlur blur(cairo_image_surface_get_data(blursurf), + extents, + cairo_image_surface_get_stride(blursurf), + aSigma); blur.Blur(); + + WillChange(); + ClearSurfaceForUnboundedSource(aOperator); + cairo_save(mContext); cairo_set_operator(mContext, GfxOpToCairoOp(aOperator)); cairo_identity_matrix(mContext);