commit 88016633b31bbc3fa5e7c1b17dcf27fc961a3496
parent f289eebba9194e9f22fce14b4e97c2da7a6e7c31
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Thu, 30 Oct 2025 22:53:12 +0000
Bug 1993820 - Tweak checked radio rendering to minimize snapping artifacts. r=dholbert
We're drawing it as a background circle, and an inner background +
border circle, which means that the outer background can snap
differently.
Draw it as an outer background + border, and an inner circle instead, so
as to minimize snapping artifacts on the outer border.
Differential Revision: https://phabricator.services.mozilla.com/D270477
Diffstat:
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/widget/Theme.cpp b/widget/Theme.cpp
@@ -633,26 +633,29 @@ void Theme::PaintRadioControl(PaintBackendData& aPaintData,
DPIRatio aDpiRatio) {
auto [backgroundColor, borderColor, checkColor] =
ComputeCheckboxColors(aState, StyleAppearance::Radio, aColors);
+ const bool isChecked = aState.HasState(ElementState::CHECKED);
{
- CSSCoord borderWidth = kCheckboxRadioBorderWidth;
- if (backgroundColor == borderColor) {
- borderWidth = 0.0f;
+ CSSCoord outerBorderWidth = kCheckboxRadioBorderWidth;
+ auto effectiveBackground = isChecked ? checkColor : backgroundColor;
+ if (effectiveBackground == borderColor) {
+ outerBorderWidth = 0.0f;
}
- PaintStrokedCircle(aPaintData, aRect, backgroundColor, borderColor,
- borderWidth, aDpiRatio);
- }
-
- if (aState.HasState(ElementState::CHECKED)) {
- // See bug 1951930 and bug 1941755 for some discussion on this chunk of
- // code.
- const CSSCoord kOuterBorderWidth = 1.0f;
- const CSSCoord kInnerBorderWidth = 2.0f;
- LayoutDeviceRect rect(aRect);
- auto width = LayoutDeviceCoord(
- ThemeDrawing::SnapBorderWidth(kOuterBorderWidth, aDpiRatio));
- rect.Deflate(width);
- PaintStrokedCircle(aPaintData, rect, backgroundColor, checkColor,
- kInnerBorderWidth, aDpiRatio);
+ PaintStrokedCircle(aPaintData, aRect, effectiveBackground, borderColor,
+ outerBorderWidth, aDpiRatio);
+ }
+
+ if (isChecked) {
+ // See bug 1951930 / bug 1941755 for discussion on this chunk of code.
+ constexpr CSSCoord kInnerBorderWidth = 2.0f;
+ LayoutDeviceRect innerCircleBounds(aRect);
+ // It's important that these are two different calls so that the snapping of
+ // the inner rect matches the one PaintStrokedCircle above does.
+ innerCircleBounds.Deflate(
+ ThemeDrawing::SnapBorderWidth(kCheckboxRadioBorderWidth, aDpiRatio));
+ innerCircleBounds.Deflate(
+ ThemeDrawing::SnapBorderWidth(kInnerBorderWidth, aDpiRatio));
+ PaintStrokedCircle(aPaintData, innerCircleBounds, backgroundColor,
+ sTransparent, 0.0f, aDpiRatio);
}
if (aState.HasState(ElementState::FOCUSRING)) {