diff --git a/dom/smil/nsSMILCSSValueType.cpp b/dom/smil/nsSMILCSSValueType.cpp index ed89e7710ae4..85fe72085eac 100644 --- a/dom/smil/nsSMILCSSValueType.cpp +++ b/dom/smil/nsSMILCSSValueType.cpp @@ -381,7 +381,7 @@ ValueFromStringHelper(nsCSSPropertyID aPropID, MOZ_ASSERT(aStyleAnimValue.GetUnit() == StyleAnimationValue::eUnit_Coord, "'font-size' value with unexpected style unit"); aStyleAnimValue.SetCoordValue(aStyleAnimValue.GetCoordValue() / - aPresContext->TextZoom()); + aPresContext->EffectiveTextZoom()); } return true; } diff --git a/dom/svg/SVGContentUtils.cpp b/dom/svg/SVGContentUtils.cpp index 5f1ae1ac024b..4ae38ce26441 100644 --- a/dom/svg/SVGContentUtils.cpp +++ b/dom/svg/SVGContentUtils.cpp @@ -304,8 +304,8 @@ SVGContentUtils::GetFontSize(nsStyleContext *aStyleContext) MOZ_ASSERT(presContext, "NULL pres context in GetFontSize"); nscoord fontSize = aStyleContext->StyleFont()->mSize; - return nsPresContext::AppUnitsToFloatCSSPixels(fontSize) / - presContext->TextZoom(); + return nsPresContext::AppUnitsToFloatCSSPixels(fontSize) / + presContext->EffectiveTextZoom(); } float @@ -352,7 +352,7 @@ SVGContentUtils::GetFontXHeight(nsStyleContext *aStyleContext) nscoord xHeight = fontMetrics->XHeight(); return nsPresContext::AppUnitsToFloatCSSPixels(xHeight) / - presContext->TextZoom(); + presContext->EffectiveTextZoom(); } nsresult SVGContentUtils::ReportToConsole(nsIDocument* doc, diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 5fb699a60c8e..f283e91c3503 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -807,8 +807,8 @@ nsIPresShell::nsIPresShell() , mFontSizeInflationForceEnabled(false) , mFontSizeInflationDisabledInMasterProcess(false) , mFontSizeInflationEnabled(false) - , mPaintingIsFrozen(false) , mFontSizeInflationEnabledIsDirty(false) + , mPaintingIsFrozen(false) , mIsNeverPainting(false) , mInFlush(false) {} @@ -11032,12 +11032,18 @@ void nsIPresShell::RecomputeFontSizeInflationEnabled() { mFontSizeInflationEnabledIsDirty = false; + mFontSizeInflationEnabled = DetermineFontSizeInflationState(); + HandleSystemFontScale(); +} + +bool +nsIPresShell::DetermineFontSizeInflationState() +{ MOZ_ASSERT(mPresContext, "our pres context should not be null"); if ((FontSizeInflationEmPerLine() == 0 && FontSizeInflationMinTwips() == 0) || mPresContext->IsChrome()) { - mFontSizeInflationEnabled = false; - return; + return false; } // Force-enabling font inflation always trumps the heuristics here. @@ -11046,15 +11052,13 @@ nsIPresShell::RecomputeFontSizeInflationEnabled() // We're in a child process. Cancel inflation if we're not // async-pan zoomed. if (!tab->AsyncPanZoomEnabled()) { - mFontSizeInflationEnabled = false; - return; + return false; } } else if (XRE_IsParentProcess()) { // We're in the master process. Cancel inflation if it's been // explicitly disabled. if (FontSizeInflationDisabledInMasterProcess()) { - mFontSizeInflationEnabled = false; - return; + return false; } } } @@ -11079,8 +11083,7 @@ nsIPresShell::RecomputeFontSizeInflationEnabled() nsCOMPtr screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1", &rv); if (!NS_SUCCEEDED(rv)) { - mFontSizeInflationEnabled = false; - return; + return false; } nsCOMPtr screen; @@ -11093,12 +11096,11 @@ nsIPresShell::RecomputeFontSizeInflationEnabled() GetDocument()->GetViewportInfo(ScreenIntSize(screenWidth, screenHeight)); if (vInf.GetDefaultZoom() >= CSSToScreenScale(1.0f) || vInf.IsAutoSizeEnabled()) { - mFontSizeInflationEnabled = false; - return; + return false; } } - mFontSizeInflationEnabled = true; + return true; } bool @@ -11111,6 +11113,23 @@ nsIPresShell::FontSizeInflationEnabled() return mFontSizeInflationEnabled; } +void +nsIPresShell::HandleSystemFontScale() +{ + float fontScale = nsLayoutUtils::SystemFontScale(); + if (fontScale == 0.0f) { + return; + } + + MOZ_ASSERT(mDocument && mPresContext, "our document and pres context should not be null"); + + if (!mFontSizeInflationEnabled && !mDocument->IsSyntheticDocument()) { + mPresContext->SetSystemFontScale(fontScale); + } else { + mPresContext->SetSystemFontScale(1.0f); + } +} + void PresShell::PausePainting() { diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index daaad818e3de..777713f7d4ba 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1708,6 +1708,17 @@ protected: */ void RecomputeFontSizeInflationEnabled(); + /** + * Does the actual work of figuring out the current state of font size inflation. + */ + bool DetermineFontSizeInflationState(); + + /** + * Apply the system font scale from the corresponding pref to the PresContext, + * taking into account the current state of font size inflation. + */ + void HandleSystemFontScale(); + void RecordAlloc(void* aPtr) { #ifdef DEBUG MOZ_ASSERT(!mAllocatedPointers.Contains(aPtr)); @@ -1915,11 +1926,12 @@ protected: bool mFontSizeInflationForceEnabled; bool mFontSizeInflationDisabledInMasterProcess; bool mFontSizeInflationEnabled; - bool mPaintingIsFrozen; // Dirty bit indicating that mFontSizeInflationEnabled needs to be recomputed. bool mFontSizeInflationEnabledIsDirty; + bool mPaintingIsFrozen; + // If a document belongs to an invisible DocShell, this flag must be set // to true, so we can avoid any paint calls for widget related to this // presshell. diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 0d516ccea7cc..488c258857a5 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -210,7 +210,9 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) mLinkHandler(nullptr), mInflationDisabledForShrinkWrap(false), mBaseMinFontSize(0), + mSystemFontScale(1.0), mTextZoom(1.0), + mEffectiveTextZoom(1.0), mFullZoom(1.0), mOverrideDPPX(0.0), mLastFontInflationScreenSize(gfxSize(-1.0, -1.0)), @@ -1318,6 +1320,29 @@ nsPresContext::GetContentLanguage() const return nullptr; } +void +nsPresContext::UpdateEffectiveTextZoom() +{ + float newZoom = mSystemFontScale * mTextZoom; + float minZoom = nsLayoutUtils::MinZoom(); + float maxZoom = nsLayoutUtils::MaxZoom(); + + if (newZoom < minZoom) { + newZoom = minZoom; + } else if (newZoom > maxZoom) { + newZoom = maxZoom; + } + + mEffectiveTextZoom = newZoom; + + if (HasCachedStyleData()) { + // Media queries could have changed, since we changed the meaning + // of 'em' units in them. + MediaFeatureValuesChanged(eRestyle_ForceDescendants, + NS_STYLE_HINT_REFLOW); + } +} + void nsPresContext::SetFullZoom(float aZoom) { diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index b1bcab1fae71..72272feddb96 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -535,6 +535,30 @@ public: nsIAtom* GetLanguageFromCharset() const { return mLanguage; } already_AddRefed GetContentLanguage() const; + /** + * Get/set a text zoom factor that is applied on top of the normal text zoom + * set by the front-end/user. + */ + float GetSystemFontScale() const { return mSystemFontScale; } + void SetSystemFontScale(float aFontScale) { + MOZ_ASSERT(aFontScale > 0.0f, "invalid font scale"); + if (aFontScale == mSystemFontScale || IsPrintingOrPrintPreview()) { + return; + } + + mSystemFontScale = aFontScale; + UpdateEffectiveTextZoom(); + } + + /** + * Get/set the text zoom factor in use. + * This value should be used if you're interested in the pure text zoom value + * controlled by the front-end, e.g. when transferring zoom levels to a new + * document. + * Code that wants to use this value for layouting and rendering purposes + * should consider using EffectiveTextZoom() instead, so as to take the system + * font scale into account as well. + */ float TextZoom() const { return mTextZoom; } void SetTextZoom(float aZoom) { MOZ_ASSERT(aZoom > 0.0f, "invalid zoom factor"); @@ -542,14 +566,23 @@ public: return; mTextZoom = aZoom; - if (HasCachedStyleData()) { - // Media queries could have changed, since we changed the meaning - // of 'em' units in them. - MediaFeatureValuesChanged(eRestyle_ForceDescendants, - NS_STYLE_HINT_REFLOW); - } + UpdateEffectiveTextZoom(); } +protected: + void UpdateEffectiveTextZoom(); + +public: + /** + * Corresponds to the product of text zoom and system font scale, limited + * by zoom.maxPercent and minPercent. + * As the system font scale is automatically set by the PresShell, code that + * e.g. wants to transfer zoom levels to a new document should use TextZoom() + * instead, which corresponds to the text zoom level that was actually set by + * the front-end/user. + */ + float EffectiveTextZoom() const { return mEffectiveTextZoom; } + /** * Get the minimum font size for the specified language. If aLanguage * is nullptr, then the document's language is used. This combines @@ -931,6 +964,7 @@ public: bool IsScreen() { return (mMedium == nsGkAtoms::screen || mType == eContext_PageLayout || mType == eContext_PrintPreview); } + bool IsPrintingOrPrintPreview() { return (mType == eContext_Print || mType == eContext_PrintPreview); } // Is this presentation in a chrome docshell? bool IsChrome() const { return mIsChrome; } @@ -1300,7 +1334,9 @@ protected: // Base minimum font size, independent of the language-specific global preference. Defaults to 0 int32_t mBaseMinFontSize; + float mSystemFontScale; // Internal text zoom factor, defaults to 1.0 float mTextZoom; // Text zoom, defaults to 1.0 + float mEffectiveTextZoom; // Text zoom * system font scale float mFullZoom; // Page zoom, defaults to 1.0 float mOverrideDPPX; // DPPX overrided, defaults to 0.0 gfxSize mLastFontInflationScreenSize; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index bc6dd26af9bf..59eb408fa40f 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -5414,7 +5414,7 @@ nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord) const nsStyleFont* font = StyleFont(); float fCoord = float(aCoord); if (font->mAllowZoom) { - fCoord /= mPresShell->GetPresContext()->TextZoom(); + fCoord /= mPresShell->GetPresContext()->EffectiveTextZoom(); } if (font->mFont.size != font->mSize) { fCoord = fCoord * (float(font->mSize) / float(font->mFont.size)); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index ceb6f9ac0dc6..1fe0fdba0b2b 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -200,7 +200,7 @@ nsStyleFont::ZoomText(const nsPresContext* aPresContext, nscoord aSize) { // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here. // The caller is expected deal with that. - return NSToCoordTruncClamped(float(aSize) * aPresContext->TextZoom()); + return NSToCoordTruncClamped(float(aSize) * aPresContext->EffectiveTextZoom()); } /* static */ nscoord @@ -208,7 +208,7 @@ nsStyleFont::UnZoomText(nsPresContext *aPresContext, nscoord aSize) { // aSize can be negative (e.g.: calc(-1px)) so we can't assert that here. // The caller is expected deal with that. - return NSToCoordTruncClamped(float(aSize) / aPresContext->TextZoom()); + return NSToCoordTruncClamped(float(aSize) / aPresContext->EffectiveTextZoom()); } /* static */ already_AddRefed