Bug 1532156 - correct marker-start for closed paths so it is the average of the start and end angles i.e. the same as marker-end r=dholbert
authorlongsonr <longsonr@gmail.com>
Sat, 16 Mar 2019 17:00:23 +0000
changeset 464572 d36eebc8899848bd3285c7b02466b3f9eb0a0f9a
parent 464571 cca61da626c0f7ced2aefa2dd1e46c38089c8e80
child 464573 4e11626a9e602aa253df00f54a53cdbbc04fd071
push id112461
push userlongsonr@gmail.com
push dateSat, 16 Mar 2019 17:01:05 +0000
treeherdermozilla-inbound@d36eebc88998 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1532156
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532156 - correct marker-start for closed paths so it is the average of the start and end angles i.e. the same as marker-end r=dholbert
dom/svg/SVGPathData.cpp
layout/reftests/svg/marker-orientation-05.svg
layout/reftests/svg/reftest.list
--- a/dom/svg/SVGPathData.cpp
+++ b/dom/svg/SVGPathData.cpp
@@ -752,16 +752,17 @@ static float AngleOfVector(const Point& 
 void SVGPathData::GetMarkerPositioningData(nsTArray<SVGMark>* aMarks) const {
   // This code should assume that ANY type of segment can appear at ANY index.
   // It should also assume that segments such as M and Z can appear in weird
   // places, and repeat multiple times consecutively.
 
   // info on current [sub]path (reset every M command):
   Point pathStart(0.0, 0.0);
   float pathStartAngle = 0.0f;
+  uint32_t pathStartIndex = 0;
 
   // info on previous segment:
   uint16_t prevSegType = PATHSEG_UNKNOWN;
   Point prevSegEnd(0.0, 0.0);
   float prevSegEndAngle = 0.0f;
   Point prevCP;  // if prev seg was a bezier, this was its last control point
 
   uint32_t i = 0;
@@ -783,16 +784,17 @@ void SVGPathData::GetMarkerPositioningDa
       case PATHSEG_MOVETO_ABS:
       case PATHSEG_MOVETO_REL:
         if (segType == PATHSEG_MOVETO_ABS) {
           segEnd = Point(mData[i], mData[i + 1]);
         } else {
           segEnd = segStart + Point(mData[i], mData[i + 1]);
         }
         pathStart = segEnd;
+        pathStartIndex = aMarks->Length();
         // If authors are going to specify multiple consecutive moveto commands
         // with markers, me might as well make the angle do something useful:
         segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
         i += 2;
         break;
 
       case PATHSEG_LINETO_ABS:
       case PATHSEG_LINETO_REL:
@@ -1037,18 +1039,17 @@ void SVGPathData::GetMarkerPositioningDa
     if (!aMarks->AppendElement(SVGMark(static_cast<float>(segEnd.x),
                                        static_cast<float>(segEnd.y), 0.0f,
                                        SVGMark::eMid))) {
       aMarks->Clear();  // OOM, so try to free some
       return;
     }
 
     if (segType == PATHSEG_CLOSEPATH && prevSegType != PATHSEG_CLOSEPATH) {
-      aMarks->LastElement().angle =
-          // aMarks->ElementAt(pathStartIndex).angle =
+      aMarks->LastElement().angle = aMarks->ElementAt(pathStartIndex).angle =
           SVGContentUtils::AngleBisect(segEndAngle, pathStartAngle);
     }
 
     prevSegType = segType;
     prevSegEnd = segEnd;
     prevSegEndAngle = segEndAngle;
   }
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/marker-orientation-05.svg
@@ -0,0 +1,20 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
+    <defs>
+        <marker id="arrowAutoStartRev" orient="auto-start-reverse" markerUnits="userSpaceOnUse" overflow="visible">
+            <path d="M25,25 L0,0 L0,50 z" fill="lime" stroke="lime" stroke-width="2" />
+        </marker>
+        <marker id="arrowSW" orient="135" markerUnits="userSpaceOnUse" overflow="visible">
+            <path d="M25,25 L0,0 L0,50 z" fill="red"/>
+        </marker>
+        <marker id="arrowAuto" orient="auto" markerUnits="userSpaceOnUse" overflow="visible">
+            <path d="M25,25 L0,0 L0,50 z" fill="red"/>
+        </marker>
+     </defs>
+    <rect width="100%" height="100%" fill="lime" />
+    <path d="M 340,100 h50 v50 h-50 z" marker-start="url(#arrowSW)" fill="none"/>
+    <path d="M 340,100 h50 v50 h-50 z" marker-start="url(#arrowAutoStartRev)" fill="none"/>
+    <g transform="translate(0, 50)">
+      <path d="M 340,100 h50 v50 h-50 z" marker-start="url(#arrowAuto)" fill="none"/>
+      <path d="M 340,100 h50 v50 h-50 z" marker-end="url(#arrowAutoStartRev)" fill="none"/>
+    </g>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -264,16 +264,17 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(
 == marker-attribute-01.svg pass.svg
 fuzzy-if(skiaContent,0-1,0-1) == marker-dynamic-opacity.html marker-dynamic-opacity-ref.html
 == marker-effects-01.svg marker-effects-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-100) == marker-viewBox-01.svg marker-viewBox-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-100) == marker-orientation-01.svg marker-orientation-01-ref.svg
 fuzzy-if(skiaContent,0-1,0-5) == marker-orientation-02.svg marker-orientation-02-ref.svg
 == marker-orientation-03.svg pass.svg
 == marker-orientation-04.svg pass.svg
+== marker-orientation-05.svg pass.svg
 
 fuzzy(0-28,0-28) == mask-and-clipPath.html mask-and-clipPath-ref.html
 == mask-and-clipPath-2.svg pass.svg
 == mask-ref-loop-01.svg pass.svg
 == mask-basic-01.svg pass.svg
 fuzzy-if(skiaContent,0-1,0-10000) == mask-basic-02.svg mask-basic-02-ref.svg
 == mask-basic-03.svg pass.svg
 == mask-basic-04.svg pass.svg