Bug 1325320 part 3 - move GetPathLengthScale to SVGGeometryElement and convert callers of SVGPathElement methods to work on the base SVGGeometryElement class and work for all shapes, not just paths r=dholbert

This commit is contained in:
Robert Longson 2018-03-13 19:52:03 +00:00
parent 6c45419ff3
commit 797f6cb1a6
8 changed files with 68 additions and 59 deletions

View File

@ -422,7 +422,9 @@ public:
/** animation elements */
eANIMATION = 1 << 10,
/** filter elements that implement SVGFilterPrimitiveStandardAttributes */
eFILTER = 1 << 11
eFILTER = 1 << 11,
/** SVGGeometryElement */
eSHAPE = 1 << 12
};
/**

View File

@ -104,9 +104,9 @@ GetStrokeDashData(SVGContentUtils::AutoStrokeOptions* aStrokeOptions,
if (dashArrayLength <= 0) {
return eContinuousStroke;
}
if (aElement->IsSVGElement(nsGkAtoms::path)) {
pathScale = static_cast<SVGPathElement*>(aElement)->
GetPathLengthScale(SVGPathElement::eForStroking);
if (aElement->IsNodeOfType(nsINode::eSHAPE)) {
pathScale = static_cast<SVGGeometryElement*>(aElement)->
GetPathLengthScale(SVGGeometryElement::eForStroking);
if (pathScale <= 0) {
return eContinuousStroke;
}

View File

@ -54,6 +54,12 @@ SVGGeometryElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
aNotify);
}
bool
SVGGeometryElement::IsNodeOfType(uint32_t aFlags) const
{
return !(aFlags & ~eSHAPE);
}
bool
SVGGeometryElement::AttributeDefinesGeometry(const nsAtom *aName)
{
@ -176,6 +182,37 @@ SVGGeometryElement::GetPointAtLength(float distance, ErrorResult& rv)
return point.forget();
}
float
SVGGeometryElement::GetPathLengthScale(PathLengthScaleForType aFor)
{
MOZ_ASSERT(aFor == eForTextPath || aFor == eForStroking,
"Unknown enum");
if (mPathLength.IsExplicitlySet()) {
float authorsPathLengthEstimate = mPathLength.GetAnimValue();
if (authorsPathLengthEstimate > 0) {
RefPtr<Path> path = GetOrBuildPathForMeasuring();
if (!path) {
// The path is empty or invalid so its length must be zero and
// we know that 0 / authorsPathLengthEstimate = 0.
return 0.0;
}
if (aFor == eForTextPath) {
// For textPath, a transform on the referenced path affects the
// textPath layout, so when calculating the actual path length
// we need to take that into account.
gfxMatrix matrix = PrependLocalTransformsTo(gfxMatrix());
if (!matrix.IsIdentity()) {
RefPtr<PathBuilder> builder =
path->TransformedCopyToBuilder(ToMatrix(matrix));
path = builder->Finish();
}
}
return path->ComputeLength() / authorsPathLengthEstimate;
}
}
return 1.0;
}
already_AddRefed<SVGAnimatedNumber>
SVGGeometryElement::PathLength()
{

View File

@ -56,6 +56,7 @@ public:
const nsAttrValue* aOldValue,
nsIPrincipal* aSubjectPrincipal,
bool aNotify) override;
bool IsNodeOfType(uint32_t aFlags) const override;
/**
* Causes this element to discard any Path object that GetOrBuildPath may
@ -207,6 +208,18 @@ public:
*/
FillRule GetFillRule();
enum PathLengthScaleForType {
eForTextPath,
eForStroking
};
/**
* Gets the ratio of the actual element's length to the content author's
* estimated length (as provided by the element's 'pathLength' attribute).
* This is used to scale stroke dashing, and to scale offsets along a textPath.
*/
float GetPathLengthScale(PathLengthScaleForType aFor);
// WebIDL
already_AddRefed<SVGAnimatedNumber> PathLength();
float GetTotalLength();

View File

@ -285,37 +285,6 @@ SVGPathElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
mD.GetAnimValue().GetMarkerPositioningData(aMarks);
}
float
SVGPathElement::GetPathLengthScale(PathLengthScaleForType aFor)
{
MOZ_ASSERT(aFor == eForTextPath || aFor == eForStroking,
"Unknown enum");
if (mPathLength.IsExplicitlySet()) {
float authorsPathLengthEstimate = mPathLength.GetAnimValue();
if (authorsPathLengthEstimate > 0) {
RefPtr<Path> path = GetOrBuildPathForMeasuring();
if (!path) {
// The path is empty or invalid so its length must be zero and
// we know that 0 / authorsPathLengthEstimate = 0.
return 0.0;
}
if (aFor == eForTextPath) {
// For textPath, a transform on the referenced path affects the
// textPath layout, so when calculating the actual path length
// we need to take that into account.
gfxMatrix matrix = PrependLocalTransformsTo(gfxMatrix());
if (!matrix.IsIdentity()) {
RefPtr<PathBuilder> builder =
path->TransformedCopyToBuilder(ToMatrix(matrix));
path = builder->Finish();
}
}
return path->ComputeLength() / authorsPathLengthEstimate;
}
}
return 1.0;
}
already_AddRefed<Path>
SVGPathElement::BuildPath(PathBuilder* aBuilder)
{

View File

@ -68,18 +68,6 @@ public:
return nsGkAtoms::d;
}
enum PathLengthScaleForType {
eForTextPath,
eForStroking
};
/**
* Gets the ratio of the actual path length to the content author's estimated
* length (as provided by the <path> element's 'pathLength' attribute). This
* is used to scale stroke dashing, and to scale offsets along a textPath.
*/
float GetPathLengthScale(PathLengthScaleForType aFor);
// WebIDL
uint32_t GetPathSegAtLength(float distance);
already_AddRefed<DOMSVGPathSegClosePath> CreateSVGPathSegClosePath();

View File

@ -42,7 +42,7 @@
#include "SVGContextPaint.h"
#include "SVGLengthList.h"
#include "SVGNumberList.h"
#include "SVGPathElement.h"
#include "SVGGeometryElement.h"
#include "SVGTextPathElement.h"
#include "nsLayoutUtils.h"
#include "nsFrameSelection.h"
@ -4987,8 +4987,8 @@ SVGTextFrame::AdjustPositionsForClusters()
}
}
SVGPathElement*
SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame)
SVGGeometryElement*
SVGTextFrame::GetTextPathGeometryElement(nsIFrame* aTextPathFrame)
{
nsSVGTextPathProperty *property =
aTextPathFrame->GetProperty(SVGObserverUtils::HrefAsTextPathProperty());
@ -5023,14 +5023,14 @@ SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame)
}
Element* element = property->GetReferencedElement();
return (element && element->IsSVGElement(nsGkAtoms::path)) ?
static_cast<SVGPathElement*>(element) : nullptr;
return (element && element->IsNodeOfType(nsINode::eSHAPE)) ?
static_cast<SVGGeometryElement*>(element) : nullptr;
}
already_AddRefed<Path>
SVGTextFrame::GetTextPath(nsIFrame* aTextPathFrame)
{
SVGPathElement* element = GetTextPathPathElement(aTextPathFrame);
SVGGeometryElement* element = GetTextPathGeometryElement(aTextPathFrame);
if (!element) {
return nullptr;
}
@ -5053,11 +5053,11 @@ SVGTextFrame::GetTextPath(nsIFrame* aTextPathFrame)
gfxFloat
SVGTextFrame::GetOffsetScale(nsIFrame* aTextPathFrame)
{
SVGPathElement* pathElement = GetTextPathPathElement(aTextPathFrame);
if (!pathElement)
SVGGeometryElement* element = GetTextPathGeometryElement(aTextPathFrame);
if (!element)
return 1.0;
return pathElement->GetPathLengthScale(dom::SVGPathElement::eForTextPath);
return element->GetPathLengthScale(dom::SVGGeometryElement::eForTextPath);
}
gfxFloat

View File

@ -34,7 +34,7 @@ class TextRenderedRunIterator;
namespace dom {
class SVGIRect;
class SVGPathElement;
class SVGGeometryElement;
} // namespace dom
/**
@ -538,8 +538,8 @@ private:
bool ShouldRenderAsPath(nsTextFrame* aFrame, bool& aShouldPaintSVGGlyphs);
// Methods to get information for a <textPath> frame.
mozilla::dom::SVGPathElement*
GetTextPathPathElement(nsIFrame* aTextPathFrame);
mozilla::dom::SVGGeometryElement*
GetTextPathGeometryElement(nsIFrame* aTextPathFrame);
already_AddRefed<Path> GetTextPath(nsIFrame* aTextPathFrame);
gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);