Bug 869611 - Stop reflowing in nsSVGPathGeometryFrame::NotifySVGChanged for ancestor transform changes. r=dholbert

This commit is contained in:
Jonathan Watt 2013-05-08 18:13:11 +01:00
Родитель 612f292926
Коммит 27d86f8e64
3 изменённых файлов: 37 добавлений и 6 удалений

Просмотреть файл

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsSVGPathGeometryElement.h"
#include "nsSVGLength2.h"
//----------------------------------------------------------------------
// Implementation
@ -27,6 +28,19 @@ nsSVGPathGeometryElement::AttributeDefinesGeometry(const nsIAtom *aName)
return false;
}
bool
nsSVGPathGeometryElement::GeometryDependsOnCoordCtx()
{
// Check the nsSVGLength2 attribute
LengthAttributesInfo info = const_cast<nsSVGPathGeometryElement*>(this)->GetLengthInfo();
for (uint32_t i = 0; i < info.mLengthCount; i++) {
if (info.mLengths[i].GetSpecifiedUnitType() == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
return true;
}
}
return false;
}
bool
nsSVGPathGeometryElement::IsMarkable()
{

Просмотреть файл

@ -27,6 +27,18 @@ public:
nsSVGPathGeometryElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual bool AttributeDefinesGeometry(const nsIAtom *aName);
/**
* Returns true if this element's geometry depends on the width or height of its
* coordinate context (typically the viewport established by its nearest <svg>
* ancestor). In other words, returns true if one of the attributes for which
* AttributeDefinesGeometry returns true has a percentage value.
*
* This could be moved up to a more general class so it can be used for non-leaf
* elements, but that would require care and for now there's no need.
*/
bool GeometryDependsOnCoordCtx();
virtual bool IsMarkable();
virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
virtual void ConstructPath(gfxContext *aCtx) = 0;

Просмотреть файл

@ -353,12 +353,17 @@ nsSVGPathGeometryFrame::NotifySVGChanged(uint32_t aFlags)
NS_ABORT_IF_FALSE(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
"Invalidation logic may need adjusting");
// Ancestor changes can't affect how we render from the perspective of
// any rendering observers that we may have, so we don't need to
// invalidate them. We also don't need to invalidate ourself, since our
// changed ancestor will have invalidated its entire area, which includes
// our area.
nsSVGUtils::ScheduleReflowSVG(this);
// Changes to our ancestors may affect how we render when we are rendered as
// part of our ancestor (specifically, if our coordinate context changes size
// and we have percentage lengths defining our geometry, then we need to be
// reflowed). However, ancestor changes cannot affect how we render when we
// are rendered as part of any rendering observers that we may have.
// Therefore no need to notify rendering observers here.
if ((aFlags & COORD_CONTEXT_CHANGED) &&
static_cast<nsSVGPathGeometryElement*>(mContent)->GeometryDependsOnCoordCtx()) {
nsSVGUtils::ScheduleReflowSVG(this);
}
}
SVGBBox