Bug 1345853 - Part 2. If the transform matrix is singular, return DrawResult::SUCCESS, instead of DrawResult::BAD_ARGS draft
authorcku <cku@mozilla.com>
Thu, 16 Mar 2017 12:06:36 +0800
changeset 552189 9067a4ce70c7ea6ee2a54782645fdf4d66d9f1ca
parent 552188 f62722e35e58513f648d26832287983f16c61446
child 552190 3ce35a66e459dc2d5b9ba987d82afa16df4b55bb
child 552253 9349b7323d87f2e440d84d9498aa8c654211a688
push id51279
push userbmo:cku@mozilla.com
push dateTue, 28 Mar 2017 05:02:15 +0000
bugs1345853, 1258510
milestone55.0a1
Bug 1345853 - Part 2. If the transform matrix is singular, return DrawResult::SUCCESS, instead of DrawResult::BAD_ARGS According to bug 1345853 comment 5, tn said: You probably want to return whatever was drawn there regardless of the DrawResult. SVGMaskFrame has the same problem. Keep in mind that DrawResult is only reporting on how drawing of any images went, not the drawing of anything else. Also looking over the patches from bug 1258510 I see a couple places where BAD_ARGS is returned if the transform matrix is singular. We would want to return SUCCESS in that case I think, because we drew what we were instructed to draw. MozReview-Commit-ID: 5XcDuKQwXTJ
layout/svg/SVGGeometryFrame.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGGradientFrame.cpp
layout/svg/nsSVGMaskFrame.cpp
layout/svg/nsSVGPatternFrame.cpp
--- a/layout/svg/SVGGeometryFrame.cpp
+++ b/layout/svg/SVGGeometryFrame.cpp
@@ -284,17 +284,17 @@ SVGGeometryFrame::PaintSVG(gfxContext& a
 {
   if (!StyleVisibility()->IsVisible())
     return DrawResult::SUCCESS;
 
   // Matrix to the geometry's user space:
   gfxMatrix newMatrix =
     aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
   if (newMatrix.IsSingular()) {
-    return DrawResult::BAD_ARGS;
+    return DrawResult::SUCCESS;
   }
 
   uint32_t paintOrder = StyleSVG()->mPaintOrder;
   DrawResult result = DrawResult::SUCCESS;
 
   if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) {
     result = Render(&aContext, eRenderFill | eRenderStroke, newMatrix);
     PaintMarkers(aContext, aTransform);
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3590,17 +3590,17 @@ SVGTextFrame::PaintSVG(gfxContext& aCont
     // If we are asked to paint before reflow has recomputed mPositions etc.
     // directly via PaintSVG, rather than via a display list, then we need
     // to bail out here too.
     return DrawResult::SUCCESS;
   }
 
   if (aTransform.IsSingular()) {
     NS_WARNING("Can't render text element!");
-    return DrawResult::BAD_ARGS;
+    return DrawResult::SUCCESS;
   }
 
   gfxMatrix matrixForPaintServers = aTransform * initialMatrix;
 
   // Check if we need to draw anything.
   if (aDirtyRect) {
     NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                  (mState & NS_FRAME_IS_NONDISPLAY),
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -216,17 +216,17 @@ nsSVGForeignObjectFrame::PaintSVG(gfxCon
     return DrawResult::SUCCESS;
 
   nsIFrame* kid = PrincipalChildList().FirstChild();
   if (!kid)
     return DrawResult::SUCCESS;
 
   if (aTransform.IsSingular()) {
     NS_WARNING("Can't render foreignObject element!");
-    return DrawResult::BAD_ARGS;
+    return DrawResult::SUCCESS;
   }
 
   nsRect kidDirtyRect = kid->GetVisualOverflowRect();
 
   /* Check if we need to draw anything. */
   if (aDirtyRect) {
     NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                  (mState & NS_FRAME_IS_NONDISPLAY),
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -267,29 +267,29 @@ nsSVGGradientFrame::GetPaintServerPatter
   }
 
   // Get the transform list (if there is one). We do this after the returns
   // above since this call can be expensive when "gradientUnits" is set to
   // "objectBoundingBox" (since that requiring a GetBBox() call).
   gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
 
   if (patternMatrix.IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
+    return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
   }
 
   // revert any vector effect transform so that the gradient appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) {
       patternMatrix *= userToOuterSVG;
     }
   }
 
   if (!patternMatrix.Invert()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
+    return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
   }
 
   RefPtr<gfxPattern> gradient = CreateGradient();
   if (!gradient) {
     return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<gfxPattern>());
   }
 
   uint16_t aSpread = GetSpreadMethod();
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -316,17 +316,17 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(Ma
                      maskSurfaceSize, aParams.opacity);
   }
 
   maskSurface->Unmap();
   destMaskSurface->Unmap();
 
   // Moz2D transforms in the opposite direction to Thebes
   if (!maskSurfaceMatrix.Invert()) {
-    return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
+    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
   }
 
   *aParams.maskTransform = ToMatrix(maskSurfaceMatrix);
   RefPtr<SourceSurface> surface = destMaskSurface.forget();
   return MakePair(result, Move(surface));
 }
 
 gfxRect
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -277,17 +277,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
     return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
   }
 
   // Construct the CTM that we will provide to our children when we
   // render them into the tile.
   gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits,
                                callerBBox, aContextMatrix, aSource);
   if (ctm.IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
   }
 
   if (patternWithChildren->mCTM) {
     *patternWithChildren->mCTM = ctm;
   } else {
     patternWithChildren->mCTM = new gfxMatrix(ctm);
   }
 
@@ -304,27 +304,27 @@ nsSVGPatternFrame::PaintPattern(const Dr
 
   // revert the vector effect transform so that the pattern appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) {
       patternTransform *= ToMatrix(userToOuterSVG);
       if (patternTransform.IsSingular()) {
         NS_WARNING("Singular matrix painting non-scaling-stroke");
-        return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+        return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
       }
     }
   }
 
   // Get the transformation matrix that we will hand to the renderer's pattern
   // routine.
   *patternMatrix = GetPatternMatrix(patternUnits, patternTransform,
                                     bbox, callerBBox, aContextMatrix);
   if (patternMatrix->IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
   }
 
   // Now that we have all of the necessary geometries, we can
   // create our surface.
   gfxRect transformedBBox = ThebesRect(patternTransform.TransformBounds(ToRect(bbox)));
 
   bool resultOverflows;
   IntSize surfaceSize =