diff --git a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
index 3ccc399937d3..5129abe007ec 100644
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -237,8 +237,6 @@ function treatAsSafeArgument(entry, varName, csuName)
["Gecko_CounterStyle_GetName", "aResult", null],
["Gecko_CounterStyle_GetSingleString", "aResult", null],
["Gecko_EnsureMozBorderColors", "aBorder", null],
- ["Gecko_ClearMozBorderColors", "aBorder", null],
- ["Gecko_AppendMozBorderColors", "aBorder", null],
["Gecko_CopyMozBorderColors", "aDest", null],
];
for (var [entryMatch, varMatch, csuMatch] of whitelist) {
@@ -470,9 +468,6 @@ function ignoreContents(entry)
// Unable to trace through dataflow, but straightforward if inspected.
"Gecko_NewNoneTransform",
- // Bug 1400438
- "Gecko_AppendMozBorderColors",
-
// Need main thread assertions or other fixes.
/EffectCompositor::GetServoAnimationRule/,
/LookAndFeel::GetColor/,
diff --git a/layout/base/crashtests/1400438-1.html b/layout/base/crashtests/1400438-1.html
new file mode 100644
index 000000000000..366e1104ff1f
--- /dev/null
+++ b/layout/base/crashtests/1400438-1.html
@@ -0,0 +1,9 @@
+
+
+
diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list
index 7da960f9ccf2..913becbd2b6b 100644
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -501,4 +501,5 @@ load 1397398-1.html
load 1397398-2.html
load 1397398-3.html
load 1398500.html
+load 1400438-1.html
load 1400599-1.html
diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp
index 7f67bab1ef8c..21d5b21e7404 100644
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -761,13 +761,11 @@ ConstructBorderRenderer(nsPresContext* aPresContext,
uint8_t borderStyles[4];
nscolor borderColors[4];
- nsBorderColors* compositeColors[4];
- // pull out styles, colors, composite colors
+ // pull out styles, colors
NS_FOR_CSS_SIDES (i) {
borderStyles[i] = aStyleBorder.GetBorderStyle(i);
borderColors[i] = ourColor->CalcComplexColor(aStyleBorder.mBorderColor[i]);
- aStyleBorder.GetCompositeColors(i, &compositeColors[i]);
}
PrintAsFormatString(" borderStyles: %d %d %d %d\n", borderStyles[0], borderStyles[1], borderStyles[2], borderStyles[3]);
@@ -787,7 +785,7 @@ ConstructBorderRenderer(nsPresContext* aPresContext,
borderWidths,
bgRadii,
borderColors,
- compositeColors,
+ aStyleBorder.mBorderColors.get(),
bgColor);
}
diff --git a/layout/painting/nsCSSRenderingBorders.cpp b/layout/painting/nsCSSRenderingBorders.cpp
index dc34e655155d..d86f8db79418 100644
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -90,9 +90,6 @@ static Color ComputeColorForLine(uint32_t aLineIndex,
nscolor aBorderColor,
nscolor aBackgroundColor);
-static Color ComputeCompositeColorForLine(uint32_t aLineIndex,
- const nsBorderColors* aBorderColors);
-
// little helper function to check if the array of 4 floats given are
// equal to the given value
static bool
@@ -178,7 +175,7 @@ nsCSSBorderRenderer::nsCSSBorderRenderer(nsPresContext* aPresContext,
const Float* aBorderWidths,
RectCornerRadii& aBorderRadii,
const nscolor* aBorderColors,
- nsBorderColors* const* aCompositeColors,
+ const nsBorderColors* aCompositeColors,
nscolor aBackgroundColor)
: mPresContext(aPresContext),
mDocument(aDocument),
@@ -191,11 +188,12 @@ nsCSSBorderRenderer::nsCSSBorderRenderer(nsPresContext* aPresContext,
PodCopy(mBorderStyles, aBorderStyles, 4);
PodCopy(mBorderWidths, aBorderWidths, 4);
PodCopy(mBorderColors, aBorderColors, 4);
- if (aCompositeColors) {
- PodCopy(mCompositeColors, aCompositeColors, 4);
- } else {
- static nsBorderColors * const noColors[4] = { nullptr };
- PodCopy(mCompositeColors, noColors, 4);
+ NS_FOR_CSS_SIDES(side) {
+ if (aCompositeColors && !(*aCompositeColors)[side].IsEmpty()) {
+ mCompositeColors[side] = &(*aCompositeColors)[side];
+ } else {
+ mCompositeColors[side] = nullptr;
+ }
}
mInnerRect = mOuterRect;
@@ -319,9 +317,11 @@ nsCSSBorderRenderer::AreBorderSideFinalStylesSame(uint8_t aSides)
if (mBorderStyles[firstStyle] != mBorderStyles[i] ||
mBorderColors[firstStyle] != mBorderColors[i] ||
- !nsBorderColors::Equal(mCompositeColors[firstStyle],
- mCompositeColors[i]))
+ !mCompositeColors[firstStyle] != !mCompositeColors[i] ||
+ (mCompositeColors[firstStyle] &&
+ *mCompositeColors[firstStyle] != *mCompositeColors[i])) {
return false;
+ }
}
/* Then if it's one of the two-tone styles and we're not
@@ -1265,18 +1265,9 @@ ComputeColorForLine(uint32_t aLineIndex,
aBorderColorStyle[aLineIndex]);
}
-Color
-ComputeCompositeColorForLine(uint32_t aLineIndex,
- const nsBorderColors* aBorderColors)
-{
- while (aLineIndex-- && aBorderColors->mNext)
- aBorderColors = aBorderColors->mNext;
-
- return Color::FromABGR(aBorderColors->mColor);
-}
-
void
-nsCSSBorderRenderer::DrawBorderSidesCompositeColors(int aSides, const nsBorderColors *aCompositeColors)
+nsCSSBorderRenderer::DrawBorderSidesCompositeColors(
+ int aSides, const nsTArray& aCompositeColors)
{
RectCornerRadii radii = mBorderRadii;
@@ -1292,9 +1283,14 @@ nsCSSBorderRenderer::DrawBorderSidesCompositeColors(int aSides, const nsBorderCo
Point itl = mInnerRect.TopLeft();
Point ibr = mInnerRect.BottomRight();
+ MOZ_ASSERT(!aCompositeColors.IsEmpty());
+ Color compositeColor;
for (uint32_t i = 0; i < uint32_t(maxBorderWidth); i++) {
- ColorPattern color(ToDeviceColor(
- ComputeCompositeColorForLine(i, aCompositeColors)));
+ // advance to next color if exists.
+ if (i < aCompositeColors.Length()) {
+ compositeColor = ToDeviceColor(Color::FromABGR(aCompositeColors[i]));
+ }
+ ColorPattern color(compositeColor);
Rect siRect = soRect;
siRect.Deflate(1.0);
@@ -1334,7 +1330,7 @@ nsCSSBorderRenderer::DrawBorderSides(int aSides)
uint8_t borderRenderStyle = NS_STYLE_BORDER_STYLE_NONE;
nscolor borderRenderColor;
- const nsBorderColors *compositeColors = nullptr;
+ const nsTArray* compositeColors = nullptr;
uint32_t borderColorStyleCount = 0;
BorderColorStyle borderColorStyleTopLeft[3], borderColorStyleBottomRight[3];
@@ -1392,7 +1388,7 @@ nsCSSBorderRenderer::DrawBorderSides(int aSides)
maxBorderWidth = std::max(maxBorderWidth, mBorderWidths[i]);
}
if (maxBorderWidth <= MAX_COMPOSITE_BORDER_WIDTH) {
- DrawBorderSidesCompositeColors(aSides, compositeColors);
+ DrawBorderSidesCompositeColors(aSides, *compositeColors);
return;
}
NS_WARNING("DrawBorderSides: too large border width for composite colors");
@@ -3145,8 +3141,10 @@ nsCSSBorderRenderer::DrawNoCompositeColorSolidBorder()
void
nsCSSBorderRenderer::DrawRectangularCompositeColors()
{
- nsBorderColors *currentColors[4];
- memcpy(currentColors, mCompositeColors, sizeof(nsBorderColors*) * 4);
+ nscolor currentColors[4];
+ NS_FOR_CSS_SIDES(side) {
+ currentColors[side] = mBorderColors[side];
+ }
Rect rect = mOuterRect;
rect.Deflate(0.5);
@@ -3156,23 +3154,26 @@ nsCSSBorderRenderer::DrawRectangularCompositeColors()
{ 0, -0.5 } };
for (int i = 0; i < mBorderWidths[0]; i++) {
+ NS_FOR_CSS_SIDES(side) {
+ // advance to the next composite color if one exists
+ if (mCompositeColors[side] &&
+ uint32_t(i) < mCompositeColors[side]->Length()) {
+ currentColors[side] = (*mCompositeColors[side])[i];
+ }
+ }
NS_FOR_CSS_SIDES(side) {
int sideNext = (side + 1) % 4;
Point firstCorner = rect.CCWCorner(side) + cornerAdjusts[side];
Point secondCorner = rect.CWCorner(side) - cornerAdjusts[side];
- Color currentColor = Color::FromABGR(
- currentColors[side] ? currentColors[side]->mColor
- : mBorderColors[side]);
+ Color currentColor = Color::FromABGR(currentColors[side]);
mDrawTarget->StrokeLine(firstCorner, secondCorner,
ColorPattern(ToDeviceColor(currentColor)));
Point cornerTopLeft = rect.CWCorner(side) - Point(0.5, 0.5);
- Color nextColor = Color::FromABGR(
- currentColors[sideNext] ? currentColors[sideNext]->mColor
- : mBorderColors[sideNext]);
+ Color nextColor = Color::FromABGR(currentColors[sideNext]);
Color cornerColor((currentColor.r + nextColor.r) / 2.f,
(currentColor.g + nextColor.g) / 2.f,
@@ -3180,17 +3181,6 @@ nsCSSBorderRenderer::DrawRectangularCompositeColors()
(currentColor.a + nextColor.a) / 2.f);
mDrawTarget->FillRect(Rect(cornerTopLeft, Size(1, 1)),
ColorPattern(ToDeviceColor(cornerColor)));
-
- if (side != 0) {
- // We'll have to keep side 0 for the color averaging on side 3.
- if (currentColors[side] && currentColors[side]->mNext) {
- currentColors[side] = currentColors[side]->mNext;
- }
- }
- }
- // Now advance the color for side 0.
- if (currentColors[0] && currentColors[0]->mNext) {
- currentColors[0] = currentColors[0]->mNext;
}
rect.Deflate(1);
}
@@ -3206,9 +3196,8 @@ nsCSSBorderRenderer::DrawBorders()
(mBorderStyles[0] == NS_STYLE_BORDER_STYLE_NONE ||
mBorderStyles[0] == NS_STYLE_BORDER_STYLE_HIDDEN ||
mBorderColors[0] == NS_RGBA(0,0,0,0))) ||
- (mCompositeColors[0] &&
- (mCompositeColors[0]->mColor == NS_RGBA(0,0,0,0) &&
- !mCompositeColors[0]->mNext))))
+ (mCompositeColors[0] && mCompositeColors[0]->Length() == 1 &&
+ (*mCompositeColors[0])[0] == NS_RGBA(0,0,0,0))))
{
// All borders are the same style, and the style is either none or hidden, or the color
// is transparent.
diff --git a/layout/painting/nsCSSRenderingBorders.h b/layout/painting/nsCSSRenderingBorders.h
index 499471861ec7..0c697447ffe4 100644
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -100,7 +100,7 @@ public:
const Float* aBorderWidths,
RectCornerRadii& aBorderRadii,
const nscolor* aBorderColors,
- nsBorderColors* const* aCompositeColors,
+ const nsBorderColors* aCompositeColors,
nscolor aBackgroundColor);
// draw the entire border
@@ -151,7 +151,9 @@ private:
nscolor mBorderColors[4];
// the lists of colors for '-moz-border-top-colors' et. al.
- nsBorderColors* mCompositeColors[4];
+ // the pointers here are either nullptr, or referring to a non-empty
+ // nsTArray, so no additional empty check is needed.
+ const nsTArray* mCompositeColors[4];
// the background color
nscolor mBackgroundColor;
@@ -235,7 +237,8 @@ private:
void DrawBorderSides (int aSides);
// function used by the above to handle -moz-border-colors
- void DrawBorderSidesCompositeColors(int aSides, const nsBorderColors *compositeColors);
+ void DrawBorderSidesCompositeColors(
+ int aSides, const nsTArray& compositeColors);
// Setup the stroke options for the given dashed/dotted side
void SetupDashedOptions(StrokeOptions* aStrokeOptions,
diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp
index c49f101f1e97..0b6c441360ac 100644
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1256,34 +1256,18 @@ Gecko_EnsureMozBorderColors(nsStyleBorder* aBorder)
aBorder->EnsureBorderColors();
}
-void Gecko_ClearMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide)
-{
- aBorder->ClearBorderColors(aSide);
-}
-
-void
-Gecko_AppendMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide,
- nscolor aColor)
-{
- aBorder->AppendBorderColor(aSide, aColor);
-}
-
void
Gecko_CopyMozBorderColors(nsStyleBorder* aDest, const nsStyleBorder* aSrc,
mozilla::Side aSide)
{
if (aSrc->mBorderColors) {
- aDest->CopyBorderColorsFrom(aSrc->mBorderColors[aSide], aSide);
+ aDest->EnsureBorderColors();
+ aDest->mBorderColors->mColors[aSide] = aSrc->mBorderColors->mColors[aSide];
+ } else {
+ aDest->ClearBorderColors(aSide);
}
}
-const nsBorderColors*
-Gecko_GetMozBorderColors(const nsStyleBorder* aBorder, mozilla::Side aSide)
-{
- MOZ_ASSERT(aBorder);
- return aBorder->mBorderColors ? aBorder->mBorderColors[aSide] : nullptr;
-}
-
void
Gecko_FontFamilyList_Clear(FontFamilyList* aList) {
aList->Clear();
diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h
index c42e44be0392..1833efa252ae 100644
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -282,13 +282,8 @@ bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_
// Border style
void Gecko_EnsureMozBorderColors(nsStyleBorder* aBorder);
-void Gecko_ClearMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide);
-void Gecko_AppendMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide,
- nscolor aColor);
void Gecko_CopyMozBorderColors(nsStyleBorder* aDest, const nsStyleBorder* aSrc,
mozilla::Side aSide);
-const nsBorderColors* Gecko_GetMozBorderColors(const nsStyleBorder* aBorder,
- mozilla::Side aSide);
// Font style
void Gecko_FontFamilyList_Clear(FontFamilyList* aList);
diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml
index 9f0e5a424707..fc12bde960b7 100644
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -190,7 +190,6 @@ whitelist-types = [
"Keyframe",
"nsAttrName",
"nsAttrValue",
- "nsBorderColors",
"nscolor",
"nsChangeHint",
"nsCSSCounterDesc",
@@ -443,7 +442,6 @@ structs-types = [
"StyleShapeSource",
"StyleTransition",
"gfxFontFeatureValueSet",
- "nsBorderColors",
"nsCSSCounterStyleRule",
"nsCSSFontFaceRule",
"nsCSSKeyword",
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index c19026f68d36..062e00ffebc5 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5490,19 +5490,14 @@ nsComputedDOMStyle::GetBorderColorsFor(mozilla::Side aSide)
const nsStyleBorder *border = StyleBorder();
if (border->mBorderColors) {
- nsBorderColors* borderColors = border->mBorderColors[aSide];
- if (borderColors) {
+ const nsTArray& borderColors = (*border->mBorderColors)[aSide];
+ if (!borderColors.IsEmpty()) {
RefPtr valueList = GetROCSSValueList(false);
-
- do {
+ for (nscolor color : borderColors) {
RefPtr primitive = new nsROCSSPrimitiveValue;
-
- SetToRGBAColor(primitive, borderColors->mColor);
-
+ SetToRGBAColor(primitive, color);
valueList->AppendCSSValue(primitive.forget());
- borderColors = borderColors->mNext;
- } while (borderColors);
-
+ }
return valueList.forget();
}
}
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 0a6efb602c04..ccccce98009e 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7748,13 +7748,10 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
case eCSSUnit_Inherit: {
conditions.SetUncacheable();
border->ClearBorderColors(side);
- if (parentContext) {
- nsBorderColors *parentColors;
- parentBorder->GetCompositeColors(side, &parentColors);
- if (parentColors) {
- border->EnsureBorderColors();
- border->mBorderColors[side] = parentColors->Clone();
- }
+ if (parentBorder->mBorderColors) {
+ border->EnsureBorderColors();
+ border->mBorderColors->mColors[side] =
+ parentBorder->mBorderColors->mColors[side];
}
break;
}
@@ -7769,7 +7766,7 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
while (list) {
if (SetColor(list->mValue, unused, mPresContext,
aContext, borderColor, conditions))
- border->AppendBorderColor(side, borderColor);
+ border->mBorderColors->mColors[side].AppendElement(borderColor);
else {
NS_NOTREACHED("unexpected item in -moz-border-*-colors list");
}
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index 87b60b23db67..1c8b9a596340 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -320,8 +320,7 @@ nsStylePadding::CalcDifference(const nsStylePadding& aNewData) const
}
nsStyleBorder::nsStyleBorder(const nsPresContext* aContext)
- : mBorderColors(nullptr)
- , mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL)
+ : mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL)
, mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH)
, mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH)
, mFloatEdge(StyleFloatEdge::ContentBox)
@@ -349,27 +348,8 @@ nsStyleBorder::nsStyleBorder(const nsPresContext* aContext)
mTwipsPerPixel = aContext->DevPixelsToAppUnits(1);
}
-nsBorderColors::~nsBorderColors()
-{
- NS_CSS_DELETE_LIST_MEMBER(nsBorderColors, this, mNext);
-}
-
-nsBorderColors*
-nsBorderColors::Clone(bool aDeep) const
-{
- nsBorderColors* result = new nsBorderColors(mColor);
- if (MOZ_UNLIKELY(!result)) {
- return result;
- }
- if (aDeep) {
- NS_CSS_CLONE_LIST_MEMBER(nsBorderColors, this, mNext, result, (false));
- }
- return result;
-}
-
nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
- : mBorderColors(nullptr)
- , mBorderRadius(aSrc.mBorderRadius)
+ : mBorderRadius(aSrc.mBorderRadius)
, mBorderImageSource(aSrc.mBorderImageSource)
, mBorderImageSlice(aSrc.mBorderImageSlice)
, mBorderImageWidth(aSrc.mBorderImageWidth)
@@ -385,9 +365,7 @@ nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
{
MOZ_COUNT_CTOR(nsStyleBorder);
if (aSrc.mBorderColors) {
- NS_FOR_CSS_SIDES(side) {
- CopyBorderColorsFrom(aSrc.mBorderColors[side], side);
- }
+ mBorderColors.reset(new nsBorderColors(*aSrc.mBorderColors));
}
NS_FOR_CSS_SIDES(side) {
@@ -399,12 +377,6 @@ nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
nsStyleBorder::~nsStyleBorder()
{
MOZ_COUNT_DTOR(nsStyleBorder);
- if (mBorderColors) {
- for (int32_t i = 0; i < 4; i++) {
- delete mBorderColors[i];
- }
- delete [] mBorderColors;
- }
}
void
@@ -516,9 +488,8 @@ nsStyleBorder::CalcDifference(const nsStyleBorder& aNewData) const
// Note that at this point if mBorderColors is non-null so is
// aNewData.mBorderColors
if (mBorderColors) {
- NS_FOR_CSS_SIDES(ix) {
- if (!nsBorderColors::Equal(mBorderColors[ix],
- aNewData.mBorderColors[ix])) {
+ NS_FOR_CSS_SIDES(side) {
+ if ((*mBorderColors)[side] != (*aNewData.mBorderColors)[side]) {
return nsChangeHint_RepaintFrame;
}
}
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 12da571c31f7..7498b1214c6d 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -984,38 +984,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding
}
};
-struct nsBorderColors
-{
- nsBorderColors* mNext;
- nscolor mColor;
-
- nsBorderColors() : mNext(nullptr), mColor(NS_RGB(0,0,0)) {}
- explicit nsBorderColors(const nscolor& aColor) : mNext(nullptr), mColor(aColor) {}
- ~nsBorderColors();
-
- nsBorderColors* Clone() const { return Clone(true); }
-
- static bool Equal(const nsBorderColors* c1,
- const nsBorderColors* c2) {
- if (c1 == c2) {
- return true;
- }
- while (c1 && c2) {
- if (c1->mColor != c2->mColor) {
- return false;
- }
- c1 = c1->mNext;
- c2 = c2->mNext;
- }
- // both should be nullptr if these are equal, otherwise one
- // has more colors than another
- return !c1 && !c2;
- }
-
-private:
- nsBorderColors* Clone(bool aDeep) const;
-};
-
struct nsCSSShadowItem
{
nscoord mXOffset;
@@ -1142,6 +1110,26 @@ static bool IsVisibleBorderStyle(uint8_t aStyle)
aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
}
+struct nsBorderColors
+{
+ nsBorderColors() = default;
+
+ // GCC cannot generate this copy constructor correctly, since nsTArray
+ // has explicit copy constructor, and we use array of nsTArray here.
+ // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82235
+ nsBorderColors(const nsBorderColors& aOther) {
+ NS_FOR_CSS_SIDES(side) {
+ mColors[side] = aOther.mColors[side];
+ }
+ }
+
+ const nsTArray& operator[](mozilla::Side aSide) const {
+ return mColors[aSide];
+ }
+
+ nsTArray mColors[4];
+};
+
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
{
explicit nsStyleBorder(const nsPresContext* aContext);
@@ -1165,27 +1153,13 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
void EnsureBorderColors() {
if (!mBorderColors) {
- mBorderColors = new nsBorderColors*[4];
- if (mBorderColors) {
- for (int32_t i = 0; i < 4; i++) {
- mBorderColors[i] = nullptr;
- }
- }
+ mBorderColors.reset(new nsBorderColors);
}
}
void ClearBorderColors(mozilla::Side aSide) {
- if (mBorderColors && mBorderColors[aSide]) {
- delete mBorderColors[aSide];
- mBorderColors[aSide] = nullptr;
- }
- }
-
- void CopyBorderColorsFrom(const nsBorderColors* aSrcBorderColors, mozilla::Side aSide) {
- if (aSrcBorderColors) {
- EnsureBorderColors();
- ClearBorderColors(aSide);
- mBorderColors[aSide] = aSrcBorderColors->Clone();
+ if (mBorderColors) {
+ mBorderColors->mColors[aSide].Clear();
}
}
@@ -1260,30 +1234,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
nsMargin GetImageOutset() const;
- void GetCompositeColors(int32_t aIndex, nsBorderColors** aColors) const
- {
- if (!mBorderColors) {
- *aColors = nullptr;
- } else {
- *aColors = mBorderColors[aIndex];
- }
- }
-
- void AppendBorderColor(int32_t aIndex, nscolor aColor)
- {
- NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
- nsBorderColors* colorEntry = new nsBorderColors(aColor);
- if (!mBorderColors[aIndex]) {
- mBorderColors[aIndex] = colorEntry;
- } else {
- nsBorderColors* last = mBorderColors[aIndex];
- while (last->mNext) {
- last = last->mNext;
- }
- last->mNext = colorEntry;
- }
- }
-
imgIRequest* GetBorderImageRequest() const
{
if (mBorderImageSource.GetType() == eStyleImageType_Image) {
@@ -1293,7 +1243,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
}
public:
- nsBorderColors** mBorderColors; // [reset] composite (stripe) colors
+ // [reset] composite (stripe) colors
+ mozilla::UniquePtr mBorderColors;
nsStyleCorners mBorderRadius; // [reset] coord, percent
nsStyleImage mBorderImageSource; // [reset]
nsStyleSides mBorderImageSlice; // [reset] factor, percent