Bug 1129854 - markers not oriented correctly for degenerate beziers. r=jwatt

This commit is contained in:
Robert Longson 2015-02-17 22:15:15 +00:00
parent 72d68495ae
commit 2bd1b5fa2b
3 changed files with 61 additions and 30 deletions

View File

@ -537,9 +537,9 @@ AngleOfVector(const Point& aVector)
}
static float
AngleOfVectorF(const Point& aVector)
AngleOfVector(const Point& cp1, const Point& cp2)
{
return static_cast<float>(AngleOfVector(aVector));
return static_cast<float>(AngleOfVector(cp1 - cp2));
}
void
@ -573,7 +573,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
{
case PATHSEG_CLOSEPATH:
segEnd = pathStart;
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
break;
case PATHSEG_MOVETO_ABS:
@ -586,7 +586,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
pathStart = segEnd;
// If authors are going to specify multiple consecutive moveto commands
// with markers, me might as well make the angle do something useful:
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
i += 2;
break;
@ -597,7 +597,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + Point(mData[i], mData[i+1]);
}
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
i += 2;
break;
@ -615,14 +615,10 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
segEnd = segStart + Point(mData[i+4], mData[i+5]);
}
prevCP = cp2;
if (cp1 == segStart) {
cp1 = cp2;
}
if (cp2 == segEnd) {
cp2 = cp1;
}
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp2);
segStartAngle =
AngleOfVector(cp1 == segStart ? (cp1 == cp2 ? segEnd : cp2) : cp1, segStart);
segEndAngle =
AngleOfVector(segEnd, cp2 == segEnd ? (cp1 == cp2 ? segStart : cp1) : cp2);
i += 6;
break;
}
@ -630,7 +626,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
case PATHSEG_CURVETO_QUADRATIC_ABS:
case PATHSEG_CURVETO_QUADRATIC_REL:
{
Point cp1, cp2; // control points
Point cp1; // control point
if (segType == PATHSEG_CURVETO_QUADRATIC_ABS) {
cp1 = Point(mData[i], mData[i+1]);
segEnd = Point(mData[i+2], mData[i+3]);
@ -639,8 +635,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
segEnd = segStart + Point(mData[i+2], mData[i+3]);
}
prevCP = cp1;
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp1);
segStartAngle = AngleOfVector(cp1 == segStart ? segEnd : cp1, segStart);
segEndAngle = AngleOfVector(segEnd, cp1 == segEnd ? segStart : cp1);
i += 4;
break;
}
@ -680,7 +676,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
if (rx == 0.0 || ry == 0.0) {
// F.6.6 step 1 - straight line or coincidental points
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
i += 7;
break;
}
@ -755,7 +751,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + Point(mData[i++], 0.0f);
}
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
break;
case PATHSEG_LINETO_VERTICAL_ABS:
@ -765,7 +761,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + Point(0.0f, mData[i++]);
}
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
break;
case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
@ -782,14 +778,10 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
segEnd = segStart + Point(mData[i+2], mData[i+3]);
}
prevCP = cp2;
if (cp1 == segStart) {
cp1 = cp2;
}
if (cp2 == segEnd) {
cp2 = cp1;
}
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp2);
segStartAngle =
AngleOfVector(cp1 == segStart ? (cp1 == cp2 ? segEnd : cp2) : cp1, segStart);
segEndAngle =
AngleOfVector(segEnd, cp2 == segEnd ? (cp1 == cp2 ? segStart : cp1) : cp2);
i += 4;
break;
}
@ -799,15 +791,14 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
{
Point cp1 = SVGPathSegUtils::IsQuadraticType(prevSegType) ?
segStart * 2 - prevCP : segStart;
Point cp2;
if (segType == PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS) {
segEnd = Point(mData[i], mData[i+1]);
} else {
segEnd = segStart + Point(mData[i], mData[i+1]);
}
prevCP = cp1;
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp1);
segStartAngle = AngleOfVector(cp1 == segStart ? segEnd : cp1, segStart);
segEndAngle = AngleOfVector(segEnd, cp1 == segEnd ? segStart : cp1);
i += 2;
break;
}

View File

@ -0,0 +1,39 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="redTriangle"
refX="0" refY="12" markerUnits="userSpaceOnUse"
markerWidth="24" markerHeight="24" orient="auto">
<path fill="red" d="M 0 0 L 24 12 L 0 24 z" />
</marker>
<marker id="limeTriangle"
refX="0" refY="12" markerUnits="userSpaceOnUse"
markerWidth="24" markerHeight="24" orient="auto" overflow="visible">
<path fill="lime" stroke-width="3" stroke="lime" d="M 0 0 L 24 12 L 0 24 z" />
</marker>
<marker id="reverseLimeTriangle"
refX="0" refY="12" markerUnits="userSpaceOnUse"
markerWidth="24" markerHeight="24" orient="auto" overflow="visible">
<path transform="rotate(180, 0, 12)" fill="lime" stroke-width="3" stroke="lime" d="M 0 0 L 24 12 L 0 24 z" />
</marker>
</defs>
<rect width="100%" height="100%" fill="lime"/>
<!-- Control point vectors are zero -->
<path d="M 50,125 C 50,125, 100,25, 100,25" stroke-width="10" stroke="red"
marker-end="url(#redTriangle)" />
<path d="M 150,125 C 200,25, 200,25, 200,25" stroke-width="10" stroke="red"
marker-end="url(#redTriangle)" />
<!-- Non-degenerate covering -->
<path d="M 50,125 L 100,25" stroke-width="13" stroke="lime"
marker-end="url(#limeTriangle)" marker-start="url(#reverseLimeTriangle)" />
<path d="M 150,125 L 200,25" stroke-width="13" stroke="lime"
marker-end="url(#limeTriangle)" marker-start="url(#reverseLimeTriangle)" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -201,6 +201,7 @@ fuzzy-if(cocoaWidget,15,19679) fuzzy-if(winWidget,1,8800) fuzzy-if(!cocoaWidget&
== marker-orientation-01.svg marker-orientation-01-ref.svg
pref(svg.marker-improvements.enabled,true) == marker-orientation-02.svg marker-orientation-02-ref.svg
== marker-orientation-03.svg pass.svg
== marker-orientation-04.svg pass.svg
== mask-basic-01.svg pass.svg
== mask-basic-02.svg mask-basic-02-ref.svg
== mask-basic-03.svg pass.svg