Bug 1299876 - Part 1. Inflate bbox by stroke used value of the target frame. draft
authorcku <cku@mozilla.com>
Mon, 03 Oct 2016 17:48:40 +0800
changeset 420112 77222e3de78da7cdd483d760d384cab4f602fdd8
parent 419914 7c576fe3279d87543f0a03b844eba7bc215e17f1
child 532722 8e39c7b837c7235c7a2fb4e27bfc5471750d1545
push id31096
push userbmo:cku@mozilla.com
push dateMon, 03 Oct 2016 10:05:16 +0000
bugs1299876
milestone52.0a1
Bug 1299876 - Part 1. Inflate bbox by stroke used value of the target frame. MozReview-Commit-ID: Et9SvNS4M6h
layout/svg/nsCSSClipPathInstance.cpp
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -67,21 +67,41 @@ nsCSSClipPathInstance::ComputeSVGReferen
 {
   MOZ_ASSERT(mTargetFrame->GetContent()->IsSVGElement());
   nsRect r;
 
   // For SVG elements without associated CSS layout box, the used value for
   // content-box, padding-box, border-box and margin-box is fill-box.
   switch (mClipPathStyle.GetReferenceBox()) {
     case StyleClipPathGeometryBox::Stroke: {
-      // XXX Bug 1299876
-      // The size of srtoke-box is not correct if this graphic element has
-      // specific stroke-linejoin or stroke-linecap.
       gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
                 nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
+      if (nsSVGUtils::HasStroke(mTargetFrame)) {
+        const nsStyleSVG* style = mTargetFrame->StyleSVG();
+        // Initialize delta as half of the stroke-width.
+        float delta = nsSVGUtils::GetStrokeWidth(mTargetFrame) / 2.0;
+
+        nsIContent* content = mTargetFrame->GetContent();
+        if (!content->IsAnyOfSVGElements(nsGkAtoms::rect,
+                                         nsGkAtoms::ellipse,
+                                         nsGkAtoms::circle,
+                                         nsGkAtoms::image)) {
+          if (style->mStrokeLinejoin == NS_STYLE_STROKE_LINEJOIN_MITER) {
+            float miter = style->mStrokeMiterlimit;
+            delta = (miter < M_SQRT2 &&
+                     style->mStrokeLinecap == NS_STYLE_STROKE_LINECAP_SQUARE)
+                    ? delta * M_SQRT2 : miter;
+          }
+          if (style->mStrokeLinecap == NS_STYLE_STROKE_LINECAP_SQUARE) {
+            delta *= 1.414;
+          }
+        }
+        bbox.Inflate(delta);
+      }
+
       r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
                                          nsPresContext::AppUnitsPerCSSPixel());
       break;
     }
     case StyleClipPathGeometryBox::View: {
       nsIContent* content = mTargetFrame->GetContent();
       nsSVGElement* element = static_cast<nsSVGElement*>(content);
       SVGSVGElement* svgElement = element->GetCtx();