Bug 1266621 part 5 - Convert border-color to store complex color. r=heycam

MozReview-Commit-ID: 19sl9f3EVgt

--HG--
extra : rebase_source : fba71e92cf7d23728a7c963ae12027e7aee7e986
This commit is contained in:
Xidorn Quan 2016-09-27 20:16:35 +10:00
parent ea44b70aba
commit e92fe57924
13 changed files with 79 additions and 242 deletions

View File

@ -673,9 +673,9 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
newStyleBorder.TrackImage(aPresContext);
NS_FOR_CSS_SIDES(side) {
newStyleBorder.SetBorderColor(side,
aStyleContext->GetVisitedDependentColor(
nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color)[side]));
nscolor color = aStyleContext->GetVisitedDependentColor(
nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color)[side]);
newStyleBorder.mBorderColor[side] = StyleComplexColor::FromColor(color);
}
DrawResult result =
PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
@ -804,13 +804,9 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
// pull out styles, colors, composite colors
NS_FOR_CSS_SIDES (i) {
bool foreground;
borderStyles[i] = aStyleBorder.GetBorderStyle(i);
aStyleBorder.GetBorderColor(i, borderColors[i], foreground);
borderColors[i] = ourColor->CalcComplexColor(aStyleBorder.mBorderColor[i]);
aStyleBorder.GetCompositeColors(i, &compositeColors[i]);
if (foreground)
borderColors[i] = ourColor->mColor;
}
PrintAsFormatString(" borderStyles: %d %d %d %d\n", borderStyles[0], borderStyles[1], borderStyles[2], borderStyles[3]);
@ -1775,16 +1771,13 @@ IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::css::Side aSide)
if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null)
return false;
nscolor color;
bool isForeground;
aBorder.GetBorderColor(aSide, color, isForeground);
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 (isForeground)
if (!color.IsNumericColor()) {
return false;
return NS_GET_A(color) == 255;
}
return NS_GET_A(color.mColor) == 255;
}
/**

View File

@ -95,13 +95,13 @@ nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx,
if (isVertical) {
border.SetBorderWidth(NS_SIDE_TOP, ruleWidth);
border.SetBorderStyle(NS_SIDE_TOP, ruleStyle);
border.SetBorderColor(NS_SIDE_TOP, ruleColor);
border.mBorderTopColor = StyleComplexColor::FromColor(ruleColor);
skipSides |= mozilla::eSideBitsLeftRight;
skipSides |= mozilla::eSideBitsBottom;
} else {
border.SetBorderWidth(NS_SIDE_LEFT, ruleWidth);
border.SetBorderStyle(NS_SIDE_LEFT, ruleStyle);
border.SetBorderColor(NS_SIDE_LEFT, ruleColor);
border.mBorderLeftColor = StyleComplexColor::FromColor(ruleColor);
skipSides |= mozilla::eSideBitsTopBottom;
skipSides |= mozilla::eSideBitsRight;
}

View File

@ -1265,9 +1265,7 @@ struct nsRecessedBorder : public nsStyleBorder {
: nsStyleBorder(aPresContext)
{
NS_FOR_CSS_SIDES(side) {
// Note: use SetBorderColor here because we want to make sure
// the "special" flags are unset.
SetBorderColor(side, NS_RGB(0, 0, 0));
mBorderColor[side] = StyleComplexColor::FromColor(NS_RGB(0, 0, 0));
mBorder.Side(side) = aBorderWidth;
// Note: use SetBorderStyle here because we want to affect
// mComputedBorder

View File

@ -3419,22 +3419,6 @@ StyleDataAtOffset(const void* aStyleStruct, ptrdiff_t aOffset)
reinterpret_cast<const uint8_t*>(aStyleStruct) + aOffset);
}
static void
ExtractBorderColor(nsStyleContext* aStyleContext, const void* aStyleBorder,
mozilla::css::Side aSide,
StyleAnimationValue& aComputedValue)
{
nscolor color;
bool foreground;
static_cast<const nsStyleBorder*>(aStyleBorder)->
GetBorderColor(aSide, color, foreground);
if (foreground) {
// FIXME: should add test for this
color = aStyleContext->StyleColor()->mColor;
}
aComputedValue.SetColorValue(color);
}
static bool
StyleCoordToValue(const nsStyleCoord& aCoord, StyleAnimationValue& aValue)
{
@ -3835,23 +3819,6 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
GetComputedColumnRuleWidth());
break;
case eCSSProperty_border_bottom_color:
ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_BOTTOM,
aComputedValue);
break;
case eCSSProperty_border_left_color:
ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_LEFT,
aComputedValue);
break;
case eCSSProperty_border_right_color:
ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_RIGHT,
aComputedValue);
break;
case eCSSProperty_border_top_color:
ExtractBorderColor(aStyleContext, styleStruct, NS_SIDE_TOP,
aComputedValue);
break;
case eCSSProperty_column_count: {
const nsStyleColumn *styleColumn =
static_cast<const nsStyleColumn*>(styleStruct);

View File

@ -790,8 +790,8 @@ CSS_PROP_BORDER(
"",
VARIANT_HCK,
kBorderColorKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
offsetof(nsStyleBorder, mBorderBottomColor),
eStyleAnimType_ComplexColor)
CSS_PROP_BORDER(
-moz-border-bottom-colors,
border_bottom_colors,
@ -1056,8 +1056,8 @@ CSS_PROP_BORDER(
"",
VARIANT_HCK,
kBorderColorKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
offsetof(nsStyleBorder, mBorderLeftColor),
eStyleAnimType_ComplexColor)
CSS_PROP_BORDER(
-moz-border-left-colors,
border_left_colors,
@ -1118,8 +1118,8 @@ CSS_PROP_BORDER(
"",
VARIANT_HCK,
kBorderColorKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
offsetof(nsStyleBorder, mBorderRightColor),
eStyleAnimType_ComplexColor)
CSS_PROP_BORDER(
-moz-border-right-colors,
border_right_colors,
@ -1192,8 +1192,8 @@ CSS_PROP_BORDER(
"",
VARIANT_HCK,
kBorderColorKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
offsetof(nsStyleBorder, mBorderTopColor),
eStyleAnimType_ComplexColor)
CSS_PROP_BORDER(
-moz-border-top-colors,
border_top_colors,

View File

@ -5271,15 +5271,7 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::GetBorderColorFor(mozilla::css::Side aSide)
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
nscolor color;
bool foreground;
StyleBorder()->GetBorderColor(aSide, color, foreground);
if (foreground) {
color = StyleColor()->mColor;
}
SetToRGBAColor(val, color);
SetValueFromComplexColor(val, StyleBorder()->mBorderColor[aSide]);
return val.forget();
}

View File

@ -7587,45 +7587,12 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
{
const nsCSSPropertyID* subprops =
nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color);
bool foreground;
NS_FOR_CSS_SIDES(side) {
const nsCSSValue& value = *aRuleData->ValueFor(subprops[side]);
if (eCSSUnit_Inherit == value.GetUnit()) {
conditions.SetUncacheable();
if (parentContext) {
parentBorder->GetBorderColor(side, borderColor, foreground);
if (foreground) {
// We want to inherit the color from the parent, not use the
// color on the element where this chunk of style data will be
// used. We can ensure that the data for the parent are fully
// computed (unlike for the element where this will be used, for
// which the color could be specified on a more specific rule).
border->SetBorderColor(side, parentContext->StyleColor()->mColor);
} else
border->SetBorderColor(side, borderColor);
} else {
// We're the root
border->SetBorderToForeground(side);
}
}
else if (SetColor(value, unused, mPresContext, aContext, borderColor,
conditions)) {
border->SetBorderColor(side, borderColor);
}
else if (eCSSUnit_Enumerated == value.GetUnit()) {
switch (value.GetIntValue()) {
case NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR:
border->SetBorderToForeground(side);
break;
default:
NS_NOTREACHED("Unexpected enumerated color");
break;
}
}
else if (eCSSUnit_Initial == value.GetUnit() ||
eCSSUnit_Unset == value.GetUnit()) {
border->SetBorderToForeground(side);
}
SetComplexColor<eUnsetInitial>(*aRuleData->ValueFor(subprops[side]),
parentBorder->mBorderColor[side],
StyleComplexColor::CurrentColor(),
mPresContext,
border->mBorderColor[side], conditions);
}
}

View File

@ -1175,14 +1175,8 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext,
const nsStyleBorder *thisVisBorder = thisVis->StyleBorder();
const nsStyleBorder *otherVisBorder = otherVis->StyleBorder();
NS_FOR_CSS_SIDES(side) {
bool thisFG, otherFG;
// Dummy initialisations to keep Valgrind/Memcheck happy.
// See bug 1122375 comment 4.
nscolor thisColor = NS_RGBA(0, 0, 0, 0);
nscolor otherColor = NS_RGBA(0, 0, 0, 0);
thisVisBorder->GetBorderColor(side, thisColor, thisFG);
otherVisBorder->GetBorderColor(side, otherColor, otherFG);
if (thisFG != otherFG || (!thisFG && thisColor != otherColor)) {
if (thisVisBorder->mBorderColor[side] !=
otherVisBorder->mBorderColor[side]) {
change = true;
break;
}

View File

@ -462,8 +462,8 @@ nsStyleBorder::nsStyleBorder(StyleStructContext aContext)
mBorderImageOutset.Set(side, nsStyleCoord(0.0f, eStyleUnit_Factor));
mBorder.Side(side) = medium;
mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
mBorderColor[side] = NS_RGB(0, 0, 0);
mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE;
mBorderColor[side] = StyleComplexColor::CurrentColor();
}
mTwipsPerPixel = aContext.DevPixelsToAppUnits(1);

View File

@ -882,10 +882,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
nscolor mBackgroundColor; // [reset]
};
#define BORDER_COLOR_FOREGROUND 0x20
#define BORDER_COLOR_SPECIAL BORDER_COLOR_FOREGROUND
#define BORDER_STYLE_MASK 0x1F
#define NS_SPACING_MARGIN 0
#define NS_SPACING_PADDING 1
#define NS_SPACING_BORDER 2
@ -1200,7 +1196,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
// HasVisibleStyle will be false even though there *is* a border.
bool HasVisibleStyle(mozilla::css::Side aSide) const
{
return IsVisibleBorderStyle(GetBorderStyle(aSide));
return IsVisibleBorderStyle(mBorderStyle[aSide]);
}
// aBorderWidth is in twips
@ -1239,14 +1235,13 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
uint8_t GetBorderStyle(mozilla::css::Side aSide) const
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
return mBorderStyle[aSide];
}
void SetBorderStyle(mozilla::css::Side aSide, uint8_t aStyle)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
mBorderStyle[aSide] = aStyle;
mComputedBorder.Side(aSide) =
(HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
}
@ -1256,27 +1251,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
return mBorderImageSource.IsLoaded();
}
void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
bool& aForeground) const
{
aForeground = false;
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0) {
aColor = mBorderColor[aSide];
} else if (mBorderStyle[aSide] & BORDER_COLOR_FOREGROUND) {
aForeground = true;
} else {
NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
}
}
void SetBorderColor(mozilla::css::Side aSide, nscolor aColor)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderColor[aSide] = aColor;
mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
}
void TrackImage(nsPresContext* aContext)
{
if (mBorderImageSource.GetType() == eStyleImageType_Image) {
@ -1314,14 +1288,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
}
last->mNext = colorEntry;
}
mBorderStyle[aIndex] &= ~BORDER_COLOR_SPECIAL;
}
void SetBorderToForeground(mozilla::css::Side aSide)
{
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
}
imgIRequest* GetBorderImageRequest() const
@ -1346,6 +1312,22 @@ public:
mozilla::StyleFloatEdge mFloatEdge; // [reset]
mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; // [reset]
protected:
uint8_t mBorderStyle[4]; // [reset] See nsStyleConsts.h
public:
// [reset] the colors to use for a simple border.
// not used for -moz-border-colors
union {
struct {
mozilla::StyleComplexColor mBorderTopColor;
mozilla::StyleComplexColor mBorderRightColor;
mozilla::StyleComplexColor mBorderBottomColor;
mozilla::StyleComplexColor mBorderLeftColor;
};
mozilla::StyleComplexColor mBorderColor[4];
};
protected:
// mComputedBorder holds the CSS2.1 computed border-width values.
// In particular, these widths take into account the border-style
@ -1368,15 +1350,25 @@ protected:
// value either. The values are rounded to the nearest device pixel.
nsMargin mBorder;
uint8_t mBorderStyle[4]; // [reset] See nsStyleConsts.h
nscolor mBorderColor[4]; // [reset] the colors to use for a simple
// border. not used for -moz-border-colors
private:
nscoord mTwipsPerPixel;
nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
};
#define ASSERT_BORDER_COLOR_FIELD(side_) \
static_assert(offsetof(nsStyleBorder, mBorder##side_##Color) == \
offsetof(nsStyleBorder, mBorderColor) + \
size_t(mozilla::eSide##side_) * \
sizeof(mozilla::StyleComplexColor), \
"mBorder" #side_ "Color must be at same offset " \
"as mBorderColor[mozilla::eSide" #side_ "]")
ASSERT_BORDER_COLOR_FIELD(Top);
ASSERT_BORDER_COLOR_FIELD(Right);
ASSERT_BORDER_COLOR_FIELD(Bottom);
ASSERT_BORDER_COLOR_FIELD(Left);
#undef ASSERT_BORDER_COLOR_FIELD
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
{

View File

@ -67,10 +67,6 @@ function cs(id) { return getComputedStyle($(id), ""); }
var got_one_root = false;
var got_one_target = false;
var got_one_target_bordertop = false;
var got_one_target_borderright = false;
var got_one_target_borderbottom = false;
var got_one_target_borderleft = false;
var got_two_target = false;
var got_three_top = false;
var got_three_right = false;
@ -144,41 +140,12 @@ document.documentElement.addEventListener("transitionend",
$("one").addEventListener("transitionend",
function(event) {
switch (event.propertyName) {
case "color":
ok(!got_one_target,
"transitionend on one on target (color)");
got_one_target = true;
event.stopPropagation();
break;
case "border-top-color":
ok(!got_one_target_bordertop,
"transitionend on one on target (border-top-color)");
got_one_target_bordertop = true;
event.stopPropagation();
break;
case "border-right-color":
ok(!got_one_target_borderright,
"transitionend on one on target (border-right-color)");
got_one_target_borderright = true;
// Let this event through to body
break;
case "border-bottom-color":
ok(!got_one_target_borderbottom,
"transitionend on one on target (border-bottom-color)");
got_one_target_borderbottom = true;
event.stopPropagation();
break;
case "border-left-color":
ok(!got_one_target_borderleft,
"transitionend on one on target (border-left-color)");
got_one_target_borderleft = true;
event.stopPropagation();
break;
default:
ok(false, "unexpected property name " + event.propertyName +
" for transitionend on one on target");
}
is(event.propertyName, "color", "unexpected " +
"property name for transitionend on one on target");
ok(!got_one_target,
"transitionend on one on target (color)");
got_one_target = true;
event.stopPropagation();
is(event.elapsedTime, 0.5,
"elapsedTime for transitionend on one");
is(cs("one").getPropertyValue(event.propertyName), "rgb(0, 255, 0)",
@ -187,11 +154,6 @@ $("one").addEventListener("transitionend",
}, false);
started_test(); // color on #one
started_test(); // border-top-color on #one
started_test(); // border-right-color on #one
started_test(); // border-right-color on #one (listener on root)
started_test(); // border-bottom-color on #one
started_test(); // border-left-color on #one
$("one").style.color = "lime";

View File

@ -109,25 +109,21 @@ var supported_properties = {
// intermediate form.
/* test_length_percent_pair_clamped */ ],
"border-bottom-color": [ test_color_transition,
test_currentcolor_transition,
test_border_color_transition ],
test_true_currentcolor_transition ],
"border-bottom-width": [ test_length_transition,
test_length_clamped ],
"border-left-color": [ test_color_transition,
test_currentcolor_transition,
test_border_color_transition ],
test_true_currentcolor_transition ],
"border-left-width": [ test_length_transition,
test_length_clamped ],
"border-right-color": [ test_color_transition,
test_currentcolor_transition,
test_border_color_transition ],
test_true_currentcolor_transition ],
"border-right-width": [ test_length_transition,
test_length_clamped ],
"border-spacing": [ test_length_pair_transition,
test_length_pair_transition_clamped ],
"border-top-color": [ test_color_transition,
test_currentcolor_transition,
test_border_color_transition ],
test_true_currentcolor_transition ],
"border-top-width": [ test_length_transition,
test_length_clamped ],
"bottom": [ test_length_transition, test_percent_transition,
@ -259,8 +255,7 @@ var supported_properties = {
"stroke-width": [ test_length_transition_svg, test_percent_transition,
test_length_clamped_svg, test_percent_clamped ],
"text-decoration": [ test_color_shorthand_transition,
test_currentcolor_shorthand_transition,
test_border_color_shorthand_transition ],
test_true_currentcolor_shorthand_transition ],
"text-decoration-color": [ test_color_transition,
test_true_currentcolor_transition ],
"text-emphasis-color": [ test_color_transition,
@ -1386,26 +1381,8 @@ function test_true_currentcolor_transition(prop, get_color=(x => x), is_shorthan
div.style.removeProperty("color");
}
function test_border_color_transition(prop, get_color=(x => x), is_shorthand=false) {
div.style.setProperty("transition-property", "none", "");
div.style.setProperty(prop, "rgb(128, 64, 0)", "");
div.style.setProperty("color", "rgb(0, 0, 128)", "");
is(get_color(cs.getPropertyValue(prop)), "rgb(128, 64, 0)",
"color-valued property " + prop + ": computed value before transition");
div.style.setProperty("transition-property", prop, "");
div.style.removeProperty(prop);
is(get_color(cs.getPropertyValue(prop)), "rgb(96, 48, 32)",
"color-valued property " + prop + ": interpolation of initial value");
if (!is_shorthand) {
check_distance(prop, "rgb(128, 64, 0)", "rgb(96, 48, 32)", "initial");
}
div.style.removeProperty("color");
}
function get_color_from_shorthand_value(value) {
var m = value.match(/rgb\([^, ]*, [^, ]*, [^, ]*\)/);
var m = value.match(/rgba?\([^, ]*, [^, ]*, [^, ]*(?:, [^, ]*)?\)/);
isnot(m, null, "shorthand property value should contain color");
return m[0];
}
@ -1418,8 +1395,8 @@ function test_currentcolor_shorthand_transition(prop) {
test_currentcolor_transition(prop, get_color_from_shorthand_value, true);
}
function test_border_color_shorthand_transition(prop) {
test_border_color_transition(prop, get_color_from_shorthand_value, true);
function test_true_currentcolor_shorthand_transition(prop) {
test_true_currentcolor_transition(prop, get_color_from_shorthand_value, true);
}
function test_clip_path_equals(computedValStr, expectedList)

View File

@ -3262,17 +3262,12 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
aRenderingContext.ThebesContext()->Save();
const nsStyleBorder* borderStyle = lineContext->StyleBorder();
nscolor color;
bool useForegroundColor;
borderStyle->GetBorderColor(NS_SIDE_LEFT, color, useForegroundColor);
if (useForegroundColor) {
// GetBorderColor didn't touch color, thus grab it from the treeline context
color = lineContext->StyleColor()->mColor;
}
// Resolve currentcolor values against the treeline context
nscolor color = lineContext->StyleColor()->
CalcComplexColor(borderStyle->mBorderLeftColor);
ColorPattern colorPatt(ToDeviceColor(color));
uint8_t style;
style = borderStyle->GetBorderStyle(NS_SIDE_LEFT);
uint8_t style = borderStyle->GetBorderStyle(NS_SIDE_LEFT);
StrokeOptions strokeOptions;
nsLayoutUtils::InitDashPattern(strokeOptions, style);