mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 18:24:02 +00:00
Bug 1090211 - Calculate the bounds of circles and ellipses using Math when we have a rectilinear transform. r=longsonr
This commit is contained in:
parent
a0c5f54031
commit
eb0dc8db18
@ -81,6 +81,34 @@ SVGCircleElement::GetLengthInfo()
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
bool
|
||||
SVGCircleElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
|
||||
const Matrix& aTransform)
|
||||
{
|
||||
float x, y, r;
|
||||
GetAnimatedLengthValues(&x, &y, &r, nullptr);
|
||||
|
||||
if (r <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
aBounds->MoveTo(x, y);
|
||||
aBounds->SetEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aTransform.IsRectilinear()) {
|
||||
// Optimize the case where we can treat the circle as a rectangle and
|
||||
// still get tight bounds.
|
||||
if (aStrokeWidth > 0.f) {
|
||||
r += aStrokeWidth / 2.f;
|
||||
}
|
||||
Rect rect(x - r, y - r, 2 * r, 2 * r);
|
||||
*aBounds = aTransform.TransformBounds(rect);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TemporaryRef<Path>
|
||||
SVGCircleElement::BuildPath(PathBuilder* aBuilder)
|
||||
{
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
virtual bool HasValidDimensions() const MOZ_OVERRIDE;
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
|
||||
const Matrix& aTransform) MOZ_OVERRIDE;
|
||||
virtual TemporaryRef<Path> BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
|
||||
|
@ -92,6 +92,35 @@ SVGEllipseElement::GetLengthInfo()
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
bool
|
||||
SVGEllipseElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
|
||||
const Matrix& aTransform)
|
||||
{
|
||||
float x, y, rx, ry;
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
|
||||
|
||||
if (rx <= 0.f || ry <= 0.f) {
|
||||
// Rendering of the element is disabled
|
||||
aBounds->MoveTo(x, y);
|
||||
aBounds->SetEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aTransform.IsRectilinear()) {
|
||||
// Optimize the case where we can treat the ellipse as a rectangle and
|
||||
// still get tight bounds.
|
||||
if (aStrokeWidth > 0.f) {
|
||||
rx += aStrokeWidth / 2.f;
|
||||
ry += aStrokeWidth / 2.f;
|
||||
}
|
||||
Rect rect(x - rx, y - ry, 2 * rx, 2 * ry);
|
||||
*aBounds = aTransform.TransformBounds(rect);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TemporaryRef<Path>
|
||||
SVGEllipseElement::BuildPath(PathBuilder* aBuilder)
|
||||
{
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
virtual bool HasValidDimensions() const MOZ_OVERRIDE;
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
|
||||
const Matrix& aTransform) MOZ_OVERRIDE;
|
||||
virtual TemporaryRef<Path> BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
|
||||
|
@ -70,6 +70,12 @@ public:
|
||||
virtual bool IsMarkable();
|
||||
virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
|
||||
|
||||
/**
|
||||
* A method that can be faster than using a Moz2D Path and calling GetBounds/
|
||||
* GetStrokedBounds on it. It also helps us avoid rounding error for simple
|
||||
* shapes and simple transforms where the Moz2D Path backends can fail to
|
||||
* produce the clean integer bounds that content authors expect in some cases.
|
||||
*/
|
||||
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
|
||||
const Matrix& aTransform) {
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user