Bug 773296 - Part 16: Add a ref-counted list nsCSSValue unit and use it for tranform lists; hold a strong reference to one on nsStyleDisplay. r=dbaron

This adds a new eCSSUnit_SharedList type for nsCSSValue, which is a
reference counted object that contains an nsCSSValueList.  We need this
so that nsStyleDisplay::mSpecifiedTransform can hold a strong reference
to a specified transform list value.  When 'transform' is specified
using a variable reference, the resulting nsCSSValue does not stick
around in the Declaration object, so we wouldn't be guaranteed that
it lives long enough for nsStyleDisplay to keep referencing it.
This commit is contained in:
Cameron McCormack
2013-12-12 13:09:44 +11:00
parent 615ac0aa43
commit 2d29cdbe6b
11 changed files with 165 additions and 26 deletions

View File

@@ -40,7 +40,7 @@
#endif #endif
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
struct nsCSSValueList; struct nsCSSValueSharedList;
using namespace mozilla::dom; using namespace mozilla::dom;
@@ -348,7 +348,8 @@ SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aSta
return; return;
} }
nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue(); nsCSSValueSharedList* interpolatedList =
interpolatedValue.GetCSSValueSharedListValue();
TransformData& data = aAnimation.data().get_TransformData(); TransformData& data = aAnimation.data().get_TransformData();
nsPoint origin = data.origin(); nsPoint origin = data.origin();

View File

@@ -4059,7 +4059,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
frame && frame->IsSVGTransformed(&svgTransform, &transformFromSVGParent); frame && frame->IsSVGTransformed(&svgTransform, &transformFromSVGParent);
/* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */ /* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */
if (aProperties.mTransformList) { if (aProperties.mTransformList) {
result = nsStyleTransformMatrix::ReadTransforms(aProperties.mTransformList, result = nsStyleTransformMatrix::ReadTransforms(aProperties.mTransformList->mHead,
frame ? frame->StyleContext() : nullptr, frame ? frame->StyleContext() : nullptr,
frame ? frame->PresContext() : nullptr, frame ? frame->PresContext() : nullptr,
dummy, bounds, aAppUnitsPerPixel); dummy, bounds, aAppUnitsPerPixel);

View File

@@ -3037,7 +3037,7 @@ public:
FrameTransformProperties(const nsIFrame* aFrame, FrameTransformProperties(const nsIFrame* aFrame,
float aAppUnitsPerPixel, float aAppUnitsPerPixel,
const nsRect* aBoundsOverride); const nsRect* aBoundsOverride);
FrameTransformProperties(const nsCSSValueList* aTransformList, FrameTransformProperties(nsCSSValueSharedList* aTransformList,
const gfxPoint3D& aToTransformOrigin, const gfxPoint3D& aToTransformOrigin,
const gfxPoint3D& aToPerspectiveOrigin, const gfxPoint3D& aToPerspectiveOrigin,
nscoord aChildPerspective) nscoord aChildPerspective)
@@ -3049,7 +3049,7 @@ public:
{} {}
const nsIFrame* mFrame; const nsIFrame* mFrame;
const nsCSSValueList* mTransformList; nsRefPtr<nsCSSValueSharedList> mTransformList;
const gfxPoint3D mToTransformOrigin; const gfxPoint3D mToTransformOrigin;
const gfxPoint3D mToPerspectiveOrigin; const gfxPoint3D mToPerspectiveOrigin;
nscoord mChildPerspective; nscoord mChildPerspective;

View File

@@ -11179,7 +11179,10 @@ bool CSSParserImpl::ParseTransform(bool aIsPrefixed)
return false; return false;
} }
} else { } else {
nsCSSValueList* cur = value.SetListValue(); nsCSSValueSharedList* list = new nsCSSValueSharedList;
value.SetSharedListValue(list);
list->mHead = new nsCSSValueList;
nsCSSValueList* cur = list->mHead;
for (;;) { for (;;) {
if (!ParseSingleTransform(aIsPrefixed, cur->mValue)) { if (!ParseSingleTransform(aIsPrefixed, cur->mValue)) {
return false; return false;

View File

@@ -162,6 +162,10 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
else if (eCSSUnit_ListDep == mUnit) { else if (eCSSUnit_ListDep == mUnit) {
mValue.mListDependent = aCopy.mValue.mListDependent; mValue.mListDependent = aCopy.mValue.mListDependent;
} }
else if (eCSSUnit_SharedList == mUnit) {
mValue.mSharedList = aCopy.mValue.mSharedList;
mValue.mSharedList->AddRef();
}
else if (eCSSUnit_PairList == mUnit) { else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList = aCopy.mValue.mPairList; mValue.mPairList = aCopy.mValue.mPairList;
mValue.mPairList->AddRef(); mValue.mPairList->AddRef();
@@ -232,6 +236,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
else if (eCSSUnit_List == mUnit) { else if (eCSSUnit_List == mUnit) {
return *mValue.mList == *aOther.mValue.mList; return *mValue.mList == *aOther.mValue.mList;
} }
else if (eCSSUnit_SharedList == mUnit) {
return *mValue.mSharedList == *aOther.mValue.mSharedList;
}
else if (eCSSUnit_PairList == mUnit) { else if (eCSSUnit_PairList == mUnit) {
return *mValue.mPairList == *aOther.mValue.mPairList; return *mValue.mPairList == *aOther.mValue.mPairList;
} }
@@ -315,6 +322,8 @@ void nsCSSValue::DoReset()
mValue.mRect->Release(); mValue.mRect->Release();
} else if (eCSSUnit_List == mUnit) { } else if (eCSSUnit_List == mUnit) {
mValue.mList->Release(); mValue.mList->Release();
} else if (eCSSUnit_SharedList == mUnit) {
mValue.mSharedList->Release();
} else if (eCSSUnit_PairList == mUnit) { } else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList->Release(); mValue.mPairList->Release();
} }
@@ -513,6 +522,14 @@ nsCSSValueList* nsCSSValue::SetListValue()
return mValue.mList; return mValue.mList;
} }
void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList)
{
Reset();
mUnit = eCSSUnit_SharedList;
mValue.mSharedList = aList;
mValue.mSharedList->AddRef();
}
void nsCSSValue::SetDependentListValue(nsCSSValueList* aList) void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
{ {
Reset(); Reset();
@@ -1198,6 +1215,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
GetRectValue().AppendToString(aProperty, aResult); GetRectValue().AppendToString(aProperty, aResult);
} else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) { } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
GetListValue()->AppendToString(aProperty, aResult); GetListValue()->AppendToString(aProperty, aResult);
} else if (eCSSUnit_SharedList == unit) {
GetSharedListValue()->AppendToString(aProperty, aResult);
} else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) { } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
switch (aProperty) { switch (aProperty) {
case eCSSProperty_font_feature_settings: case eCSSProperty_font_feature_settings:
@@ -1258,6 +1277,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
case eCSSUnit_Rect: break; case eCSSUnit_Rect: break;
case eCSSUnit_List: break; case eCSSUnit_List: break;
case eCSSUnit_ListDep: break; case eCSSUnit_ListDep: break;
case eCSSUnit_SharedList: break;
case eCSSUnit_PairList: break; case eCSSUnit_PairList: break;
case eCSSUnit_PairListDep: break; case eCSSUnit_PairListDep: break;
@@ -1384,6 +1404,12 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
case eCSSUnit_ListDep: case eCSSUnit_ListDep:
break; break;
// SharedList
case eCSSUnit_SharedList:
// Makes more sense not to measure, since it most cases the list
// will be shared.
break;
// PairList // PairList
case eCSSUnit_PairList: case eCSSUnit_PairList:
n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf); n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
@@ -1522,6 +1548,41 @@ nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) co
return n; return n;
} }
// --- nsCSSValueSharedList -----------------
nsCSSValueSharedList::~nsCSSValueSharedList()
{
MOZ_COUNT_DTOR(nsCSSValueSharedList);
if (mHead) {
NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
delete mHead;
}
}
void
nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
{
if (mHead) {
mHead->AppendToString(aProperty, aResult);
}
}
bool
nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
{
return !mHead == !aOther.mHead &&
(!mHead || *mHead == *aOther.mHead);
}
size_t
nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
size_t n = 0;
n += aMallocSizeOf(this);
n += mHead->SizeOfIncludingThis(aMallocSizeOf);
return n;
}
// --- nsCSSRect ----------------- // --- nsCSSRect -----------------
nsCSSRect::nsCSSRect(void) nsCSSRect::nsCSSRect(void)

View File

@@ -197,8 +197,10 @@ enum nsCSSUnit {
eCSSUnit_List = 53, // (nsCSSValueList*) list of values eCSSUnit_List = 53, // (nsCSSValueList*) list of values
eCSSUnit_ListDep = 54, // (nsCSSValueList*) same as List eCSSUnit_ListDep = 54, // (nsCSSValueList*) same as List
// but does not own the list // but does not own the list
eCSSUnit_PairList = 55, // (nsCSSValuePairList*) list of value pairs eCSSUnit_SharedList = 55, // (nsCSSValueSharedList*) same as list
eCSSUnit_PairListDep = 56, // (nsCSSValuePairList*) same as PairList // but reference counted and shared
eCSSUnit_PairList = 56, // (nsCSSValuePairList*) list of value pairs
eCSSUnit_PairListDep = 57, // (nsCSSValuePairList*) same as PairList
// but does not own the list // but does not own the list
eCSSUnit_Integer = 70, // (int) simple value eCSSUnit_Integer = 70, // (int) simple value
@@ -257,6 +259,7 @@ struct nsCSSRect;
struct nsCSSRect_heap; struct nsCSSRect_heap;
struct nsCSSValueList; struct nsCSSValueList;
struct nsCSSValueList_heap; struct nsCSSValueList_heap;
struct nsCSSValueSharedList;
struct nsCSSValuePairList; struct nsCSSValuePairList;
struct nsCSSValuePairList_heap; struct nsCSSValuePairList_heap;
struct nsCSSValueTriplet; struct nsCSSValueTriplet;
@@ -430,6 +433,12 @@ public:
return mValue.mTokenStream; return mValue.mTokenStream;
} }
nsCSSValueSharedList* GetSharedListValue() const
{
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_SharedList, "not a shared list value");
return mValue.mSharedList;
}
// bodies of these are below // bodies of these are below
inline nsCSSValuePair& GetPairValue(); inline nsCSSValuePair& GetPairValue();
inline const nsCSSValuePair& GetPairValue() const; inline const nsCSSValuePair& GetPairValue() const;
@@ -498,6 +507,7 @@ public:
void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream); void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValuePair* aPair);
void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
void SetSharedListValue(nsCSSValueSharedList* aList);
void SetDependentListValue(nsCSSValueList* aList); void SetDependentListValue(nsCSSValueList* aList);
void SetDependentPairListValue(nsCSSValuePairList* aList); void SetDependentPairListValue(nsCSSValuePairList* aList);
void SetTripletValue(const nsCSSValueTriplet* aTriplet); void SetTripletValue(const nsCSSValueTriplet* aTriplet);
@@ -557,6 +567,7 @@ protected:
nsCSSValueTriplet_heap* mTriplet; nsCSSValueTriplet_heap* mTriplet;
nsCSSValueList_heap* mList; nsCSSValueList_heap* mList;
nsCSSValueList* mListDependent; nsCSSValueList* mListDependent;
nsCSSValueSharedList* mSharedList;
nsCSSValuePairList_heap* mPairList; nsCSSValuePairList_heap* mPairList;
nsCSSValuePairList* mPairListDependent; nsCSSValuePairList* mPairListDependent;
} mValue; } mValue;
@@ -701,6 +712,38 @@ struct nsCSSValueList_heap : public nsCSSValueList {
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
}; };
// This is a reference counted list value. Note that the object is
// a wrapper for the reference count and a pointer to the head of the
// list, whereas the other list types (such as nsCSSValueList) do
// not have such a wrapper.
struct nsCSSValueSharedList {
nsCSSValueSharedList()
{
MOZ_COUNT_CTOR(nsCSSValueSharedList);
}
// Takes ownership of aList.
nsCSSValueSharedList(nsCSSValueList* aList)
: mHead(aList)
{
MOZ_COUNT_CTOR(nsCSSValueSharedList);
}
~nsCSSValueSharedList();
NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList)
void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
bool operator==(nsCSSValueSharedList const& aOther) const;
bool operator!=(const nsCSSValueSharedList& aOther) const
{ return !(*this == aOther); }
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
nsCSSValueList* mHead;
};
// This has to be here so that the relationship between nsCSSValueList // This has to be here so that the relationship between nsCSSValueList
// and nsCSSValueList_heap is visible. // and nsCSSValueList_heap is visible.
inline nsCSSValueList* inline nsCSSValueList*

View File

@@ -1232,7 +1232,7 @@ nsComputedDOMStyle::DoGetTransform()
bool dummy; bool dummy;
gfx3DMatrix matrix = gfx3DMatrix matrix =
nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform, nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead,
mStyleContextHolder, mStyleContextHolder,
mStyleContextHolder->PresContext(), mStyleContextHolder->PresContext(),
dummy, dummy,

View File

@@ -5354,15 +5354,16 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
canStoreInRuleTree = false; canStoreInRuleTree = false;
break; break;
case eCSSUnit_List: case eCSSUnit_SharedList: {
case eCSSUnit_ListDep: { nsCSSValueSharedList* list = transformValue->GetSharedListValue();
const nsCSSValueList* head = transformValue->GetListValue(); nsCSSValueList* head = list->mHead;
MOZ_ASSERT(head, "transform list must have at least one item");
// can get a _None in here from transform animation // can get a _None in here from transform animation
if (head->mValue.GetUnit() == eCSSUnit_None) { if (head->mValue.GetUnit() == eCSSUnit_None) {
NS_ABORT_IF_FALSE(head->mNext == nullptr, "none must be alone"); NS_ABORT_IF_FALSE(head->mNext == nullptr, "none must be alone");
display->mSpecifiedTransform = nullptr; display->mSpecifiedTransform = nullptr;
} else { } else {
display->mSpecifiedTransform = head; // weak pointer, owned by rule display->mSpecifiedTransform = list;
} }
break; break;
} }

View File

@@ -2277,8 +2277,11 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
} }
case eUnit_Transform: { case eUnit_Transform: {
const nsCSSValueList *list1 = aValue1.GetCSSValueListValue(); const nsCSSValueList* list1 = aValue1.GetCSSValueSharedListValue()->mHead;
const nsCSSValueList *list2 = aValue2.GetCSSValueListValue(); const nsCSSValueList* list2 = aValue2.GetCSSValueSharedListValue()->mHead;
MOZ_ASSERT(list1);
MOZ_ASSERT(list2);
// We want to avoid the matrix decomposition when we can, since // We want to avoid the matrix decomposition when we can, since
// avoiding it can produce better results both for compound // avoiding it can produce better results both for compound
@@ -2332,8 +2335,7 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
} }
} }
aResultValue.SetAndAdoptCSSValueListValue(result.forget(), aResultValue.SetTransformValue(new nsCSSValueSharedList(result.forget()));
eUnit_Transform);
return true; return true;
} }
case eUnit_BackgroundPosition: { case eUnit_BackgroundPosition: {
@@ -2649,11 +2651,14 @@ nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
case eUnit_Dasharray: case eUnit_Dasharray:
case eUnit_Shadow: case eUnit_Shadow:
case eUnit_Filter: case eUnit_Filter:
case eUnit_Transform:
case eUnit_BackgroundPosition: case eUnit_BackgroundPosition:
aSpecifiedValue. aSpecifiedValue.
SetDependentListValue(aComputedValue.GetCSSValueListValue()); SetDependentListValue(aComputedValue.GetCSSValueListValue());
break; break;
case eUnit_Transform:
aSpecifiedValue.
SetSharedListValue(aComputedValue.GetCSSValueSharedListValue());
break;
case eUnit_CSSValuePairList: case eUnit_CSSValuePairList:
aSpecifiedValue. aSpecifiedValue.
SetDependentPairListValue(aComputedValue.GetCSSValuePairListValue()); SetDependentPairListValue(aComputedValue.GetCSSValuePairListValue());
@@ -3308,7 +3313,7 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
if (display->mSpecifiedTransform) { if (display->mSpecifiedTransform) {
// Clone, and convert all lengths (not percents) to pixels. // Clone, and convert all lengths (not percents) to pixels.
nsCSSValueList **resultTail = getter_Transfers(result); nsCSSValueList **resultTail = getter_Transfers(result);
for (const nsCSSValueList *l = display->mSpecifiedTransform; for (const nsCSSValueList *l = display->mSpecifiedTransform->mHead;
l; l = l->mNext) { l; l = l->mNext) {
nsCSSValueList *clone = new nsCSSValueList; nsCSSValueList *clone = new nsCSSValueList;
*resultTail = clone; *resultTail = clone;
@@ -3321,8 +3326,8 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
result->mValue.SetNoneValue(); result->mValue.SetNoneValue();
} }
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(), aComputedValue.SetTransformValue(
eUnit_Transform); new nsCSSValueSharedList(result.forget()));
break; break;
} }
@@ -3568,7 +3573,6 @@ nsStyleAnimation::Value::operator=(const Value& aOther)
case eUnit_Filter: case eUnit_Filter:
case eUnit_Dasharray: case eUnit_Dasharray:
case eUnit_Shadow: case eUnit_Shadow:
case eUnit_Transform:
case eUnit_BackgroundPosition: case eUnit_BackgroundPosition:
NS_ABORT_IF_FALSE(mUnit == eUnit_Shadow || mUnit == eUnit_Filter || NS_ABORT_IF_FALSE(mUnit == eUnit_Shadow || mUnit == eUnit_Filter ||
aOther.mValue.mCSSValueList, aOther.mValue.mCSSValueList,
@@ -3582,6 +3586,10 @@ nsStyleAnimation::Value::operator=(const Value& aOther)
mValue.mCSSValueList = nullptr; mValue.mCSSValueList = nullptr;
} }
break; break;
case eUnit_Transform:
mValue.mCSSValueSharedList = aOther.mValue.mCSSValueSharedList;
mValue.mCSSValueSharedList->AddRef();
break;
case eUnit_CSSValuePairList: case eUnit_CSSValuePairList:
NS_ABORT_IF_FALSE(aOther.mValue.mCSSValuePairList, NS_ABORT_IF_FALSE(aOther.mValue.mCSSValuePairList,
"value pair lists may not be null"); "value pair lists may not be null");
@@ -3728,6 +3736,15 @@ nsStyleAnimation::Value::SetAndAdoptCSSValueListValue(
mValue.mCSSValueList = aValueList; // take ownership mValue.mCSSValueList = aValueList; // take ownership
} }
void
nsStyleAnimation::Value::SetTransformValue(nsCSSValueSharedList* aList)
{
FreeValue();
mUnit = eUnit_Transform;
mValue.mCSSValueSharedList = aList;
mValue.mCSSValueSharedList->AddRef();
}
void void
nsStyleAnimation::Value::SetAndAdoptCSSValuePairListValue( nsStyleAnimation::Value::SetAndAdoptCSSValuePairListValue(
nsCSSValuePairList *aValuePairList) nsCSSValuePairList *aValuePairList)
@@ -3745,6 +3762,8 @@ nsStyleAnimation::Value::FreeValue()
delete mValue.mCSSValue; delete mValue.mCSSValue;
} else if (IsCSSValueListUnit(mUnit)) { } else if (IsCSSValueListUnit(mUnit)) {
delete mValue.mCSSValueList; delete mValue.mCSSValueList;
} else if (IsCSSValueSharedListValue(mUnit)) {
mValue.mCSSValueSharedList->Release();
} else if (IsCSSValuePairUnit(mUnit)) { } else if (IsCSSValuePairUnit(mUnit)) {
delete mValue.mCSSValuePair; delete mValue.mCSSValuePair;
} else if (IsCSSValueTripletUnit(mUnit)) { } else if (IsCSSValueTripletUnit(mUnit)) {
@@ -3794,9 +3813,10 @@ nsStyleAnimation::Value::operator==(const Value& aOther) const
case eUnit_Dasharray: case eUnit_Dasharray:
case eUnit_Filter: case eUnit_Filter:
case eUnit_Shadow: case eUnit_Shadow:
case eUnit_Transform:
case eUnit_BackgroundPosition: case eUnit_BackgroundPosition:
return *mValue.mCSSValueList == *aOther.mValue.mCSSValueList; return *mValue.mCSSValueList == *aOther.mValue.mCSSValueList;
case eUnit_Transform:
return *mValue.mCSSValueSharedList == *aOther.mValue.mCSSValueSharedList;
case eUnit_CSSValuePairList: case eUnit_CSSValuePairList:
return *mValue.mCSSValuePairList == *aOther.mValue.mCSSValuePairList; return *mValue.mCSSValuePairList == *aOther.mValue.mCSSValuePairList;
case eUnit_UnparsedString: case eUnit_UnparsedString:

View File

@@ -242,6 +242,7 @@ public:
nsCSSValueTriplet* mCSSValueTriplet; nsCSSValueTriplet* mCSSValueTriplet;
nsCSSRect* mCSSRect; nsCSSRect* mCSSRect;
nsCSSValueList* mCSSValueList; nsCSSValueList* mCSSValueList;
nsCSSValueSharedList* mCSSValueSharedList;
nsCSSValuePairList* mCSSValuePairList; nsCSSValuePairList* mCSSValuePairList;
nsStringBuffer* mString; nsStringBuffer* mString;
} mValue; } mValue;
@@ -297,6 +298,10 @@ public:
NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch"); NS_ASSERTION(IsCSSValueListUnit(mUnit), "unit mismatch");
return mValue.mCSSValueList; return mValue.mCSSValueList;
} }
nsCSSValueSharedList* GetCSSValueSharedListValue() const {
NS_ASSERTION(IsCSSValueSharedListValue(mUnit), "unit mismatch");
return mValue.mCSSValueSharedList;
}
nsCSSValuePairList* GetCSSValuePairListValue() const { nsCSSValuePairList* GetCSSValuePairListValue() const {
NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch"); NS_ASSERTION(IsCSSValuePairListUnit(mUnit), "unit mismatch");
return mValue.mCSSValuePairList; return mValue.mCSSValuePairList;
@@ -351,6 +356,8 @@ public:
void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit); void SetAndAdoptCSSValueListValue(nsCSSValueList *aValue, Unit aUnit);
void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue); void SetAndAdoptCSSValuePairListValue(nsCSSValuePairList *aValue);
void SetTransformValue(nsCSSValueSharedList* aList);
Value& operator=(const Value& aOther); Value& operator=(const Value& aOther);
bool operator==(const Value& aOther) const; bool operator==(const Value& aOther) const;
@@ -382,9 +389,12 @@ public:
} }
static bool IsCSSValueListUnit(Unit aUnit) { static bool IsCSSValueListUnit(Unit aUnit) {
return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter || return aUnit == eUnit_Dasharray || aUnit == eUnit_Filter ||
aUnit == eUnit_Shadow || aUnit == eUnit_Transform || aUnit == eUnit_Shadow ||
aUnit == eUnit_BackgroundPosition; aUnit == eUnit_BackgroundPosition;
} }
static bool IsCSSValueSharedListValue(Unit aUnit) {
return aUnit == eUnit_Transform;
}
static bool IsCSSValuePairListUnit(Unit aUnit) { static bool IsCSSValuePairListUnit(Unit aUnit) {
return aUnit == eUnit_CSSValuePairList; return aUnit == eUnit_CSSValuePairList;
} }

View File

@@ -1724,10 +1724,10 @@ struct nsStyleDisplay {
// mSpecifiedTransform is the list of transform functions as // mSpecifiedTransform is the list of transform functions as
// specified, or null to indicate there is no transform. (inherit or // specified, or null to indicate there is no transform. (inherit or
// initial are replaced by an actual list of transform functions, or // initial are replaced by an actual list of transform functions, or
// null, as appropriate.) (owned by the style rule) // null, as appropriate.)
uint8_t mBackfaceVisibility; uint8_t mBackfaceVisibility;
uint8_t mTransformStyle; uint8_t mTransformStyle;
const nsCSSValueList *mSpecifiedTransform; // [reset] nsRefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
nsStyleCoord mChildPerspective; // [reset] coord nsStyleCoord mChildPerspective; // [reset] coord
nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc