mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-26 17:17:31 +09:00
PR #2643 - The border-radius Directive Should Apply to Outlines
However, `-moz-outline-radius` should still override any `border-radius`. This is primarily done for backward compatibility with some themes. Additionally, it also allows for more advanced outline control than the CSS spec provides, without breaking spec. Finally, if the spec is ever updated to include `outline-radius`, we'll be ready to drop the `-moz-` prefix! Note: BZ 315209 has an inadvertent double-negative in nsDisplayList.cpp: HasRadius() essentially returns the opposite value it should.
This commit is contained in:
parent
a1d0cf1e05
commit
cee682b980
4 changed files with 48 additions and 33 deletions
|
|
@ -855,8 +855,6 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
nsStyleContext* aStyleContext)
|
nsStyleContext* aStyleContext)
|
||||||
{
|
{
|
||||||
nscoord twipsRadii[8];
|
|
||||||
|
|
||||||
// Get our style context's color struct.
|
// Get our style context's color struct.
|
||||||
const nsStyleOutline* ourOutline = aStyleContext->StyleOutline();
|
const nsStyleOutline* ourOutline = aStyleContext->StyleOutline();
|
||||||
MOZ_ASSERT(ourOutline != NS_STYLE_BORDER_STYLE_NONE,
|
MOZ_ASSERT(ourOutline != NS_STYLE_BORDER_STYLE_NONE,
|
||||||
|
|
@ -898,24 +896,6 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
|
||||||
if (innerRect.Contains(aDirtyRect))
|
if (innerRect.Contains(aDirtyRect))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsRect outerRect = innerRect;
|
|
||||||
outerRect.Inflate(width, width);
|
|
||||||
|
|
||||||
// get the radius for our outline
|
|
||||||
nsIFrame::ComputeBorderRadii(ourOutline->mOutlineRadius, aBorderArea.Size(),
|
|
||||||
outerRect.Size(), Sides(), twipsRadii);
|
|
||||||
|
|
||||||
// Get our conversion values
|
|
||||||
nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
|
|
||||||
|
|
||||||
// get the outer rectangles
|
|
||||||
Rect oRect(NSRectToRect(outerRect, twipsPerPixel));
|
|
||||||
|
|
||||||
// convert the radii
|
|
||||||
nsMargin outlineMargin(width, width, width, width);
|
|
||||||
RectCornerRadii outlineRadii;
|
|
||||||
ComputePixelRadii(twipsRadii, twipsPerPixel, &outlineRadii);
|
|
||||||
|
|
||||||
if (outlineStyle == NS_STYLE_BORDER_STYLE_AUTO) {
|
if (outlineStyle == NS_STYLE_BORDER_STYLE_AUTO) {
|
||||||
if (nsLayoutUtils::IsOutlineStyleAutoEnabled()) {
|
if (nsLayoutUtils::IsOutlineStyleAutoEnabled()) {
|
||||||
nsITheme* theme = aPresContext->GetTheme();
|
nsITheme* theme = aPresContext->GetTheme();
|
||||||
|
|
@ -935,6 +915,36 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
|
||||||
outlineStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
outlineStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RectCornerRadii outlineRadii;
|
||||||
|
nsRect outerRect = innerRect;
|
||||||
|
outerRect.Inflate(width, width);
|
||||||
|
|
||||||
|
const nscoord oneDevPixel = aPresContext->AppUnitsPerDevPixel();
|
||||||
|
Rect oRect(NSRectToRect(outerRect, oneDevPixel));
|
||||||
|
|
||||||
|
const Float outlineWidths[4] = {
|
||||||
|
Float(width) / oneDevPixel, Float(width) / oneDevPixel,
|
||||||
|
Float(width) / oneDevPixel, Float(width) / oneDevPixel};
|
||||||
|
|
||||||
|
// convert the radii
|
||||||
|
nscoord twipsRadii[8];
|
||||||
|
|
||||||
|
// get the radius for our outline
|
||||||
|
if (nsLayoutUtils::HasNonZeroCorner(ourOutline->mOutlineRadius)) {
|
||||||
|
nsIFrame::ComputeBorderRadii(ourOutline->mOutlineRadius, aBorderArea.Size(),
|
||||||
|
outerRect.Size(), Sides(), twipsRadii);
|
||||||
|
ComputePixelRadii(twipsRadii, oneDevPixel, &outlineRadii);
|
||||||
|
} else if (aForFrame->GetBorderRadii(twipsRadii)) {
|
||||||
|
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};
|
||||||
|
nsCSSBorderRenderer::ComputeOuterRadii(innerRadii, widths, &outlineRadii);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t outlineStyles[4] = { outlineStyle, outlineStyle,
|
uint8_t outlineStyles[4] = { outlineStyle, outlineStyle,
|
||||||
outlineStyle, outlineStyle };
|
outlineStyle, outlineStyle };
|
||||||
|
|
||||||
|
|
@ -947,12 +957,7 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
|
||||||
outlineColor,
|
outlineColor,
|
||||||
outlineColor };
|
outlineColor };
|
||||||
|
|
||||||
// convert the border widths
|
Rect dirtyRect = NSRectToRect(aDirtyRect, oneDevPixel);
|
||||||
Float outlineWidths[4] = { Float(width / twipsPerPixel),
|
|
||||||
Float(width / twipsPerPixel),
|
|
||||||
Float(width / twipsPerPixel),
|
|
||||||
Float(width / twipsPerPixel) };
|
|
||||||
Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel);
|
|
||||||
|
|
||||||
nsIDocument* document = nullptr;
|
nsIDocument* document = nullptr;
|
||||||
nsIContent* content = aForFrame->GetContent();
|
nsIContent* content = aForFrame->GetContent();
|
||||||
|
|
|
||||||
|
|
@ -3757,18 +3757,23 @@ nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder,
|
||||||
mFrame->StyleContext());
|
mFrame->StyleContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nsDisplayOutline::HasRadius() const {
|
||||||
|
if (nsLayoutUtils::HasNonZeroCorner(mFrame->StyleOutline()->mOutlineRadius)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return nsLayoutUtils::HasNonZeroCorner(mFrame->StyleBorder()->mBorderRadius);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsDisplayOutline::IsInvisibleInRect(const nsRect& aRect)
|
nsDisplayOutline::IsInvisibleInRect(const nsRect& aRect)
|
||||||
{
|
{
|
||||||
const nsStyleOutline* outline = mFrame->StyleOutline();
|
const nsStyleOutline* outline = mFrame->StyleOutline();
|
||||||
nsRect borderBox(ToReferenceFrame(), mFrame->GetSize());
|
nsRect borderBox(ToReferenceFrame(), mFrame->GetSize());
|
||||||
if (borderBox.Contains(aRect) &&
|
if (borderBox.Contains(aRect) && !HasRadius() &&
|
||||||
!nsLayoutUtils::HasNonZeroCorner(outline->mOutlineRadius)) {
|
outline->mOutlineOffset >= 0) {
|
||||||
if (outline->mOutlineOffset >= 0) {
|
// aRect is entirely inside the border-rect, and the outline isn't
|
||||||
// aRect is entirely inside the border-rect, and the outline isn't
|
// rendered inside the border-rect, so the outline is not visible.
|
||||||
// rendered inside the border-rect, so the outline is not visible.
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -3220,6 +3220,9 @@ public:
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
|
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
|
||||||
NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
|
NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool HasRadius() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,8 @@ nsStyleBorder::CalcDifference(const nsStyleBorder& aNewData) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that border radius is used as a fallback for outline radius, if set.
|
||||||
|
// Any optimizations here should apply to both.
|
||||||
if (mBorderRadius != aNewData.mBorderRadius ||
|
if (mBorderRadius != aNewData.mBorderRadius ||
|
||||||
!mBorderColors != !aNewData.mBorderColors) {
|
!mBorderColors != !aNewData.mBorderColors) {
|
||||||
return nsChangeHint_RepaintFrame;
|
return nsChangeHint_RepaintFrame;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue