layout/svg/nsSVGUtils.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 NS_SVGUTILS_H
michael@0 7 #define NS_SVGUTILS_H
michael@0 8
michael@0 9 // include math.h to pick up definition of M_ maths defines e.g. M_PI
michael@0 10 #define _USE_MATH_DEFINES
michael@0 11 #include <math.h>
michael@0 12
michael@0 13 #include "DrawMode.h"
michael@0 14 #include "gfx2DGlue.h"
michael@0 15 #include "gfxMatrix.h"
michael@0 16 #include "gfxPoint.h"
michael@0 17 #include "gfxRect.h"
michael@0 18 #include "mozilla/gfx/Rect.h"
michael@0 19 #include "nsAlgorithm.h"
michael@0 20 #include "nsChangeHint.h"
michael@0 21 #include "nsColor.h"
michael@0 22 #include "nsCOMPtr.h"
michael@0 23 #include "nsID.h"
michael@0 24 #include "nsISupportsBase.h"
michael@0 25 #include "nsMathUtils.h"
michael@0 26 #include "nsStyleStruct.h"
michael@0 27 #include "mozilla/Constants.h"
michael@0 28 #include <algorithm>
michael@0 29
michael@0 30 class gfxContext;
michael@0 31 class gfxPattern;
michael@0 32 class nsFrameList;
michael@0 33 class nsIContent;
michael@0 34 class nsIDocument;
michael@0 35 class nsIFrame;
michael@0 36 class nsPresContext;
michael@0 37 class nsRenderingContext;
michael@0 38 class nsStyleContext;
michael@0 39 class nsStyleCoord;
michael@0 40 class nsSVGDisplayContainerFrame;
michael@0 41 class nsSVGElement;
michael@0 42 class nsSVGEnum;
michael@0 43 class nsSVGLength2;
michael@0 44 class nsSVGOuterSVGFrame;
michael@0 45 class nsSVGPathGeometryFrame;
michael@0 46 class nsTextFrame;
michael@0 47 class gfxTextContextPaint;
michael@0 48
michael@0 49 struct nsStyleSVG;
michael@0 50 struct nsStyleSVGPaint;
michael@0 51 struct nsRect;
michael@0 52 struct nsIntRect;
michael@0 53 struct nsPoint;
michael@0 54
michael@0 55 namespace mozilla {
michael@0 56 class SVGAnimatedPreserveAspectRatio;
michael@0 57 class SVGPreserveAspectRatio;
michael@0 58 namespace dom {
michael@0 59 class Element;
michael@0 60 } // namespace dom
michael@0 61 namespace gfx {
michael@0 62 class SourceSurface;
michael@0 63 }
michael@0 64 } // namespace mozilla
michael@0 65
michael@0 66 // maximum dimension of an offscreen surface - choose so that
michael@0 67 // the surface size doesn't overflow a 32-bit signed int using
michael@0 68 // 4 bytes per pixel; in line with gfxASurface::CheckSurfaceSize
michael@0 69 // In fact Macs can't even manage that
michael@0 70 #define NS_SVG_OFFSCREEN_MAX_DIMENSION 4096
michael@0 71
michael@0 72 #define SVG_HIT_TEST_FILL 0x01
michael@0 73 #define SVG_HIT_TEST_STROKE 0x02
michael@0 74 #define SVG_HIT_TEST_CHECK_MRECT 0x04
michael@0 75
michael@0 76
michael@0 77 bool NS_SVGDisplayListHitTestingEnabled();
michael@0 78 bool NS_SVGDisplayListPaintingEnabled();
michael@0 79
michael@0 80 /**
michael@0 81 * Sometimes we need to distinguish between an empty box and a box
michael@0 82 * that contains an element that has no size e.g. a point at the origin.
michael@0 83 */
michael@0 84 class SVGBBox {
michael@0 85 typedef mozilla::gfx::Rect Rect;
michael@0 86
michael@0 87 public:
michael@0 88 SVGBBox()
michael@0 89 : mIsEmpty(true) {}
michael@0 90
michael@0 91 SVGBBox(const Rect& aRect)
michael@0 92 : mBBox(aRect), mIsEmpty(false) {}
michael@0 93
michael@0 94 SVGBBox(const gfxRect& aRect)
michael@0 95 : mBBox(ToRect(aRect)), mIsEmpty(false) {}
michael@0 96
michael@0 97 gfxRect ToThebesRect() const {
michael@0 98 return ThebesRect(mBBox);
michael@0 99 }
michael@0 100
michael@0 101 bool IsEmpty() const {
michael@0 102 return mIsEmpty;
michael@0 103 }
michael@0 104
michael@0 105 void UnionEdges(const SVGBBox& aSVGBBox) {
michael@0 106 if (aSVGBBox.mIsEmpty) {
michael@0 107 return;
michael@0 108 }
michael@0 109 mBBox = mIsEmpty ? aSVGBBox.mBBox : mBBox.UnionEdges(aSVGBBox.mBBox);
michael@0 110 mIsEmpty = false;
michael@0 111 }
michael@0 112
michael@0 113 private:
michael@0 114 Rect mBBox;
michael@0 115 bool mIsEmpty;
michael@0 116 };
michael@0 117
michael@0 118 // GRRR WINDOWS HATE HATE HATE
michael@0 119 #undef CLIP_MASK
michael@0 120
michael@0 121 class MOZ_STACK_CLASS SVGAutoRenderState
michael@0 122 {
michael@0 123 public:
michael@0 124 enum RenderMode {
michael@0 125 /**
michael@0 126 * Used to inform SVG frames that they should paint as normal.
michael@0 127 */
michael@0 128 NORMAL,
michael@0 129 /**
michael@0 130 * Used to inform SVG frames when they are painting as the child of a
michael@0 131 * simple clipPath. In this case they should only draw their basic geometry
michael@0 132 * as a path. They should not fill, stroke, or paint anything else.
michael@0 133 */
michael@0 134 CLIP,
michael@0 135 /**
michael@0 136 * Used to inform SVG frames when they are painting as the child of a
michael@0 137 * complex clipPath that requires the use of a clip mask. In this case they
michael@0 138 * should only draw their basic geometry as a path and then fill it using
michael@0 139 * fully opaque white. They should not stroke, or paint anything else.
michael@0 140 */
michael@0 141 CLIP_MASK
michael@0 142 };
michael@0 143
michael@0 144 SVGAutoRenderState(nsRenderingContext *aContext, RenderMode aMode
michael@0 145 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
michael@0 146 ~SVGAutoRenderState();
michael@0 147
michael@0 148 void SetPaintingToWindow(bool aPaintingToWindow);
michael@0 149
michael@0 150 static RenderMode GetRenderMode(nsRenderingContext *aContext);
michael@0 151 static bool IsPaintingToWindow(nsRenderingContext *aContext);
michael@0 152
michael@0 153 private:
michael@0 154 nsRenderingContext *mContext;
michael@0 155 void *mOriginalRenderState;
michael@0 156 RenderMode mMode;
michael@0 157 bool mPaintingToWindow;
michael@0 158 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
michael@0 159 };
michael@0 160
michael@0 161
michael@0 162 #define NS_ISVGFILTERREFERENCE_IID \
michael@0 163 { 0x9744ee20, 0x1bcf, 0x4c62, \
michael@0 164 { 0x86, 0x7d, 0xd3, 0x7a, 0x91, 0x60, 0x3e, 0xef } }
michael@0 165
michael@0 166 class nsISVGFilterReference : public nsISupports
michael@0 167 {
michael@0 168 public:
michael@0 169 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISVGFILTERREFERENCE_IID)
michael@0 170 virtual void Invalidate() = 0;
michael@0 171 };
michael@0 172
michael@0 173 NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGFilterReference, NS_ISVGFILTERREFERENCE_IID)
michael@0 174
michael@0 175 /**
michael@0 176 * General functions used by all of SVG layout and possibly content code.
michael@0 177 * If a method is used by content and depends only on other content methods
michael@0 178 * it should go in SVGContentUtils instead.
michael@0 179 */
michael@0 180 class nsSVGUtils
michael@0 181 {
michael@0 182 public:
michael@0 183 typedef mozilla::dom::Element Element;
michael@0 184
michael@0 185 static void Init();
michael@0 186
michael@0 187 /**
michael@0 188 * Gets the nearest nsSVGInnerSVGFrame or nsSVGOuterSVGFrame frame. aFrame
michael@0 189 * must be an SVG frame. If aFrame is of type nsGkAtoms::svgOuterSVGFrame,
michael@0 190 * returns nullptr.
michael@0 191 */
michael@0 192 static nsSVGDisplayContainerFrame* GetNearestSVGViewport(nsIFrame *aFrame);
michael@0 193
michael@0 194 /**
michael@0 195 * Returns the frame's post-filter visual overflow rect when passed the
michael@0 196 * frame's pre-filter visual overflow rect. If the frame is not currently
michael@0 197 * being filtered, this function simply returns aUnfilteredRect.
michael@0 198 */
michael@0 199 static nsRect GetPostFilterVisualOverflowRect(nsIFrame *aFrame,
michael@0 200 const nsRect &aUnfilteredRect);
michael@0 201
michael@0 202 /**
michael@0 203 * Schedules an update of the frame's bounds (which will in turn invalidate
michael@0 204 * the new area that the frame should paint to).
michael@0 205 *
michael@0 206 * This does nothing when passed an NS_FRAME_IS_NONDISPLAY frame.
michael@0 207 * In future we may want to allow ReflowSVG to be called on such frames,
michael@0 208 * but that would be better implemented as a ForceReflowSVG function to
michael@0 209 * be called synchronously while painting them without marking or paying
michael@0 210 * attention to dirty bits like this function.
michael@0 211 *
michael@0 212 * This is very similar to PresShell::FrameNeedsReflow. The main reason that
michael@0 213 * we have this function instead of using FrameNeedsReflow is because we need
michael@0 214 * to be able to call it under nsSVGOuterSVGFrame::NotifyViewportChange when
michael@0 215 * that function is called by nsSVGOuterSVGFrame::Reflow. FrameNeedsReflow
michael@0 216 * is not suitable for calling during reflow though, and it asserts as much.
michael@0 217 * The reason that we want to be callable under NotifyViewportChange is
michael@0 218 * because we want to synchronously notify and dirty the nsSVGOuterSVGFrame's
michael@0 219 * children so that when nsSVGOuterSVGFrame::DidReflow is called its children
michael@0 220 * will be updated for the new size as appropriate. Otherwise we'd have to
michael@0 221 * post an event to the event loop to mark dirty flags and request an update.
michael@0 222 *
michael@0 223 * Another reason that we don't currently want to call
michael@0 224 * PresShell::FrameNeedsReflow is because passing eRestyle to it to get it to
michael@0 225 * mark descendants dirty would cause it to descend through
michael@0 226 * nsSVGForeignObjectFrame frames to mark their children dirty, but we want to
michael@0 227 * handle nsSVGForeignObjectFrame specially. It would also do unnecessary work
michael@0 228 * descending into NS_FRAME_IS_NONDISPLAY frames.
michael@0 229 */
michael@0 230 static void ScheduleReflowSVG(nsIFrame *aFrame);
michael@0 231
michael@0 232 /**
michael@0 233 * Returns true if the frame or any of its children need ReflowSVG
michael@0 234 * to be called on them.
michael@0 235 */
michael@0 236 static bool NeedsReflowSVG(nsIFrame *aFrame);
michael@0 237
michael@0 238 /*
michael@0 239 * Update the filter invalidation region for ancestor frames, if relevant.
michael@0 240 */
michael@0 241 static void NotifyAncestorsOfFilterRegionChange(nsIFrame *aFrame);
michael@0 242
michael@0 243 /* Computes the input length in terms of object space coordinates.
michael@0 244 Input: rect - bounding box
michael@0 245 length - length to be converted
michael@0 246 */
michael@0 247 static float ObjectSpace(const gfxRect &aRect, const nsSVGLength2 *aLength);
michael@0 248
michael@0 249 /* Computes the input length in terms of user space coordinates.
michael@0 250 Input: content - object to be used for determining user space
michael@0 251 Input: length - length to be converted
michael@0 252 */
michael@0 253 static float UserSpace(nsSVGElement *aSVGElement, const nsSVGLength2 *aLength);
michael@0 254
michael@0 255 /* Computes the input length in terms of user space coordinates.
michael@0 256 Input: aFrame - object to be used for determining user space
michael@0 257 length - length to be converted
michael@0 258 */
michael@0 259 static float UserSpace(nsIFrame *aFrame, const nsSVGLength2 *aLength);
michael@0 260
michael@0 261 /* Find the outermost SVG frame of the passed frame */
michael@0 262 static nsSVGOuterSVGFrame *
michael@0 263 GetOuterSVGFrame(nsIFrame *aFrame);
michael@0 264
michael@0 265 /**
michael@0 266 * Get the covered region for a frame. Return null if it's not an SVG frame.
michael@0 267 * @param aRect gets a rectangle in app units
michael@0 268 * @return the outer SVG frame which aRect is relative to
michael@0 269 */
michael@0 270 static nsIFrame*
michael@0 271 GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame, nsRect* aRect);
michael@0 272
michael@0 273 /* Paint SVG frame with SVG effects - aDirtyRect is the area being
michael@0 274 * redrawn, in device pixel coordinates relative to the outer svg */
michael@0 275 static void
michael@0 276 PaintFrameWithEffects(nsRenderingContext *aContext,
michael@0 277 const nsIntRect *aDirtyRect,
michael@0 278 nsIFrame *aFrame,
michael@0 279 nsIFrame* aTransformRoot = nullptr);
michael@0 280
michael@0 281 /* Hit testing - check if point hits the clipPath of indicated
michael@0 282 * frame. Returns true if no clipPath set. */
michael@0 283 static bool
michael@0 284 HitTestClip(nsIFrame *aFrame, const nsPoint &aPoint);
michael@0 285
michael@0 286 /* Hit testing - check if point hits any children of frame. */
michael@0 287
michael@0 288 static nsIFrame *
michael@0 289 HitTestChildren(nsIFrame *aFrame, const nsPoint &aPoint);
michael@0 290
michael@0 291 /*
michael@0 292 * Returns the CanvasTM of the indicated frame, whether it's a
michael@0 293 * child SVG frame, container SVG frame, or a regular frame.
michael@0 294 * For regular frames, we just return an identity matrix.
michael@0 295 */
michael@0 296 static gfxMatrix GetCanvasTM(nsIFrame* aFrame, uint32_t aFor,
michael@0 297 nsIFrame* aTransformRoot = nullptr);
michael@0 298
michael@0 299 /**
michael@0 300 * Returns the transform from aFrame's user space to canvas space. Only call
michael@0 301 * with SVG frames. This is like GetCanvasTM, except that it only includes
michael@0 302 * the transforms from aFrame's user space (i.e. the coordinate context
michael@0 303 * established by its 'transform' attribute, or else the coordinate context
michael@0 304 * that its _parent_ establishes for its children) to outer-<svg> device
michael@0 305 * space. Specifically, it does not include any other transforms introduced
michael@0 306 * by the frame such as x/y offsets and viewBox attributes.
michael@0 307 */
michael@0 308 static gfxMatrix GetUserToCanvasTM(nsIFrame* aFrame, uint32_t aFor);
michael@0 309
michael@0 310 /**
michael@0 311 * Notify the descendants of aFrame of a change to one of their ancestors
michael@0 312 * that might affect them.
michael@0 313 */
michael@0 314 static void
michael@0 315 NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags);
michael@0 316
michael@0 317 /*
michael@0 318 * Get frame's covered region by walking the children and doing union.
michael@0 319 */
michael@0 320 static nsRect
michael@0 321 GetCoveredRegion(const nsFrameList &aFrames);
michael@0 322
michael@0 323 // Converts aPoint from an app unit point in outer-<svg> content rect space
michael@0 324 // to an app unit point in a frame's SVG userspace.
michael@0 325 // This is a temporary helper we should no longer need after bug 614732 is
michael@0 326 // fixed.
michael@0 327 static nsPoint
michael@0 328 TransformOuterSVGPointToChildFrame(nsPoint aPoint,
michael@0 329 const gfxMatrix& aFrameToCanvasTM,
michael@0 330 nsPresContext* aPresContext);
michael@0 331
michael@0 332 static nsRect
michael@0 333 TransformFrameRectToOuterSVG(const nsRect& aRect,
michael@0 334 const gfxMatrix& aMatrix,
michael@0 335 nsPresContext* aPresContext);
michael@0 336
michael@0 337 /*
michael@0 338 * Convert a surface size to an integer for use by thebes
michael@0 339 * possibly making it smaller in the process so the surface does not
michael@0 340 * use excessive memory.
michael@0 341 *
michael@0 342 * @param aSize the desired surface size
michael@0 343 * @param aResultOverflows true if the desired surface size is too big
michael@0 344 * @return the surface size to use
michael@0 345 */
michael@0 346 static gfxIntSize ConvertToSurfaceSize(const gfxSize& aSize,
michael@0 347 bool *aResultOverflows);
michael@0 348
michael@0 349 /*
michael@0 350 * Hit test a given rectangle/matrix.
michael@0 351 */
michael@0 352 static bool
michael@0 353 HitTestRect(const mozilla::gfx::Matrix &aMatrix,
michael@0 354 float aRX, float aRY, float aRWidth, float aRHeight,
michael@0 355 float aX, float aY);
michael@0 356
michael@0 357
michael@0 358 /**
michael@0 359 * Get the clip rect for the given frame, taking into account the CSS 'clip'
michael@0 360 * property. See:
michael@0 361 * http://www.w3.org/TR/SVG11/masking.html#OverflowAndClipProperties
michael@0 362 * The arguments for aX, aY, aWidth and aHeight should be the dimensions of
michael@0 363 * the viewport established by aFrame.
michael@0 364 */
michael@0 365 static gfxRect
michael@0 366 GetClipRectForFrame(nsIFrame *aFrame,
michael@0 367 float aX, float aY, float aWidth, float aHeight);
michael@0 368
michael@0 369 static void SetClipRect(gfxContext *aContext,
michael@0 370 const gfxMatrix &aCTM,
michael@0 371 const gfxRect &aRect);
michael@0 372
michael@0 373 /* Using group opacity instead of fill or stroke opacity on a
michael@0 374 * geometry object seems to be a common authoring mistake. If we're
michael@0 375 * not applying filters and not both stroking and filling, we can
michael@0 376 * generate the same result without going through the overhead of a
michael@0 377 * push/pop group. */
michael@0 378 static bool
michael@0 379 CanOptimizeOpacity(nsIFrame *aFrame);
michael@0 380
michael@0 381 /**
michael@0 382 * Take the CTM to userspace for an element, and adjust it to a CTM to its
michael@0 383 * object bounding box space if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX.
michael@0 384 * (I.e. so that [0,0] is at the top left of its bbox, and [1,1] is at the
michael@0 385 * bottom right of its bbox).
michael@0 386 *
michael@0 387 * If the bbox is empty, this will return a singular matrix.
michael@0 388 */
michael@0 389 static gfxMatrix
michael@0 390 AdjustMatrixForUnits(const gfxMatrix &aMatrix,
michael@0 391 nsSVGEnum *aUnits,
michael@0 392 nsIFrame *aFrame);
michael@0 393
michael@0 394 enum BBoxFlags {
michael@0 395 eBBoxIncludeFill = 1 << 0,
michael@0 396 eBBoxIncludeFillGeometry = 1 << 1,
michael@0 397 eBBoxIncludeStroke = 1 << 2,
michael@0 398 eBBoxIncludeStrokeGeometry = 1 << 3,
michael@0 399 eBBoxIncludeMarkers = 1 << 4
michael@0 400 };
michael@0 401 /**
michael@0 402 * Get the SVG bbox (the SVG spec's simplified idea of bounds) of aFrame in
michael@0 403 * aFrame's userspace.
michael@0 404 */
michael@0 405 static gfxRect GetBBox(nsIFrame *aFrame,
michael@0 406 uint32_t aFlags = eBBoxIncludeFillGeometry);
michael@0 407
michael@0 408 /*
michael@0 409 * "User space" is the space that the frame's BBox (as calculated by
michael@0 410 * nsSVGUtils::GetBBox) is in. "Frame space" is the space that has its origin
michael@0 411 * at the top left of the union of the frame's border-box rects over all
michael@0 412 * continuations.
michael@0 413 * This function returns the offset one needs to add to something in frame
michael@0 414 * space in order to get its coordinates in user space.
michael@0 415 */
michael@0 416 static gfxPoint FrameSpaceInCSSPxToUserSpaceOffset(nsIFrame *aFrame);
michael@0 417
michael@0 418 /**
michael@0 419 * Convert a userSpaceOnUse/objectBoundingBoxUnits rectangle that's specified
michael@0 420 * using four nsSVGLength2 values into a user unit rectangle in user space.
michael@0 421 *
michael@0 422 * @param aXYWH pointer to 4 consecutive nsSVGLength2 objects containing
michael@0 423 * the x, y, width and height values in that order
michael@0 424 * @param aBBox the bounding box of the object the rect is relative to;
michael@0 425 * may be null if aUnits is not SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
michael@0 426 * @param aFrame the object in which to interpret user-space units;
michael@0 427 * may be null if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
michael@0 428 */
michael@0 429 static gfxRect
michael@0 430 GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
michael@0 431 const gfxRect &aBBox, nsIFrame *aFrame);
michael@0 432
michael@0 433 /**
michael@0 434 * Find the first frame, starting with aStartFrame and going up its
michael@0 435 * parent chain, that is not an svgAFrame.
michael@0 436 */
michael@0 437 static nsIFrame* GetFirstNonAAncestorFrame(nsIFrame* aStartFrame);
michael@0 438
michael@0 439 static bool OuterSVGIsCallingReflowSVG(nsIFrame *aFrame);
michael@0 440 static bool AnyOuterSVGIsCallingReflowSVG(nsIFrame *aFrame);
michael@0 441
michael@0 442 /*
michael@0 443 * Get any additional transforms that apply only to stroking
michael@0 444 * e.g. non-scaling-stroke
michael@0 445 */
michael@0 446 static gfxMatrix GetStrokeTransform(nsIFrame *aFrame);
michael@0 447
michael@0 448 /**
michael@0 449 * Compute the maximum possible device space stroke extents of a path given
michael@0 450 * the path's device space path extents, its stroke style and its ctm.
michael@0 451 *
michael@0 452 * This is a workaround for the lack of suitable cairo API for getting the
michael@0 453 * tight device space stroke extents of a path. This basically gives us the
michael@0 454 * tightest extents that we can guarantee fully enclose the inked stroke
michael@0 455 * without doing the calculations for the actual tight extents. We exploit
michael@0 456 * the fact that cairo does have an API for getting the tight device space
michael@0 457 * fill/path extents.
michael@0 458 *
michael@0 459 * This should die once bug 478152 is fixed.
michael@0 460 */
michael@0 461 static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
michael@0 462 nsTextFrame* aFrame,
michael@0 463 const gfxMatrix& aMatrix);
michael@0 464 static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
michael@0 465 nsSVGPathGeometryFrame* aFrame,
michael@0 466 const gfxMatrix& aMatrix);
michael@0 467
michael@0 468 /**
michael@0 469 * Convert a floating-point value to a 32-bit integer value, clamping to
michael@0 470 * the range of valid integers.
michael@0 471 */
michael@0 472 static int32_t ClampToInt(double aVal)
michael@0 473 {
michael@0 474 return NS_lround(std::max(double(INT32_MIN),
michael@0 475 std::min(double(INT32_MAX), aVal)));
michael@0 476 }
michael@0 477
michael@0 478 static nscolor GetFallbackOrPaintColor(gfxContext *aContext,
michael@0 479 nsStyleContext *aStyleContext,
michael@0 480 nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
michael@0 481
michael@0 482 /**
michael@0 483 * Set up cairo context with an object pattern
michael@0 484 */
michael@0 485 static bool SetupContextPaint(gfxContext *aContext,
michael@0 486 gfxTextContextPaint *aContextPaint,
michael@0 487 const nsStyleSVGPaint& aPaint,
michael@0 488 float aOpacity);
michael@0 489
michael@0 490 /**
michael@0 491 * Sets the current paint on the specified gfxContent to be the SVG 'fill'
michael@0 492 * for the given frame.
michael@0 493 */
michael@0 494 static bool SetupCairoFillPaint(nsIFrame* aFrame, gfxContext* aContext,
michael@0 495 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 496
michael@0 497 /**
michael@0 498 * Sets the current paint on the specified gfxContent to be the SVG 'stroke'
michael@0 499 * for the given frame.
michael@0 500 */
michael@0 501 static bool SetupCairoStrokePaint(nsIFrame* aFrame, gfxContext* aContext,
michael@0 502 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 503
michael@0 504 static float GetOpacity(nsStyleSVGOpacitySource aOpacityType,
michael@0 505 const float& aOpacity,
michael@0 506 gfxTextContextPaint *aOuterContextPaint);
michael@0 507
michael@0 508 /*
michael@0 509 * @return false if there is no stroke
michael@0 510 */
michael@0 511 static bool HasStroke(nsIFrame* aFrame,
michael@0 512 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 513
michael@0 514 static float GetStrokeWidth(nsIFrame* aFrame,
michael@0 515 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 516
michael@0 517 /*
michael@0 518 * Set up a cairo context for measuring the bounding box of a stroked path.
michael@0 519 */
michael@0 520 static void SetupCairoStrokeBBoxGeometry(nsIFrame* aFrame,
michael@0 521 gfxContext *aContext,
michael@0 522 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 523
michael@0 524 /*
michael@0 525 * Set up a cairo context for a stroked path (including any dashing that
michael@0 526 * applies).
michael@0 527 */
michael@0 528 static void SetupCairoStrokeGeometry(nsIFrame* aFrame, gfxContext *aContext,
michael@0 529 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 530
michael@0 531 /*
michael@0 532 * Set up a cairo context for stroking, including setting up any stroke-related
michael@0 533 * properties such as dashing and setting the current paint on the gfxContext.
michael@0 534 */
michael@0 535 static bool SetupCairoStroke(nsIFrame* aFrame, gfxContext *aContext,
michael@0 536 gfxTextContextPaint *aContextPaint = nullptr);
michael@0 537
michael@0 538 /**
michael@0 539 * This function returns a set of bit flags indicating which parts of the
michael@0 540 * element (fill, stroke, bounds) should intercept pointer events. It takes
michael@0 541 * into account the type of element and the value of the 'pointer-events'
michael@0 542 * property on the element.
michael@0 543 */
michael@0 544 static uint16_t GetGeometryHitTestFlags(nsIFrame* aFrame);
michael@0 545
michael@0 546 /**
michael@0 547 * Render a SVG glyph.
michael@0 548 * @param aElement the SVG glyph element to render
michael@0 549 * @param aContext the thebes aContext to draw to
michael@0 550 * @param aDrawMode fill or stroke or both (see DrawMode)
michael@0 551 * @return true if rendering succeeded
michael@0 552 */
michael@0 553 static bool PaintSVGGlyph(Element* aElement, gfxContext* aContext,
michael@0 554 DrawMode aDrawMode,
michael@0 555 gfxTextContextPaint* aContextPaint);
michael@0 556 /**
michael@0 557 * Get the extents of a SVG glyph.
michael@0 558 * @param aElement the SVG glyph element
michael@0 559 * @param aSVGToAppSpace the matrix mapping the SVG glyph space to the
michael@0 560 * target context space
michael@0 561 * @param aResult the result (valid when true is returned)
michael@0 562 * @return true if calculating the extents succeeded
michael@0 563 */
michael@0 564 static bool GetSVGGlyphExtents(Element* aElement,
michael@0 565 const gfxMatrix& aSVGToAppSpace,
michael@0 566 gfxRect* aResult);
michael@0 567
michael@0 568 /**
michael@0 569 * Returns the app unit canvas bounds of a userspace rect.
michael@0 570 *
michael@0 571 * @param aToCanvas Transform from userspace to canvas device space.
michael@0 572 */
michael@0 573 static nsRect
michael@0 574 ToCanvasBounds(const gfxRect &aUserspaceRect,
michael@0 575 const gfxMatrix &aToCanvas,
michael@0 576 const nsPresContext *presContext);
michael@0 577 };
michael@0 578
michael@0 579 #endif

mercurial