|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef GFX_BLUR_H |
|
7 #define GFX_BLUR_H |
|
8 |
|
9 #include "gfxTypes.h" |
|
10 #include "nsSize.h" |
|
11 #include "nsAutoPtr.h" |
|
12 #include "gfxPoint.h" |
|
13 #include "mozilla/RefPtr.h" |
|
14 |
|
15 class gfxContext; |
|
16 struct gfxRect; |
|
17 struct gfxRGBA; |
|
18 class gfxCornerSizes; |
|
19 class gfxMatrix; |
|
20 |
|
21 namespace mozilla { |
|
22 namespace gfx { |
|
23 class AlphaBoxBlur; |
|
24 class SourceSurface; |
|
25 class DrawTarget; |
|
26 } |
|
27 } |
|
28 |
|
29 /** |
|
30 * Implementation of a triple box blur approximation of a Gaussian blur. |
|
31 * |
|
32 * A Gaussian blur is good for blurring because, when done independently |
|
33 * in the horizontal and vertical directions, it matches the result that |
|
34 * would be obtained using a different (rotated) set of axes. A triple |
|
35 * box blur is a very close approximation of a Gaussian. |
|
36 * |
|
37 * Creates an 8-bit alpha channel context for callers to draw in, |
|
38 * spreads the contents of that context, blurs the contents, and applies |
|
39 * it as an alpha mask on a different existing context. |
|
40 * |
|
41 * A spread N makes each output pixel the maximum value of all source |
|
42 * pixels within a square of side length 2N+1 centered on the output pixel. |
|
43 * |
|
44 * A temporary surface is created in the Init function. The caller then draws |
|
45 * any desired content onto the context acquired through GetContext, and lastly |
|
46 * calls Paint to apply the blurred content as an alpha mask. |
|
47 */ |
|
48 class gfxAlphaBoxBlur |
|
49 { |
|
50 public: |
|
51 gfxAlphaBoxBlur(); |
|
52 |
|
53 ~gfxAlphaBoxBlur(); |
|
54 |
|
55 /** |
|
56 * Constructs a box blur and initializes the temporary surface. |
|
57 * @param aRect The coordinates of the surface to create in device units. |
|
58 * |
|
59 * @param aBlurRadius The blur radius in pixels. This is the radius of |
|
60 * the entire (triple) kernel function. Each individual box blur has |
|
61 * radius approximately 1/3 this value, or diameter approximately 2/3 |
|
62 * this value. This parameter should nearly always be computed using |
|
63 * CalculateBlurRadius, below. |
|
64 * |
|
65 * @param aDirtyRect A pointer to a dirty rect, measured in device units, |
|
66 * if available. This will be used for optimizing the blur operation. It |
|
67 * is safe to pass nullptr here. |
|
68 * |
|
69 * @param aSkipRect A pointer to a rect, measured in device units, that |
|
70 * represents an area where blurring is unnecessary and shouldn't be done |
|
71 * for speed reasons. It is safe to pass nullptr here. |
|
72 */ |
|
73 gfxContext* Init(const gfxRect& aRect, |
|
74 const gfxIntSize& aSpreadRadius, |
|
75 const gfxIntSize& aBlurRadius, |
|
76 const gfxRect* aDirtyRect, |
|
77 const gfxRect* aSkipRect); |
|
78 |
|
79 /** |
|
80 * Returns the context that should be drawn to supply the alpha mask to be |
|
81 * blurred. If the returned surface is null, then there was an error in |
|
82 * its creation. |
|
83 */ |
|
84 gfxContext* GetContext() |
|
85 { |
|
86 return mContext; |
|
87 } |
|
88 |
|
89 /** |
|
90 * Does the actual blurring/spreading and mask applying. Users of this |
|
91 * object must have drawn whatever they want to be blurred onto the internal |
|
92 * gfxContext returned by GetContext before calling this. |
|
93 * |
|
94 * @param aDestinationCtx The graphics context on which to apply the |
|
95 * blurred mask. |
|
96 */ |
|
97 void Paint(gfxContext* aDestinationCtx); |
|
98 |
|
99 /** |
|
100 * Calculates a blur radius that, when used with box blur, approximates |
|
101 * a Gaussian blur with the given standard deviation. The result of |
|
102 * this function should be used as the aBlurRadius parameter to Init, |
|
103 * above. |
|
104 */ |
|
105 static gfxIntSize CalculateBlurRadius(const gfxPoint& aStandardDeviation); |
|
106 |
|
107 /** |
|
108 * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent |
|
109 * to calling Init(), drawing a rectangle onto the returned surface |
|
110 * and then calling Paint, but may let us optimize better in the |
|
111 * backend. |
|
112 * |
|
113 * @param aDestinationCtx The destination to blur to. |
|
114 * @param aRect The rectangle to blur in device pixels. |
|
115 * @param aCornerRadii Corner radii for aRect, if it is a rounded |
|
116 * rectangle. |
|
117 * @param aBlurRadius The standard deviation of the blur. |
|
118 * @param aShadowColor The color to draw the blurred shadow. |
|
119 * @param aDirtyRect An area in device pixels that is dirty and needs |
|
120 * to be redrawn. |
|
121 * @param aSkipRect An area in device pixels to avoid blurring over, |
|
122 * to prevent unnecessary work. |
|
123 */ |
|
124 static void BlurRectangle(gfxContext *aDestinationCtx, |
|
125 const gfxRect& aRect, |
|
126 gfxCornerSizes* aCornerRadii, |
|
127 const gfxPoint& aBlurStdDev, |
|
128 const gfxRGBA& aShadowColor, |
|
129 const gfxRect& aDirtyRect, |
|
130 const gfxRect& aSkipRect); |
|
131 |
|
132 |
|
133 |
|
134 protected: |
|
135 /** |
|
136 * The context of the temporary alpha surface. |
|
137 */ |
|
138 nsRefPtr<gfxContext> mContext; |
|
139 |
|
140 /** |
|
141 * The temporary alpha surface. |
|
142 */ |
|
143 nsAutoArrayPtr<unsigned char> mData; |
|
144 |
|
145 /** |
|
146 * The object that actually does the blurring for us. |
|
147 */ |
|
148 mozilla::gfx::AlphaBoxBlur *mBlur; |
|
149 }; |
|
150 |
|
151 #endif /* GFX_BLUR_H */ |