--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6642,23 +6642,34 @@ struct BackgroundItemComputer<nsCSSValue
"bad height type");
MOZ_ASSERT((size.mWidthType != nsStyleBackground::Size::eContain &&
size.mWidthType != nsStyleBackground::Size::eCover) ||
size.mWidthType == size.mHeightType,
"contain/cover apply to both dimensions or to neither");
}
};
-template <class ComputedValueItem>
+// A helper that facilitates access to a field that's directly on the
+// background layer.
+template <class ComputedValueItem,
+ ComputedValueItem nsStyleBackground::Layer::* LayerField>
+struct LayerFieldAcc
+{
+ static ComputedValueItem& Access(nsStyleBackground::Layer& aLayer)
+ { return aLayer.*LayerField; }
+ static const ComputedValueItem& Access(const nsStyleBackground::Layer& aLayer)
+ { return aLayer.*LayerField; }
+};
+
+template <class LayerPropAcc, class ComputedValueItem>
static void
SetBackgroundList(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
const nsAutoTArray<nsStyleBackground::Layer, 1> &aParentLayers,
- ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
ComputedValueItem aInitialValue,
uint32_t aParentItemCount,
uint32_t& aItemCount,
uint32_t& aMaxItemCount,
bool& aRebuild,
RuleNodeCacheConditions& aConditions)
{
switch (aValue.GetUnit()) {
@@ -6666,25 +6677,25 @@ SetBackgroundList(nsStyleContext* aStyle
break;
case eCSSUnit_Inherit:
aRebuild = true;
aConditions.SetUncacheable();
aLayers.EnsureLengthAtLeast(aParentItemCount);
aItemCount = aParentItemCount;
for (uint32_t i = 0; i < aParentItemCount; ++i) {
- aLayers[i].*aResultLocation = aParentLayers[i].*aResultLocation;
+ LayerPropAcc::Access(aLayers[i]) = LayerPropAcc::Access(aParentLayers[i]);
}
break;
case eCSSUnit_Initial:
case eCSSUnit_Unset:
aRebuild = true;
aItemCount = 1;
- aLayers[0].*aResultLocation = aInitialValue;
+ LayerPropAcc::Access(aLayers[0]) = aInitialValue;
break;
case eCSSUnit_List:
case eCSSUnit_ListDep: {
aRebuild = true;
aItemCount = 0;
const nsCSSValueList* item = aValue.GetListValue();
do {
@@ -6692,40 +6703,38 @@ SetBackgroundList(nsStyleContext* aStyle
item->mValue.GetUnit() != eCSSUnit_Inherit &&
item->mValue.GetUnit() != eCSSUnit_Initial &&
item->mValue.GetUnit() != eCSSUnit_Unset,
"unexpected unit");
++aItemCount;
aLayers.EnsureLengthAtLeast(aItemCount);
BackgroundItemComputer<nsCSSValueList, ComputedValueItem>
::ComputeValue(aStyleContext, item,
- aLayers[aItemCount-1].*aResultLocation,
+ LayerPropAcc::Access(aLayers[aItemCount-1]),
aConditions);
item = item->mNext;
} while (item);
break;
}
default:
MOZ_ASSERT(false, "unexpected unit");
}
if (aItemCount > aMaxItemCount)
aMaxItemCount = aItemCount;
}
-template <class ComputedValueItem>
+template <class LayerPropAcc, class ComputedValueItem>
static void
SetBackgroundPairList(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
const nsAutoTArray<nsStyleBackground::Layer, 1>
&aParentLayers,
- ComputedValueItem nsStyleBackground::Layer::*
- aResultLocation,
ComputedValueItem aInitialValue,
uint32_t aParentItemCount,
uint32_t& aItemCount,
uint32_t& aMaxItemCount,
bool& aRebuild,
RuleNodeCacheConditions& aConditions)
{
switch (aValue.GetUnit()) {
@@ -6733,25 +6742,26 @@ SetBackgroundPairList(nsStyleContext* aS
break;
case eCSSUnit_Inherit:
aRebuild = true;
aConditions.SetUncacheable();
aLayers.EnsureLengthAtLeast(aParentItemCount);
aItemCount = aParentItemCount;
for (uint32_t i = 0; i < aParentItemCount; ++i) {
- aLayers[i].*aResultLocation = aParentLayers[i].*aResultLocation;
+ LayerPropAcc::Access(aLayers[i]) =
+ LayerPropAcc::Access(aParentLayers[i]);
}
break;
case eCSSUnit_Initial:
case eCSSUnit_Unset:
aRebuild = true;
aItemCount = 1;
- aLayers[0].*aResultLocation = aInitialValue;
+ LayerPropAcc::Access(aLayers[0]) = aInitialValue;
break;
case eCSSUnit_PairList:
case eCSSUnit_PairListDep: {
aRebuild = true;
aItemCount = 0;
const nsCSSValuePairList* item = aValue.GetPairListValue();
do {
@@ -6761,43 +6771,42 @@ SetBackgroundPairList(nsStyleContext* aS
item->mYValue.GetUnit() != eCSSUnit_Inherit &&
item->mYValue.GetUnit() != eCSSUnit_Initial &&
item->mYValue.GetUnit() != eCSSUnit_Unset,
"unexpected unit");
++aItemCount;
aLayers.EnsureLengthAtLeast(aItemCount);
BackgroundItemComputer<nsCSSValuePairList, ComputedValueItem>
::ComputeValue(aStyleContext, item,
- aLayers[aItemCount-1].*aResultLocation,
+ LayerPropAcc::Access(aLayers[aItemCount-1]),
aConditions);
item = item->mNext;
} while (item);
break;
}
default:
MOZ_ASSERT(false, "unexpected unit");
}
if (aItemCount > aMaxItemCount)
aMaxItemCount = aItemCount;
}
-template <class ComputedValueItem>
+template <class LayerPropAcc>
static void
-FillBackgroundList(nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
- ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
- uint32_t aItemCount, uint32_t aFillCount)
+FillBackgroundList(nsAutoTArray<nsStyleBackground::Layer, 1> &aLayers,
+ uint32_t aItemCount, uint32_t aFillCount)
{
NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length");
for (uint32_t sourceLayer = 0, destLayer = aItemCount;
destLayer < aFillCount;
++sourceLayer, ++destLayer) {
- aLayers[destLayer].*aResultLocation =
- aLayers[sourceLayer].*aResultLocation;
+ LayerPropAcc::Access(aLayers[destLayer]) =
+ LayerPropAcc::Access(aLayers[sourceLayer]);
}
}
const void*
nsRuleNode::ComputeBackgroundData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
nsRuleNode* aHighestNode,
@@ -6818,106 +6827,122 @@ nsRuleNode::ComputeBackgroundData(void*
"unexpected color unit");
}
uint32_t maxItemCount = 1;
bool rebuild = false;
// background-image: url (stored as image), none, inherit [list]
nsStyleImage initialImage;
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundImage(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mImage,
+ SetBackgroundList<
+ LayerFieldAcc<nsStyleImage, &nsStyleBackground::Layer::mImage>
+ >(aContext, *aRuleData->ValueForBackgroundImage(),
+ bg->mLayers, parentBG->mLayers,
initialImage, parentBG->mImageCount, bg->mImageCount,
maxItemCount, rebuild, conditions);
// background-repeat: enum, inherit, initial [pair list]
nsStyleBackground::Repeat initialRepeat;
initialRepeat.SetInitialValues();
- SetBackgroundPairList(aContext, *aRuleData->ValueForBackgroundRepeat(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mRepeat,
+ SetBackgroundPairList<
+ LayerFieldAcc<nsStyleBackground::Repeat, &nsStyleBackground::Layer::mRepeat>
+ >(aContext, *aRuleData->ValueForBackgroundRepeat(),
+ bg->mLayers, parentBG->mLayers,
initialRepeat, parentBG->mRepeatCount,
bg->mRepeatCount, maxItemCount, rebuild,
conditions);
// background-attachment: enum, inherit, initial [list]
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundAttachment(),
+ SetBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mAttachment>
+ >(aContext, *aRuleData->ValueForBackgroundAttachment(),
bg->mLayers, parentBG->mLayers,
- &nsStyleBackground::Layer::mAttachment,
uint8_t(NS_STYLE_BG_ATTACHMENT_SCROLL),
parentBG->mAttachmentCount,
bg->mAttachmentCount, maxItemCount, rebuild,
conditions);
// background-clip: enum, inherit, initial [list]
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundClip(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mClip,
+ SetBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mClip>
+ >(aContext, *aRuleData->ValueForBackgroundClip(),
+ bg->mLayers, parentBG->mLayers,
uint8_t(NS_STYLE_BG_CLIP_BORDER), parentBG->mClipCount,
bg->mClipCount, maxItemCount, rebuild, conditions);
// background-blend-mode: enum, inherit, initial [list]
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundBlendMode(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mBlendMode,
+ SetBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mBlendMode>
+ >(aContext, *aRuleData->ValueForBackgroundBlendMode(),
+ bg->mLayers, parentBG->mLayers,
uint8_t(NS_STYLE_BLEND_NORMAL), parentBG->mBlendModeCount,
bg->mBlendModeCount, maxItemCount, rebuild,
conditions);
// background-origin: enum, inherit, initial [list]
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundOrigin(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mOrigin,
+ SetBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mOrigin>
+ >(aContext, *aRuleData->ValueForBackgroundOrigin(),
+ bg->mLayers, parentBG->mLayers,
uint8_t(NS_STYLE_BG_ORIGIN_PADDING), parentBG->mOriginCount,
bg->mOriginCount, maxItemCount, rebuild,
conditions);
- // background-position: enum, length, percent (flags), inherit [pair list]
+ // background-position: enum, length, percent (flags), inherit [list]
nsStyleBackground::Position initialPosition;
initialPosition.SetInitialPercentValues(0.0f);
- SetBackgroundList(aContext, *aRuleData->ValueForBackgroundPosition(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mPosition,
+ SetBackgroundList<
+ LayerFieldAcc<nsStyleBackground::Position, &nsStyleBackground::Layer::mPosition>
+ >(aContext, *aRuleData->ValueForBackgroundPosition(),
+ bg->mLayers, parentBG->mLayers,
initialPosition, parentBG->mPositionCount,
bg->mPositionCount, maxItemCount, rebuild,
conditions);
// background-size: enum, length, auto, inherit, initial [pair list]
nsStyleBackground::Size initialSize;
initialSize.SetInitialValues();
- SetBackgroundPairList(aContext, *aRuleData->ValueForBackgroundSize(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mSize,
+ SetBackgroundPairList<
+ LayerFieldAcc<nsStyleBackground::Size, &nsStyleBackground::Layer::mSize>
+ >(aContext, *aRuleData->ValueForBackgroundSize(),
+ bg->mLayers, parentBG->mLayers,
initialSize, parentBG->mSizeCount,
bg->mSizeCount, maxItemCount, rebuild,
conditions);
if (rebuild) {
// Delete any extra items. We need to keep layers in which any
// property was specified.
bg->mLayers.TruncateLength(maxItemCount);
uint32_t fillCount = bg->mImageCount;
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mImage,
- bg->mImageCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mRepeat,
- bg->mRepeatCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mAttachment,
- bg->mAttachmentCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mClip,
- bg->mClipCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mBlendMode,
- bg->mBlendModeCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mOrigin,
- bg->mOriginCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mPosition,
- bg->mPositionCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mSize,
- bg->mSizeCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<nsStyleImage, &nsStyleBackground::Layer::mImage>
+ >(bg->mLayers, bg->mImageCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<nsStyleBackground::Repeat, &nsStyleBackground::Layer::mRepeat>
+ >(bg->mLayers, bg->mRepeatCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mAttachment>
+ >(bg->mLayers, bg->mAttachmentCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mClip>
+ >(bg->mLayers, bg->mClipCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mBlendMode>
+ >(bg->mLayers, bg->mBlendModeCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<uint8_t, &nsStyleBackground::Layer::mOrigin>
+ >(bg->mLayers, bg->mOriginCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<nsStyleBackground::Position, &nsStyleBackground::Layer::mPosition>
+ >(bg->mLayers, bg->mPositionCount, fillCount);
+ FillBackgroundList<
+ LayerFieldAcc<nsStyleBackground::Size, &nsStyleBackground::Layer::mSize>
+ >(bg->mLayers, bg->mSizeCount, fillCount);
}
// Now that the dust has settled, register the images with the document
for (uint32_t i = 0; i < bg->mImageCount; ++i)
bg->mLayers[i].TrackImages(aContext->PresContext());
COMPUTE_END_RESET(Background, bg)
}