зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1325319 - Implement isPointInFill() and isPointInStroke() for SVGGeometryElement r=longsonr,bzbarsky
Differential Revision: https://phabricator.services.mozilla.com/D33592 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
5cab43f3ff
Коммит
00989decc6
|
@ -15,6 +15,7 @@
|
|||
#include "SVGEllipseElement.h"
|
||||
#include "SVGGeometryProperty.h"
|
||||
#include "SVGRectElement.h"
|
||||
#include "mozilla/dom/DOMPointBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
@ -114,6 +115,18 @@ already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForMeasuring() {
|
|||
return GetOrBuildPath(drawTarget, fillRule);
|
||||
}
|
||||
|
||||
// This helper is currently identical to GetOrBuildPathForMeasuring.
|
||||
// We keep it a separate method because for length measuring purpose,
|
||||
// fillRule isn't really needed. Derived class (e.g. SVGPathElement)
|
||||
// may override GetOrBuildPathForMeasuring() to ignore fillRule. And
|
||||
// GetOrBuildPathForMeasuring() itself may be modified in the future.
|
||||
already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForHitTest() {
|
||||
RefPtr<DrawTarget> drawTarget =
|
||||
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
|
||||
FillRule fillRule = mCachedPath ? mCachedPath->GetFillRule() : GetFillRule();
|
||||
return GetOrBuildPath(drawTarget, fillRule);
|
||||
}
|
||||
|
||||
bool SVGGeometryElement::IsGeometryChangedViaCSS(
|
||||
ComputedStyle const& aNewStyle, ComputedStyle const& aOldStyle) const {
|
||||
if (IsSVGElement(nsGkAtoms::rect)) {
|
||||
|
@ -153,6 +166,54 @@ FillRule SVGGeometryElement::GetFillRule() {
|
|||
return fillRule;
|
||||
}
|
||||
|
||||
static Point GetPointFrom(const DOMPointInit& aPoint) {
|
||||
return Point(aPoint.mX, aPoint.mY);
|
||||
}
|
||||
|
||||
bool SVGGeometryElement::IsPointInFill(const DOMPointInit& aPoint) {
|
||||
auto point = GetPointFrom(aPoint);
|
||||
|
||||
RefPtr<Path> path = GetOrBuildPathForHitTest();
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return path->ContainsPoint(point, {});
|
||||
}
|
||||
|
||||
bool SVGGeometryElement::IsPointInStroke(const DOMPointInit& aPoint) {
|
||||
auto point = GetPointFrom(aPoint);
|
||||
|
||||
RefPtr<Path> path = GetOrBuildPathForHitTest();
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
SVGGeometryProperty::DoForComputedStyle(this, [&](const ComputedStyle* s) {
|
||||
// Per spec, we should take vector-effect into account.
|
||||
if (s->StyleSVGReset()->HasNonScalingStroke()) {
|
||||
auto mat = SVGContentUtils::GetCTM(this, true);
|
||||
if (mat.HasNonTranslation()) {
|
||||
// We have non-scaling-stroke as well as a non-translation transform.
|
||||
// We should transform the path first then apply the stroke on the
|
||||
// transformed path to preserve the stroke-width.
|
||||
RefPtr<PathBuilder> builder = path->TransformedCopyToBuilder(mat);
|
||||
|
||||
path = builder->Finish();
|
||||
point = mat.TransformPoint(point);
|
||||
}
|
||||
}
|
||||
|
||||
SVGContentUtils::AutoStrokeOptions strokeOptions;
|
||||
SVGContentUtils::GetStrokeOptions(&strokeOptions, this, s, nullptr);
|
||||
|
||||
res = path->StrokeContainsPoint(strokeOptions, point, {});
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
float SVGGeometryElement::GetTotalLength() {
|
||||
RefPtr<Path> flat = GetOrBuildPathForMeasuring();
|
||||
return flat ? flat->ComputeLength() : 0.f;
|
||||
|
|
|
@ -216,6 +216,8 @@ class SVGGeometryElement : public SVGGeometryElementBase {
|
|||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedNumber> PathLength();
|
||||
bool IsPointInFill(const DOMPointInit& aPoint);
|
||||
bool IsPointInStroke(const DOMPointInit& aPoint);
|
||||
float GetTotalLength();
|
||||
already_AddRefed<nsISVGPoint> GetPointAtLength(float distance,
|
||||
ErrorResult& rv);
|
||||
|
@ -227,6 +229,9 @@ class SVGGeometryElement : public SVGGeometryElementBase {
|
|||
SVGAnimatedNumber mPathLength;
|
||||
static NumberInfo sNumberInfo;
|
||||
mutable RefPtr<Path> mCachedPath;
|
||||
|
||||
private:
|
||||
already_AddRefed<Path> GetOrBuildPathForHitTest();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -14,6 +14,9 @@ interface SVGGeometryElement : SVGGraphicsElement {
|
|||
[SameObject]
|
||||
readonly attribute SVGAnimatedNumber pathLength;
|
||||
|
||||
boolean isPointInFill(optional DOMPointInit point);
|
||||
boolean isPointInStroke(optional DOMPointInit point);
|
||||
|
||||
float getTotalLength();
|
||||
[NewObject, Throws]
|
||||
SVGPoint getPointAtLength(float distance);
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
[SVGElement interface: attribute correspondingUseElement]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: operation isPointInFill(DOMPointInit)]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: operation isPointInStroke(DOMPointInit)]
|
||||
expected: FAIL
|
||||
|
||||
[SVGAnimatedRect interface: objects.svg.viewBox must inherit property "baseVal" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -260,126 +254,42 @@
|
|||
[SVGTransform interface: objects.svg.createSVGTransform() must inherit property "matrix" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.path must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.path with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.path must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.path with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.path must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.path must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.rect must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.rect with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.rect must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.rect with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.rect must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.rect must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.circle must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.circle with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.circle must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.circle with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.circle must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.circle must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.ellipse must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.ellipse with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.ellipse must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.ellipse with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.ellipse must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.ellipse must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.line must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.line with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.line must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.line with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.line must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.line must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.polyline must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.polyline with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.polyline must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.polyline with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.polyline must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.polyline must inherit property "correspondingUseElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.polygon must inherit property "isPointInFill(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInFill(DOMPointInit) on objects.polygon with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: objects.polygon must inherit property "isPointInStroke(DOMPointInit)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement interface: calling isPointInStroke(DOMPointInit) on objects.polygon with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[SVGElement interface: objects.polygon must inherit property "correspondingElement" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,19 +1,4 @@
|
|||
[SVGGeometryElement.isPointInFill-01.svg]
|
||||
[SVGGeometryElement.prototype.isPointInFill, 'visibility' and 'pointer-events' have no effect.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInFill, 'fill-rule'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInFill, non-finite argument.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInFill, no arguments.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInFill, 'clip-rule' never overrides 'fill-rule'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInFill, functional test.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,37 +1,3 @@
|
|||
[SVGGeometryElement.isPointInStroke-01.svg]
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'visibility' and 'pointer-events' have no effect.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'vector-effect' have no effect.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, no arguments.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'pathLength'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, functional test.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'stroke-miterlimit'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'stroke-dasharray'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'stroke-linecap'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'stroke-linejoin'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, non-finite argument.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'stroke-dashoffset'.]
|
||||
expected: FAIL
|
||||
|
||||
[SVGGeometryElement.prototype.isPointInStroke, 'vector-effect'.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400"
|
||||
xmlns:h="http://www.w3.org/1999/xhtml">
|
||||
<title>SVGGeometryElement.prototype.isPointInStroke</title>
|
||||
<metadata>
|
||||
|
|
До Ширина: | Высота: | Размер: 7.6 KiB После Ширина: | Высота: | Размер: 7.6 KiB |
Загрузка…
Ссылка в новой задаче