michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GFX_BLUR_H michael@0: #define GFX_BLUR_H michael@0: michael@0: #include "gfxTypes.h" michael@0: #include "nsSize.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "gfxPoint.h" michael@0: #include "mozilla/RefPtr.h" michael@0: michael@0: class gfxContext; michael@0: struct gfxRect; michael@0: struct gfxRGBA; michael@0: class gfxCornerSizes; michael@0: class gfxMatrix; michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: class AlphaBoxBlur; michael@0: class SourceSurface; michael@0: class DrawTarget; michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Implementation of a triple box blur approximation of a Gaussian blur. michael@0: * michael@0: * A Gaussian blur is good for blurring because, when done independently michael@0: * in the horizontal and vertical directions, it matches the result that michael@0: * would be obtained using a different (rotated) set of axes. A triple michael@0: * box blur is a very close approximation of a Gaussian. michael@0: * michael@0: * Creates an 8-bit alpha channel context for callers to draw in, michael@0: * spreads the contents of that context, blurs the contents, and applies michael@0: * it as an alpha mask on a different existing context. michael@0: * michael@0: * A spread N makes each output pixel the maximum value of all source michael@0: * pixels within a square of side length 2N+1 centered on the output pixel. michael@0: * michael@0: * A temporary surface is created in the Init function. The caller then draws michael@0: * any desired content onto the context acquired through GetContext, and lastly michael@0: * calls Paint to apply the blurred content as an alpha mask. michael@0: */ michael@0: class gfxAlphaBoxBlur michael@0: { michael@0: public: michael@0: gfxAlphaBoxBlur(); michael@0: michael@0: ~gfxAlphaBoxBlur(); michael@0: michael@0: /** michael@0: * Constructs a box blur and initializes the temporary surface. michael@0: * @param aRect The coordinates of the surface to create in device units. michael@0: * michael@0: * @param aBlurRadius The blur radius in pixels. This is the radius of michael@0: * the entire (triple) kernel function. Each individual box blur has michael@0: * radius approximately 1/3 this value, or diameter approximately 2/3 michael@0: * this value. This parameter should nearly always be computed using michael@0: * CalculateBlurRadius, below. michael@0: * michael@0: * @param aDirtyRect A pointer to a dirty rect, measured in device units, michael@0: * if available. This will be used for optimizing the blur operation. It michael@0: * is safe to pass nullptr here. michael@0: * michael@0: * @param aSkipRect A pointer to a rect, measured in device units, that michael@0: * represents an area where blurring is unnecessary and shouldn't be done michael@0: * for speed reasons. It is safe to pass nullptr here. michael@0: */ michael@0: gfxContext* Init(const gfxRect& aRect, michael@0: const gfxIntSize& aSpreadRadius, michael@0: const gfxIntSize& aBlurRadius, michael@0: const gfxRect* aDirtyRect, michael@0: const gfxRect* aSkipRect); michael@0: michael@0: /** michael@0: * Returns the context that should be drawn to supply the alpha mask to be michael@0: * blurred. If the returned surface is null, then there was an error in michael@0: * its creation. michael@0: */ michael@0: gfxContext* GetContext() michael@0: { michael@0: return mContext; michael@0: } michael@0: michael@0: /** michael@0: * Does the actual blurring/spreading and mask applying. Users of this michael@0: * object must have drawn whatever they want to be blurred onto the internal michael@0: * gfxContext returned by GetContext before calling this. michael@0: * michael@0: * @param aDestinationCtx The graphics context on which to apply the michael@0: * blurred mask. michael@0: */ michael@0: void Paint(gfxContext* aDestinationCtx); michael@0: michael@0: /** michael@0: * Calculates a blur radius that, when used with box blur, approximates michael@0: * a Gaussian blur with the given standard deviation. The result of michael@0: * this function should be used as the aBlurRadius parameter to Init, michael@0: * above. michael@0: */ michael@0: static gfxIntSize CalculateBlurRadius(const gfxPoint& aStandardDeviation); michael@0: michael@0: /** michael@0: * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent michael@0: * to calling Init(), drawing a rectangle onto the returned surface michael@0: * and then calling Paint, but may let us optimize better in the michael@0: * backend. michael@0: * michael@0: * @param aDestinationCtx The destination to blur to. michael@0: * @param aRect The rectangle to blur in device pixels. michael@0: * @param aCornerRadii Corner radii for aRect, if it is a rounded michael@0: * rectangle. michael@0: * @param aBlurRadius The standard deviation of the blur. michael@0: * @param aShadowColor The color to draw the blurred shadow. michael@0: * @param aDirtyRect An area in device pixels that is dirty and needs michael@0: * to be redrawn. michael@0: * @param aSkipRect An area in device pixels to avoid blurring over, michael@0: * to prevent unnecessary work. michael@0: */ michael@0: static void BlurRectangle(gfxContext *aDestinationCtx, michael@0: const gfxRect& aRect, michael@0: gfxCornerSizes* aCornerRadii, michael@0: const gfxPoint& aBlurStdDev, michael@0: const gfxRGBA& aShadowColor, michael@0: const gfxRect& aDirtyRect, michael@0: const gfxRect& aSkipRect); michael@0: michael@0: michael@0: michael@0: protected: michael@0: /** michael@0: * The context of the temporary alpha surface. michael@0: */ michael@0: nsRefPtr mContext; michael@0: michael@0: /** michael@0: * The temporary alpha surface. michael@0: */ michael@0: nsAutoArrayPtr mData; michael@0: michael@0: /** michael@0: * The object that actually does the blurring for us. michael@0: */ michael@0: mozilla::gfx::AlphaBoxBlur *mBlur; michael@0: }; michael@0: michael@0: #endif /* GFX_BLUR_H */