Bug 1328868 - Part 2 - Apply the system font scale as an additional text zoom factor to all pages that are not font inflated. r=tnikkel

We want to use a similar model as Chrome on Android does for scaling our display of web content, that is use font inflation for desktop pages and plain text zooming for everything else.

Since we don't want to simply clobber any text zoom that might have been set by the user/front-end code, we allow setting and storing the system font scale separately on the PresContext. We then calculate the effective text zoom value as the product of the system font scale and the current text zoom value.

Any function that is using the PresContext's TextZoom value for layouting/rendering is switched over to this new EffectiveTextZoom value, whereas functions that are interested in the text zoom as actually set by the user/front-end (e.g. the nsDocumentViewer, or the code responsible for copying text and full zoom settings into the new PresContext on page navigation) continue using the plain TextZoom value.

As long as font inflation is enabled in principle (e.g. font.size.inflation.minTwips != 0), every page starts out as eligible for font inflation until the relevant meta viewport tags marking the page as "mobile friendly" have been detected. Since the PresShell caches the font inflation state and only recalculates it when necessary, we make use of that and set the PresContext's system font scale as necessary whenever the font inflation state has been refreshed.

MozReview-Commit-ID: 2InyE04wKAW

--HG--
extra : rebase_source : 3f6d7128f37c1dc18f67a6655f86d9a3003fe90b
extra : source : 6100458b97289f9aea5ac8fda57ded045e6860b7
This commit is contained in:
Jan Henning 2017-02-25 13:22:52 +01:00
Родитель 320ff25d1c
Коммит 8a6b5c9c8a
8 изменённых файлов: 118 добавлений и 26 удалений

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

@ -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;
}

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

@ -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,

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

@ -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<nsIScreenManager> screenMgr =
do_GetService("@mozilla.org/gfx/screenmanager;1", &rv);
if (!NS_SUCCEEDED(rv)) {
mFontSizeInflationEnabled = false;
return;
return false;
}
nsCOMPtr<nsIScreen> 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()
{

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

@ -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.

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

@ -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)
{

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

@ -535,6 +535,30 @@ public:
nsIAtom* GetLanguageFromCharset() const { return mLanguage; }
already_AddRefed<nsIAtom> 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;

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

@ -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));

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

@ -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<nsIAtom>