diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index f54831035fa3..2a488975ef20 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -9880,16 +9880,17 @@ static void ComputeAndIncludeOutlineArea(nsIFrame* aFrame, innerRect); } - const nscoord offset = outline->mOutlineOffset.ToAppUnits(); nsRect outerRect(innerRect); + outerRect.Inflate(outline->EffectiveOffsetFor(outerRect)); + if (outline->mOutlineStyle.IsAuto()) { nsPresContext* pc = aFrame->PresContext(); - outerRect.Inflate(offset); + pc->Theme()->GetWidgetOverflow(pc->DeviceContext(), aFrame, StyleAppearance::FocusOutline, &outerRect); } else { - nscoord width = outline->GetOutlineWidth(); - outerRect.Inflate(width + offset); + const nscoord width = outline->GetOutlineWidth(); + outerRect.Inflate(width); } nsRect& vo = aOverflowAreas.InkOverflow(); diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp index 506ec94a9b25..5f39ed0b7236 100644 --- a/layout/painting/nsCSSRendering.cpp +++ b/layout/painting/nsCSSRendering.cpp @@ -962,9 +962,10 @@ nsCSSRendering::CreateBorderRendererForNonThemedOutline( return Nothing(); } - const nscoord offset = ourOutline->mOutlineOffset.ToAppUnits(); nsRect innerRect = aInnerRect; - innerRect.Inflate(offset); + + const nsSize effectiveOffset = ourOutline->EffectiveOffsetFor(innerRect); + innerRect.Inflate(effectiveOffset); // If the dirty rect is completely inside the border area (e.g., only the // content is being painted), then we can skip out now @@ -975,7 +976,7 @@ nsCSSRendering::CreateBorderRendererForNonThemedOutline( return Nothing(); } - nscoord width = ourOutline->GetOutlineWidth(); + const nscoord width = ourOutline->GetOutlineWidth(); StyleBorderStyle outlineStyle; // Themed outlines are handled by our callers, if supported. @@ -1009,10 +1010,13 @@ nsCSSRendering::CreateBorderRendererForNonThemedOutline( RectCornerRadii innerRadii; ComputePixelRadii(twipsRadii, oneDevPixel, &innerRadii); - Float devPixelOffset = aPresContext->AppUnitsToFloatDevPixels(offset); - const Float widths[4] = { - outlineWidths[0] + devPixelOffset, outlineWidths[1] + devPixelOffset, - outlineWidths[2] + devPixelOffset, outlineWidths[3] + devPixelOffset}; + const auto devPxOffset = LayoutDeviceSize::FromAppUnits( + effectiveOffset, aPresContext->AppUnitsPerDevPixel()); + + const Float widths[4] = {outlineWidths[0] + devPxOffset.Height(), + outlineWidths[1] + devPxOffset.Width(), + outlineWidths[2] + devPxOffset.Height(), + outlineWidths[3] + devPxOffset.Width()}; nsCSSBorderRenderer::ComputeOuterRadii(innerRadii, widths, &outlineRadii); } diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 0fffd8f5b2bb..a1dc5d44556c 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -4015,7 +4015,7 @@ void nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) { nsRect rect = GetInnerRect() + ToReferenceFrame(); nsPresContext* pc = mFrame->PresContext(); if (IsThemedOutline()) { - rect.Inflate(mFrame->StyleOutline()->mOutlineOffset.ToAppUnits()); + rect.Inflate(mFrame->StyleOutline()->EffectiveOffsetFor(rect)); pc->Theme()->DrawWidgetBackground(aCtx, mFrame, StyleAppearance::FocusOutline, rect, GetPaintRect(aBuilder, aCtx)); @@ -4044,7 +4044,7 @@ bool nsDisplayOutline::CreateWebRenderCommands( nsPresContext* pc = mFrame->PresContext(); nsRect rect = GetInnerRect() + ToReferenceFrame(); if (IsThemedOutline()) { - rect.Inflate(mFrame->StyleOutline()->mOutlineOffset.ToAppUnits()); + rect.Inflate(mFrame->StyleOutline()->EffectiveOffsetFor(rect)); return pc->Theme()->CreateWebRenderCommandsForWidget( aBuilder, aResources, aSc, aManager, mFrame, StyleAppearance::FocusOutline, rect); diff --git a/layout/reftests/bugs/424236-5-ref.html b/layout/reftests/bugs/424236-5-ref.html index 4b74721f0758..e524214986e8 100644 --- a/layout/reftests/bugs/424236-5-ref.html +++ b/layout/reftests/bugs/424236-5-ref.html @@ -8,7 +8,6 @@ + +

PASS if there is a thin red line in the middle of the box.

+
+ +
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-ui/negative-outline-offset.html b/testing/web-platform/tests/css/css-ui/negative-outline-offset.html new file mode 100644 index 000000000000..3d20df08539d --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/negative-outline-offset.html @@ -0,0 +1,16 @@ + + + + + +

PASS if there is a thin red line in the middle of the box.

+
\ No newline at end of file