Bug 1697210 - Make disabled checkbox / radio buttons do the right thing when painted with non-webrender. r=mstange

data:text/html,<input type=checkbox checked disabled>

Has a weird double border because the DrawTarget codepath fills and
strokes the same path, which is fine if the border is opaque, but not
otherwise.

Since this is the only use for a non-opaque border that we have, I
think, dealing with it on the caller seems a bit simpler. But let me
know if you want me to fix it more generally in
PaintRoundedRectWithRadius. I think for the semi-transparent border
case we'd need to create two paths, one for the background and one for
the border, which is a bit unfortunate.

The webrender codepath does the right thing, but of course that doesn't
get used for checkboxes.

Differential Revision: https://phabricator.services.mozilla.com/D107815
This commit is contained in:
Emilio Cobos Álvarez 2021-03-12 12:28:44 +00:00
parent 7b300cde76
commit bcb55cbfee

View File

@ -724,11 +724,23 @@ void nsNativeBasicTheme::PaintCheckboxControl(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
const CSSCoord radius = 2.0f;
auto [backgroundColor, borderColor] =
ComputeCheckboxColors(aState, StyleAppearance::Checkbox);
PaintRoundedRectWithRadius(aDrawTarget, aRect, backgroundColor, borderColor,
kCheckboxRadioBorderWidth, radius, aDpiRatio);
{
const CSSCoord radius = 2.0f;
CSSCoord borderWidth = kCheckboxRadioBorderWidth;
if (backgroundColor == borderColor) {
borderWidth = 0.0f;
}
PaintRoundedRectWithRadius(aDrawTarget, aRect, backgroundColor, borderColor,
borderWidth, radius, aDpiRatio);
}
if (aState.HasState(NS_EVENT_STATE_INDETERMINATE)) {
PaintIndeterminateMark(aDrawTarget, aRect, aState);
} else if (aState.HasState(NS_EVENT_STATE_CHECKED)) {
PaintCheckMark(aDrawTarget, aRect, aState);
}
if (aState.HasState(NS_EVENT_STATE_FOCUSRING)) {
PaintRoundedFocusRect(aDrawTarget, aRect, aDpiRatio, 5.0f, 1.0f);
@ -878,20 +890,24 @@ void nsNativeBasicTheme::PaintRadioControl(PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
const CSSCoord borderWidth = 2.0f;
auto [backgroundColor, borderColor] =
ComputeCheckboxColors(aState, StyleAppearance::Radio);
PaintStrokedCircle(aPaintData, aRect, backgroundColor, borderColor,
borderWidth, aDpiRatio);
{
CSSCoord borderWidth = kCheckboxRadioBorderWidth;
if (backgroundColor == borderColor) {
borderWidth = 0.0f;
}
PaintStrokedCircle(aPaintData, aRect, backgroundColor, borderColor,
borderWidth, aDpiRatio);
}
if (aState.HasState(NS_EVENT_STATE_CHECKED)) {
LayoutDeviceRect rect(aRect);
rect.Deflate(SnapBorderWidth(borderWidth, aDpiRatio));
rect.Deflate(SnapBorderWidth(kCheckboxRadioBorderWidth, aDpiRatio));
auto checkColor = ComputeCheckmarkColor(aState);
PaintStrokedCircle(aPaintData, rect, backgroundColor, checkColor,
borderWidth, aDpiRatio);
kCheckboxRadioBorderWidth, aDpiRatio);
}
if (aState.HasState(NS_EVENT_STATE_FOCUSRING)) {
@ -1455,11 +1471,6 @@ bool nsNativeBasicTheme::DoDrawWidgetBackground(PaintBackendData& aPaintData,
} else {
auto rect = CheckBoxRadioRect(devPxRect);
PaintCheckboxControl(aPaintData, rect, eventState, dpiRatio);
if (GetIndeterminate(aFrame)) {
PaintIndeterminateMark(aPaintData, rect, eventState);
} else if (IsChecked(aFrame)) {
PaintCheckMark(aPaintData, rect, eventState);
}
}
break;
}