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
18 : * Crocodile Clips Ltd..
19 : * Portions created by the Initial Developer are Copyright (C) 2001
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
24 : * Jonathan Watt <jonathan.watt@strath.ac.uk>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef __NS_SVGSVGELEMENT_H__
41 : #define __NS_SVGSVGELEMENT_H__
42 :
43 : #include "DOMSVGTests.h"
44 : #include "mozilla/dom/FromParser.h"
45 : #include "nsIDOMSVGFitToViewBox.h"
46 : #include "nsIDOMSVGLocatable.h"
47 : #include "nsIDOMSVGPoint.h"
48 : #include "nsIDOMSVGSVGElement.h"
49 : #include "nsIDOMSVGZoomAndPan.h"
50 : #include "nsSVGEnum.h"
51 : #include "nsSVGLength2.h"
52 : #include "nsSVGStylableElement.h"
53 : #include "nsSVGViewBox.h"
54 : #include "SVGAnimatedPreserveAspectRatio.h"
55 :
56 : class nsIDOMSVGMatrix;
57 : class nsSMILTimeContainer;
58 :
59 : typedef nsSVGStylableElement nsSVGSVGElementBase;
60 :
61 : class nsSVGSVGElement;
62 :
63 : class nsSVGTranslatePoint {
64 : public:
65 0 : nsSVGTranslatePoint(float aX, float aY) :
66 0 : mX(aX), mY(aY) {}
67 :
68 : void SetX(float aX)
69 : { mX = aX; }
70 : void SetY(float aY)
71 : { mY = aY; }
72 0 : float GetX() const
73 0 : { return mX; }
74 0 : float GetY() const
75 0 : { return mY; }
76 :
77 : nsresult ToDOMVal(nsSVGSVGElement *aElement, nsIDOMSVGPoint **aResult);
78 :
79 : private:
80 :
81 0 : struct DOMVal : public nsIDOMSVGPoint {
82 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
83 1464 : NS_DECL_CYCLE_COLLECTION_CLASS(DOMVal)
84 :
85 0 : DOMVal(nsSVGTranslatePoint* aVal, nsSVGSVGElement *aElement)
86 0 : : mVal(aVal), mElement(aElement) {}
87 :
88 0 : NS_IMETHOD GetX(float *aValue)
89 0 : { *aValue = mVal->GetX(); return NS_OK; }
90 0 : NS_IMETHOD GetY(float *aValue)
91 0 : { *aValue = mVal->GetY(); return NS_OK; }
92 :
93 : NS_IMETHOD SetX(float aValue);
94 : NS_IMETHOD SetY(float aValue);
95 :
96 : NS_IMETHOD MatrixTransform(nsIDOMSVGMatrix *matrix,
97 : nsIDOMSVGPoint **_retval);
98 :
99 : nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement
100 : nsRefPtr<nsSVGSVGElement> mElement;
101 : };
102 :
103 : float mX;
104 : float mY;
105 : };
106 :
107 : class svgFloatSize {
108 : public:
109 0 : svgFloatSize(float aWidth, float aHeight)
110 : : width(aWidth)
111 0 : , height(aHeight)
112 0 : {}
113 0 : bool operator!=(const svgFloatSize& rhs) {
114 0 : return width != rhs.width || height != rhs.height;
115 : }
116 : float width;
117 : float height;
118 : };
119 :
120 : class nsSVGSVGElement : public nsSVGSVGElementBase,
121 : public nsIDOMSVGSVGElement,
122 : public DOMSVGTests,
123 : public nsIDOMSVGFitToViewBox,
124 : public nsIDOMSVGLocatable,
125 : public nsIDOMSVGZoomAndPan
126 0 : {
127 : friend class nsSVGOuterSVGFrame;
128 : friend class nsSVGInnerSVGFrame;
129 : friend class nsSVGImageFrame;
130 :
131 : protected:
132 : friend nsresult NS_NewSVGSVGElement(nsIContent **aResult,
133 : already_AddRefed<nsINodeInfo> aNodeInfo,
134 : mozilla::dom::FromParser aFromParser);
135 : nsSVGSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo,
136 : mozilla::dom::FromParser aFromParser);
137 :
138 : public:
139 : typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
140 : typedef mozilla::SVGPreserveAspectRatio SVGPreserveAspectRatio;
141 :
142 : // interfaces:
143 : NS_DECL_ISUPPORTS_INHERITED
144 1464 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGSVGElement, nsSVGSVGElementBase)
145 : NS_DECL_NSIDOMSVGSVGELEMENT
146 : NS_DECL_NSIDOMSVGFITTOVIEWBOX
147 : NS_DECL_NSIDOMSVGLOCATABLE
148 : NS_DECL_NSIDOMSVGZOOMANDPAN
149 :
150 : // xxx I wish we could use virtual inheritance
151 0 : NS_FORWARD_NSIDOMNODE(nsSVGSVGElementBase::)
152 0 : NS_FORWARD_NSIDOMELEMENT(nsSVGSVGElementBase::)
153 0 : NS_FORWARD_NSIDOMSVGELEMENT(nsSVGSVGElementBase::)
154 :
155 : /**
156 : * For use by zoom controls to allow currentScale, currentTranslate.x and
157 : * currentTranslate.y to be set by a single operation that dispatches a
158 : * single SVGZoom event (instead of one SVGZoom and two SVGScroll events).
159 : */
160 : NS_IMETHOD SetCurrentScaleTranslate(float s, float x, float y);
161 :
162 : /**
163 : * For use by pan controls to allow currentTranslate.x and currentTranslate.y
164 : * to be set by a single operation that dispatches a single SVGScroll event
165 : * (instead of two).
166 : */
167 : NS_IMETHOD SetCurrentTranslate(float x, float y);
168 :
169 : /**
170 : * Retrieve the value of currentScale and currentTranslate.
171 : */
172 0 : const nsSVGTranslatePoint& GetCurrentTranslate() { return mCurrentTranslate; }
173 0 : float GetCurrentScale() { return mCurrentScale; }
174 :
175 : /**
176 : * Retrieve the value of currentScale, currentTranslate.x or
177 : * currentTranslate.y prior to the last change made to any one of them.
178 : */
179 0 : const nsSVGTranslatePoint& GetPreviousTranslate() { return mPreviousTranslate; }
180 0 : float GetPreviousScale() { return mPreviousScale; }
181 :
182 : nsSMILTimeContainer* GetTimedDocumentRoot();
183 :
184 : // nsIContent interface
185 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
186 : virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
187 :
188 : // nsSVGElement specializations:
189 : virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
190 : TransformTypes aWhich = eAllTransforms) const;
191 : virtual bool HasValidDimensions() const;
192 :
193 : // nsSVGSVGElement methods:
194 : float GetLength(PRUint8 mCtxType);
195 : // Copy our width or height to the target
196 : void SyncWidthOrHeight(nsIAtom* aName, nsSVGElement *aTarget) const;
197 :
198 : // public helpers:
199 : gfxMatrix GetViewBoxTransform() const;
200 0 : bool HasValidViewbox() const { return mViewBox.IsValid(); }
201 :
202 : // This services any pending notifications for the transform on on this root
203 : // <svg> node needing to be recalculated. (Only applicable in
204 : // SVG-as-an-image documents.)
205 : virtual void FlushImageTransformInvalidation();
206 :
207 : virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
208 :
209 0 : svgFloatSize GetViewportSize() const {
210 0 : return svgFloatSize(mViewportWidth, mViewportHeight);
211 : }
212 :
213 0 : void SetViewportSize(const svgFloatSize& aSize) {
214 0 : mViewportWidth = aSize.width;
215 0 : mViewportHeight = aSize.height;
216 0 : }
217 :
218 : virtual nsXPCClassInfo* GetClassInfo();
219 :
220 : private:
221 : // Methods for <image> elements to override my "PreserveAspectRatio" value.
222 : // These are private so that only our friends (nsSVGImageFrame in
223 : // particular) have access.
224 : void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
225 : void ClearImageOverridePreserveAspectRatio();
226 : const SVGPreserveAspectRatio* GetImageOverridePreserveAspectRatio() const;
227 :
228 : // Returns true if we should synthesize a viewBox for ourselves (that is,
229 : // if we're the outermost <svg> in an image document, and we're not currently
230 : // being painted by an <svg:image> element). This method also assumes that we
231 : // lack a valid viewBox attribute.
232 : bool ShouldSynthesizeViewBox() const;
233 :
234 : protected:
235 : // nsSVGElement overrides
236 : bool IsEventName(nsIAtom* aName);
237 :
238 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
239 : nsIContent* aBindingParent,
240 : bool aCompileEventHandlers);
241 : virtual void UnbindFromTree(bool aDeep, bool aNullParent);
242 :
243 : // implementation helpers:
244 :
245 0 : bool IsRoot() const {
246 0 : NS_ASSERTION((IsInDoc() && !GetParent()) ==
247 : (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
248 : "Can't determine if we're root");
249 0 : return IsInDoc() && !GetParent();
250 : }
251 :
252 : /**
253 : * Returns true if this is an SVG <svg> element that is the child of
254 : * another non-foreignObject SVG element.
255 : */
256 0 : bool IsInner() const {
257 0 : const nsIContent *parent = GetFlattenedTreeParent();
258 0 : return parent && parent->IsSVG() &&
259 0 : parent->Tag() != nsGkAtoms::foreignObject;
260 : }
261 :
262 : /*
263 : * While binding to the tree we need to determine if we will be the outermost
264 : * <svg> element _before_ the children are bound (as they want to know what
265 : * timed document root to register with) and therefore _before_ our parent is
266 : * set (both actions are performed by nsGenericElement::BindToTree) so we
267 : * can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
268 : * basically a simplified version of GetOwnerSVGElement that uses the parent
269 : * parameters passed in instead.
270 : */
271 : bool WillBeOutermostSVG(nsIContent* aParent,
272 : nsIContent* aBindingParent) const;
273 :
274 : // invalidate viewbox -> viewport xform & inform frames
275 : void InvalidateTransformNotifyFrame();
276 :
277 : // Returns true if we have at least one of the following:
278 : // - a (valid or invalid) value for the preserveAspectRatio attribute
279 : // - a SMIL-animated value for the preserveAspectRatio attribute
280 : bool HasPreserveAspectRatio();
281 :
282 : virtual LengthAttributesInfo GetLengthInfo();
283 :
284 : enum { X, Y, WIDTH, HEIGHT };
285 : nsSVGLength2 mLengthAttributes[4];
286 : static LengthInfo sLengthInfo[4];
287 :
288 : virtual EnumAttributesInfo GetEnumInfo();
289 :
290 : enum { ZOOMANDPAN };
291 : nsSVGEnum mEnumAttributes[1];
292 : static nsSVGEnumMapping sZoomAndPanMap[];
293 : static EnumInfo sEnumInfo[1];
294 :
295 : virtual nsSVGViewBox *GetViewBox();
296 : virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
297 :
298 : nsSVGViewBox mViewBox;
299 : SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
300 :
301 : nsSVGSVGElement *mCoordCtx;
302 :
303 : // The size of the rectangular SVG viewport into which we render. This is
304 : // not (necessarily) the same as the content area. See:
305 : //
306 : // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
307 : //
308 : // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
309 : // flag this as an inner <svg> to save the overhead of GetCtx calls?
310 : // XXXjwatt our frame should probably reset these when it's destroyed.
311 : float mViewportWidth, mViewportHeight;
312 :
313 : // The time container for animations within this SVG document fragment. Set
314 : // for all outermost <svg> elements (not nested <svg> elements).
315 : nsAutoPtr<nsSMILTimeContainer> mTimedDocumentRoot;
316 :
317 : // zoom and pan
318 : // IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
319 : // code to change any of these!
320 : nsSVGTranslatePoint mCurrentTranslate;
321 : float mCurrentScale;
322 : nsSVGTranslatePoint mPreviousTranslate;
323 : float mPreviousScale;
324 : PRInt32 mRedrawSuspendCount;
325 :
326 : // For outermost <svg> elements created from parsing, animation is started by
327 : // the onload event in accordance with the SVG spec, but for <svg> elements
328 : // created by script or promoted from inner <svg> to outermost <svg> we need
329 : // to manually kick off animation when they are bound to the tree.
330 : bool mStartAnimationOnBindToTree;
331 : bool mImageNeedsTransformInvalidation;
332 : bool mIsPaintingSVGImageElement;
333 : };
334 :
335 : #endif
|