зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d998d6d499
Коммит
fb97ff055b
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче