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 464696 d36eebc88998
parent 464695 cca61da626c0
child 464697 4e11626a9e60
push id35717
push useraciure@mozilla.com
push dateSun, 17 Mar 2019 09:45:26 +0000
treeherdermozilla-central@e0861be8d6c0 [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