diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 54f965e9d2..0bca63885b 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1743,7 +1743,9 @@ nsCSSRendering::PaintBackground(const PaintBGParams& aParams)
}
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)
return true;
@@ -1765,25 +1767,20 @@ IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null)
return false;
- StyleComplexColor color = aBorder.mBorderColor[aSide];
- // We don't know the foreground color here, so if it's being used
- // we must assume it might be transparent.
- if (!color.IsNumericColor()) {
- return false;
- }
- return NS_GET_A(color.mColor) == 255;
+ nscolor color = aColor.CalcComplexColor(aBorder.mBorderColor[aSide]);
+ return NS_GET_A(color) == 255;
}
/**
* Returns true if all border edges are either missing or opaque.
*/
static bool
-IsOpaqueBorder(const nsStyleBorder& aBorder)
+IsOpaqueBorder(const nsStyleBorder& aBorder, const nsStyleColor& aColor)
{
if (aBorder.mBorderColors)
return false;
NS_FOR_CSS_SIDES(i) {
- if (!IsOpaqueBorderEdge(aBorder, i))
+ if (!IsOpaqueBorderEdge(aBorder, aColor, i))
return false;
}
return true;
@@ -1916,7 +1913,7 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
}
bool isSolidBorder =
- aWillPaintBorder && IsOpaqueBorder(aBorder);
+ aWillPaintBorder && IsOpaqueBorder(aBorder, *aForFrame->StyleColor());
if (isSolidBorder && layerClip == StyleGeometryBox::Border) {
// If we have rounded corners, we need to inflate the background
// drawing area a bit to avoid seams between the border and
diff --git a/layout/reftests/border-radius/currentcolor-border-radius-ref.html b/layout/reftests/border-radius/currentcolor-border-radius-ref.html
new file mode 100644
index 0000000000..94f7b98702
--- /dev/null
+++ b/layout/reftests/border-radius/currentcolor-border-radius-ref.html
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/layout/reftests/border-radius/currentcolor-border-radius.html b/layout/reftests/border-radius/currentcolor-border-radius.html
new file mode 100644
index 0000000000..ae93c104b9
--- /dev/null
+++ b/layout/reftests/border-radius/currentcolor-border-radius.html
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/layout/reftests/border-radius/reftest.list b/layout/reftests/border-radius/reftest.list
index 4b2d2f4ee6..c9de171ba0 100644
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -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
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
== corner-split.html corner-split-ref.svg # bug 1185636
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index af512e2626..2657bad496 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3312,6 +3312,66 @@ nsComputedDOMStyle::DoGetBorderRightWidth()
return GetBorderWidthFor(eSideRight);
}
+already_AddRefed
+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 valueList = GetROCSSValueList(false);
+
+ RefPtr 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 right = new nsROCSSPrimitiveValue;
+ right->SetAppUnits(widths[eSideRight]);
+ valueList->AppendCSSValue(right.forget());
+ return valueList.forget();
+ }
+
+ RefPtr right = new nsROCSSPrimitiveValue;
+ right->SetAppUnits(widths[eSideRight]);
+ valueList->AppendCSSValue(right.forget());
+
+ RefPtr bottom = new nsROCSSPrimitiveValue;
+ bottom->SetAppUnits(widths[eSideBottom]);
+ valueList->AppendCSSValue(bottom.forget());
+ return valueList.forget();
+ }
+
+ RefPtr right = new nsROCSSPrimitiveValue;
+ right->SetAppUnits(widths[eSideRight]);
+ valueList->AppendCSSValue(right.forget());
+
+ RefPtr bottom = new nsROCSSPrimitiveValue;
+ bottom->SetAppUnits(widths[eSideBottom]);
+ valueList->AppendCSSValue(bottom.forget());
+
+ RefPtr left = new nsROCSSPrimitiveValue;
+ left->SetAppUnits(widths[eSideLeft]);
+ valueList->AppendCSSValue(left.forget());
+
+ return valueList.forget();
+}
+
already_AddRefed
nsComputedDOMStyle::DoGetBorderTopColor()
{
@@ -6960,4 +7020,5 @@ already_AddRefed
nsComputedDOMStyle::DoGetOverflowBlockEnd()
{
return DoGetOverflowBlock();
-}
\ No newline at end of file
+}
+
diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h
index a4c1b559a0..0715f18444 100644
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -345,6 +345,7 @@ private:
already_AddRefed DoGetBorderBottomWidth();
already_AddRefed DoGetBorderLeftWidth();
already_AddRefed DoGetBorderRightWidth();
+ already_AddRefed DoGetBorderWidth();
already_AddRefed DoGetBorderTopColor();
already_AddRefed DoGetBorderBottomColor();
already_AddRefed DoGetBorderLeftColor();
diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h
index 50a32dccc6..b62a484376 100644
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -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_style, BorderTopStyle)
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(box_decoration_break, BoxDecorationBreak)
COMPUTED_STYLE_PROP(box_shadow, BoxShadow)
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 063e6cc10e..8721fcc6bf 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -8352,7 +8352,9 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_CALC_LENGTH_ONLY |
SETCOORD_UNSET_INITIAL,
aContext, mPresContext, conditions)) {
- outline->mOutlineOffset = tempCoord.GetCoordValue();
+ outline->mOutlineOffset =
+ NS_ROUND_OFFSET_TO_PIXELS(tempCoord.GetCoordValue(),
+ mPresContext->AppUnitsPerDevPixel());
} else {
NS_ASSERTION(outlineOffsetValue->GetUnit() == eCSSUnit_Null,
"unexpected unit");
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index edecefdf08..0584f2afca 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1148,18 +1148,16 @@ private:
// 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.
#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
// between zero and one device pixels are always rounded up to one device pixel.
#define NS_ROUND_CARET_TO_PIXELS(l,tpp) \
- ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
-// Outline offset is rounded to the nearest integer number of pixels, but values
-// between zero and one device pixels are always rounded up to one device pixel.
-// Note that the offset can be negative.
+ NS_ROUND_BORDER_TO_PIXELS(l,tpp)
+// Outline offset is snapped like border widths, preserving the sign.
#define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
(((l) == 0) ? 0 : \
- ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
- std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
+ (((l) > 0) ? NS_ROUND_BORDER_TO_PIXELS((l), (tpp)) : \
+ std::min(-(tpp), (l) / (tpp) * (tpp))))
// Returns if the given border style type is visible or not
static bool IsVisibleBorderStyle(uint8_t aStyle)
diff --git a/layout/style/test/test_border_width_rounding.html b/layout/style/test/test_border_width_rounding.html
index f7c2faabda..2de866b200 100644
--- a/layout/style/test/test_border_width_rounding.html
+++ b/layout/style/test/test_border_width_rounding.html
@@ -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("outlineWidth", "outlineStyle", "solid");
+checkOffset("outlineOffset");