Bug 1919040 - Fix some pre-existing transform invalidation issues. r=longsonr

When the transform attribute was removed from <g> we weren't notifying
of TRANSFORM_CHANGED.

Differential Revision: https://phabricator.services.mozilla.com/D222498
This commit is contained in:
Emilio Cobos Álvarez 2024-09-18 15:22:50 +00:00
Родитель d998d6d499
Коммит fb97ff055b
5 изменённых файлов: 38 добавлений и 32 удалений

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

@ -371,6 +371,17 @@ void SVGDisplayContainerFrame::ReflowSVG() {
NS_FRAME_HAS_DIRTY_CHILDREN);
}
void SVGDisplayContainerFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) {
nsContainerFrame::DidSetComputedStyle(aOldStyle);
if (!aOldStyle) {
return;
}
if (StyleDisplay()->CalcTransformPropertyDifference(
*aOldStyle->StyleDisplay())) {
NotifySVGChanged(TRANSFORM_CHANGED);
}
}
void SVGDisplayContainerFrame::NotifySVGChanged(uint32_t aFlags) {
MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED),
"Invalidation logic may need adjusting");

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

@ -77,7 +77,6 @@ class SVGContainerFrame : public nsContainerFrame {
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) override;
void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override {}
@ -117,6 +116,7 @@ class SVGDisplayContainerFrame : public SVGContainerFrame,
NS_DECL_ABSTRACT_FRAME(SVGDisplayContainerFrame)
// nsIFrame:
void DidSetComputedStyle(ComputedStyle*) override;
void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
const nsLineList::iterator* aPrevFrameLine,
nsFrameList&& aFrameList) override;

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

@ -113,7 +113,7 @@ void SVGGeometryFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
if (StyleDisplay()->CalcTransformPropertyDifference(
*aOldComputedStyle->StyleDisplay())) {
SVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
NotifySVGChanged(TRANSFORM_CHANGED);
}
if (element->IsGeometryChangedViaCSS(*Style(), *aOldComputedStyle)) {

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

@ -2979,42 +2979,39 @@ void SVGTextFrame::NotifySVGChanged(uint32_t aFlags) {
bool needNewBounds = false;
bool needGlyphMetricsUpdate = false;
bool needNewCanvasTM = false;
if ((aFlags & COORD_CONTEXT_CHANGED) &&
HasAnyStateBits(NS_STATE_SVG_POSITIONING_MAY_USE_PERCENTAGES)) {
needGlyphMetricsUpdate = true;
}
if (aFlags & TRANSFORM_CHANGED) {
needNewCanvasTM = true;
if (mCanvasTM && mCanvasTM->IsSingular()) {
// We won't have calculated the glyph positions correctly.
needNewBounds = true;
needGlyphMetricsUpdate = true;
}
mCanvasTM = nullptr;
if (StyleSVGReset()->HasNonScalingStroke()) {
// Stroke currently contributes to our mRect, and our stroke depends on
// the transform to our outer-<svg> if |vector-effect:non-scaling-stroke|.
needNewBounds = true;
}
}
// If the scale at which we computed our mFontSizeScaleFactor has changed by
// at least a factor of two, reflow the text. This avoids reflowing text
// at every tick of a transform animation, but ensures our glyph metrics
// do not get too far out of sync with the final font size on the screen.
if (needNewCanvasTM && mLastContextScale != 0.0f) {
mCanvasTM = nullptr;
// If we are a non-display frame, then we don't want to get the transform
// since the context scale does not use it.
if (!HasAnyStateBits(NS_FRAME_IS_NONDISPLAY)) {
// Compare the old and new context scales.
float scale = GetContextScale(this);
float change = scale / mLastContextScale;
if (change >= 2.0f || change <= 0.5f) {
// If the scale at which we computed our mFontSizeScaleFactor has changed by
// at least a factor of two, reflow the text. This avoids reflowing text at
// every tick of a transform animation, but ensures our glyph metrics
// do not get too far out of sync with the final font size on the screen.
const float scale = GetContextScale(this);
if (scale != mLastContextScale) {
if (mLastContextScale == 0.0f) {
needNewBounds = true;
needGlyphMetricsUpdate = true;
} else {
float change = scale / mLastContextScale;
if (change >= 2.0f || change <= 0.5f) {
needNewBounds = true;
needGlyphMetricsUpdate = true;
}
}
}
}
@ -3322,7 +3319,9 @@ void SVGTextFrame::ReflowSVG() {
// Due to rounding issues when we have a transform applied, we sometimes
// don't include an additional row of pixels. For now, just inflate our
// covered region.
mRect.Inflate(ceil(presContext->AppUnitsPerDevPixel() / mLastContextScale));
if (mLastContextScale != 0.0f) {
mRect.Inflate(ceil(presContext->AppUnitsPerDevPixel() / mLastContextScale));
}
}
if (HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
@ -5130,6 +5129,9 @@ void SVGTextFrame::DoReflow() {
#define PRECISE_SIZE 200.0
bool SVGTextFrame::UpdateFontSizeScaleFactor() {
float contextScale = GetContextScale(this);
mLastContextScale = contextScale;
double oldFontSizeScaleFactor = mFontSizeScaleFactor;
bool geometricPrecision = false;
@ -5169,9 +5171,6 @@ bool SVGTextFrame::UpdateFontSizeScaleFactor() {
return mFontSizeScaleFactor != oldFontSizeScaleFactor;
}
float contextScale = GetContextScale(this);
mLastContextScale = contextScale;
double minTextRunSize = min * contextScale;
double maxTextRunSize = max * contextScale;

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

@ -183,11 +183,7 @@ class SVGTextFrame final : public SVGDisplayContainerFrame {
protected:
explicit SVGTextFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: SVGDisplayContainerFrame(aStyle, aPresContext, kClassID),
mTrailingUndisplayedCharacters(0),
mFontSizeScaleFactor(1.0f),
mLastContextScale(1.0f),
mLengthAdjustScaleFactor(1.0f) {
: SVGDisplayContainerFrame(aStyle, aPresContext, kClassID) {
AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_SVG_TEXT |
NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY |
NS_STATE_SVG_POSITIONING_DIRTY);
@ -542,7 +538,7 @@ class SVGTextFrame final : public SVGDisplayContainerFrame {
*
* mTrailingUndisplayedCharacters would be 2.
*/
uint32_t mTrailingUndisplayedCharacters;
uint32_t mTrailingUndisplayedCharacters = 0;
/**
* Computed position information for each DOM character within the <text>.
@ -571,20 +567,20 @@ class SVGTextFrame final : public SVGDisplayContainerFrame {
* screen. (The "reasonable" range as determined by some #defines in
* SVGTextFrame.cpp is 8..200.)
*/
float mFontSizeScaleFactor;
float mFontSizeScaleFactor = 1.0f;
/**
* The scale of the context that we last used to compute mFontSizeScaleFactor.
* We record this so that we can tell when our scale transform has changed
* enough to warrant reflowing the text.
*/
float mLastContextScale;
float mLastContextScale = 1.0f;
/**
* The amount that we need to scale each rendered run to account for
* lengthAdjust="spacingAndGlyphs".
*/
float mLengthAdjustScaleFactor;
float mLengthAdjustScaleFactor = 1.0f;
};
} // namespace mozilla