Bug 1773342 - Treat text scale factor as an additional zoom factor, on both GTK and Windows. r=stransky,handyman

GTK already did this, sorta, in a platform-specific way: by hacking in the
scale factor in the CSS screen code. I think this is cleaner, since we have a
centralized place to compute the full zoom in nsPresContext, and that code path
is fairly well tested.

This also would make it trivial to make this text zoom rather than full zoom in
the future, if we wanted (which is probably _technically_ more correct, even
though less pretty less pretty).

This also allows us to remove some hacks where we were undoing the text scale
factor on Linux (since stuff like scrollbars already ignore full zoom).

Depends on D148675

Differential Revision: https://phabricator.services.mozilla.com/D148676
This commit is contained in:
Emilio Cobos Álvarez 2022-06-09 23:02:11 +00:00
parent f7208152a1
commit 40b88fe3ed
8 changed files with 39 additions and 39 deletions

View File

@ -1865,15 +1865,25 @@ nsDOMWindowUtils::ToScreenRectInCSSUnits(float aX, float aY, float aWidth,
nsPresContext* presContext = GetPresContext();
MOZ_ASSERT(presContext);
nsRect appUnitsRect = LayoutDeviceRect::ToAppUnits(
ViewAs<LayoutDevicePixel>(
rect, PixelCastJustification::ScreenIsParentLayerForRoot),
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
CSSRect cssUnitsRect = CSSRect::FromAppUnits(appUnitsRect);
auto devRect = ViewAs<LayoutDevicePixel>(
rect, PixelCastJustification::ScreenIsParentLayerForRoot);
// We want to return the screen rect in CSS units of the browser chrome. The
// browser chrome doesn't have any built-in zoom, except for the text scale
// factor.
//
// TODO(emilio): It'd be cleaner to convert callers to use plain toScreenRect,
// and perform the screen -> CSS rect in the parent process instead, probably.
LayoutDeviceToCSSScale scale = [&] {
float auPerDev =
presContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
auPerDev /= LookAndFeel::GetTextScaleFactor();
return LayoutDeviceToCSSScale(auPerDev / AppUnitsPerCSSPixel());
}();
CSSRect cssRect = devRect * scale;
RefPtr<DOMRect> outRect = new DOMRect(mWindow);
outRect->SetRect(cssUnitsRect.x, cssUnitsRect.y, cssUnitsRect.width,
cssUnitsRect.height);
outRect->SetRect(cssRect.x, cssRect.y, cssRect.width, cssRect.height);
outRect.forget(aResult);
return NS_OK;
}

View File

@ -929,7 +929,15 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
// matter... Medium also doesn't affect those.
return;
}
SetFullZoom(browsingContext->FullZoom());
// NOTE(emilio): We use the OS "text scale factor" as an extra source for full
// zoom, rather than text zoom (which would seem the obvious choice at first).
// is for a variety of reasons:
// * It generally creates more visually consistent results.
// * It has always been the effective behavior on GTK.
// * It matches other browsers as well.
float effectiveFullZoom =
browsingContext->FullZoom() * LookAndFeel::GetTextScaleFactor();
SetFullZoom(effectiveFullZoom);
SetTextZoom(browsingContext->TextZoom());
SetOverrideDPPX(browsingContext->OverrideDPPX());
@ -1581,6 +1589,9 @@ void nsPresContext::ThemeChangedInternal() {
LookAndFeel::HandleGlobalThemeChange();
// Full zoom might have changed as a result of the text scale factor.
RecomputeBrowsingContextDependentData();
// Changes to system metrics and other look and feel values can change media
// queries on them.
//

View File

@ -445,6 +445,10 @@ class LookAndFeel {
return GetColor(aId, aFrame).valueOr(aDefault);
}
static float GetTextScaleFactor() {
return GetFloat(FloatID::TextScaleFactor, 1.0f);
}
/**
* GetInt() and GetFloat() return a int or float value for aID. The result
* might be distance, time, some flags or a int value which has particular

View File

@ -131,16 +131,4 @@ void ScrollbarDrawingGTK::RecomputeScrollbarParams() {
defaultSize = overrideSize;
}
mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
// On GTK, widgets don't account for text scale factor, but that's included
// in the usual DPI computations, so we undo that here, just like
// GetMonitorScaleFactor does it in nsNativeThemeGTK.
float scale =
LookAndFeel::GetFloat(LookAndFeel::FloatID::TextScaleFactor, 1.0f);
if (scale != 1.0f) {
mVerticalScrollbarWidth =
uint32_t(round(float(mVerticalScrollbarWidth) / scale));
mHorizontalScrollbarHeight =
uint32_t(round(float(mHorizontalScrollbarHeight) / scale));
}
}

View File

@ -204,8 +204,7 @@ static already_AddRefed<Screen> MakeScreenGtk(GdkScreen* aScreen,
}
#endif
CSSToLayoutDeviceScale defaultCssScale(gdkScaleFactor *
gfxPlatformGtk::GetFontScaleFactor());
CSSToLayoutDeviceScale defaultCssScale(gdkScaleFactor);
float dpi = 96.0f;
gint heightMM = gdk_screen_get_monitor_height_mm(aScreen, aMonitorNum);
@ -371,8 +370,7 @@ already_AddRefed<Screen> ScreenGetterWayland::MakeScreenWayland(gint aMonitor) {
// Use per-monitor scaling factor in gtk/wayland, or 1.0 otherwise.
DesktopToLayoutDeviceScale contentsScale(monitor->scale);
CSSToLayoutDeviceScale defaultCssScale(monitor->scale *
gfxPlatformGtk::GetFontScaleFactor());
CSSToLayoutDeviceScale defaultCssScale(monitor->scale);
float dpi = 96.0f;
gint heightMM = monitor->height_mm;

View File

@ -66,17 +66,7 @@ static inline gint GetMonitorScaleFactor(nsPresContext* aPresContext) {
double scale = StaticPrefs::layout_css_devPixelsPerPx();
if (scale <= 0) {
if (nsCOMPtr<nsIWidget> rootWidget = aPresContext->GetRootWidget()) {
// We need to use GetDefaultScale() despite it returns monitor scale
// factor multiplied by font scale factor because it is the only scale
// updated in nsPuppetWidget.
// Since we don't want to apply font scale factor for UI elements
// (because GTK does not do so) we need to remove that from returned
// value. The computed monitor scale factor needs to be rounded before
// casting to integer to avoid rounding errors which would lead to
// returning 0.
int monitorScale = int(
round(rootWidget->GetDefaultScale().scale /
LookAndFeel::GetFloat(LookAndFeel::FloatID::TextScaleFactor)));
int monitorScale = int(round(rootWidget->GetDefaultScale().scale));
// Monitor scale can be negative if it has not been initialized in the
// puppet widget yet. We also make sure that we return positive value.
if (monitorScale < 1) {

View File

@ -646,9 +646,7 @@ float nsWindow::GetDPI() {
return dpi;
}
double nsWindow::GetDefaultScaleInternal() {
return FractionalScaleFactor() * gfxPlatformGtk::GetFontScaleFactor();
}
double nsWindow::GetDefaultScaleInternal() { return FractionalScaleFactor(); }
DesktopToLayoutDeviceScale nsWindow::GetDesktopToDeviceScale() {
#ifdef MOZ_WAYLAND

View File

@ -576,7 +576,8 @@ LookAndFeelFont nsLookAndFeel::GetLookAndFeelFontInternal(
result.haveFont() = false;
// Get scaling factor from physical to logical pixels
double pixelScale = 1.0 / WinUtils::SystemScaleFactor();
double pixelScale =
1.0 / WinUtils::SystemScaleFactor() / LookAndFeel::GetTextScaleFactor();
// The lfHeight is in pixels, and it needs to be adjusted for the
// device it will be displayed on.