Bug 550426 - Add support for {background,mask}-position-{x,y}, StyleAnimation changes. r=dbaron

MozReview-Commit-ID: 8Qb0asWMgVA
***

--HG--
extra : rebase_source : 694f057c76a2632ed5b6280ddc84bd1cc34d3ecb
This commit is contained in:
Markus Stange 2016-04-21 20:23:35 -04:00
Родитель 10d8636821
Коммит de8b8de801
3 изменённых файлов: 138 добавлений и 23 удалений

Просмотреть файл

@ -449,6 +449,32 @@ CalcPositionSquareDistance(const nsCSSValue& aPos1,
return squareDistance;
}
static PixelCalcValue
CalcBackgroundCoord(const nsCSSValue& aCoord)
{
NS_ASSERTION(aCoord.GetUnit() == eCSSUnit_Array,
"Expected array");
nsCSSValue::Array* array = aCoord.GetArrayValue();
MOZ_ASSERT(array->Count() == 2 &&
array->Item(0).GetUnit() == eCSSUnit_Null &&
array->Item(1).GetUnit() != eCSSUnit_Null,
"Invalid position value");
return ExtractCalcValue(array->Item(1));
}
double
CalcPositionCoordSquareDistance(const nsCSSValue& aPos1,
const nsCSSValue& aPos2)
{
PixelCalcValue calcVal1 = CalcBackgroundCoord(aPos1);
PixelCalcValue calcVal2 = CalcBackgroundCoord(aPos2);
float difflen = calcVal2.mLength - calcVal1.mLength;
float diffpct = calcVal2.mPercent - calcVal1.mPercent;
return difflen * difflen + diffpct * diffpct;
}
// CLASS METHODS
// -------------
@ -844,7 +870,7 @@ StyleAnimationValue::ComputeDistance(nsCSSProperty aProperty,
case eUnit_Transform: {
return false;
}
case eUnit_BackgroundPosition: {
case eUnit_BackgroundPositionCoord: {
const nsCSSValueList *position1 = aStartValue.GetCSSValueListValue();
const nsCSSValueList *position2 = aEndValue.GetCSSValueListValue();
@ -852,7 +878,7 @@ StyleAnimationValue::ComputeDistance(nsCSSProperty aProperty,
MOZ_ASSERT(!position1 == !position2, "lists should be same length");
while (position1 && position2) {
squareDistance += CalcPositionSquareDistance(position1->mValue,
squareDistance += CalcPositionCoordSquareDistance(position1->mValue,
position2->mValue);
position1 = position1->mNext;
position2 = position2->mNext;
@ -2191,6 +2217,26 @@ AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
return result.forget();
}
static void
AddPositionCoords(double aCoeff1, const nsCSSValue& aPos1,
double aCoeff2, const nsCSSValue& aPos2,
nsCSSValue& aResultPos)
{
const nsCSSValue::Array* posArray1 = aPos1.GetArrayValue();
const nsCSSValue::Array* posArray2 = aPos2.GetArrayValue();
nsCSSValue::Array* resultPosArray = nsCSSValue::Array::Create(2);
aResultPos.SetArrayValue(resultPosArray, eCSSUnit_Array);
/* Only compute element 1. The <position-coord> is
* 'uncomputed' to only that element.
*/
const nsCSSValue& v1 = posArray1->Item(1);
const nsCSSValue& v2 = posArray2->Item(1);
nsCSSValue& vr = resultPosArray->Item(1);
AddCSSValueCanonicalCalc(aCoeff1, v1,
aCoeff2, v2, vr);
}
bool
StyleAnimationValue::AddWeighted(nsCSSProperty aProperty,
double aCoeff1,
@ -2665,7 +2711,7 @@ StyleAnimationValue::AddWeighted(nsCSSProperty aProperty,
aResultValue.SetTransformValue(new nsCSSValueSharedList(result.forget()));
return true;
}
case eUnit_BackgroundPosition: {
case eUnit_BackgroundPositionCoord: {
const nsCSSValueList *position1 = aValue1.GetCSSValueListValue();
const nsCSSValueList *position2 = aValue2.GetCSSValueListValue();
nsAutoPtr<nsCSSValueList> result;
@ -2675,7 +2721,7 @@ StyleAnimationValue::AddWeighted(nsCSSProperty aProperty,
*resultTail = item;
resultTail = &item->mNext;
AddPositions(aCoeff1, position1->mValue,
AddPositionCoords(aCoeff1, position1->mValue,
aCoeff2, position2->mValue, item->mValue);
position1 = position1->mNext;
@ -2688,7 +2734,7 @@ StyleAnimationValue::AddWeighted(nsCSSProperty aProperty,
}
aResultValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_BackgroundPosition);
eUnit_BackgroundPositionCoord);
return true;
}
case eUnit_CSSValuePairList: {
@ -3057,7 +3103,7 @@ StyleAnimationValue::UncomputeValue(nsCSSProperty aProperty,
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPosition:
case eUnit_BackgroundPositionCoord:
{
nsCSSValueList* computedList = aComputedValue.GetCSSValueListValue();
if (computedList) {
@ -3096,7 +3142,7 @@ StyleAnimationValue::UncomputeValue(nsCSSProperty aProperty,
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPosition:
case eUnit_BackgroundPositionCoord:
{
UniquePtr<nsCSSValueList> computedList =
aComputedValue.TakeCSSValueListValue();
@ -3276,6 +3322,23 @@ SetPositionValue(const nsStyleImageLayers::Position& aPos, nsCSSValue& aCSSValue
SetCalcValue(&aPos.mYPosition, yValue);
}
static void
SetPositionCoordValue(const nsStyleImageLayers::Position::PositionCoord& aPosCoord,
nsCSSValue& aCSSValue)
{
RefPtr<nsCSSValue::Array> posArray = nsCSSValue::Array::Create(2);
aCSSValue.SetArrayValue(posArray.get(), eCSSUnit_Array);
// NOTE: Array entry #0 here is intentionally left untouched, with
// eCSSUnit_Null. The purpose of this entry in our specified-style
// <position-coord> representation is to store edge names. But for values
// extracted from computed style (which is what we're dealing with here),
// we'll just have a normalized "x"/"y" position, with no edge names needed.
nsCSSValue& value = posArray->Item(1);
SetCalcValue(&aPosCoord, value);
}
/*
* Assign |aOutput = aInput|, except with any non-pixel lengths
* replaced with the equivalent in pixels, and any non-canonical calc()
@ -3319,22 +3382,43 @@ SubstitutePixelValues(nsStyleContext* aStyleContext,
}
static void
ExtractImageLayerPositionList(const nsStyleImageLayers& aLayer,
ExtractImageLayerPositionXList(const nsStyleImageLayers& aLayer,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(aLayer.mPositionCount > 0, "unexpected count");
MOZ_ASSERT(aLayer.mPositionXCount > 0, "unexpected count");
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = aLayer.mPositionCount; i != i_end; ++i) {
for (uint32_t i = 0, i_end = aLayer.mPositionXCount; i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
SetPositionValue(aLayer.mLayers[i].mPosition, item->mValue);
SetPositionCoordValue(aLayer.mLayers[i].mPosition.mXPosition,
item->mValue);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
StyleAnimationValue::eUnit_BackgroundPosition);
StyleAnimationValue::eUnit_BackgroundPositionCoord);
}
static void
ExtractImageLayerPositionYList(const nsStyleImageLayers& aLayer,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(aLayer.mPositionYCount > 0, "unexpected count");
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = aLayer.mPositionYCount; i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
SetPositionCoordValue(aLayer.mLayers[i].mPosition.mYPosition,
item->mValue);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
StyleAnimationValue::eUnit_BackgroundPositionCoord);
}
static void
@ -3821,17 +3905,34 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
break;
}
case eCSSProperty_background_position: {
case eCSSProperty_background_position_x: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerPositionList(layers, aComputedValue);
ExtractImageLayerPositionXList(layers, aComputedValue);
break;
}
case eCSSProperty_background_position_y: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerPositionYList(layers, aComputedValue);
break;
}
#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask_position: {
case eCSSProperty_mask_position_x: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerPositionList(layers, aComputedValue);
ExtractImageLayerPositionXList(layers, aComputedValue);
break;
}
case eCSSProperty_mask_position_y: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerPositionYList(layers, aComputedValue);
break;
}
#endif
@ -4248,7 +4349,7 @@ StyleAnimationValue::operator=(const StyleAnimationValue& aOther)
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPosition:
case eUnit_BackgroundPositionCoord:
MOZ_ASSERT(mUnit == eUnit_Shadow || mUnit == eUnit_Filter ||
aOther.mValue.mCSSValueList,
"value lists other than shadows and filters may not be null");
@ -4512,7 +4613,7 @@ StyleAnimationValue::operator==(const StyleAnimationValue& aOther) const
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPosition:
case eUnit_BackgroundPositionCoord:
return nsCSSValueList::Equal(mValue.mCSSValueList,
aOther.mValue.mCSSValueList);
case eUnit_Shape:

Просмотреть файл

@ -285,7 +285,7 @@ public:
eUnit_Shape, // nsCSSValue::Array* (never null)
eUnit_Filter, // nsCSSValueList* (may be null)
eUnit_Transform, // nsCSSValueList* (never null)
eUnit_BackgroundPosition, // nsCSSValueList* (never null)
eUnit_BackgroundPositionCoord, // nsCSSValueList* (never null)
eUnit_CSSValuePairList, // nsCSSValuePairList* (never null)
eUnit_UnparsedString // nsStringBuffer* (never null)
};
@ -486,7 +486,7 @@ private:
static bool IsCSSValueListUnit(Unit aUnit) {
return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter ||
aUnit == eUnit_Shadow ||
aUnit == eUnit_BackgroundPosition;
aUnit == eUnit_BackgroundPositionCoord;
}
static bool IsCSSValueSharedListValue(Unit aUnit) {
return aUnit == eUnit_Transform;

Просмотреть файл

@ -282,6 +282,20 @@ if (SupportsMaskShorthand()) {
// since mask-position uses calc() as
// an intermediate form.
/* test_length_percent_pair_unclamped */ ];
supported_properties["mask-position-x"] = [ test_background_position_coord_transition,
test_length_transition,
test_percent_transition,
// FIXME: We don't currently test clamping,
// since background-position-x uses calc() as
// an intermediate form.
/* test_length_percent_pair_unclamped */ ];
supported_properties["mask-position-y"] = [ test_background_position_coord_transition,
test_length_transition,
test_percent_transition,
// FIXME: We don't currently test clamping,
// since background-position-y uses calc() as
// an intermediate form.
/* test_length_percent_pair_unclamped */ ];
supported_properties["mask-size"] = [ test_background_size_transition,
// FIXME: We don't currently test clamping,
// since mask-size uses calc() as an