Bug 1187770 - work around draw targets that don't display zero-length lines. r=longsonr

This commit is contained in:
Tom Klein 2015-08-01 10:09:00 +02:00
parent 8594823f0a
commit 5b1d4a44e8
8 changed files with 59 additions and 9 deletions

View File

@ -39,6 +39,8 @@ class Matrix;
} // namespace gfx
} // namespace mozilla
#define SVG_ZERO_LENGTH_PATH_FIX_FACTOR 512
inline bool
IsSVGWhitespace(char aChar)
{

View File

@ -37,6 +37,23 @@ SVGLineElement::SVGLineElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeIn
{
}
void
SVGLineElement::MaybeAdjustForZeroLength(float aX1, float aY1,
float& aX2, float aY2)
{
if (aX1 == aX2 && aY1 == aY2) {
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(&strokeOptions, this, nullptr, nullptr,
SVGContentUtils::eIgnoreStrokeDashing);
if (strokeOptions.mLineCap != CapStyle::BUTT) {
float tinyLength =
strokeOptions.mLineWidth / SVG_ZERO_LENGTH_PATH_FIX_FACTOR;
aX2 += tinyLength;
}
}
}
//----------------------------------------------------------------------
// nsIDOMNode methods
@ -112,6 +129,8 @@ SVGLineElement::GetAsSimplePath(SimplePath* aSimplePath)
{
float x1, y1, x2, y2;
GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nullptr);
MaybeAdjustForZeroLength(x1, y1, x2, y2);
aSimplePath->SetLine(x1, y1, x2, y2);
}
@ -121,6 +140,7 @@ SVGLineElement::BuildPath(PathBuilder* aBuilder)
float x1, y1, x2, y2;
GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nullptr);
MaybeAdjustForZeroLength(x1, y1, x2, y2);
aBuilder->MoveTo(Point(x1, y1));
aBuilder->LineTo(Point(x2, y2));

View File

@ -25,6 +25,10 @@ protected:
virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
friend nsresult (::NS_NewSVGLineElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
// If the input line has length zero and linecaps aren't butt, adjust |aX2| by
// a tiny amount to a barely-nonzero-length line that all of our draw targets
// will render
void MaybeAdjustForZeroLength(float aX1, float aY1, float& aX2, float aY2);
public:
// nsIContent interface

View File

@ -255,7 +255,7 @@ ApproximateZeroLengthSubpathSquareCaps(PathBuilder* aPB,
// line is rather arbitrary, other than being chosen to meet the requirements
// described in the comment above.
Float tinyLength = aStrokeWidth / 512;
Float tinyLength = aStrokeWidth / SVG_ZERO_LENGTH_PATH_FIX_FACTOR;
aPB->LineTo(aPoint + Point(tinyLength, 0));
aPB->MoveTo(aPoint);

View File

@ -6,11 +6,12 @@
<title>Test 'stroke-linecap: round' with zero length path segments</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1075399 -->
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1075399 for paths and
https://bugzilla.mozilla.org/show_bug.cgi?id=1187770 for lines -->
<style>
path {
path, line {
stroke-width: 20px;
stroke-linecap: round;
}
@ -20,7 +21,7 @@ circle {
}
/* expect lime circles to cover red circles */
path.circles-expected {
path.circles-expected, line.circles-expected {
stroke: lime;
}
@ -158,4 +159,11 @@ path.coverer {
<circle cy="80" r="8"/>
<path class="circles-expected" d="M0,0v81" stroke-dasharray="0" />
</g>
<!-- Column 6: test zero-length line -->
<g transform="translate(625, 25)">
<circle cy="0" r="8" />
<line class="circles-expected" x1="0" y1="0" x2="0" y2="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -6,13 +6,15 @@
<title>Test invalidation for 'stroke-linecap: round' with zero length path segments</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1075399 -->
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1075399 for path and
https://bugzilla.mozilla.org/show_bug.cgi?id=1187770 for line -->
<script>
function run()
{
document.getElementById('path').setAttribute('stroke-linecap', 'butt');
document.getElementById('line').setAttribute('stroke-linecap', 'butt');
document.documentElement.removeAttribute('class');
}
@ -24,5 +26,7 @@ window.addEventListener("MozReftestInvalidate", run, false);
<path id="path" stroke="red" stroke-width="200" stroke-linecap="round"
d="M100,100 L100,100"/>
<line id="line" stroke="red" stroke-width="200" stroke-linecap="round"
x1="300" y1="300" x2="300" y2="300"/>
</svg>

Before

Width:  |  Height:  |  Size: 751 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -6,11 +6,12 @@
<title>Test 'stroke-linecap: square' with zero length path segments</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=589648 -->
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=589648 for paths and
https://bugzilla.mozilla.org/show_bug.cgi?id=1187770 for lines -->
<style>
path {
path, line {
stroke-width: 20px;
stroke-linecap: square;
}
@ -20,7 +21,7 @@ rect {
}
/* expect lime squares to cover red rects */
path.squares-expected {
path.squares-expected, line.squares-expected {
stroke: lime;
}
@ -144,4 +145,10 @@ path.coverer {
<path class="coverer" d="M20,20 L30,30 M70,70 L80,80"/>
</g>
<!-- Column 5: test zero-length line -->
<g transform="translate(525, 25)">
<rect x="-9" y="-9" width="18" height="18"/>
<line class="squares-expected" x1="0" y1="0" x2="0" y2="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -6,13 +6,15 @@
<title>Test 'stroke-linecap: square' with zero length path segments</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=589648 -->
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=589648 for path and
https://bugzilla.mozilla.org/show_bug.cgi?id=1187770 for line -->
<script>
function run()
{
document.getElementById('path').setAttribute('stroke-linecap', 'butt');
document.getElementById('line').setAttribute('stroke-linecap', 'butt');
document.documentElement.removeAttribute('class');
}
@ -25,4 +27,7 @@ window.addEventListener("MozReftestInvalidate", run, false);
<path id="path" stroke="red" stroke-width="200" stroke-linecap="square"
d="M100,100 L100,100"/>
<line id="line" stroke="red" stroke-width="200" stroke-linecap="square"
x1="300" y1="300" x2="300" y2="300"/>
</svg>

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 1012 B