1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
15 * The Original Code is the Mozilla SVG project.
17 * The Initial Developer of the Original Code is IBM Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either of the GNU General Public License Version 2 or later (the "GPL"),
25 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #ifndef __NS_SVGFILTERINSTANCE_H__
38 #define __NS_SVGFILTERINSTANCE_H__
40 #include "nsIDOMSVGLength.h"
41 #include "nsIDOMSVGRect.h"
42 #include "nsIDOMSVGFilters.h"
44 #include "nsIContent.h"
45 #include "nsAutoPtr.h"
46 #include "nsSVGFilters.h"
47 #include "nsISVGChildFrame.h"
48 #include "nsSVGString.h"
50 #include "gfxImageSurface.h"
54 class nsSVGFilterElement
;
55 class nsSVGFilterPaintCallback
;
58 * This class performs all filter processing.
60 * We build a graph of the filter image data flow, essentially
61 * converting the filter graph to SSA. This lets us easily propagate
62 * analysis data (such as bounding-boxes) over the filter primitive graph.
64 class NS_STACK_CLASS nsSVGFilterInstance
67 float GetPrimitiveLength(nsSVGLength2
*aLength
) const;
69 nsSVGFilterInstance(nsIFrame
*aTargetFrame
,
70 nsSVGFilterPaintCallback
*aPaintCallback
,
71 nsSVGFilterElement
*aFilterElement
,
72 nsIDOMSVGRect
*aTargetBBox
,
73 const gfxRect
& aFilterRect
,
74 const nsIntSize
& aFilterSpaceSize
,
75 nsIDOMSVGMatrix
*aFilterSpaceToDeviceSpaceTransform
,
76 const nsIntRect
& aDirtyOutputRect
,
77 const nsIntRect
& aDirtyInputRect
,
78 PRUint16 aPrimitiveUnits
) :
79 mTargetFrame(aTargetFrame
),
80 mPaintCallback(aPaintCallback
),
81 mFilterElement(aFilterElement
),
82 mTargetBBox(aTargetBBox
),
83 mFilterSpaceToDeviceSpaceTransform(aFilterSpaceToDeviceSpaceTransform
),
84 mFilterRect(aFilterRect
),
85 mFilterSpaceSize(aFilterSpaceSize
),
86 mDirtyOutputRect(aDirtyOutputRect
),
87 mDirtyInputRect(aDirtyInputRect
),
88 mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize
),
89 mPrimitiveUnits(aPrimitiveUnits
) {
92 // The area covered by temporary images, in filter space
93 void SetSurfaceRect(const nsIntRect
& aRect
) { mSurfaceRect
= aRect
; }
95 gfxRect
GetFilterRect() const { return mFilterRect
; }
97 const nsIntSize
& GetFilterSpaceSize() { return mFilterSpaceSize
; }
98 PRUint32
GetFilterResX() const { return mFilterSpaceSize
.width
; }
99 PRUint32
GetFilterResY() const { return mFilterSpaceSize
.height
; }
101 const nsIntRect
& GetSurfaceRect() const { return mSurfaceRect
; }
102 PRInt32
GetSurfaceWidth() const { return mSurfaceRect
.width
; }
103 PRInt32
GetSurfaceHeight() const { return mSurfaceRect
.height
; }
105 nsresult
Render(gfxASurface
** aOutput
);
106 nsresult
ComputeOutputDirtyRect(nsIntRect
* aDirty
);
107 nsresult
ComputeSourceNeededRect(nsIntRect
* aDirty
);
108 nsresult
ComputeOutputBBox(nsIntRect
* aBBox
);
110 already_AddRefed
<nsIDOMSVGMatrix
> GetUserSpaceToFilterSpaceTransform() const;
111 nsIDOMSVGMatrix
* GetFilterSpaceToDeviceSpaceTransform() const {
112 return mFilterSpaceToDeviceSpaceTransform
.get();
116 typedef nsSVGFE::Image Image
;
117 typedef nsSVGFE::ColorModel ColorModel
;
119 struct PrimitiveInfo
{
121 // the bounding box of the result image produced by this primitive, in
123 nsIntRect mResultBoundingBox
;
124 // the bounding box of the part of the result image that is actually
125 // needed by other primitives or by the filter result, in filter space
126 // (used for Render only)
127 nsIntRect mResultNeededBox
;
128 // the bounding box of the part of the result image that could be
129 // changed by changes to mDirtyInputRect in the source image(s)
130 // (used for ComputeOutputDirtyRect only)
131 nsIntRect mResultChangeBox
;
135 // Can't use nsAutoTArray here, because these Info objects
136 // live in nsTArrays themselves and nsTArray moves the elements
137 // around in memory, which breaks nsAutoTArray.
138 nsTArray
<PrimitiveInfo
*> mInputs
;
140 PrimitiveInfo() : mFE(nsnull
), mImageUsers(0) {}
143 class ImageAnalysisEntry
: public nsStringHashKey
{
145 ImageAnalysisEntry(KeyTypePointer aStr
) : nsStringHashKey(aStr
) { }
146 ImageAnalysisEntry(const ImageAnalysisEntry
& toCopy
) : nsStringHashKey(toCopy
),
147 mInfo(toCopy
.mInfo
) { }
149 PrimitiveInfo
* mInfo
;
152 nsresult
BuildSources();
153 // Build graph of PrimitiveInfo nodes describing filter primitives
154 nsresult
BuildPrimitives();
155 // Compute bounding boxes of the filter primitive outputs
156 void ComputeResultBoundingBoxes();
157 // Compute bounding boxes of what we actually *need* from the filter
159 void ComputeNeededBoxes();
160 // Compute bounding boxes of what could have changed given some changes
161 // to the source images.
162 void ComputeResultChangeBoxes();
163 nsIntRect
ComputeUnionOfAllNeededBoxes();
164 nsresult
BuildSourceImages();
166 // Allocates an image surface that covers mSurfaceRect (it uses
167 // device offsets so that its origin is positioned at mSurfaceRect.TopLeft()
168 // when using cairo to draw into the surface). The surface is cleared
169 // to transparent black.
170 already_AddRefed
<gfxImageSurface
> CreateImage();
172 void ComputeFilterPrimitiveSubregion(PrimitiveInfo
* aInfo
);
173 void EnsureColorModel(PrimitiveInfo
* aPrimitive
,
174 ColorModel aColorModel
);
176 gfxRect
UserSpaceToFilterSpace(const gfxRect
& aUserSpace
) const;
177 void ClipToFilterSpace(nsIntRect
* aRect
) const
179 nsIntRect
filterSpace(nsIntPoint(0, 0), mFilterSpaceSize
);
180 aRect
->IntersectRect(*aRect
, filterSpace
);
182 void ClipToGfxRect(nsIntRect
* aRect
, const gfxRect
& aGfx
) const;
184 nsIFrame
* mTargetFrame
;
185 nsSVGFilterPaintCallback
* mPaintCallback
;
186 nsSVGFilterElement
* mFilterElement
;
187 nsCOMPtr
<nsIDOMSVGRect
> mTargetBBox
;
188 nsCOMPtr
<nsIDOMSVGMatrix
> mFilterSpaceToDeviceSpaceTransform
;
190 nsIntSize mFilterSpaceSize
;
191 nsIntRect mDirtyOutputRect
;
192 nsIntRect mDirtyInputRect
;
193 nsIntRect mSurfaceRect
;
194 PRUint16 mPrimitiveUnits
;
196 PrimitiveInfo mSourceColorAlpha
;
197 PrimitiveInfo mSourceAlpha
;
198 nsTArray
<PrimitiveInfo
> mPrimitives
;