layout/svg/nsSVGEffects.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef NSSVGEFFECTS_H_
michael@0 7 #define NSSVGEFFECTS_H_
michael@0 8
michael@0 9 #include "mozilla/Attributes.h"
michael@0 10 #include "FramePropertyTable.h"
michael@0 11 #include "mozilla/dom/Element.h"
michael@0 12 #include "nsHashKeys.h"
michael@0 13 #include "nsID.h"
michael@0 14 #include "nsIFrame.h"
michael@0 15 #include "nsIMutationObserver.h"
michael@0 16 #include "nsInterfaceHashtable.h"
michael@0 17 #include "nsISupportsBase.h"
michael@0 18 #include "nsISupportsImpl.h"
michael@0 19 #include "nsReferencedElement.h"
michael@0 20 #include "nsStubMutationObserver.h"
michael@0 21 #include "nsSVGUtils.h"
michael@0 22 #include "nsTHashtable.h"
michael@0 23 #include "nsURIHashKey.h"
michael@0 24
michael@0 25 class nsIAtom;
michael@0 26 class nsIPresShell;
michael@0 27 class nsIURI;
michael@0 28 class nsSVGClipPathFrame;
michael@0 29 class nsSVGPaintServerFrame;
michael@0 30 class nsSVGFilterFrame;
michael@0 31 class nsSVGMaskFrame;
michael@0 32
michael@0 33 /*
michael@0 34 * This interface allows us to be notified when a piece of SVG content is
michael@0 35 * re-rendered.
michael@0 36 *
michael@0 37 * Concrete implementations of this interface need to implement
michael@0 38 * "GetTarget()" to specify the piece of SVG content that they'd like to
michael@0 39 * monitor, and they need to implement "DoUpdate" to specify how we'll react
michael@0 40 * when that content gets re-rendered. They also need to implement a
michael@0 41 * constructor and destructor, which should call StartListening and
michael@0 42 * StopListening, respectively.
michael@0 43 */
michael@0 44 class nsSVGRenderingObserver : public nsStubMutationObserver {
michael@0 45 public:
michael@0 46 typedef mozilla::dom::Element Element;
michael@0 47 nsSVGRenderingObserver()
michael@0 48 : mInObserverList(false)
michael@0 49 {}
michael@0 50 virtual ~nsSVGRenderingObserver()
michael@0 51 {}
michael@0 52
michael@0 53 // nsISupports
michael@0 54 NS_DECL_ISUPPORTS
michael@0 55
michael@0 56 // nsIMutationObserver
michael@0 57 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
michael@0 58 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
michael@0 59 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
michael@0 60 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
michael@0 61
michael@0 62 void InvalidateViaReferencedElement();
michael@0 63
michael@0 64 // When a nsSVGRenderingObserver list gets forcibly cleared, it uses this
michael@0 65 // callback to notify every observer that's cleared from it, so they can
michael@0 66 // react.
michael@0 67 void NotifyEvictedFromRenderingObserverList();
michael@0 68
michael@0 69 bool IsInObserverList() const { return mInObserverList; }
michael@0 70
michael@0 71 nsIFrame* GetReferencedFrame();
michael@0 72 /**
michael@0 73 * @param aOK this is only for the convenience of callers. We set *aOK to false
michael@0 74 * if the frame is the wrong type
michael@0 75 */
michael@0 76 nsIFrame* GetReferencedFrame(nsIAtom* aFrameType, bool* aOK);
michael@0 77
michael@0 78 Element* GetReferencedElement();
michael@0 79
michael@0 80 virtual bool ObservesReflow() { return true; }
michael@0 81
michael@0 82 protected:
michael@0 83 // Non-virtual protected methods
michael@0 84 void StartListening();
michael@0 85 void StopListening();
michael@0 86
michael@0 87 // Virtual protected methods
michael@0 88 virtual void DoUpdate() = 0; // called when the referenced resource changes.
michael@0 89
michael@0 90 // This is an internally-used version of GetReferencedElement that doesn't
michael@0 91 // forcibly add us as an observer. (whereas GetReferencedElement does)
michael@0 92 virtual Element* GetTarget() = 0;
michael@0 93
michael@0 94 // Whether we're in our referenced element's observer list at this time.
michael@0 95 bool mInObserverList;
michael@0 96 };
michael@0 97
michael@0 98
michael@0 99 /*
michael@0 100 * SVG elements reference supporting resources by element ID. We need to
michael@0 101 * track when those resources change and when the DOM changes in ways
michael@0 102 * that affect which element is referenced by a given ID (e.g., when
michael@0 103 * element IDs change). The code here is responsible for that.
michael@0 104 *
michael@0 105 * When a frame references a supporting resource, we create a property
michael@0 106 * object derived from nsSVGIDRenderingObserver to manage the relationship. The
michael@0 107 * property object is attached to the referencing frame.
michael@0 108 */
michael@0 109 class nsSVGIDRenderingObserver : public nsSVGRenderingObserver {
michael@0 110 public:
michael@0 111 typedef mozilla::dom::Element Element;
michael@0 112 nsSVGIDRenderingObserver(nsIURI* aURI, nsIFrame *aFrame,
michael@0 113 bool aReferenceImage);
michael@0 114 virtual ~nsSVGIDRenderingObserver();
michael@0 115
michael@0 116 protected:
michael@0 117 Element* GetTarget() MOZ_OVERRIDE { return mElement.get(); }
michael@0 118
michael@0 119 // This is called when the referenced resource changes.
michael@0 120 virtual void DoUpdate() MOZ_OVERRIDE;
michael@0 121
michael@0 122 class SourceReference : public nsReferencedElement {
michael@0 123 public:
michael@0 124 SourceReference(nsSVGIDRenderingObserver* aContainer) : mContainer(aContainer) {}
michael@0 125 protected:
michael@0 126 virtual void ElementChanged(Element* aFrom, Element* aTo) MOZ_OVERRIDE {
michael@0 127 mContainer->StopListening();
michael@0 128 nsReferencedElement::ElementChanged(aFrom, aTo);
michael@0 129 mContainer->StartListening();
michael@0 130 mContainer->DoUpdate();
michael@0 131 }
michael@0 132 /**
michael@0 133 * Override IsPersistent because we want to keep tracking the element
michael@0 134 * for the ID even when it changes.
michael@0 135 */
michael@0 136 virtual bool IsPersistent() MOZ_OVERRIDE { return true; }
michael@0 137 private:
michael@0 138 nsSVGIDRenderingObserver* mContainer;
michael@0 139 };
michael@0 140
michael@0 141 SourceReference mElement;
michael@0 142 // The frame that this property is attached to
michael@0 143 nsIFrame *mFrame;
michael@0 144 // When a presshell is torn down, we don't delete the properties for
michael@0 145 // each frame until after the frames are destroyed. So here we remember
michael@0 146 // the presshell for the frames we care about and, before we use the frame,
michael@0 147 // we test the presshell to see if it's destroying itself. If it is,
michael@0 148 // then the frame pointer is not valid and we know the frame has gone away.
michael@0 149 nsIPresShell *mFramePresShell;
michael@0 150 };
michael@0 151
michael@0 152 /**
michael@0 153 * In a filter chain, there can be multiple SVG reference filters.
michael@0 154 * e.g. filter: url(#svg-filter-1) blur(10px) url(#svg-filter-2);
michael@0 155 *
michael@0 156 * This class keeps track of one SVG reference filter in a filter chain.
michael@0 157 * e.g. url(#svg-filter-1)
michael@0 158 *
michael@0 159 * It fires invalidations when the SVG filter element's id changes or when
michael@0 160 * the SVG filter element's content changes.
michael@0 161 *
michael@0 162 * The nsSVGFilterProperty class manages a list of nsSVGFilterReferences.
michael@0 163 */
michael@0 164 class nsSVGFilterReference :
michael@0 165 public nsSVGIDRenderingObserver, public nsISVGFilterReference {
michael@0 166 public:
michael@0 167 nsSVGFilterReference(nsIURI *aURI, nsIFrame *aFilteredFrame)
michael@0 168 : nsSVGIDRenderingObserver(aURI, aFilteredFrame, false) {}
michael@0 169
michael@0 170 bool ReferencesValidResource() { return GetFilterFrame(); }
michael@0 171
michael@0 172 /**
michael@0 173 * @return the filter frame, or null if there is no filter frame
michael@0 174 */
michael@0 175 nsSVGFilterFrame *GetFilterFrame();
michael@0 176
michael@0 177 // nsISupports
michael@0 178 NS_DECL_ISUPPORTS
michael@0 179
michael@0 180 // nsISVGFilterReference
michael@0 181 virtual void Invalidate() MOZ_OVERRIDE { DoUpdate(); };
michael@0 182
michael@0 183 private:
michael@0 184 // nsSVGIDRenderingObserver
michael@0 185 virtual void DoUpdate() MOZ_OVERRIDE;
michael@0 186 };
michael@0 187
michael@0 188 /**
michael@0 189 * This class manages a list of nsSVGFilterReferences, which represent SVG
michael@0 190 * reference filters in a filter chain.
michael@0 191 * e.g. filter: url(#svg-filter-1) blur(10px) url(#svg-filter-2);
michael@0 192 *
michael@0 193 * In the above example, the nsSVGFilterProperty will manage two
michael@0 194 * nsSVGFilterReferences, one for each SVG reference filter. CSS filters like
michael@0 195 * "blur(10px)" don't reference filter elements, so they don't need an
michael@0 196 * nsSVGFilterReference. The style system invalidates changes to CSS filters.
michael@0 197 */
michael@0 198 class nsSVGFilterProperty : public nsISupports {
michael@0 199 public:
michael@0 200 nsSVGFilterProperty(const nsTArray<nsStyleFilter> &aFilters,
michael@0 201 nsIFrame *aFilteredFrame);
michael@0 202 virtual ~nsSVGFilterProperty();
michael@0 203
michael@0 204 const nsTArray<nsStyleFilter>& GetFilters() { return mFilters; }
michael@0 205 bool ReferencesValidResources();
michael@0 206 bool IsInObserverLists() const;
michael@0 207 void Invalidate();
michael@0 208
michael@0 209 // nsISupports
michael@0 210 NS_DECL_ISUPPORTS
michael@0 211
michael@0 212 private:
michael@0 213 nsTArray<nsSVGFilterReference*> mReferences;
michael@0 214 nsTArray<nsStyleFilter> mFilters;
michael@0 215 };
michael@0 216
michael@0 217 class nsSVGMarkerProperty : public nsSVGIDRenderingObserver {
michael@0 218 public:
michael@0 219 nsSVGMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
michael@0 220 : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {}
michael@0 221
michael@0 222 protected:
michael@0 223 virtual void DoUpdate() MOZ_OVERRIDE;
michael@0 224 };
michael@0 225
michael@0 226 class nsSVGTextPathProperty : public nsSVGIDRenderingObserver {
michael@0 227 public:
michael@0 228 nsSVGTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
michael@0 229 : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage)
michael@0 230 , mValid(true) {}
michael@0 231
michael@0 232 virtual bool ObservesReflow() MOZ_OVERRIDE { return false; }
michael@0 233
michael@0 234 protected:
michael@0 235 virtual void DoUpdate() MOZ_OVERRIDE;
michael@0 236
michael@0 237 private:
michael@0 238 /**
michael@0 239 * Returns true if the target of the textPath is the frame of a 'path' element.
michael@0 240 */
michael@0 241 bool TargetIsValid();
michael@0 242
michael@0 243 bool mValid;
michael@0 244 };
michael@0 245
michael@0 246 class nsSVGPaintingProperty : public nsSVGIDRenderingObserver {
michael@0 247 public:
michael@0 248 nsSVGPaintingProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
michael@0 249 : nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {}
michael@0 250
michael@0 251 protected:
michael@0 252 virtual void DoUpdate() MOZ_OVERRIDE;
michael@0 253 };
michael@0 254
michael@0 255 /**
michael@0 256 * A manager for one-shot nsSVGRenderingObserver tracking.
michael@0 257 * nsSVGRenderingObservers can be added or removed. They are not strongly
michael@0 258 * referenced so an observer must be removed before it dies.
michael@0 259 * When InvalidateAll is called, all outstanding references get
michael@0 260 * InvalidateViaReferencedElement()
michael@0 261 * called on them and the list is cleared. The intent is that
michael@0 262 * the observer will force repainting of whatever part of the document
michael@0 263 * is needed, and then at paint time the observer will do a clean lookup
michael@0 264 * of the referenced element and [re-]add itself to the element's observer list.
michael@0 265 *
michael@0 266 * InvalidateAll must be called before this object is destroyed, i.e.
michael@0 267 * before the referenced frame is destroyed. This should normally happen
michael@0 268 * via nsSVGContainerFrame::RemoveFrame, since only frames in the frame
michael@0 269 * tree should be referenced.
michael@0 270 */
michael@0 271 class nsSVGRenderingObserverList {
michael@0 272 public:
michael@0 273 nsSVGRenderingObserverList()
michael@0 274 : mObservers(5)
michael@0 275 {
michael@0 276 MOZ_COUNT_CTOR(nsSVGRenderingObserverList);
michael@0 277 }
michael@0 278
michael@0 279 ~nsSVGRenderingObserverList() {
michael@0 280 InvalidateAll();
michael@0 281 MOZ_COUNT_DTOR(nsSVGRenderingObserverList);
michael@0 282 }
michael@0 283
michael@0 284 void Add(nsSVGRenderingObserver* aObserver)
michael@0 285 { mObservers.PutEntry(aObserver); }
michael@0 286 void Remove(nsSVGRenderingObserver* aObserver)
michael@0 287 { mObservers.RemoveEntry(aObserver); }
michael@0 288 #ifdef DEBUG
michael@0 289 bool Contains(nsSVGRenderingObserver* aObserver)
michael@0 290 { return (mObservers.GetEntry(aObserver) != nullptr); }
michael@0 291 #endif
michael@0 292 bool IsEmpty()
michael@0 293 { return mObservers.Count() == 0; }
michael@0 294
michael@0 295 /**
michael@0 296 * Drop all our observers, and notify them that we have changed and dropped
michael@0 297 * our reference to them.
michael@0 298 */
michael@0 299 void InvalidateAll();
michael@0 300
michael@0 301 /**
michael@0 302 * Drop all observers that observe reflow, and notify them that we have changed and dropped
michael@0 303 * our reference to them.
michael@0 304 */
michael@0 305 void InvalidateAllForReflow();
michael@0 306
michael@0 307 /**
michael@0 308 * Drop all our observers, and notify them that we have dropped our reference
michael@0 309 * to them.
michael@0 310 */
michael@0 311 void RemoveAll();
michael@0 312
michael@0 313 private:
michael@0 314 nsTHashtable<nsPtrHashKey<nsSVGRenderingObserver> > mObservers;
michael@0 315 };
michael@0 316
michael@0 317 class nsSVGEffects {
michael@0 318 public:
michael@0 319 typedef mozilla::dom::Element Element;
michael@0 320 typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
michael@0 321 typedef nsInterfaceHashtable<nsURIHashKey, nsIMutationObserver>
michael@0 322 URIObserverHashtable;
michael@0 323
michael@0 324 static void DestroySupports(void* aPropertyValue)
michael@0 325 {
michael@0 326 (static_cast<nsISupports*>(aPropertyValue))->Release();
michael@0 327 }
michael@0 328
michael@0 329 static void DestroyHashtable(void* aPropertyValue)
michael@0 330 {
michael@0 331 delete static_cast<URIObserverHashtable*> (aPropertyValue);
michael@0 332 }
michael@0 333
michael@0 334 NS_DECLARE_FRAME_PROPERTY(FilterProperty, DestroySupports)
michael@0 335 NS_DECLARE_FRAME_PROPERTY(MaskProperty, DestroySupports)
michael@0 336 NS_DECLARE_FRAME_PROPERTY(ClipPathProperty, DestroySupports)
michael@0 337 NS_DECLARE_FRAME_PROPERTY(MarkerBeginProperty, DestroySupports)
michael@0 338 NS_DECLARE_FRAME_PROPERTY(MarkerMiddleProperty, DestroySupports)
michael@0 339 NS_DECLARE_FRAME_PROPERTY(MarkerEndProperty, DestroySupports)
michael@0 340 NS_DECLARE_FRAME_PROPERTY(FillProperty, DestroySupports)
michael@0 341 NS_DECLARE_FRAME_PROPERTY(StrokeProperty, DestroySupports)
michael@0 342 NS_DECLARE_FRAME_PROPERTY(HrefProperty, DestroySupports)
michael@0 343 NS_DECLARE_FRAME_PROPERTY(BackgroundImageProperty, DestroyHashtable)
michael@0 344
michael@0 345 /**
michael@0 346 * Get the paint server for a aTargetFrame.
michael@0 347 */
michael@0 348 static nsSVGPaintServerFrame *GetPaintServer(nsIFrame *aTargetFrame,
michael@0 349 const nsStyleSVGPaint *aPaint,
michael@0 350 const FramePropertyDescriptor *aProperty);
michael@0 351
michael@0 352 struct EffectProperties {
michael@0 353 nsSVGFilterProperty* mFilter;
michael@0 354 nsSVGPaintingProperty* mMask;
michael@0 355 nsSVGPaintingProperty* mClipPath;
michael@0 356
michael@0 357 /**
michael@0 358 * @return the clip-path frame, or null if there is no clip-path frame
michael@0 359 * @param aOK if a clip-path was specified and the designated element
michael@0 360 * exists but is an element of the wrong type, *aOK is set to false.
michael@0 361 * Otherwise *aOK is untouched.
michael@0 362 */
michael@0 363 nsSVGClipPathFrame *GetClipPathFrame(bool *aOK);
michael@0 364 /**
michael@0 365 * @return the mask frame, or null if there is no mask frame
michael@0 366 * @param aOK if a mask was specified and the designated element
michael@0 367 * exists but is an element of the wrong type, *aOK is set to false.
michael@0 368 * Otherwise *aOK is untouched.
michael@0 369 */
michael@0 370 nsSVGMaskFrame *GetMaskFrame(bool *aOK);
michael@0 371
michael@0 372 bool HasValidFilter() {
michael@0 373 return mFilter && mFilter->ReferencesValidResources();
michael@0 374 }
michael@0 375
michael@0 376 bool HasNoFilterOrHasValidFilter() {
michael@0 377 return !mFilter || mFilter->ReferencesValidResources();
michael@0 378 }
michael@0 379 };
michael@0 380
michael@0 381 /**
michael@0 382 * @param aFrame should be the first continuation
michael@0 383 */
michael@0 384 static EffectProperties GetEffectProperties(nsIFrame *aFrame);
michael@0 385
michael@0 386 /**
michael@0 387 * Called when changes to an element (e.g. CSS property changes) cause its
michael@0 388 * frame to start/stop referencing (or reference different) SVG resource
michael@0 389 * elements. (_Not_ called for changes to referenced resource elements.)
michael@0 390 *
michael@0 391 * This function handles such changes by discarding _all_ the frame's SVG
michael@0 392 * effects frame properties (causing those properties to stop watching their
michael@0 393 * target element). It also synchronously (re)creates the filter and marker
michael@0 394 * frame properties (XXX why not the other properties?), which makes it
michael@0 395 * useful for initializing those properties during first reflow.
michael@0 396 *
michael@0 397 * XXX rename to something more meaningful like RefreshResourceReferences?
michael@0 398 */
michael@0 399 static void UpdateEffects(nsIFrame *aFrame);
michael@0 400
michael@0 401 /**
michael@0 402 * @param aFrame should be the first continuation
michael@0 403 */
michael@0 404 static nsSVGFilterProperty *GetFilterProperty(nsIFrame *aFrame);
michael@0 405
michael@0 406 /**
michael@0 407 * @param aFrame must be a first-continuation.
michael@0 408 */
michael@0 409 static void AddRenderingObserver(Element *aElement, nsSVGRenderingObserver *aObserver);
michael@0 410 /**
michael@0 411 * @param aFrame must be a first-continuation.
michael@0 412 */
michael@0 413 static void RemoveRenderingObserver(Element *aElement, nsSVGRenderingObserver *aObserver);
michael@0 414
michael@0 415 /**
michael@0 416 * Removes all rendering observers from aElement.
michael@0 417 */
michael@0 418 static void RemoveAllRenderingObservers(Element *aElement);
michael@0 419
michael@0 420 /**
michael@0 421 * This can be called on any frame. We invalidate the observers of aFrame's
michael@0 422 * element, if any, or else walk up to the nearest observable SVG parent
michael@0 423 * frame with observers and invalidate them instead.
michael@0 424 *
michael@0 425 * Note that this method is very different to e.g.
michael@0 426 * nsNodeUtils::AttributeChanged which walks up the content node tree all the
michael@0 427 * way to the root node (not stopping if it encounters a non-container SVG
michael@0 428 * node) invalidating all mutation observers (not just
michael@0 429 * nsSVGRenderingObservers) on all nodes along the way (not just the first
michael@0 430 * node it finds with observers). In other words, by doing all the
michael@0 431 * things in parentheses in the preceding sentence, this method uses
michael@0 432 * knowledge about our implementation and what can be affected by SVG effects
michael@0 433 * to make invalidation relatively lightweight when an SVG effect changes.
michael@0 434 */
michael@0 435 static void InvalidateRenderingObservers(nsIFrame *aFrame);
michael@0 436
michael@0 437 enum {
michael@0 438 INVALIDATE_REFLOW = 1
michael@0 439 };
michael@0 440
michael@0 441 /**
michael@0 442 * This can be called on any element or frame. Only direct observers of this
michael@0 443 * (frame's) element, if any, are invalidated.
michael@0 444 */
michael@0 445 static void InvalidateDirectRenderingObservers(Element *aElement, uint32_t aFlags = 0);
michael@0 446 static void InvalidateDirectRenderingObservers(nsIFrame *aFrame, uint32_t aFlags = 0);
michael@0 447
michael@0 448 /**
michael@0 449 * Get an nsSVGMarkerProperty for the frame, creating a fresh one if necessary
michael@0 450 */
michael@0 451 static nsSVGMarkerProperty *
michael@0 452 GetMarkerProperty(nsIURI *aURI, nsIFrame *aFrame,
michael@0 453 const FramePropertyDescriptor *aProperty);
michael@0 454 /**
michael@0 455 * Get an nsSVGTextPathProperty for the frame, creating a fresh one if necessary
michael@0 456 */
michael@0 457 static nsSVGTextPathProperty *
michael@0 458 GetTextPathProperty(nsIURI *aURI, nsIFrame *aFrame,
michael@0 459 const FramePropertyDescriptor *aProperty);
michael@0 460 /**
michael@0 461 * Get an nsSVGPaintingProperty for the frame, creating a fresh one if necessary
michael@0 462 */
michael@0 463 static nsSVGPaintingProperty *
michael@0 464 GetPaintingProperty(nsIURI *aURI, nsIFrame *aFrame,
michael@0 465 const FramePropertyDescriptor *aProperty);
michael@0 466 /**
michael@0 467 * Get an nsSVGPaintingProperty for the frame for that URI, creating a fresh
michael@0 468 * one if necessary
michael@0 469 */
michael@0 470 static nsSVGPaintingProperty *
michael@0 471 GetPaintingPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
michael@0 472 const FramePropertyDescriptor *aProp);
michael@0 473 };
michael@0 474
michael@0 475 #endif /*NSSVGEFFECTS_H_*/

mercurial