mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 01:17:34 +09:00
Fix CSS border rounding and currentcolor clipping
This commit is contained in:
parent
6c7e6095b5
commit
84b9b77335
10 changed files with 147 additions and 21 deletions
|
|
@ -1743,7 +1743,9 @@ nsCSSRendering::PaintBackground(const PaintBGParams& aParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
|
IsOpaqueBorderEdge(const nsStyleBorder& aBorder,
|
||||||
|
const nsStyleColor& aColor,
|
||||||
|
mozilla::Side aSide)
|
||||||
{
|
{
|
||||||
if (aBorder.GetComputedBorder().Side(aSide) == 0)
|
if (aBorder.GetComputedBorder().Side(aSide) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1765,25 +1767,20 @@ IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
|
||||||
if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null)
|
if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
StyleComplexColor color = aBorder.mBorderColor[aSide];
|
nscolor color = aColor.CalcComplexColor(aBorder.mBorderColor[aSide]);
|
||||||
// We don't know the foreground color here, so if it's being used
|
return NS_GET_A(color) == 255;
|
||||||
// we must assume it might be transparent.
|
|
||||||
if (!color.IsNumericColor()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return NS_GET_A(color.mColor) == 255;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if all border edges are either missing or opaque.
|
* Returns true if all border edges are either missing or opaque.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
IsOpaqueBorder(const nsStyleBorder& aBorder)
|
IsOpaqueBorder(const nsStyleBorder& aBorder, const nsStyleColor& aColor)
|
||||||
{
|
{
|
||||||
if (aBorder.mBorderColors)
|
if (aBorder.mBorderColors)
|
||||||
return false;
|
return false;
|
||||||
NS_FOR_CSS_SIDES(i) {
|
NS_FOR_CSS_SIDES(i) {
|
||||||
if (!IsOpaqueBorderEdge(aBorder, i))
|
if (!IsOpaqueBorderEdge(aBorder, aColor, i))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1916,7 +1913,7 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSolidBorder =
|
bool isSolidBorder =
|
||||||
aWillPaintBorder && IsOpaqueBorder(aBorder);
|
aWillPaintBorder && IsOpaqueBorder(aBorder, *aForFrame->StyleColor());
|
||||||
if (isSolidBorder && layerClip == StyleGeometryBox::Border) {
|
if (isSolidBorder && layerClip == StyleGeometryBox::Border) {
|
||||||
// If we have rounded corners, we need to inflate the background
|
// If we have rounded corners, we need to inflate the background
|
||||||
// drawing area a bit to avoid seams between the border and
|
// drawing area a bit to avoid seams between the border and
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color: #fff;
|
||||||
|
background: var(--color);
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
width: 51px;
|
||||||
|
height: 51px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #323232;
|
||||||
|
border: 10px solid var(--color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div></div>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color: #fff;
|
||||||
|
background: var(--color);
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
width: 51px;
|
||||||
|
height: 51px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #323232;
|
||||||
|
border: 10px solid currentcolor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div></div>
|
||||||
|
|
@ -89,6 +89,8 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.te
|
||||||
# Test for antialiasing gaps between background and border
|
# Test for antialiasing gaps between background and border
|
||||||
fuzzy-if(gtkWidget,1,9) fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(d2d,5,40) fuzzy-if(skiaContent,1,9) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
|
fuzzy-if(gtkWidget,1,9) fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(d2d,5,40) fuzzy-if(skiaContent,1,9) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
|
||||||
|
|
||||||
|
== currentcolor-border-radius.html currentcolor-border-radius-ref.html
|
||||||
|
|
||||||
== color-layer-1a.html color-layer-1-ref.html
|
== color-layer-1a.html color-layer-1-ref.html
|
||||||
|
|
||||||
== corner-split.html corner-split-ref.svg # bug 1185636
|
== corner-split.html corner-split-ref.svg # bug 1185636
|
||||||
|
|
|
||||||
|
|
@ -3312,6 +3312,66 @@ nsComputedDOMStyle::DoGetBorderRightWidth()
|
||||||
return GetBorderWidthFor(eSideRight);
|
return GetBorderWidthFor(eSideRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<CSSValue>
|
||||||
|
nsComputedDOMStyle::DoGetBorderWidth()
|
||||||
|
{
|
||||||
|
nscoord widths[4];
|
||||||
|
if (mInnerFrame) {
|
||||||
|
AssertFlushedPendingReflows();
|
||||||
|
const nsMargin& usedBorder = mInnerFrame->GetUsedBorder();
|
||||||
|
NS_FOR_CSS_SIDES(side) {
|
||||||
|
widths[side] = usedBorder.Side(side);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const nsStyleBorder* border = StyleBorder();
|
||||||
|
NS_FOR_CSS_SIDES(side) {
|
||||||
|
widths[side] = border->GetComputedBorderWidth(side);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> top = new nsROCSSPrimitiveValue;
|
||||||
|
top->SetAppUnits(widths[eSideTop]);
|
||||||
|
valueList->AppendCSSValue(top.forget());
|
||||||
|
|
||||||
|
if (widths[eSideRight] == widths[eSideLeft]) {
|
||||||
|
if (widths[eSideTop] == widths[eSideBottom]) {
|
||||||
|
if (widths[eSideTop] == widths[eSideRight]) {
|
||||||
|
return valueList.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||||
|
right->SetAppUnits(widths[eSideRight]);
|
||||||
|
valueList->AppendCSSValue(right.forget());
|
||||||
|
return valueList.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||||
|
right->SetAppUnits(widths[eSideRight]);
|
||||||
|
valueList->AppendCSSValue(right.forget());
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> bottom = new nsROCSSPrimitiveValue;
|
||||||
|
bottom->SetAppUnits(widths[eSideBottom]);
|
||||||
|
valueList->AppendCSSValue(bottom.forget());
|
||||||
|
return valueList.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||||
|
right->SetAppUnits(widths[eSideRight]);
|
||||||
|
valueList->AppendCSSValue(right.forget());
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> bottom = new nsROCSSPrimitiveValue;
|
||||||
|
bottom->SetAppUnits(widths[eSideBottom]);
|
||||||
|
valueList->AppendCSSValue(bottom.forget());
|
||||||
|
|
||||||
|
RefPtr<nsROCSSPrimitiveValue> left = new nsROCSSPrimitiveValue;
|
||||||
|
left->SetAppUnits(widths[eSideLeft]);
|
||||||
|
valueList->AppendCSSValue(left.forget());
|
||||||
|
|
||||||
|
return valueList.forget();
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<CSSValue>
|
already_AddRefed<CSSValue>
|
||||||
nsComputedDOMStyle::DoGetBorderTopColor()
|
nsComputedDOMStyle::DoGetBorderTopColor()
|
||||||
{
|
{
|
||||||
|
|
@ -6961,3 +7021,4 @@ nsComputedDOMStyle::DoGetOverflowBlockEnd()
|
||||||
{
|
{
|
||||||
return DoGetOverflowBlock();
|
return DoGetOverflowBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,7 @@ private:
|
||||||
already_AddRefed<CSSValue> DoGetBorderBottomWidth();
|
already_AddRefed<CSSValue> DoGetBorderBottomWidth();
|
||||||
already_AddRefed<CSSValue> DoGetBorderLeftWidth();
|
already_AddRefed<CSSValue> DoGetBorderLeftWidth();
|
||||||
already_AddRefed<CSSValue> DoGetBorderRightWidth();
|
already_AddRefed<CSSValue> DoGetBorderRightWidth();
|
||||||
|
already_AddRefed<CSSValue> DoGetBorderWidth();
|
||||||
already_AddRefed<CSSValue> DoGetBorderTopColor();
|
already_AddRefed<CSSValue> DoGetBorderTopColor();
|
||||||
already_AddRefed<CSSValue> DoGetBorderBottomColor();
|
already_AddRefed<CSSValue> DoGetBorderBottomColor();
|
||||||
already_AddRefed<CSSValue> DoGetBorderLeftColor();
|
already_AddRefed<CSSValue> DoGetBorderLeftColor();
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ COMPUTED_STYLE_PROP(border_top_left_radius, BorderTopLeftRadius)
|
||||||
COMPUTED_STYLE_PROP(border_top_right_radius, BorderTopRightRadius)
|
COMPUTED_STYLE_PROP(border_top_right_radius, BorderTopRightRadius)
|
||||||
COMPUTED_STYLE_PROP(border_top_style, BorderTopStyle)
|
COMPUTED_STYLE_PROP(border_top_style, BorderTopStyle)
|
||||||
COMPUTED_STYLE_PROP(border_top_width, BorderTopWidth)
|
COMPUTED_STYLE_PROP(border_top_width, BorderTopWidth)
|
||||||
//// COMPUTED_STYLE_PROP(border_width, BorderWidth)
|
COMPUTED_STYLE_PROP(border_width, BorderWidth)
|
||||||
COMPUTED_STYLE_PROP(bottom, Bottom)
|
COMPUTED_STYLE_PROP(bottom, Bottom)
|
||||||
COMPUTED_STYLE_PROP(box_decoration_break, BoxDecorationBreak)
|
COMPUTED_STYLE_PROP(box_decoration_break, BoxDecorationBreak)
|
||||||
COMPUTED_STYLE_PROP(box_shadow, BoxShadow)
|
COMPUTED_STYLE_PROP(box_shadow, BoxShadow)
|
||||||
|
|
|
||||||
|
|
@ -8352,7 +8352,9 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
|
||||||
SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_CALC_LENGTH_ONLY |
|
SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_CALC_LENGTH_ONLY |
|
||||||
SETCOORD_UNSET_INITIAL,
|
SETCOORD_UNSET_INITIAL,
|
||||||
aContext, mPresContext, conditions)) {
|
aContext, mPresContext, conditions)) {
|
||||||
outline->mOutlineOffset = tempCoord.GetCoordValue();
|
outline->mOutlineOffset =
|
||||||
|
NS_ROUND_OFFSET_TO_PIXELS(tempCoord.GetCoordValue(),
|
||||||
|
mPresContext->AppUnitsPerDevPixel());
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(outlineOffsetValue->GetUnit() == eCSSUnit_Null,
|
NS_ASSERTION(outlineOffsetValue->GetUnit() == eCSSUnit_Null,
|
||||||
"unexpected unit");
|
"unexpected unit");
|
||||||
|
|
|
||||||
|
|
@ -1148,18 +1148,16 @@ private:
|
||||||
// Border widths are rounded to the nearest integer number of pixels, but values
|
// Border widths are rounded to the nearest integer number of pixels, but values
|
||||||
// between zero and one device pixels are always rounded up to one device pixel.
|
// between zero and one device pixels are always rounded up to one device pixel.
|
||||||
#define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
|
#define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
|
||||||
((l) == 0) ? 0 : std::max((tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp))
|
(((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)))
|
||||||
// Caret widths are rounded to the nearest-below integer number of pixels, but values
|
// Caret widths are rounded to the nearest-below integer number of pixels, but values
|
||||||
// between zero and one device pixels are always rounded up to one device pixel.
|
// between zero and one device pixels are always rounded up to one device pixel.
|
||||||
#define NS_ROUND_CARET_TO_PIXELS(l,tpp) \
|
#define NS_ROUND_CARET_TO_PIXELS(l,tpp) \
|
||||||
((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
|
NS_ROUND_BORDER_TO_PIXELS(l,tpp)
|
||||||
// Outline offset is rounded to the nearest integer number of pixels, but values
|
// Outline offset is snapped like border widths, preserving the sign.
|
||||||
// between zero and one device pixels are always rounded up to one device pixel.
|
|
||||||
// Note that the offset can be negative.
|
|
||||||
#define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
|
#define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
|
||||||
(((l) == 0) ? 0 : \
|
(((l) == 0) ? 0 : \
|
||||||
((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
|
(((l) > 0) ? NS_ROUND_BORDER_TO_PIXELS((l), (tpp)) : \
|
||||||
std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
|
std::min(-(tpp), (l) / (tpp) * (tpp))))
|
||||||
|
|
||||||
// Returns if the given border style type is visible or not
|
// Returns if the given border style type is visible or not
|
||||||
static bool IsVisibleBorderStyle(uint8_t aStyle)
|
static bool IsVisibleBorderStyle(uint8_t aStyle)
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,37 @@ function checkWidth(property, setupProperty, setupValue) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkOffset(property) {
|
||||||
|
tests.forEach(function(test) {
|
||||||
|
var specified = test[0];
|
||||||
|
var expected = test[1];
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.style[property] = specified;
|
||||||
|
display.appendChild(div);
|
||||||
|
|
||||||
|
is(document.defaultView.getComputedStyle(div, "")[property], expected,
|
||||||
|
property + " computes " + specified + " as " + expected);
|
||||||
|
|
||||||
|
display.removeChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
tests.forEach(function(test) {
|
||||||
|
var specified = test[0];
|
||||||
|
var expected = test[0] == "0px" ? "0px" : "-" + test[1];
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.style[property] = "-" + specified;
|
||||||
|
display.appendChild(div);
|
||||||
|
|
||||||
|
is(document.defaultView.getComputedStyle(div, "")[property], expected,
|
||||||
|
property + " computes -" + specified + " as " + expected);
|
||||||
|
|
||||||
|
display.removeChild(div);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
checkWidth("borderWidth", "borderStyle", "solid");
|
checkWidth("borderWidth", "borderStyle", "solid");
|
||||||
checkWidth("outlineWidth", "outlineStyle", "solid");
|
checkWidth("outlineWidth", "outlineStyle", "solid");
|
||||||
|
checkOffset("outlineOffset");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue