commit d45de9c0f73a5fe192041547d6b0f64135a62b78
parent 4e64d65b0b2e2a2dac151ffaad6f6b455c69a53c
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Wed, 3 Dec 2025 07:13:12 +0000
Bug 1998555 - Make sure that nsIBaseWindow scale agrees with nsDeviceContext. r=jwatt
At some resolutions (like 1.75x) the difference with the app units
rounding that nsDeviceContext does eventually is enough to cause a few
pixels of difference for a big screen.
Make sure that nsIBaseWindow accounts for the resolution the same way
layout and rendering eventually do.
Differential Revision: https://phabricator.services.mozilla.com/D274749
Diffstat:
3 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/gfx/src/nsDeviceContext.cpp b/gfx/src/nsDeviceContext.cpp
@@ -44,6 +44,19 @@ nsDeviceContext::nsDeviceContext()
nsDeviceContext::~nsDeviceContext() = default;
+int32_t nsDeviceContext::ComputeAppUnitsPerDevPixelForWidgetScale(
+ CSSToLayoutDeviceScale aScale) {
+ return std::max(1, NS_lround(AppUnitsPerCSSPixel() / aScale.scale));
+}
+
+int32_t nsDeviceContext::ApplyFullZoomToAPD(int32_t aUnzoomedAppUnits,
+ float aFullZoom) {
+ if (aFullZoom == 1.0f) {
+ return aUnzoomedAppUnits;
+ }
+ return std::max(1, NSToIntRound(float(aUnzoomedAppUnits) / aFullZoom));
+}
+
void nsDeviceContext::SetDPI() {
float dpi;
@@ -53,7 +66,8 @@ void nsDeviceContext::SetDPI() {
mPrintingScale = mDeviceContextSpec->GetPrintingScale();
mPrintingTranslate = mDeviceContextSpec->GetPrintingTranslate();
mAppUnitsPerDevPixelAtUnitFullZoom =
- NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
+ ComputeAppUnitsPerDevPixelForWidgetScale(
+ CSSToLayoutDeviceScale(96.0f / dpi));
} else {
// A value of -1 means use the maximum of 96 and the system DPI.
// A value of 0 means use the system DPI. A positive value is used as the
@@ -76,7 +90,7 @@ void nsDeviceContext::SetDPI() {
mWidget ? mWidget->GetDefaultScale() : CSSToLayoutDeviceScale(1.0);
MOZ_ASSERT(scale.scale > 0.0);
mAppUnitsPerDevPixelAtUnitFullZoom =
- std::max(1, NS_lround(AppUnitsPerCSSPixel() / scale.scale));
+ ComputeAppUnitsPerDevPixelForWidgetScale(scale);
}
NS_ASSERTION(dpi != -1.0, "no dpi set");
@@ -365,22 +379,15 @@ bool nsDeviceContext::SetFullZoom(float aScale) {
return oldAppUnitsPerDevPixel != mAppUnitsPerDevPixel;
}
-static int32_t ApplyFullZoom(int32_t aUnzoomedAppUnits, float aFullZoom) {
- if (aFullZoom == 1.0f) {
- return aUnzoomedAppUnits;
- }
- return std::max(1, NSToIntRound(float(aUnzoomedAppUnits) / aFullZoom));
-}
-
int32_t nsDeviceContext::AppUnitsPerDevPixelInTopLevelChromePage() const {
// The only zoom that applies to chrome pages is the system zoom, if any.
- return ApplyFullZoom(mAppUnitsPerDevPixelAtUnitFullZoom,
- LookAndFeel::SystemZoomSettings().mFullZoom);
+ return ApplyFullZoomToAPD(mAppUnitsPerDevPixelAtUnitFullZoom,
+ LookAndFeel::SystemZoomSettings().mFullZoom);
}
void nsDeviceContext::UpdateAppUnitsForFullZoom() {
mAppUnitsPerDevPixel =
- ApplyFullZoom(mAppUnitsPerDevPixelAtUnitFullZoom, mFullZoom);
+ ApplyFullZoomToAPD(mAppUnitsPerDevPixelAtUnitFullZoom, mFullZoom);
// adjust mFullZoom to reflect appunit rounding
mFullZoom = float(mAppUnitsPerDevPixelAtUnitFullZoom) / mAppUnitsPerDevPixel;
}
diff --git a/gfx/src/nsDeviceContext.h b/gfx/src/nsDeviceContext.h
@@ -91,6 +91,10 @@ class nsDeviceContext final {
*/
int32_t AppUnitsPerDevPixel() const { return mAppUnitsPerDevPixel; }
+ static int32_t ComputeAppUnitsPerDevPixelForWidgetScale(
+ mozilla::CSSToLayoutDeviceScale);
+ static int32_t ApplyFullZoomToAPD(int32_t aAppUnitsPerPixel, float aFullZoom);
+
/**
* Convert device pixels which is used for gfx/thebes to nearest
* (rounded) app units
diff --git a/widget/nsIBaseWindow.cpp b/widget/nsIBaseWindow.cpp
@@ -4,11 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIBaseWindow.h"
+#include "nsDeviceContext.h"
#include "mozilla/LookAndFeel.h"
using namespace mozilla;
CSSToLayoutDeviceScale nsIBaseWindow::UnscaledDevicePixelsPerCSSPixel() {
- return CSSToLayoutDeviceScale(GetWidgetCSSToDeviceScale() *
- LookAndFeel::SystemZoomSettings().mFullZoom);
+ CSSToLayoutDeviceScale widgetScale(GetWidgetCSSToDeviceScale());
+ int32_t apd =
+ nsDeviceContext::ComputeAppUnitsPerDevPixelForWidgetScale(widgetScale);
+ apd = nsDeviceContext::ApplyFullZoomToAPD(
+ apd, LookAndFeel::SystemZoomSettings().mFullZoom);
+ return CSSToLayoutDeviceScale(double(AppUnitsPerCSSPixel()) / double(apd));
}