Bug 686281 - Implement CSS mask animation; r?:dbaron
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -842,17 +842,17 @@ nsFrame::DidSetStyleContext(nsStyleConte
// calls GetUsed(Margin|Border|Padding)() before the next reflow, we
// can give an accurate answer.
// We don't want to set the property if one already exists.
FrameProperties props = Properties();
nsMargin oldValue(0, 0, 0, 0);
nsMargin newValue(0, 0, 0, 0);
const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin();
if (oldMargin && oldMargin->GetMargin(oldValue)) {
- if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
+ if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
!props.Get(UsedMarginProperty())) {
props.Set(UsedMarginProperty(), new nsMargin(oldValue));
}
}
const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding();
if (oldPadding && oldPadding->GetPadding(oldValue)) {
if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) &&
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2973,16 +2973,104 @@ SubstitutePixelValues(nsStyleContext* aS
conditions);
aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len),
eCSSUnit_Pixel);
} else {
aOutput = aInput;
}
}
+static void
+ExtractStyleLayerPosition(const nsStyleImageLayers &layers,
+ StyleAnimationValue& aComputedValue)
+{
+ nsAutoPtr<nsCSSValueList> result;
+ nsCSSValueList **resultTail = getter_Transfers(result);
+ for (uint32_t i = 0, i_end = layers.mPositionCount; i != i_end; ++i) {
+ nsCSSValueList *item = new nsCSSValueList;
+ *resultTail = item;
+ resultTail = &item->mNext;
+ SetPositionValue(layers.mLayers[i].mPosition, item->mValue);
+ }
+
+ aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
+ StyleAnimationValue::eUnit_BackgroundPosition);
+}
+
+static void
+ExtractStyleLayerSize(const nsStyleImageLayers &layers,
+ StyleAnimationValue& aComputedValue)
+{
+ nsAutoPtr<nsCSSValuePairList> result;
+ nsCSSValuePairList **resultTail = getter_Transfers(result);
+ for (uint32_t i = 0, i_end = layers.mSizeCount; i != i_end; ++i) {
+ nsCSSValuePairList *item = new nsCSSValuePairList;
+ *resultTail = item;
+ resultTail = &item->mNext;
+
+ const nsStyleImageLayers::Size &size = layers.mLayers[i].mSize;
+ switch (size.mWidthType) {
+ case nsStyleImageLayers::Size::eContain:
+ case nsStyleImageLayers::Size::eCover:
+ item->mXValue.SetIntValue(size.mWidthType,
+ eCSSUnit_Enumerated);
+ break;
+ case nsStyleImageLayers::Size::eAuto:
+ item->mXValue.SetAutoValue();
+ break;
+ case nsStyleImageLayers::Size::eLengthPercentage:
+ // XXXbz is there a good reason we can't just
+ // SetCalcValue(&size.mWidth, item->mXValue) here?
+ if (!size.mWidth.mHasPercent &&
+ // negative values must have come from calc()
+ size.mWidth.mLength >= 0) {
+ MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
+ "Shouldn't have mPercent");
+ nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
+ } else if (size.mWidth.mLength == 0 &&
+ // negative values must have come from calc()
+ size.mWidth.mPercent >= 0.0f) {
+ item->mXValue.SetPercentValue(size.mWidth.mPercent);
+ } else {
+ SetCalcValue(&size.mWidth, item->mXValue);
+ }
+ break;
+ }
+
+ switch (size.mHeightType) {
+ case nsStyleImageLayers::Size::eContain:
+ case nsStyleImageLayers::Size::eCover:
+ // leave it null
+ break;
+ case nsStyleImageLayers::Size::eAuto:
+ item->mYValue.SetAutoValue();
+ break;
+ case nsStyleImageLayers::Size::eLengthPercentage:
+ // XXXbz is there a good reason we can't just
+ // SetCalcValue(&size.mHeight, item->mYValue) here?
+ if (!size.mHeight.mHasPercent &&
+ // negative values must have come from calc()
+ size.mHeight.mLength >= 0) {
+ MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
+ "Shouldn't have mPercent");
+ nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
+ } else if (size.mHeight.mLength == 0 &&
+ // negative values must have come from calc()
+ size.mHeight.mPercent >= 0.0f) {
+ item->mYValue.SetPercentValue(size.mHeight.mPercent);
+ } else {
+ SetCalcValue(&size.mHeight, item->mYValue);
+ }
+ break;
+ }
+ }
+
+ aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
+}
+
bool
StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
nsStyleContext* aStyleContext,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
"bad property");
const void* styleStruct =
@@ -3271,102 +3359,42 @@ StyleAnimationValue::ExtractComputedValu
SetPositionValue(stylePos->mObjectPosition, *val);
aComputedValue.SetAndAdoptCSSValueValue(val.forget(),
eUnit_ObjectPosition);
break;
}
case eCSSProperty_background_position: {
- const nsStyleBackground *bg =
- static_cast<const nsStyleBackground*>(styleStruct);
- nsAutoPtr<nsCSSValueList> result;
- nsCSSValueList **resultTail = getter_Transfers(result);
- MOZ_ASSERT(bg->mLayers.mPositionCount > 0, "unexpected count");
- for (uint32_t i = 0, i_end = bg->mLayers.mPositionCount; i != i_end; ++i) {
- nsCSSValueList *item = new nsCSSValueList;
- *resultTail = item;
- resultTail = &item->mNext;
- SetPositionValue(bg->mLayers.mLayers[i].mPosition, item->mValue);
- }
-
- aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
- eUnit_BackgroundPosition);
+ const nsStyleImageLayers &layers =
+ static_cast<const nsStyleBackground*>(styleStruct)->mLayers;
+ MOZ_ASSERT(layers.mPositionCount > 0, "unexpected count");
+ ExtractStyleLayerPosition(layers, aComputedValue);
+ break;
+ }
+
+ case eCSSProperty_mask_position: {
+ const nsStyleImageLayers &layers =
+ static_cast<const nsStyleSVGReset*>(styleStruct)->mLayers;
+ ExtractStyleLayerPosition(layers, aComputedValue);
break;
}
case eCSSProperty_background_size: {
- const nsStyleBackground *bg =
- static_cast<const nsStyleBackground*>(styleStruct);
- nsAutoPtr<nsCSSValuePairList> result;
- nsCSSValuePairList **resultTail = getter_Transfers(result);
- MOZ_ASSERT(bg->mLayers.mSizeCount > 0, "unexpected count");
- for (uint32_t i = 0, i_end = bg->mLayers.mSizeCount; i != i_end; ++i) {
- nsCSSValuePairList *item = new nsCSSValuePairList;
- *resultTail = item;
- resultTail = &item->mNext;
-
- const nsStyleImageLayers::Size &size = bg->mLayers.mLayers[i].mSize;
- switch (size.mWidthType) {
- case nsStyleImageLayers::Size::eContain:
- case nsStyleImageLayers::Size::eCover:
- item->mXValue.SetIntValue(size.mWidthType,
- eCSSUnit_Enumerated);
- break;
- case nsStyleImageLayers::Size::eAuto:
- item->mXValue.SetAutoValue();
- break;
- case nsStyleImageLayers::Size::eLengthPercentage:
- // XXXbz is there a good reason we can't just
- // SetCalcValue(&size.mWidth, item->mXValue) here?
- if (!size.mWidth.mHasPercent &&
- // negative values must have come from calc()
- size.mWidth.mLength >= 0) {
- MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
- "Shouldn't have mPercent");
- nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
- } else if (size.mWidth.mLength == 0 &&
- // negative values must have come from calc()
- size.mWidth.mPercent >= 0.0f) {
- item->mXValue.SetPercentValue(size.mWidth.mPercent);
- } else {
- SetCalcValue(&size.mWidth, item->mXValue);
- }
- break;
- }
-
- switch (size.mHeightType) {
- case nsStyleImageLayers::Size::eContain:
- case nsStyleImageLayers::Size::eCover:
- // leave it null
- break;
- case nsStyleImageLayers::Size::eAuto:
- item->mYValue.SetAutoValue();
- break;
- case nsStyleImageLayers::Size::eLengthPercentage:
- // XXXbz is there a good reason we can't just
- // SetCalcValue(&size.mHeight, item->mYValue) here?
- if (!size.mHeight.mHasPercent &&
- // negative values must have come from calc()
- size.mHeight.mLength >= 0) {
- MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
- "Shouldn't have mPercent");
- nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
- } else if (size.mHeight.mLength == 0 &&
- // negative values must have come from calc()
- size.mHeight.mPercent >= 0.0f) {
- item->mYValue.SetPercentValue(size.mHeight.mPercent);
- } else {
- SetCalcValue(&size.mHeight, item->mYValue);
- }
- break;
- }
- }
-
- aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
+ const nsStyleImageLayers &layers =
+ static_cast<const nsStyleBackground*>(styleStruct)->mLayers;
+ MOZ_ASSERT(layers.mSizeCount > 0, "unexpected count");
+ ExtractStyleLayerSize(layers, aComputedValue);
+ break;
+ }
+
+ case eCSSProperty_mask_size: {
+ const nsStyleImageLayers &layers =
+ static_cast<const nsStyleSVGReset*>(styleStruct)->mLayers;
+ ExtractStyleLayerSize(layers, aComputedValue);
break;
}
case eCSSProperty_filter: {
const nsStyleSVGReset *svgReset =
static_cast<const nsStyleSVGReset*>(styleStruct);
const nsTArray<nsStyleFilter>& filters = svgReset->mFilters;
nsAutoPtr<nsCSSValueList> result;
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -4062,30 +4062,30 @@ CSS_PROP_SVGRESET(
MaskPosition,
CSS_PROPERTY_PARSE_FUNCTION |
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
CSS_PROPERTY_STORES_CALC,
"layout.css.masking.enabled",
0,
kImageLayerPositionKTable,
CSS_PROP_NO_OFFSET,
- eStyleAnimType_None)
+ eStyleAnimType_Custom)
CSS_PROP_SVGRESET(
mask-size,
mask_size,
MaskSize,
CSS_PROPERTY_PARSE_FUNCTION |
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
CSS_PROPERTY_VALUE_NONNEGATIVE |
CSS_PROPERTY_STORES_CALC,
"layout.css.masking.enabled",
0,
kImageLayerSizeKTable,
CSS_PROP_NO_OFFSET,
- eStyleAnimType_None)
+ eStyleAnimType_Custom)
CSS_PROP_SVGRESET(
mask-type,
mask_type,
MaskType,
CSS_PROPERTY_PARSE_VALUE,
"layout.css.masking.enabled",
VARIANT_HK,
kMaskTypeKTable,