Commit b36d94ab authored by Hyunjune's avatar Hyunjune Committed by Commit Bot

When SVGGeometryElement.getPointAtLength is called with with non-rendered, throw exception

getPointAtLength[1] on SVGGeometryElement should throw InvalidStateError
for with non-rendered, so this patch throws InvalidStateError if there is no LayoutObject on the target element.

[1] https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength

Bug: 972979
Change-Id: I26eb5330127ebbca9fbf55d796ce8159a09bfcb4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2147168
Commit-Queue: Hyunjune Kim <hyunjune.kim@samsung.com>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790367}
parent e7cc9815
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_circle_element.h" #include "third_party/blink/renderer/core/svg/svg_circle_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h"
#include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/core/svg/svg_length.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
...@@ -62,8 +63,8 @@ Path SVGCircleElement::AsPath() const { ...@@ -62,8 +63,8 @@ Path SVGCircleElement::AsPath() const {
Path path; Path path;
SVGLengthContext length_context(this); SVGLengthContext length_context(this);
DCHECK(GetLayoutObject()); const ComputedStyle& style = ComputedStyleRef();
const ComputedStyle& style = GetLayoutObject()->StyleRef();
const SVGComputedStyle& svg_style = style.SvgStyle(); const SVGComputedStyle& svg_style = style.SvgStyle();
float r = length_context.ValueForLength(svg_style.R(), style, float r = length_context.ValueForLength(svg_style.R(), style,
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_ellipse_element.h" #include "third_party/blink/renderer/core/svg/svg_ellipse_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h"
#include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/core/svg/svg_length.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
...@@ -70,8 +71,8 @@ Path SVGEllipseElement::AsPath() const { ...@@ -70,8 +71,8 @@ Path SVGEllipseElement::AsPath() const {
Path path; Path path;
SVGLengthContext length_context(this); SVGLengthContext length_context(this);
DCHECK(GetLayoutObject()); const ComputedStyle& style = ComputedStyleRef();
const ComputedStyle& style = GetLayoutObject()->StyleRef();
const SVGComputedStyle& svg_style = style.SvgStyle(); const SVGComputedStyle& svg_style = style.SvgStyle();
FloatSize radii(ToFloatSize( FloatSize radii(ToFloatSize(
......
...@@ -154,22 +154,36 @@ float SVGGeometryElement::getTotalLength(ExceptionState& exception_state) { ...@@ -154,22 +154,36 @@ float SVGGeometryElement::getTotalLength(ExceptionState& exception_state) {
return AsPath().length(); return AsPath().length();
} }
SVGPointTearOff* SVGGeometryElement::getPointAtLength(float length) { SVGPointTearOff* SVGGeometryElement::getPointAtLength(
float length,
ExceptionState& exception_state) {
GetDocument().UpdateStyleAndLayoutForNode(this, GetDocument().UpdateStyleAndLayoutForNode(this,
DocumentUpdateReason::kJavaScript); DocumentUpdateReason::kJavaScript);
FloatPoint point; if (!EnsureComputedStyle()) {
if (GetLayoutObject()) { exception_state.ThrowDOMException(
const Path& path = AsPath(); DOMExceptionCode::kInvalidStateError,
if (length < 0) { "The element is in an inactive document.");
length = 0; return nullptr;
} else {
float computed_length = path.length();
if (length > computed_length)
length = computed_length;
}
point = path.PointAtLength(length);
} }
const Path& path = AsPath();
if (path.IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The element's path is empty.");
return nullptr;
}
if (length < 0) {
length = 0;
} else {
float computed_length = path.length();
if (length > computed_length)
length = computed_length;
}
FloatPoint point = path.PointAtLength(length);
return SVGPointTearOff::CreateDetached(point); return SVGPointTearOff::CreateDetached(point);
} }
......
...@@ -52,7 +52,7 @@ class SVGGeometryElement : public SVGGraphicsElement { ...@@ -52,7 +52,7 @@ class SVGGeometryElement : public SVGGraphicsElement {
SVGAnimatedNumber* pathLength() const { return path_length_.Get(); } SVGAnimatedNumber* pathLength() const { return path_length_.Get(); }
virtual float getTotalLength(ExceptionState&); virtual float getTotalLength(ExceptionState&);
virtual SVGPointTearOff* getPointAtLength(float distance); virtual SVGPointTearOff* getPointAtLength(float distance, ExceptionState&);
float AuthorPathLength() const; float AuthorPathLength() const;
float PathLengthScaleFactor() const; float PathLengthScaleFactor() const;
......
...@@ -38,5 +38,5 @@ interface SVGGeometryElement : SVGGraphicsElement { ...@@ -38,5 +38,5 @@ interface SVGGeometryElement : SVGGraphicsElement {
[HighEntropy, Measure] boolean isPointInFill(SVGPoint point); [HighEntropy, Measure] boolean isPointInFill(SVGPoint point);
[HighEntropy, Measure] boolean isPointInStroke(SVGPoint point); [HighEntropy, Measure] boolean isPointInStroke(SVGPoint point);
[HighEntropy, Measure, RaisesException] float getTotalLength(); [HighEntropy, Measure, RaisesException] float getTotalLength();
[HighEntropy, Measure] SVGPoint getPointAtLength(float distance); [HighEntropy, Measure, RaisesException] SVGPoint getPointAtLength(float distance);
}; };
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_line_element.h" #include "third_party/blink/renderer/core/svg/svg_line_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/core/svg/svg_length.h"
#include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
...@@ -66,6 +67,8 @@ Path SVGLineElement::AsPath() const { ...@@ -66,6 +67,8 @@ Path SVGLineElement::AsPath() const {
Path path; Path path;
SVGLengthContext length_context(this); SVGLengthContext length_context(this);
DCHECK(GetComputedStyle());
path.MoveTo(FloatPoint(x1()->CurrentValue()->Value(length_context), path.MoveTo(FloatPoint(x1()->CurrentValue()->Value(length_context),
y1()->CurrentValue()->Value(length_context))); y1()->CurrentValue()->Value(length_context)));
path.AddLineTo(FloatPoint(x2()->CurrentValue()->Value(length_context), path.AddLineTo(FloatPoint(x2()->CurrentValue()->Value(length_context),
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_path_element.h" #include "third_party/blink/renderer/core/svg/svg_path_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/svg/svg_mpath_element.h" #include "third_party/blink/renderer/core/svg/svg_mpath_element.h"
#include "third_party/blink/renderer/core/svg/svg_path_query.h" #include "third_party/blink/renderer/core/svg/svg_path_query.h"
...@@ -47,8 +48,8 @@ Path SVGPathElement::AttributePath() const { ...@@ -47,8 +48,8 @@ Path SVGPathElement::AttributePath() const {
} }
const StylePath* SVGPathElement::GetStylePath() const { const StylePath* SVGPathElement::GetStylePath() const {
if (LayoutObject* layout_object = GetLayoutObject()) { if (const ComputedStyle* style = GetComputedStyle()) {
const StylePath* style_path = layout_object->StyleRef().SvgStyle().D(); const StylePath* style_path = style->SvgStyle().D();
if (style_path) if (style_path)
return style_path; return style_path;
return StylePath::EmptyPath(); return StylePath::EmptyPath();
...@@ -70,10 +71,26 @@ float SVGPathElement::getTotalLength(ExceptionState& exception_state) { ...@@ -70,10 +71,26 @@ float SVGPathElement::getTotalLength(ExceptionState& exception_state) {
return SVGPathQuery(PathByteStream()).GetTotalLength(); return SVGPathQuery(PathByteStream()).GetTotalLength();
} }
SVGPointTearOff* SVGPathElement::getPointAtLength(float length) { SVGPointTearOff* SVGPathElement::getPointAtLength(
float length,
ExceptionState& exception_state) {
GetDocument().UpdateStyleAndLayoutForNode(this, GetDocument().UpdateStyleAndLayoutForNode(this,
DocumentUpdateReason::kJavaScript); DocumentUpdateReason::kJavaScript);
SVGPathQuery path_query(PathByteStream()); if (!EnsureComputedStyle()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"The element is in an inactive document.");
return nullptr;
}
const SVGPathByteStream& byte_stream = PathByteStream();
if (byte_stream.IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The element's path is empty.");
return nullptr;
}
SVGPathQuery path_query(byte_stream);
if (length < 0) { if (length < 0) {
length = 0; length = 0;
} else { } else {
......
...@@ -39,7 +39,7 @@ class SVGPathElement final : public SVGGeometryElement { ...@@ -39,7 +39,7 @@ class SVGPathElement final : public SVGGeometryElement {
Path AttributePath() const; Path AttributePath() const;
float getTotalLength(ExceptionState&) override; float getTotalLength(ExceptionState&) override;
SVGPointTearOff* getPointAtLength(float distance) override; SVGPointTearOff* getPointAtLength(float distance, ExceptionState&) override;
SVGAnimatedPath* GetPath() const { return path_.Get(); } SVGAnimatedPath* GetPath() const { return path_.Get(); }
float ComputePathLength() const override; float ComputePathLength() const override;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_poly_element.h" #include "third_party/blink/renderer/core/svg/svg_poly_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/svg/svg_animated_point_list.h" #include "third_party/blink/renderer/core/svg/svg_animated_point_list.h"
#include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
...@@ -43,6 +44,7 @@ void SVGPolyElement::Trace(Visitor* visitor) const { ...@@ -43,6 +44,7 @@ void SVGPolyElement::Trace(Visitor* visitor) const {
Path SVGPolyElement::AsPathFromPoints() const { Path SVGPolyElement::AsPathFromPoints() const {
Path path; Path path;
DCHECK(GetComputedStyle());
const SVGPointList* points_value = Points()->CurrentValue(); const SVGPointList* points_value = Points()->CurrentValue();
if (points_value->IsEmpty()) if (points_value->IsEmpty())
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/svg/svg_rect_element.h" #include "third_party/blink/renderer/core/svg/svg_rect_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_rect.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_rect.h"
#include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/core/svg/svg_length.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
...@@ -86,8 +87,7 @@ Path SVGRectElement::AsPath() const { ...@@ -86,8 +87,7 @@ Path SVGRectElement::AsPath() const {
Path path; Path path;
SVGLengthContext length_context(this); SVGLengthContext length_context(this);
DCHECK(GetLayoutObject()); const ComputedStyle& style = ComputedStyleRef();
const ComputedStyle& style = GetLayoutObject()->StyleRef();
FloatSize size(ToFloatSize( FloatSize size(ToFloatSize(
length_context.ResolveLengthPair(style.Width(), style.Height(), style))); length_context.ResolveLengthPair(style.Width(), style.Height(), style)));
......
<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml">
<title>SVGGeometryElement.prototype.getPointAtLength() query with 'pathLength'</title> <title>SVGGeometryElement.prototype.getPointAtLength() query with 'pathLength'</title>
<h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/> <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
<path id='pathElement' d='M0,0L100,0L100,100' pathLength="1000"/>
<h:script src="/resources/testharness.js"/> <h:script src="/resources/testharness.js"/>
<h:script src="/resources/testharnessreport.js"/> <h:script src="/resources/testharnessreport.js"/>
<script> <script>
test(function() { test(function() {
let path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); let path = document.getElementById('pathElement');
path.setAttribute('d', 'M0,0L100,0L100,100');
path.setAttribute('pathLength', '1000');
var point = path.getPointAtLength(50); var point = path.getPointAtLength(50);
assert_approx_equals(point.x, 50, 1e-5); assert_approx_equals(point.x, 50, 1e-5);
......
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:html="http://www.w3.org/1999/xhtml">
<title>When SVGGeometryElement.getPointAtLength is called with an element that is not in the document, throw exception</title>
<html:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
<html:script src="/resources/testharness.js"/>
<html:script src="/resources/testharnessreport.js"/>
<script><![CDATA[
test(function() {
var pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
pathElement.setAttribute("d", 'M0,20 L400,20 L640,20');
assert_throws_dom("InvalidStateError", function() { pathElement.getPointAtLength(700) });
}, document.title + " with SVGPathElement");
test(function() {
var rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rectElement.setAttribute("rx", 0);
rectElement.setAttribute("ry", 0);
rectElement.setAttribute("width", 200);
rectElement.setAttribute("height", 300);
assert_throws_dom("InvalidStateError", function() { rectElement.getPointAtLength(300); });
}, document.title + " with SVGRectElement");
test(function() {
var circleElement = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circleElement.setAttribute("r", 10);
assert_throws_dom("InvalidStateError", function() { circleElement.getPointAtLength(100); });
}, document.title + " with SVGCircleElement");
]]></script>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml">
<title>SVGGeometryElement.getPointAtLength: 'display' and a valid path</title>
<h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
<h:script src="/resources/testharness.js"/>
<h:script src="/resources/testharnessreport.js"/>
<path id='pathElement1' d='M0,0L100,0L100,100' description='path with display: defualt'/>
<path id='pathElement2' style='display:none' d='M0,0L100,0L100,100' description='path with display: none'/>
<rect id='rectElement1' x='0' y='0' width='50' height='50' description='rect with display: default'/>
<rect id='rectElement2' style='display:none' x='0' y='0' width='50' height='50' description='rect with display: none'/>
<circle id='circleElement1' cx='0' cy='0' r='50' description='circle with display: defualt'/>
<circle id='circleElement2' style='display:none' cx='0' cy='0' r='50' description='circle with display: none'/>
<polygon id='polygonElement1' points="0,0 50,0 50,50 0,50" description='polygon with display: default'/>
<polygon id='polygonElement2' style='display:none' points="0,0 50,0 50,50 0,50" description='polygon with display: none'/>
<polyline id='polylineElement1' points="0,0 50,0 50,50 0,50" description='polyline with display: default'/>
<polyline id='polylineElement2' style='display:none' points="0,0 50,0 50,50 0,50" description='polyline with display: none'/>
<ellipse id='ellipseElement1' cx='0' cy='0' rx='50' ry='50' description='ellipse with display: default'/>
<ellipse id='ellipseElement2' style='display:none' cx='0' cy='0' rx='50' ry='50' description='ellipse with display: none'/>
<script>
['pathElement1', 'pathElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(50);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['rectElement1', 'rectElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(50);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['circleElement1', 'circleElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(0);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['polygonElement1', 'polygonElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(50);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['polylineElement1', 'polylineElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(50);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['ellipseElement1', 'ellipseElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
var point = element.getPointAtLength(0);
assert_approx_equals(point.x, 50, 1e-5);
assert_approx_equals(point.y, 0, 1e-5);
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
</script>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml">
<title>SVGGeometryElement.getPointAtLength: 'display' and empty path</title>
<h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
<h:script src="/resources/testharness.js"/>
<h:script src="/resources/testharnessreport.js"/>
<path id='pathElement1' description='path with display: defualt and an empty path'/>
<path id='pathElement2' style='display:none' description='path with display: none and an empty path'/>
<rect id='rectElement1' description='rect with display: defualt and an empty path'/>
<rect id='rectElement2' style='display:none' description='rect with display: none and an empty path'/>
<circle id='circleElement1' description='circle with display: default and an empty path'/>
<circle id='circleElement2' style='display:none' description='circle with display: none and an empty path'/>
<polygon id='polygonElement1' description='polygon with display: defualt and an empty path'/>
<polygon id='polygonElement2' style='display:none' description='polygon with display: none and an empty path'/>
<polyline id='polylineElement1' description='polyline with display: default and an empty path'/>
<polyline id='polylineElement2' style='display:none' description='polyline with display: none and an empty path'/>
<ellipse id='ellipseElement1' description='ellipse with display: default and an empty path'/>
<ellipse id='ellipseElement2' style='display:none' description='ellipse with display: none and an empty path'/>
<script>
['pathElement1', 'pathElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['rectElement1', 'rectElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['circleElement1', 'circleElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['polygonElement1', 'polygonElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['polylineElement1', 'polylineElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
['ellipseElement1', 'ellipseElement2'].forEach(elementId => {
test(function() {
let element = document.getElementById(elementId);
assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); });
}, document.title + ', ' +
document.getElementById(elementId).getAttribute('description'));
});
</script>
</svg>
<!DOCTYPE html>
<title>SVGGeometryElement.getPointAtLength method (element detached)</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
test(function() {
var pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
function pointAtLength(string) {
pathElement.setAttribute("d", string);
var point = pathElement.getPointAtLength(700);
return [Math.round(point.x), Math.round(point.y)];
}
assert_array_equals(pointAtLength('M0,20 L400,20 L640,20'), [640, 20]);
assert_array_equals(pointAtLength('M0,20 L400,20 L640,20 z'), [580, 20]);
assert_array_equals(pointAtLength('M0,20 L400,20 z M 320,20 L640,20'), [100, 20]);
assert_array_equals(pointAtLength('M0,20 L20,40'), [20, 40]);
}, document.title + " with SVGPathElement");
test(function() {
var rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
function pointAtLength(rx, ry, width, height) {
rectElement.setAttribute("rx", rx);
rectElement.setAttribute("ry", ry);
rectElement.setAttribute("width", width);
rectElement.setAttribute("height", height);
var point = rectElement.getPointAtLength(300);
return [Math.round(point.x), Math.round(point.y)];
}
assert_array_equals(pointAtLength(0, 0, 200, 300), [0, 0]);
assert_array_equals(pointAtLength(50, 50, 200, 300), [0, 0]);
}, document.title + " with SVGRectElement");
test(function() {
var circleElement = document.createElementNS("http://www.w3.org/2000/svg", "circle");
function pointAtLength(radius) {
circleElement.setAttribute("r", radius);
var point = circleElement.getPointAtLength(100);
return [Math.round(point.x), Math.round(point.y)];
}
assert_array_equals(pointAtLength(10), [0, 0]);
assert_array_equals(pointAtLength(100), [0, 0]);
}, document.title + " with SVGCircleElement");
</script>
\ No newline at end of file
...@@ -6,8 +6,8 @@ if (window.testRunner) ...@@ -6,8 +6,8 @@ if (window.testRunner)
function go() { function go() {
var oSVGPolygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon"); var oSVGPolygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
var oSVGPath = document.createElementNS("http://www.w3.org/2000/svg", "path"); var svgRoot = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var oSVGPoint1 = oSVGPath.getPointAtLength(0.0); var oSVGPoint1 = svgRoot.createSVGPoint();
oSVGPolygon.points.initialize(oSVGPoint1); oSVGPolygon.points.initialize(oSVGPoint1);
oSVGPolygon.points.removeItem(-9223372036854775802); oSVGPolygon.points.removeItem(-9223372036854775802);
alert("Accessing old oSVGPoint1.x: " + oSVGPoint1.x); alert("Accessing old oSVGPoint1.x: " + oSVGPoint1.x);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment