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
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 the Mozilla SVG project.
16 : *
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.
20 : *
21 : * Contributor(s):
22 : *
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.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #ifndef __NS_SVGFILTERINSTANCE_H__
38 : #define __NS_SVGFILTERINSTANCE_H__
39 :
40 : #include "nsIDOMSVGLength.h"
41 : #include "nsIDOMSVGFilters.h"
42 : #include "nsRect.h"
43 : #include "nsIContent.h"
44 : #include "nsAutoPtr.h"
45 : #include "nsSVGFilters.h"
46 : #include "nsSVGNumber2.h"
47 : #include "nsSVGNumberPair.h"
48 :
49 : #include "gfxImageSurface.h"
50 :
51 : class nsSVGElement;
52 : class nsSVGFilterElement;
53 : class nsSVGFilterPaintCallback;
54 : struct gfxRect;
55 :
56 : /**
57 : * This class performs all filter processing.
58 : *
59 : * We build a graph of the filter image data flow, essentially
60 : * converting the filter graph to SSA. This lets us easily propagate
61 : * analysis data (such as bounding-boxes) over the filter primitive graph.
62 : */
63 : class NS_STACK_CLASS nsSVGFilterInstance
64 0 : {
65 : public:
66 0 : nsSVGFilterInstance(nsIFrame *aTargetFrame,
67 : nsSVGFilterPaintCallback *aPaintCallback,
68 : nsSVGFilterElement *aFilterElement,
69 : const gfxRect &aTargetBBox,
70 : const gfxRect& aFilterRect,
71 : const nsIntSize& aFilterSpaceSize,
72 : const gfxMatrix &aFilterSpaceToDeviceSpaceTransform,
73 : const nsIntRect& aTargetBounds,
74 : const nsIntRect& aDirtyOutputRect,
75 : const nsIntRect& aDirtyInputRect,
76 : PRUint16 aPrimitiveUnits) :
77 : mTargetFrame(aTargetFrame),
78 : mPaintCallback(aPaintCallback),
79 : mFilterElement(aFilterElement),
80 : mTargetBBox(aTargetBBox),
81 : mFilterSpaceToDeviceSpaceTransform(aFilterSpaceToDeviceSpaceTransform),
82 : mFilterRect(aFilterRect),
83 : mFilterSpaceSize(aFilterSpaceSize),
84 : mTargetBounds(aTargetBounds),
85 : mDirtyOutputRect(aDirtyOutputRect),
86 : mDirtyInputRect(aDirtyInputRect),
87 : mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize),
88 0 : mPrimitiveUnits(aPrimitiveUnits) {
89 0 : }
90 :
91 : // The area covered by temporary images, in filter space
92 : void SetSurfaceRect(const nsIntRect& aRect) { mSurfaceRect = aRect; }
93 :
94 : gfxRect GetFilterRect() const { return mFilterRect; }
95 :
96 : const nsIntSize& GetFilterSpaceSize() { return mFilterSpaceSize; }
97 : PRUint32 GetFilterResX() const { return mFilterSpaceSize.width; }
98 : PRUint32 GetFilterResY() const { return mFilterSpaceSize.height; }
99 :
100 : const nsIntRect& GetSurfaceRect() const { return mSurfaceRect; }
101 : PRInt32 GetSurfaceWidth() const { return mSurfaceRect.width; }
102 : PRInt32 GetSurfaceHeight() const { return mSurfaceRect.height; }
103 :
104 : nsresult Render(gfxASurface** aOutput);
105 : nsresult ComputeOutputDirtyRect(nsIntRect* aDirty);
106 : nsresult ComputeSourceNeededRect(nsIntRect* aDirty);
107 : nsresult ComputeOutputBBox(nsIntRect* aBBox);
108 :
109 : float GetPrimitiveNumber(PRUint8 aCtxType, const nsSVGNumber2 *aNumber) const
110 : {
111 : return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue());
112 : }
113 : float GetPrimitiveNumber(PRUint8 aCtxType, const nsSVGNumberPair *aNumberPair,
114 : nsSVGNumberPair::PairIndex aIndex) const
115 : {
116 : return GetPrimitiveNumber(aCtxType, aNumberPair->GetAnimValue(aIndex));
117 : }
118 : /**
119 : * Converts a point and a length in filter primitive units into filter space.
120 : * For object-bounding-box units, the object bounding box offset is applied
121 : * to the point.
122 : */
123 : void ConvertLocation(float aValues[3]) const;
124 :
125 : gfxMatrix GetUserSpaceToFilterSpaceTransform() const;
126 0 : gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
127 0 : return mFilterSpaceToDeviceSpaceTransform;
128 : }
129 : gfxPoint FilterSpaceToUserSpace(const gfxPoint& aPt) const;
130 :
131 : private:
132 : typedef nsSVGFE::Image Image;
133 : typedef nsSVGFE::ColorModel ColorModel;
134 :
135 0 : struct PrimitiveInfo {
136 : nsSVGFE* mFE;
137 : // the bounding box of the result image produced by this primitive, in
138 : // filter space
139 : nsIntRect mResultBoundingBox;
140 : // the bounding box of the part of the result image that is actually
141 : // needed by other primitives or by the filter result, in filter space
142 : // (used for Render only)
143 : nsIntRect mResultNeededBox;
144 : // the bounding box of the part of the result image that could be
145 : // changed by changes to mDirtyInputRect in the source image(s)
146 : // (used for ComputeOutputDirtyRect only)
147 : nsIntRect mResultChangeBox;
148 : Image mImage;
149 : PRInt32 mImageUsers;
150 :
151 : // Can't use nsAutoTArray here, because these Info objects
152 : // live in nsTArrays themselves and nsTArray moves the elements
153 : // around in memory, which breaks nsAutoTArray.
154 : nsTArray<PrimitiveInfo*> mInputs;
155 :
156 0 : PrimitiveInfo() : mFE(nsnull), mImageUsers(0) {}
157 : };
158 :
159 0 : class ImageAnalysisEntry : public nsStringHashKey {
160 : public:
161 0 : ImageAnalysisEntry(KeyTypePointer aStr) : nsStringHashKey(aStr) { }
162 : ImageAnalysisEntry(const ImageAnalysisEntry& toCopy) : nsStringHashKey(toCopy),
163 : mInfo(toCopy.mInfo) { }
164 :
165 : PrimitiveInfo* mInfo;
166 : };
167 :
168 : nsresult BuildSources();
169 : // Build graph of PrimitiveInfo nodes describing filter primitives
170 : nsresult BuildPrimitives();
171 : // Compute bounding boxes of the filter primitive outputs
172 : void ComputeResultBoundingBoxes();
173 : // Compute bounding boxes of what we actually *need* from the filter
174 : // primitive outputs
175 : void ComputeNeededBoxes();
176 : // Compute bounding boxes of what could have changed given some changes
177 : // to the source images.
178 : void ComputeResultChangeBoxes();
179 : nsIntRect ComputeUnionOfAllNeededBoxes();
180 : nsresult BuildSourceImages();
181 :
182 : // Allocates an image surface that covers mSurfaceRect (it uses
183 : // device offsets so that its origin is positioned at mSurfaceRect.TopLeft()
184 : // when using cairo to draw into the surface). The surface is cleared
185 : // to transparent black.
186 : already_AddRefed<gfxImageSurface> CreateImage();
187 :
188 : void ComputeFilterPrimitiveSubregion(PrimitiveInfo* aInfo);
189 : void EnsureColorModel(PrimitiveInfo* aPrimitive,
190 : ColorModel aColorModel);
191 :
192 : /**
193 : * Scales a numeric filter primitive length in the X, Y or "XY" directions
194 : * into a length in filter space (no offset is applied).
195 : */
196 : float GetPrimitiveNumber(PRUint8 aCtxType, float aValue) const;
197 :
198 : gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
199 0 : void ClipToFilterSpace(nsIntRect* aRect) const
200 : {
201 0 : nsIntRect filterSpace(nsIntPoint(0, 0), mFilterSpaceSize);
202 0 : aRect->IntersectRect(*aRect, filterSpace);
203 0 : }
204 : void ClipToGfxRect(nsIntRect* aRect, const gfxRect& aGfx) const;
205 :
206 : nsIFrame* mTargetFrame;
207 : nsSVGFilterPaintCallback* mPaintCallback;
208 : nsSVGFilterElement* mFilterElement;
209 : // Bounding box of the target element, in user space
210 : gfxRect mTargetBBox;
211 : gfxMatrix mFilterSpaceToDeviceSpaceTransform;
212 : gfxRect mFilterRect;
213 : nsIntSize mFilterSpaceSize;
214 : // Filter-space bounds of the target image (SourceAlpha/SourceGraphic)
215 : nsIntRect mTargetBounds;
216 : nsIntRect mDirtyOutputRect;
217 : nsIntRect mDirtyInputRect;
218 : nsIntRect mSurfaceRect;
219 : PRUint16 mPrimitiveUnits;
220 :
221 : PrimitiveInfo mSourceColorAlpha;
222 : PrimitiveInfo mSourceAlpha;
223 : nsTArray<PrimitiveInfo> mPrimitives;
224 : };
225 :
226 : #endif
|