1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is gfx thebes code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2008
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Eric Butler <zantifon@gmail.com>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "gfxBlur.h"
39 :
40 : #include "mozilla/gfx/Blur.h"
41 :
42 : using namespace mozilla::gfx;
43 :
44 0 : gfxAlphaBoxBlur::gfxAlphaBoxBlur()
45 0 : : mBlur(nsnull)
46 : {
47 0 : }
48 :
49 0 : gfxAlphaBoxBlur::~gfxAlphaBoxBlur()
50 : {
51 0 : delete mBlur;
52 0 : }
53 :
54 : gfxContext*
55 0 : gfxAlphaBoxBlur::Init(const gfxRect& aRect,
56 : const gfxIntSize& aSpreadRadius,
57 : const gfxIntSize& aBlurRadius,
58 : const gfxRect* aDirtyRect,
59 : const gfxRect* aSkipRect)
60 : {
61 0 : mozilla::gfx::Rect rect(aRect.x, aRect.y, aRect.width, aRect.height);
62 0 : IntSize spreadRadius(aSpreadRadius.width, aSpreadRadius.height);
63 0 : IntSize blurRadius(aBlurRadius.width, aBlurRadius.height);
64 0 : nsAutoPtr<mozilla::gfx::Rect> dirtyRect;
65 0 : if (aDirtyRect) {
66 0 : dirtyRect = new mozilla::gfx::Rect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height);
67 : }
68 0 : nsAutoPtr<mozilla::gfx::Rect> skipRect;
69 0 : if (aSkipRect) {
70 0 : skipRect = new mozilla::gfx::Rect(aSkipRect->x, aSkipRect->y, aSkipRect->width, aSkipRect->height);
71 : }
72 :
73 0 : mBlur = new AlphaBoxBlur(rect, spreadRadius, blurRadius, dirtyRect, skipRect);
74 :
75 0 : unsigned char* data = mBlur->GetData();
76 0 : if (!data)
77 0 : return nsnull;
78 :
79 0 : IntSize size = mBlur->GetSize();
80 : // Make an alpha-only surface to draw on. We will play with the data after
81 : // everything is drawn to create a blur effect.
82 : mImageSurface = new gfxImageSurface(data, gfxIntSize(size.width, size.height),
83 0 : mBlur->GetStride(),
84 0 : gfxASurface::ImageFormatA8);
85 0 : if (mImageSurface->CairoStatus())
86 0 : return nsnull;
87 :
88 0 : IntRect irect = mBlur->GetRect();
89 0 : gfxPoint topleft(irect.TopLeft().x, irect.TopLeft().y);
90 :
91 : // Use a device offset so callers don't need to worry about translating
92 : // coordinates, they can draw as if this was part of the destination context
93 : // at the coordinates of rect.
94 0 : mImageSurface->SetDeviceOffset(-topleft);
95 :
96 0 : mContext = new gfxContext(mImageSurface);
97 :
98 0 : return mContext;
99 : }
100 :
101 : void
102 0 : gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
103 : {
104 0 : if (!mContext)
105 0 : return;
106 :
107 0 : mBlur->Blur();
108 :
109 0 : mozilla::gfx::Rect* dirtyrect = mBlur->GetDirtyRect();
110 :
111 : // Avoid a semi-expensive clip operation if we can, otherwise
112 : // clip to the dirty rect
113 0 : if (dirtyrect) {
114 0 : aDestinationCtx->Save();
115 0 : aDestinationCtx->NewPath();
116 0 : gfxRect dirty(dirtyrect->x, dirtyrect->y, dirtyrect->width, dirtyrect->height);
117 0 : aDestinationCtx->Rectangle(dirty);
118 0 : aDestinationCtx->Clip();
119 0 : aDestinationCtx->Mask(mImageSurface, offset);
120 0 : aDestinationCtx->Restore();
121 : } else {
122 0 : aDestinationCtx->Mask(mImageSurface, offset);
123 : }
124 : }
125 :
126 0 : gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
127 : {
128 0 : mozilla::gfx::Point std(aStd.x, aStd.y);
129 0 : IntSize size = AlphaBoxBlur::CalculateBlurRadius(std);
130 0 : return gfxIntSize(size.width, size.height);
131 : }
|