зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1383650 - Invalidate path cache when geometry changed via CSS r=longsonr
We cached the path of an element. Previously we only need to invalidate the cached path if an geometry attribute is changed. Now we also need to invalidate if the corresponding CSS is changed. Differential Revision: https://phabricator.services.mozilla.com/D30472 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
9264ebe151
Коммит
4e7e1be890
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ComputedStyle.h"
|
||||
#include "mozilla/dom/SVGCircleElement.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
@ -139,5 +140,15 @@ already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGCircleElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
|
||||
return newSVGReset->mCx != oldSVGReset->mCx ||
|
||||
newSVGReset->mCy != oldSVGReset->mCy ||
|
||||
newSVGReset->mR != oldSVGReset->mR;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -14,6 +14,8 @@ nsresult NS_NewSVGCircleElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGCircleElementBase;
|
||||
|
@ -43,6 +45,9 @@ class SVGCircleElement final : public SVGCircleElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cx();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cy();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ComputedStyle.h"
|
||||
#include "mozilla/dom/SVGEllipseElement.h"
|
||||
#include "mozilla/dom/SVGEllipseElementBinding.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
|
@ -151,5 +152,16 @@ already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGEllipseElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
|
||||
return newSVGReset->mCx != oldSVGReset->mCx ||
|
||||
newSVGReset->mCy != oldSVGReset->mCy ||
|
||||
newSVGReset->mRx != oldSVGReset->mRx ||
|
||||
newSVGReset->mRy != oldSVGReset->mRy;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -14,6 +14,8 @@ nsresult NS_NewSVGEllipseElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGEllipseElementBase;
|
||||
|
@ -43,6 +45,9 @@ class SVGEllipseElement final : public SVGEllipseElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cx();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Cy();
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
#include "SVGCircleElement.h"
|
||||
#include "SVGEllipseElement.h"
|
||||
#include "SVGRectElement.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
@ -111,6 +114,22 @@ already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForMeasuring() {
|
|||
return GetOrBuildPath(drawTarget, fillRule);
|
||||
}
|
||||
|
||||
bool SVGGeometryElement::IsGeometryChangedViaCSS(
|
||||
ComputedStyle const& aNewStyle, ComputedStyle const& aOldStyle) const {
|
||||
if (IsSVGElement(nsGkAtoms::rect)) {
|
||||
return SVGRectElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
|
||||
if (IsSVGElement(nsGkAtoms::circle)) {
|
||||
return SVGCircleElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
|
||||
if (IsSVGElement(nsGkAtoms::ellipse)) {
|
||||
return SVGEllipseElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FillRule SVGGeometryElement::GetFillRule() {
|
||||
FillRule fillRule =
|
||||
FillRule::FILL_WINDING; // Equivalent to StyleFillRule::Nonzero
|
||||
|
|
|
@ -191,6 +191,13 @@ class SVGGeometryElement : public SVGGeometryElementBase {
|
|||
*/
|
||||
virtual already_AddRefed<Path> GetOrBuildPathForMeasuring();
|
||||
|
||||
/**
|
||||
* Return |true| if some geometry properties (|x|, |y|, etc) are changed
|
||||
* because of CSS change.
|
||||
*/
|
||||
bool IsGeometryChangedViaCSS(ComputedStyle const& aNewStyle,
|
||||
ComputedStyle const& aOldStyle) const;
|
||||
|
||||
/**
|
||||
* Returns the current computed value of the CSS property 'fill-rule' for
|
||||
* this element.
|
||||
|
|
|
@ -226,5 +226,20 @@ already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
|
|||
return aBuilder->Finish();
|
||||
}
|
||||
|
||||
bool SVGRectElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle) {
|
||||
auto *newSVGReset = aNewStyle.StyleSVGReset(),
|
||||
*oldSVGReset = aOldStyle.StyleSVGReset();
|
||||
auto *newPosition = aNewStyle.StylePosition(),
|
||||
*oldPosition = aOldStyle.StylePosition();
|
||||
|
||||
return newSVGReset->mX != oldSVGReset->mX ||
|
||||
newSVGReset->mY != oldSVGReset->mY ||
|
||||
newPosition->mWidth != oldPosition->mWidth ||
|
||||
newPosition->mHeight != oldPosition->mHeight ||
|
||||
newSVGReset->mRx != oldSVGReset->mRx ||
|
||||
newSVGReset->mRy != oldSVGReset->mRy;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -14,6 +14,8 @@ nsresult NS_NewSVGRectElement(
|
|||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef SVGGeometryElement SVGRectElementBase;
|
||||
|
@ -44,6 +46,9 @@ class SVGRectElement final : public SVGRectElementBase {
|
|||
|
||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||
|
||||
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
|
||||
const ComputedStyle& aOldStyle);
|
||||
|
||||
// WebIDL
|
||||
already_AddRefed<DOMSVGAnimatedLength> X();
|
||||
already_AddRefed<DOMSVGAnimatedLength> Y();
|
||||
|
|
|
@ -197,6 +197,10 @@ void SVGGeometryFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (element->IsGeometryChangedViaCSS(*Style(), *aOldComputedStyle)) {
|
||||
element->ClearAnyCachedPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче