Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / layout / svg / base / src / nsSVGUtils.h
blob42c4dee1b7c599500f1d702380779dd77de28d2b
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
13 * License.
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.
21 * Contributor(s):
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_SVGUTILS_H
38 #define NS_SVGUTILS_H
40 // include math.h to pick up definition of M_PI if the platform defines it
41 #define _USE_MATH_DEFINES
42 #include <math.h>
44 #include "nscore.h"
45 #include "nsCOMPtr.h"
46 #include "nsRect.h"
47 #include "gfxContext.h"
48 #include "nsIRenderingContext.h"
50 class nsIDocument;
51 class nsPresContext;
52 class nsIContent;
53 class nsStyleCoord;
54 class nsIDOMSVGRect;
55 class nsFrameList;
56 class nsIFrame;
57 struct nsStyleSVGPaint;
58 class nsIDOMSVGElement;
59 class nsIDOMSVGLength;
60 class nsIDOMSVGMatrix;
61 class nsIURI;
62 class nsSVGOuterSVGFrame;
63 class nsIPresShell;
64 class nsIDOMSVGAnimatedPreserveAspectRatio;
65 class nsIAtom;
66 class nsSVGLength2;
67 class nsSVGElement;
68 class nsSVGSVGElement;
69 class nsAttrValue;
70 class gfxContext;
71 class gfxASurface;
72 class gfxPattern;
73 class gfxImageSurface;
74 struct gfxRect;
75 struct gfxMatrix;
76 struct gfxSize;
77 struct gfxIntSize;
78 struct nsStyleFont;
79 class nsSVGEnum;
80 class nsISVGChildFrame;
82 #ifndef M_PI
83 #define M_PI 3.14159265358979323846
84 #endif
86 // SVG Frame state bits
87 #define NS_STATE_IS_OUTER_SVG 0x00100000
89 #define NS_STATE_SVG_DIRTY 0x00200000
91 /* are we the child of a non-display container? */
92 #define NS_STATE_SVG_NONDISPLAY_CHILD 0x00400000
94 #define NS_STATE_SVG_PROPAGATE_TRANSFORM 0x00800000
96 /**
97 * Byte offsets of channels in a native packed gfxColor or cairo image surface.
99 #ifdef IS_BIG_ENDIAN
100 #define GFX_ARGB32_OFFSET_A 0
101 #define GFX_ARGB32_OFFSET_R 1
102 #define GFX_ARGB32_OFFSET_G 2
103 #define GFX_ARGB32_OFFSET_B 3
104 #else
105 #define GFX_ARGB32_OFFSET_A 3
106 #define GFX_ARGB32_OFFSET_R 2
107 #define GFX_ARGB32_OFFSET_G 1
108 #define GFX_ARGB32_OFFSET_B 0
109 #endif
111 // maximum dimension of an offscreen surface - choose so that
112 // the surface size doesn't overflow a 32-bit signed int using
113 // 4 bytes per pixel; in line with gfxASurface::CheckSurfaceSize
114 #define NS_SVG_OFFSCREEN_MAX_DIMENSION 16384
117 * Checks the svg enable preference and if a renderer could
118 * successfully be created. Declared as a function instead of a
119 * nsSVGUtil method so that files that can't pull in nsSVGUtils.h (due
120 * to cairo.h usage) can still query this information.
122 PRBool NS_SVGEnabled();
124 // GRRR WINDOWS HATE HATE HATE
125 #undef CLIP_MASK
127 class nsSVGRenderState
129 public:
130 enum RenderMode { NORMAL, CLIP, CLIP_MASK };
133 * Render SVG to a legacy rendering context
135 nsSVGRenderState(nsIRenderingContext *aContext);
137 * Render SVG to a temporary surface
139 nsSVGRenderState(gfxASurface *aSurface);
141 nsIRenderingContext *GetRenderingContext(nsIFrame *aFrame);
142 gfxContext *GetGfxContext() { return mGfxContext; }
144 void SetRenderMode(RenderMode aMode) { mRenderMode = aMode; }
145 RenderMode GetRenderMode() { return mRenderMode; }
147 private:
148 RenderMode mRenderMode;
149 nsCOMPtr<nsIRenderingContext> mRenderingContext;
150 nsRefPtr<gfxContext> mGfxContext;
153 class nsAutoSVGRenderMode
155 public:
156 nsAutoSVGRenderMode(nsSVGRenderState *aState,
157 nsSVGRenderState::RenderMode aMode) : mState(aState) {
158 mOriginalMode = aState->GetRenderMode();
159 aState->SetRenderMode(aMode);
161 ~nsAutoSVGRenderMode() { mState->SetRenderMode(mOriginalMode); }
163 private:
164 nsSVGRenderState *mState;
165 nsSVGRenderState::RenderMode mOriginalMode;
168 #define NS_ISVGFILTERPROPERTY_IID \
169 { 0x9744ee20, 0x1bcf, 0x4c62, \
170 { 0x86, 0x7d, 0xd3, 0x7a, 0x91, 0x60, 0x3e, 0xef } }
172 class nsISVGFilterProperty : public nsISupports
174 public:
175 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISVGFILTERPROPERTY_IID)
176 virtual void Invalidate() = 0;
179 NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGFilterProperty, NS_ISVGFILTERPROPERTY_IID)
181 class nsSVGUtils
183 public:
185 * Get a font-size (em) of an nsIContent
187 static float GetFontSize(nsIContent *aContent);
188 static float GetFontSize(nsIFrame *aFrame);
190 * Get an x-height of of an nsIContent
192 static float GetFontXHeight(nsIContent *aContent);
193 static float GetFontXHeight(nsIFrame *aFrame);
196 * Converts image data from premultipled to unpremultiplied alpha
198 static void UnPremultiplyImageDataAlpha(PRUint8 *data,
199 PRInt32 stride,
200 const nsIntRect &rect);
202 * Converts image data from unpremultipled to premultiplied alpha
204 static void PremultiplyImageDataAlpha(PRUint8 *data,
205 PRInt32 stride,
206 const nsIntRect &rect);
208 * Converts image data from premultiplied sRGB to Linear RGB
210 static void ConvertImageDataToLinearRGB(PRUint8 *data,
211 PRInt32 stride,
212 const nsIntRect &rect);
214 * Converts image data from LinearRGB to premultiplied sRGB
216 static void ConvertImageDataFromLinearRGB(PRUint8 *data,
217 PRInt32 stride,
218 const nsIntRect &rect);
221 * Report a localized error message to the error console.
223 static nsresult ReportToConsole(nsIDocument* doc,
224 const char* aWarning,
225 const PRUnichar **aParams,
226 PRUint32 aParamsLength);
229 * Converts a nsStyleCoord into a userspace value. Handles units
230 * Factor (straight userspace), Coord (dimensioned), and Percent (of
231 * the current SVG viewport)
233 static float CoordToFloat(nsPresContext *aPresContext,
234 nsSVGElement *aContent,
235 const nsStyleCoord &aCoord);
237 * Return the nearest viewport element
239 static nsresult GetNearestViewportElement(nsIContent *aContent,
240 nsIDOMSVGElement * *aNearestViewportElement);
243 * Get the farthest viewport element
245 static nsresult GetFarthestViewportElement(nsIContent *aContent,
246 nsIDOMSVGElement * *aFarthestViewportElement);
249 * Creates a bounding box by walking the children and doing union.
251 static nsresult GetBBox(nsFrameList *aFrames, nsIDOMSVGRect **_retval);
254 * Figures out the worst case invalidation area for a frame, taking
255 * filters into account.
256 * @param aRect the area in app units that needs to be invalidated in aFrame
257 * @return the rect in app units that should be invalidated, taking
258 * filters into account. Will return aRect when no filters are present.
260 static nsRect FindFilterInvalidation(nsIFrame *aFrame, const nsRect& aRect);
263 * Invalidates the area covered by the frame
265 static void InvalidateCoveredRegion(nsIFrame *aFrame);
268 * Update the area covered by the frame
270 static void UpdateGraphic(nsISVGChildFrame *aSVGFrame);
273 * Update the filter invalidation region for ancestor frames, if relevant.
275 static void NotifyAncestorsOfFilterRegionChange(nsIFrame *aFrame);
277 /* enum for specifying coordinate direction for ObjectSpace/UserSpace */
278 enum ctxDirection { X, Y, XY };
281 * Computes sqrt((aWidth^2 + aHeight^2)/2);
283 static double ComputeNormalizedHypotenuse(double aWidth, double aHeight);
285 /* Computes the input length in terms of object space coordinates.
286 Input: rect - bounding box
287 length - length to be converted
289 static float ObjectSpace(nsIDOMSVGRect *aRect, const nsSVGLength2 *aLength);
291 /* Computes the input length in terms of user space coordinates.
292 Input: content - object to be used for determining user space
293 Input: length - length to be converted
295 static float UserSpace(nsSVGElement *aSVGElement, const nsSVGLength2 *aLength);
297 /* Computes the input length in terms of user space coordinates.
298 Input: aFrame - object to be used for determining user space
299 length - length to be converted
301 static float UserSpace(nsIFrame *aFrame, const nsSVGLength2 *aLength);
303 /* Tranforms point by the matrix. In/out: x,y */
304 static void
305 TransformPoint(nsIDOMSVGMatrix *matrix,
306 float *x, float *y);
308 /* Returns the angle halfway between the two specified angles */
309 static float
310 AngleBisect(float a1, float a2);
312 /* Find the outermost SVG frame of the passed frame */
313 static nsSVGOuterSVGFrame *
314 GetOuterSVGFrame(nsIFrame *aFrame);
317 * Get the covered region for a frame. Return null if it's not an SVG frame.
318 * @param aRect gets a rectangle in app units
319 * @return the outer SVG frame which aRect is relative to
321 static nsIFrame*
322 GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame, nsRect* aRect);
324 /* Generate a viewbox to viewport tranformation matrix */
326 static already_AddRefed<nsIDOMSVGMatrix>
327 GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
328 float aViewboxX, float aViewboxY,
329 float aViewboxWidth, float aViewboxHeight,
330 nsIDOMSVGAnimatedPreserveAspectRatio *aPreserveAspectRatio,
331 PRBool aIgnoreAlign = PR_FALSE);
333 /* Paint SVG frame with SVG effects - aDirtyRect is the area being
334 * redrawn, in device pixel coordinates relative to the outer svg */
335 static void
336 PaintFrameWithEffects(nsSVGRenderState *aContext,
337 const nsIntRect *aDirtyRect,
338 nsIFrame *aFrame);
340 /* Hit testing - check if point hits the clipPath of indicated
341 * frame. Returns true if no clipPath set. */
342 static PRBool
343 HitTestClip(nsIFrame *aFrame, const nsPoint &aPoint);
345 /* Hit testing - check if point hits any children of frame. */
347 static nsIFrame *
348 HitTestChildren(nsIFrame *aFrame, const nsPoint &aPoint);
350 /* Add observation of an nsISVGValue to an nsISVGValueObserver */
351 static void
352 AddObserver(nsISupports *aObserver, nsISupports *aTarget);
354 /* Remove observation of an nsISVGValue from an nsISVGValueObserver */
355 static void
356 RemoveObserver(nsISupports *aObserver, nsISupports *aTarget);
359 * Returns the CanvasTM of the indicated frame, whether it's a
360 * child SVG frame, container SVG frame, or a regular frame.
361 * For regular frames, we just return an identity matrix.
363 static already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM(nsIFrame *aFrame);
366 * Tells child frames that something that might affect them has changed
368 static void
369 NotifyChildrenOfSVGChange(nsIFrame *aFrame, PRUint32 aFlags);
372 * Get frame's covered region by walking the children and doing union.
374 static nsRect
375 GetCoveredRegion(const nsFrameList &aFrames);
378 * Convert a rect from device pixel units to app pixel units by inflation.
380 static nsRect
381 ToAppPixelRect(nsPresContext *aPresContext,
382 double xmin, double ymin, double xmax, double ymax);
383 static nsRect
384 ToAppPixelRect(nsPresContext *aPresContext, const gfxRect& rect);
387 * Convert a surface size to an integer for use by thebes
388 * possibly making it smaller in the process so the surface does not
389 * use excessive memory.
390 * @param aSize the desired surface size
391 * @param aResultOverflows true if the desired surface size is too big
392 * @return the surface size to use
394 static gfxIntSize
395 ConvertToSurfaceSize(const gfxSize& aSize, PRBool *aResultOverflows);
398 * Get a pointer to a surface that can be used to create thebes
399 * contexts for various measurement purposes.
401 static gfxASurface *
402 GetThebesComputationalSurface();
405 * Convert a nsIDOMSVGMatrix to a gfxMatrix.
407 static gfxMatrix
408 ConvertSVGMatrixToThebes(nsIDOMSVGMatrix *aMatrix);
411 * Hit test a given rectangle/matrix.
413 static PRBool
414 HitTestRect(nsIDOMSVGMatrix *aMatrix,
415 float aRX, float aRY, float aRWidth, float aRHeight,
416 float aX, float aY);
419 static void CompositeSurfaceMatrix(gfxContext *aContext,
420 gfxASurface *aSurface,
421 nsIDOMSVGMatrix *aCTM, float aOpacity);
423 static void CompositePatternMatrix(gfxContext *aContext,
424 gfxPattern *aPattern,
425 nsIDOMSVGMatrix *aCTM, float aWidth, float aHeight, float aOpacity);
427 static void SetClipRect(gfxContext *aContext,
428 nsIDOMSVGMatrix *aCTM, float aX, float aY,
429 float aWidth, float aHeight);
432 * If aIn can be represented exactly using an nsIntRect (i.e. integer-aligned edges and
433 * coordinates in the PRInt32 range) then we set aOut to that rectangle, otherwise
434 * return failure.
436 static nsresult GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
439 * Restricts aRect to pixels that intersect aGfxRect.
441 static void ClipToGfxRect(nsIntRect* aRect, const gfxRect& aGfxRect);
443 /* Using group opacity instead of fill or stroke opacity on a
444 * geometry object seems to be a common authoring mistake. If we're
445 * not applying filters and not both stroking and filling, we can
446 * generate the same result without going through the overhead of a
447 * push/pop group. */
448 static PRBool
449 CanOptimizeOpacity(nsIFrame *aFrame);
451 /* Calculate the maximum expansion of a matrix */
452 static float
453 MaxExpansion(nsIDOMSVGMatrix *aMatrix);
455 /* Take a CTM and adjust for object bounding box coordinates, if needed */
456 static already_AddRefed<nsIDOMSVGMatrix>
457 AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
458 nsSVGEnum *aUnits,
459 nsIFrame *aFrame);
462 * Get bounding-box for aFrame. Matrix propagation is disabled so the
463 * bounding box is computed in terms of aFrame's own user space.
465 static already_AddRefed<nsIDOMSVGRect>
466 GetBBox(nsIFrame *aFrame);
468 * Compute a rectangle in userSpaceOnUse or objectBoundingBoxUnits.
469 * @param aXYWH pointer to 4 consecutive nsSVGLength2 objects containing
470 * the x, y, width and height values in that order
471 * @param aBBox the bounding box of the object the rect is relative to;
472 * may be null if aUnits is not SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
473 * @param aFrame the object in which to interpret user-space units;
474 * may be null if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
476 static gfxRect
477 GetRelativeRect(PRUint16 aUnits, const nsSVGLength2 *aXYWH, nsIDOMSVGRect *aBBox,
478 nsIFrame *aFrame);
480 #ifdef DEBUG
481 static void
482 WritePPM(const char *fname, gfxImageSurface *aSurface);
483 #endif
485 private:
486 /* Computational (nil) surfaces */
487 static gfxASurface *mThebesComputationalSurface;
490 #endif