Bug 997735 - Rename nsSVGIntegrationUtils::GetOffsetToUserSpace to GetOffsetToBoundingBox. r=roc
authorMarkus Stange <mstange@themasta.com>
Wed, 23 Apr 2014 11:47:31 +0200
changeset 180104 77a55da6682761f7d7284b671f56d9ce2ff7499a
parent 180103 f8f94f19e05b9cda0f5c81178094c2f2cc581fc5
child 180105 fcd9986a84c58232fdf6a2f8cb6ee994e5be3612
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersroc
bugs997735
milestone31.0a1
Bug 997735 - Rename nsSVGIntegrationUtils::GetOffsetToUserSpace to GetOffsetToBoundingBox. r=roc There are three spaces that nsSVGIntegrationUtils needs to convert between. I'll call them "frame space", "bounding box frame space" and "user space". "Bounding box frame space" has its origin at the top left of the union of a frame's border boxes over all continuations. For SVG frames, "frame space" and "bounding box frame space" are the same because SVG frames don't have multiple continuations. For non-SVG frames, "bounding box frame space" and "user space" are the same. However, for SVG frames, "bounding box frame space" and "user space" are different! For example, for a <rect x="100" y="100">, the point 0,0 in frame space is at the rect's top left corner, but the point 0,0 in user space is 100,100 pixels away from the rect's corner. nsSVGIntegrationUtils::GetOffsetToUserSpace took the non-SVG viewpoint, but it's misleading for SVG frames.
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGIntegrationUtils.h
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -149,18 +149,20 @@ nsSVGIntegrationUtils::UsingEffectsForFr
   // Even when SVG display lists are disabled, returning true for SVG frames
   // does not adversely affect any of our callers. Therefore we don't bother
   // checking the SDL prefs here, since we don't know if we're being called for
   // painting or hit-testing anyway.
   const nsStyleSVGReset *style = aFrame->StyleSVGReset();
   return (style->HasFilters() || style->mClipPath || style->mMask);
 }
 
-/* static */ nsPoint
-nsSVGIntegrationUtils::GetOffsetToUserSpace(nsIFrame* aFrame)
+// For non-SVG frames, this gives the offset to the frame's "user space".
+// For SVG frames, this returns a zero offset.
+static nsPoint
+GetOffsetToBoundingBox(nsIFrame* aFrame)
 {
   if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     // Do NOT call GetAllInFlowRectsUnion for SVG - it will get the
     // covered region relative to the nsSVGOuterSVGFrame, which is absolutely
     // not what we want. SVG frames are always in user space, so they have
     // no offset adjustment to make.
     return nsPoint();
   }
@@ -203,26 +205,26 @@ gfxRect
 nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame)
 {
   NS_ASSERTION(!aNonSVGFrame->IsFrameOfType(nsIFrame::eSVG),
                "SVG frames should not get here");
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame);
   // 'r' is in "user space":
   nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(),
-                                              GetOffsetToUserSpace(firstFrame));
+                                              GetOffsetToBoundingBox(firstFrame));
   return nsLayoutUtils::RectToGfxRect(r,
            aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel());
 }
 
 // XXX Since we're called during reflow, this method is broken for frames with
 // continuations. When we're called for a frame with continuations, we're
 // called for each continuation in turn as it's reflowed. However, it isn't
 // until the last continuation is reflowed that this method's
-// GetOffsetToUserSpace() and GetPreEffectsVisualOverflowUnion() calls will
+// GetOffsetToBoundingBox() and GetPreEffectsVisualOverflowUnion() calls will
 // obtain valid border boxes for all the continuations. As a result, we'll
 // end up returning bogus post-filter visual overflow rects for all the prior
 // continuations. Unfortunately, by the time the last continuation is
 // reflowed, it's too late to go back and set and propagate the overflow
 // rects on the previous continuations.
 //
 // The reason that we need to pass an override bbox to
 // GetPreEffectsVisualOverflowUnion rather than just letting it call into our
@@ -257,33 +259,33 @@ nsRect
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
   if (!effectProperties.HasValidFilter()) {
     return aPreEffectsOverflowRect;
   }
 
   // Create an override bbox - see comment above:
-  nsPoint firstFrameToUserSpace = GetOffsetToUserSpace(firstFrame);
+  nsPoint firstFrameToBoundingBox = GetOffsetToBoundingBox(firstFrame);
   // overrideBBox is in "user space", in _CSS_ pixels:
   // XXX Why are we rounding out to pixel boundaries? We don't do that in
   // GetSVGBBoxForNonSVGFrame, and it doesn't appear to be necessary.
   gfxRect overrideBBox =
     nsLayoutUtils::RectToGfxRect(
       GetPreEffectsVisualOverflowUnion(firstFrame, aFrame,
                                        aPreEffectsOverflowRect,
-                                       firstFrameToUserSpace),
+                                       firstFrameToBoundingBox),
       aFrame->PresContext()->AppUnitsPerCSSPixel());
   overrideBBox.RoundOut();
 
   nsRect overflowRect =
     nsFilterInstance::GetPostFilterBounds(firstFrame, &overrideBBox);
 
   // Return overflowRect relative to aFrame, rather than "user space":
-  return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace);
+  return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToBoundingBox);
 }
 
 nsIntRect
 nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
                                                       const nsPoint& aToReferenceFrame,
                                                       const nsIntRect& aInvalidRect)
 {
   if (aInvalidRect.IsEmpty()) {
@@ -305,28 +307,28 @@ nsSVGIntegrationUtils::AdjustInvalidArea
     // The frame is either not there or not currently available,
     // perhaps because we're in the middle of tearing stuff down.
     // Be conservative, return our visual overflow rect relative
     // to the reference frame.
     nsRect overflow = aFrame->GetVisualOverflowRect() + aToReferenceFrame;
     return overflow.ToOutsidePixels(appUnitsPerDevPixel);
   }
 
-  // Convert aInvalidRect into "user space" in app units:
-  nsPoint toUserSpace =
-    aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
+  // Convert aInvalidRect into bounding box frame space in app units:
+  nsPoint toBoundingBox =
+    aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame);
   // The initial rect was relative to the reference frame, so we need to
   // remove that offset to get a rect relative to the current frame.
-  toUserSpace -= aToReferenceFrame;
-  nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toUserSpace;
+  toBoundingBox -= aToReferenceFrame;
+  nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toBoundingBox;
 
   // Adjust the dirty area for effects, and shift it back to being relative to
   // the reference frame.
   nsRect result = nsFilterInstance::GetPostFilterDirtyArea(firstFrame,
-    preEffectsRect) - toUserSpace;
+    preEffectsRect) - toBoundingBox;
   // Return the result, in pixels relative to the reference frame.
   return result.ToOutsidePixels(appUnitsPerDevPixel);
 }
 
 nsRect
 nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(nsIFrame* aFrame,
                                                        const nsRect& aDirtyRect)
 {
@@ -336,36 +338,37 @@ nsSVGIntegrationUtils::GetRequiredSource
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   nsSVGFilterProperty *prop = nsSVGEffects::GetFilterProperty(firstFrame);
   if (!prop || !prop->ReferencesValidResources()) {
     return aDirtyRect;
   }
   
   // Convert aDirtyRect into "user space" in app units:
   nsPoint toUserSpace =
-    aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
+    aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame);
   nsRect postEffectsRect = aDirtyRect + toUserSpace;
 
   // Return ther result, relative to aFrame, not in user space:
   return nsFilterInstance::GetPreFilterNeededArea(firstFrame, postEffectsRect)
     - toUserSpace;
 }
 
 bool
 nsSVGIntegrationUtils::HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   // Convert aPt to user space:
   nsPoint toUserSpace;
   if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
+    // XXXmstange Isn't this wrong for svg:use and innerSVG frames?
     toUserSpace = aFrame->GetPosition();
   } else {
     toUserSpace =
-      aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
+      aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame);
   }
   nsPoint pt = aPt + toUserSpace;
   return nsSVGUtils::HitTestClip(firstFrame, pt);
 }
 
 class RegularFramePaintCallback : public nsSVGFilterPaintCallback
 {
 public:
@@ -455,17 +458,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf
     return; // Some resource is missing. We shouldn't paint anything.
   }
 
   bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true;
 
   gfxContext* gfx = aCtx->ThebesContext();
   gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
 
-  nsPoint firstFrameOffset = GetOffsetToUserSpace(firstFrame);
+  nsPoint firstFrameOffset = GetOffsetToBoundingBox(firstFrame);
   nsPoint offset = aBuilder->ToReferenceFrame(firstFrame) - firstFrameOffset;
   nsPoint offsetWithoutSVGGeomFramePos;
   if (firstFrame->IsFrameOfType(nsIFrame::eSVG)) {
     offsetWithoutSVGGeomFramePos = offset;
   } else {
     /* Snap the offset if the reference frame is not a SVG frame,
      * since other frames will be snapped to pixel when rendering. */
     offsetWithoutSVGGeomFramePos = nsPoint(
@@ -615,17 +618,17 @@ PaintFrameCallback::operator()(gfxContex
   aContext->Clip();
 
   aContext->Multiply(gfxMatrix(aTransform).Invert());
 
   // nsLayoutUtils::PaintFrame will anchor its painting at mFrame. But we want
   // to have it anchored at the top left corner of the bounding box of all of
   // mFrame's continuations. So we add a translation transform.
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
-  nsPoint offset = nsSVGIntegrationUtils::GetOffsetToUserSpace(mFrame);
+  nsPoint offset = GetOffsetToBoundingBox(mFrame);
   gfxPoint devPxOffset = gfxPoint(offset.x, offset.y) / appUnitsPerDevPixel;
   aContext->Multiply(gfxMatrix().Translate(devPxOffset));
 
   gfxSize paintServerSize =
     gfxSize(mPaintServerSize.width, mPaintServerSize.height) /
       mFrame->PresContext()->AppUnitsPerDevPixel();
 
   // nsLayoutUtils::PaintFrame wants to render with paintServerSize, but we
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -38,43 +38,16 @@ class nsSVGIntegrationUtils MOZ_FINAL
 public:
   /**
    * Returns true if SVG effects are currently applied to this frame.
    */
   static bool
   UsingEffectsForFrame(const nsIFrame* aFrame);
 
   /**
-   * In SVG, an element's "user space" is simply the coordinate system in place
-   * at the time that it is drawn. For non-SVG frames, we want any SVG effects
-   * to be applied to the union of the border-box rects of all of a given
-   * frame's continuations. This means that, when we paint a non-SVG frame with
-   * effects, we want to offset the effects by the distance from the frame's
-   * origin (the top left of its border box) to the top left of the union of
-   * the border-box rects of all its continuations. In other words, we need to
-   * apply this offset as a suplimental translation to the current coordinate
-   * system in order to establish the correct user space before calling into
-   * the SVG effects code. For the purposes of the nsSVGIntegrationUtils code
-   * we somewhat misappropriate the term "user space" by using it to refer
-   * specifically to this adjusted coordinate system.
-   *
-   * For consistency with nsIFrame::GetOffsetTo, the offset this method returns
-   * is the offset you need to add to a point that's relative to aFrame's
-   * origin (the top left of its border box) to convert it to aFrame's user
-   * space. In other words the value returned is actually the offset from the
-   * origin of aFrame's user space to aFrame.
-   *
-   * Note: This method currently only accepts a frame's first continuation
-   * since none of our current callers need to be able to pass in other
-   * continuations.
-   */
-  static nsPoint
-  GetOffsetToUserSpace(nsIFrame* aFrame);
-
-  /**
    * Returns the size of the union of the border-box rects of all of
    * aNonSVGFrame's continuations.
    */
   static nsSize
   GetContinuationUnionSize(nsIFrame* aNonSVGFrame);
 
   /**
    * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they