mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 643419 - pathLength should affect stroke-dasharray. r=dholbert
This commit is contained in:
parent
d0281e5301
commit
a93f118660
@ -127,6 +127,7 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
|
||||
}
|
||||
|
||||
mBaseVal = val;
|
||||
mIsBaseSet = PR_TRUE;
|
||||
if (!mIsAnimated) {
|
||||
mAnimVal = mBaseVal;
|
||||
}
|
||||
@ -155,6 +156,7 @@ nsSVGNumber2::SetBaseValue(float aValue,
|
||||
PRBool aDoSetAttr)
|
||||
{
|
||||
mBaseVal = aValue;
|
||||
mIsBaseSet = PR_TRUE;
|
||||
if (!mIsAnimated) {
|
||||
mAnimVal = mBaseVal;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
mAnimVal = mBaseVal = aValue;
|
||||
mAttrEnum = aAttrEnum;
|
||||
mIsAnimated = PR_FALSE;
|
||||
mIsBaseSet = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult SetBaseValueString(const nsAString& aValue,
|
||||
@ -70,6 +71,14 @@ public:
|
||||
float GetAnimValue() const
|
||||
{ return mAnimVal; }
|
||||
|
||||
// Returns PR_TRUE if the animated value of this number has been explicitly
|
||||
// set (either by animation, or by taking on the base value which has been
|
||||
// explicitly set by markup or a DOM call), PR_FALSE otherwise.
|
||||
// If this returns PR_FALSE, the animated value is still valid, that is,
|
||||
// useable, and represents the default base value of the attribute.
|
||||
PRBool IsExplicitlySet() const
|
||||
{ return mIsAnimated || mIsBaseSet; }
|
||||
|
||||
nsresult ToDOMAnimatedNumber(nsIDOMSVGAnimatedNumber **aResult,
|
||||
nsSVGElement* aSVGElement);
|
||||
#ifdef MOZ_SMIL
|
||||
@ -83,6 +92,7 @@ private:
|
||||
float mBaseVal;
|
||||
PRUint8 mAttrEnum; // element specified tracking for attribute
|
||||
PRPackedBool mIsAnimated;
|
||||
PRPackedBool mIsBaseSet;
|
||||
|
||||
public:
|
||||
struct DOMAnimatedNumber : public nsIDOMSVGAnimatedNumber
|
||||
|
@ -122,8 +122,11 @@ nsSVGPathElement::GetPointAtLength(float distance, nsIDOMSVGPoint **_retval)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
float totalLength = flat->GetLength();
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::pathLength)) {
|
||||
if (mPathLength.IsExplicitlySet()) {
|
||||
float pathLength = mPathLength.GetAnimValue();
|
||||
if (pathLength <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
distance *= totalLength / pathLength;
|
||||
}
|
||||
distance = NS_MAX(0.f, distance);
|
||||
@ -400,11 +403,8 @@ nsSVGPathElement::GetFlattenedPath(const gfxMatrix &aMatrix)
|
||||
PRBool
|
||||
nsSVGPathElement::AttributeDefinesGeometry(const nsIAtom *aName)
|
||||
{
|
||||
if (aName == nsGkAtoms::d ||
|
||||
aName == nsGkAtoms::pathLength)
|
||||
return PR_TRUE;
|
||||
|
||||
return PR_FALSE;
|
||||
return aName == nsGkAtoms::d ||
|
||||
aName == nsGkAtoms::pathLength;
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -425,3 +425,18 @@ nsSVGPathElement::ConstructPath(gfxContext *aCtx)
|
||||
mD.GetAnimValue().ConstructPath(aCtx);
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
nsSVGPathElement::GetScale()
|
||||
{
|
||||
if (mPathLength.IsExplicitlySet()) {
|
||||
|
||||
nsRefPtr<gfxFlattenedPath> flat =
|
||||
GetFlattenedPath(PrependLocalTransformTo(gfxMatrix()));
|
||||
float pathLength = mPathLength.GetAnimValue();
|
||||
|
||||
if (flat && pathLength != 0) {
|
||||
return flat->GetLength() / pathLength;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ class nsSVGPathElement : public nsSVGPathElementBase,
|
||||
public nsIDOMSVGAnimatedPathData
|
||||
{
|
||||
friend class nsSVGPathFrame;
|
||||
friend class nsSVGTextPathFrame;
|
||||
|
||||
protected:
|
||||
friend nsresult NS_NewSVGPathElement(nsIContent **aResult,
|
||||
@ -99,6 +98,8 @@ public:
|
||||
return nsGkAtoms::d;
|
||||
}
|
||||
|
||||
gfxFloat GetScale();
|
||||
|
||||
protected:
|
||||
|
||||
// nsSVGElement method
|
||||
|
@ -73,6 +73,7 @@ _TEST_FILES = \
|
||||
test_nonAnimStrings.xhtml \
|
||||
test_pathAnimInterpolation.xhtml \
|
||||
test_pathSeg.xhtml \
|
||||
test_pointAtLength.xhtml \
|
||||
test_pointer-events.xhtml \
|
||||
test_pointer-events-2.xhtml \
|
||||
test_scientific.html \
|
||||
|
50
content/svg/content/test/test_pointAtLength.xhtml
Normal file
50
content/svg/content/test/test_pointAtLength.xhtml
Normal file
@ -0,0 +1,50 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=643419
|
||||
-->
|
||||
<head>
|
||||
<title>Test getPointAtLength</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function run()
|
||||
{
|
||||
var p1 = document.getElementById("p1");
|
||||
var point = p1.getPointAtLength(200);
|
||||
is(point.x, 200);
|
||||
is(point.y, 50);
|
||||
|
||||
// set the pathLength to twice its actual length
|
||||
p1.setAttribute("pathLength", "800");
|
||||
var point = p1.getPointAtLength(200);
|
||||
is(point.x, 100);
|
||||
is(point.y, 50);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run, false);
|
||||
]]>
|
||||
</script>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=643419">Mozilla Bug 643419</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="750">
|
||||
<defs>
|
||||
<path id="p1" d="M 0 50 h 400"/>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
12
layout/reftests/svg/pathLength-01.svg
Normal file
12
layout/reftests/svg/pathLength-01.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
-->
|
||||
<svg viewBox="0 0 100 2" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="red"/>
|
||||
<!-- This path is really 400 units long (and its halfway point is at the
|
||||
right edge of our viewBox). We use pathLength to normalize its length
|
||||
to 20, though, so the first 10-unit-long dash in stroke-dasharray ends
|
||||
up covering 10/20 = 1/2 of the path. This covers the whole viewBox. -->
|
||||
<path d="M-100,1 h400" pathLength="20" stroke-dasharray="10" fill="none" stroke="lime" stroke-width="2"/>
|
||||
</svg>
|
After Width: | Height: | Size: 677 B |
13
layout/reftests/svg/pathLength-02.svg
Normal file
13
layout/reftests/svg/pathLength-02.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
-->
|
||||
<svg viewBox="0 0 100 2" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<!-- This path is really 400 units long (and its halfway point is at the
|
||||
right edge of our viewBox). We use pathLength to normalize its length
|
||||
to 20, though, so the first 5-unit-long dash in stroke-dasharray ends
|
||||
up covering 5/20 = 1/4 of the path. The hole in the dasharray spans
|
||||
the viewBox -->
|
||||
<path d="M-100,1 h400" pathLength="20" stroke-dasharray="5" fill="none" stroke="red" stroke-width="2"/>
|
||||
</svg>
|
After Width: | Height: | Size: 695 B |
@ -152,6 +152,8 @@ random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundin
|
||||
== path-02.svg pass.svg
|
||||
== path-03.svg pass.svg
|
||||
== path-04.svg pass.svg
|
||||
== pathLength-01.svg pass.svg
|
||||
== pathLength-02.svg pass.svg
|
||||
== pattern-invalid-01.svg pattern-invalid-01-ref.svg
|
||||
== pattern-live-01a.svg pattern-live-01-ref.svg
|
||||
== pattern-live-01b.svg pattern-live-01-ref.svg
|
||||
@ -198,6 +200,7 @@ fails-if(Android) random-if(gtk2Widget) != text-language-01.xhtml text-language-
|
||||
== text-stroke-scaling-01.svg text-stroke-scaling-01-ref.svg
|
||||
== stroke-linecap-square-w-zero-length-segs-01.svg pass.svg
|
||||
== stroke-linecap-square-w-zero-length-segs-02.svg pass.svg
|
||||
== textPath-01.svg textPath-01-ref.svg
|
||||
== text-style-01a.svg text-style-01-ref.svg
|
||||
== text-style-01b.svg text-style-01-ref.svg
|
||||
== text-style-01c.svg text-style-01-ref.svg
|
||||
|
@ -0,0 +1,31 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" class="reftest-wait">
|
||||
<title>Test that pathLength of paths has no effect in animation</title>
|
||||
<defs>
|
||||
<path id="path" pathLength="100" d="M-200,0 h400" />
|
||||
</defs>
|
||||
<script xlink:href="../smil-util.js" type="text/javascript"/>
|
||||
<script type="text/javascript">
|
||||
function doTest() {
|
||||
setTimeAndSnapshot(0.5, true);
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
|
||||
<!-- calcMode="linear" -->
|
||||
<rect x="10" y="10" width="100" height="100" fill="red"/>
|
||||
<rect x="10" y="10" width="100" height="100" fill="lime">
|
||||
<animateMotion dur="1s" keyPoints="0;1" keyTimes="0;1" calcMode="linear">
|
||||
<mpath xlink:href="#path" />
|
||||
</animateMotion>
|
||||
</rect>
|
||||
|
||||
<!-- calcMode="paced" -->
|
||||
<rect x="10" y="110" width="100" height="100" fill="red"/>
|
||||
<rect x="10" y="110" width="100" height="100" fill="lime">
|
||||
<animateMotion dur="1s">
|
||||
<mpath xlink:href="#path" />
|
||||
</animateMotion>
|
||||
</rect>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -3,7 +3,6 @@
|
||||
|
||||
== animateMotion-by-1.svg lime.svg
|
||||
== animateMotion-from-to-1.svg lime.svg
|
||||
== animateMotion-mpath-target-transform-1.svg lime.svg
|
||||
== animateMotion-rotate-1a.svg lime.svg
|
||||
== animateMotion-rotate-1b.svg lime.svg
|
||||
== animateMotion-rotate-2.svg lime.svg
|
||||
@ -12,4 +11,6 @@
|
||||
== animateMotion-values-paced-1b.svg animateMotion-values-paced-1-ref.svg
|
||||
|
||||
# Tests involving <mpath> sub-element
|
||||
== animateMotion-mpath-pathLength-1.svg lime.svg
|
||||
== animateMotion-mpath-targetChange-1.svg lime.svg
|
||||
== animateMotion-mpath-target-transform-1.svg lime.svg
|
||||
|
16
layout/reftests/svg/textPath-01-ref.svg
Normal file
16
layout/reftests/svg/textPath-01-ref.svg
Normal file
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Reference to check that percentage startOffset ignores pathLength</title>
|
||||
|
||||
<defs>
|
||||
<path id="x" d="M 0 100 h 400"/>
|
||||
</defs>
|
||||
|
||||
<text>
|
||||
<textPath xlink:href="#x" font-size="20" fill="black" startOffset="50%">Should see this</textPath>
|
||||
</text>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 487 B |
16
layout/reftests/svg/textPath-01.svg
Normal file
16
layout/reftests/svg/textPath-01.svg
Normal file
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/licenses/publicdomain/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Testcase to check that percentage startOffset ignores pathLength</title>
|
||||
|
||||
<defs>
|
||||
<path id="x" pathLength="20" d="M 0 100 h 400"/>
|
||||
</defs>
|
||||
|
||||
<text>
|
||||
<textPath xlink:href="#x" font-size="20" fill="black" startOffset="50%">Should see this</textPath>
|
||||
</text>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 503 B |
@ -35,6 +35,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsPresContext.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsSVGPaintServerFrame.h"
|
||||
@ -116,13 +117,22 @@ nsSVGGeometryFrame::GetStrokeDashArray(gfxFloat **aDashes, PRUint32 *aCount)
|
||||
nsPresContext *presContext = PresContext();
|
||||
gfxFloat totalLength = 0.0f;
|
||||
|
||||
gfxFloat pathScale = 1.0;
|
||||
|
||||
if (mContent->Tag() == nsGkAtoms::path) {
|
||||
pathScale = static_cast<nsSVGPathElement*>(mContent)->GetScale();
|
||||
if (pathScale <= 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
dashes = new gfxFloat[count];
|
||||
if (dashes) {
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
dashes[i] =
|
||||
nsSVGUtils::CoordToFloat(presContext,
|
||||
ctx,
|
||||
dasharray[i]);
|
||||
dasharray[i]) * pathScale;
|
||||
if (dashes[i] < 0.0f) {
|
||||
delete [] dashes;
|
||||
return NS_OK;
|
||||
|
@ -142,20 +142,16 @@ already_AddRefed<gfxFlattenedPath>
|
||||
nsSVGTextPathFrame::GetFlattenedPath()
|
||||
{
|
||||
nsIFrame *path = GetPathFrame();
|
||||
return path ? GetFlattenedPath(path) : nsnull;
|
||||
|
||||
if (path) {
|
||||
nsSVGPathGeometryElement *element =
|
||||
static_cast<nsSVGPathGeometryElement*>(path->GetContent());
|
||||
|
||||
return element->GetFlattenedPath(element->PrependLocalTransformTo(gfxMatrix()));
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFlattenedPath>
|
||||
nsSVGTextPathFrame::GetFlattenedPath(nsIFrame *path)
|
||||
{
|
||||
NS_PRECONDITION(path, "Unexpected null path");
|
||||
|
||||
nsSVGPathGeometryElement *element =
|
||||
static_cast<nsSVGPathGeometryElement*>(path->GetContent());
|
||||
|
||||
return element->GetFlattenedPath(element->PrependLocalTransformTo(gfxMatrix()));
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
nsSVGTextPathFrame::GetStartOffset()
|
||||
{
|
||||
@ -169,9 +165,8 @@ nsSVGTextPathFrame::GetStartOffset()
|
||||
if (length->IsPercentage()) {
|
||||
nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath();
|
||||
return data ? (val * data->GetLength() / 100.0) : 0.0;
|
||||
} else {
|
||||
return val * GetPathScale();
|
||||
}
|
||||
return val * GetPathScale();
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
@ -181,14 +176,7 @@ nsSVGTextPathFrame::GetPathScale()
|
||||
if (!pathFrame)
|
||||
return 1.0;
|
||||
|
||||
nsSVGPathElement *path = static_cast<nsSVGPathElement*>(pathFrame->GetContent());
|
||||
float pl = path->mPathLength.GetAnimValue();
|
||||
|
||||
if (pl == 0.0f)
|
||||
return 1.0;
|
||||
|
||||
nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath(pathFrame);
|
||||
return data ? data->GetLength() / pl : 1.0;
|
||||
return static_cast<nsSVGPathElement*>(pathFrame->GetContent())->GetScale();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -91,9 +91,6 @@ protected:
|
||||
virtual void GetXY(SVGUserUnitList *aX, SVGUserUnitList *aY);
|
||||
virtual void GetDxDy(SVGUserUnitList *aDx, SVGUserUnitList *aDy);
|
||||
virtual const SVGNumberList *GetRotate();
|
||||
|
||||
private:
|
||||
already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIFrame *path);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user