зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1299741 part 7 - Support storing ComplexColor in nsCSSValue and StyleAnimationValue. r=heycam
This is a complete rewrite of the original part 8. Instead of storing the ratio in mValueExtra, all values are stored in a struct in heap, so that we support range outside [0.0, 1.0] in computation. MozReview-Commit-ID: 7xUZSgQE5vA --HG-- extra : rebase_source : 722d2aee06e59cdf061d0daae43d8dbc0a9641b4
This commit is contained in:
Родитель
8f2d2e59dd
Коммит
154df81de1
|
@ -3211,6 +3211,11 @@ StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
|
|||
aSpecifiedValue = *val;
|
||||
break;
|
||||
}
|
||||
case eUnit_ComplexColor: {
|
||||
aSpecifiedValue.SetComplexColorValue(
|
||||
do_AddRef(aComputedValue.mValue.mComplexColor));
|
||||
break;
|
||||
}
|
||||
case eUnit_CSSValuePair: {
|
||||
// Rule node processing expects pair values to be collapsed to a
|
||||
// single value if both halves would be equal, for most but not
|
||||
|
@ -4517,6 +4522,11 @@ StyleAnimationValue::operator=(const StyleAnimationValue& aOther)
|
|||
mValue.mString = aOther.mValue.mString;
|
||||
mValue.mString->AddRef();
|
||||
break;
|
||||
case eUnit_ComplexColor:
|
||||
MOZ_ASSERT(aOther.mValue.mComplexColor);
|
||||
mValue.mComplexColor = aOther.mValue.mComplexColor;
|
||||
mValue.mComplexColor->AddRef();
|
||||
break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -4594,6 +4604,27 @@ StyleAnimationValue::SetCurrentColorValue()
|
|||
mUnit = eUnit_CurrentColor;
|
||||
}
|
||||
|
||||
void
|
||||
StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aColor)
|
||||
{
|
||||
if (aColor.IsCurrentColor()) {
|
||||
SetCurrentColorValue();
|
||||
} else if (aColor.IsNumericColor()) {
|
||||
SetColorValue(aColor.mColor);
|
||||
} else {
|
||||
SetComplexColorValue(do_AddRef(new ComplexColorValue(aColor)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StyleAnimationValue::SetComplexColorValue(
|
||||
already_AddRefed<ComplexColorValue> aValue)
|
||||
{
|
||||
FreeValue();
|
||||
mUnit = eUnit_ComplexColor;
|
||||
mValue.mComplexColor = aValue.take();
|
||||
}
|
||||
|
||||
void
|
||||
StyleAnimationValue::SetUnparsedStringValue(const nsString& aString)
|
||||
{
|
||||
|
@ -4712,6 +4743,8 @@ StyleAnimationValue::FreeValue()
|
|||
} else if (IsStringUnit(mUnit)) {
|
||||
MOZ_ASSERT(mValue.mString, "expecting non-null string");
|
||||
mValue.mString->Release();
|
||||
} else if (mUnit == eUnit_ComplexColor) {
|
||||
mValue.mComplexColor->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4768,6 +4801,8 @@ StyleAnimationValue::operator==(const StyleAnimationValue& aOther) const
|
|||
case eUnit_UnparsedString:
|
||||
return (NS_strcmp(GetStringBufferValue(),
|
||||
aOther.GetStringBufferValue()) == 0);
|
||||
case eUnit_ComplexColor:
|
||||
return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("incomplete case");
|
||||
|
|
|
@ -320,6 +320,7 @@ public:
|
|||
eUnit_Color, // nsCSSValue* (never null), always with an nscolor or
|
||||
// an nsCSSValueFloatColor
|
||||
eUnit_CurrentColor,
|
||||
eUnit_ComplexColor, // ComplexColorValue* (never null)
|
||||
eUnit_Calc, // nsCSSValue* (never null), always with a single
|
||||
// calc() expression that's either length or length+percent
|
||||
eUnit_ObjectPosition, // nsCSSValue* (never null), always with a
|
||||
|
@ -354,6 +355,7 @@ private:
|
|||
nsCSSValueSharedList* mCSSValueSharedList;
|
||||
nsCSSValuePairList* mCSSValuePairList;
|
||||
nsStringBuffer* mString;
|
||||
css::ComplexColorValue* mComplexColor;
|
||||
} mValue;
|
||||
|
||||
public:
|
||||
|
@ -431,6 +433,14 @@ public:
|
|||
/// @return the scale for this value, calculated with reference to @aForFrame.
|
||||
gfxSize GetScaleValue(const nsIFrame* aForFrame) const;
|
||||
|
||||
const css::ComplexColorData& GetComplexColorData() const {
|
||||
MOZ_ASSERT(mUnit == eUnit_ComplexColor, "unit mismatch");
|
||||
return *mValue.mComplexColor;
|
||||
}
|
||||
StyleComplexColor GetStyleComplexColorValue() const {
|
||||
return GetComplexColorData().ToComplexColor();
|
||||
}
|
||||
|
||||
UniquePtr<nsCSSValueList> TakeCSSValueListValue() {
|
||||
nsCSSValueList* list = GetCSSValueListValue();
|
||||
mValue.mCSSValueList = nullptr;
|
||||
|
@ -487,6 +497,8 @@ public:
|
|||
void SetFloatValue(float aFloat);
|
||||
void SetColorValue(nscolor aColor);
|
||||
void SetCurrentColorValue();
|
||||
void SetComplexColorValue(const StyleComplexColor& aColor);
|
||||
void SetComplexColorValue(already_AddRefed<css::ComplexColorValue> aValue);
|
||||
void SetUnparsedStringValue(const nsString& aString);
|
||||
void SetCSSValueArrayValue(nsCSSValue::Array* aValue, Unit aUnit);
|
||||
|
||||
|
|
|
@ -161,6 +161,10 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
|
|||
mValue.mFloatColor = aCopy.mValue.mFloatColor;
|
||||
mValue.mFloatColor->AddRef();
|
||||
}
|
||||
else if (eCSSUnit_ComplexColor == mUnit) {
|
||||
mValue.mComplexColor = aCopy.mValue.mComplexColor;
|
||||
mValue.mComplexColor->AddRef();
|
||||
}
|
||||
else if (UnitHasArrayValue()) {
|
||||
mValue.mArray = aCopy.mValue.mArray;
|
||||
mValue.mArray->AddRef();
|
||||
|
@ -271,6 +275,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
|
|||
else if (IsFloatColorUnit()) {
|
||||
return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
|
||||
}
|
||||
else if (eCSSUnit_ComplexColor == mUnit) {
|
||||
return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
|
||||
}
|
||||
else if (UnitHasArrayValue()) {
|
||||
return *mValue.mArray == *aOther.mValue.mArray;
|
||||
}
|
||||
|
@ -377,6 +384,8 @@ void nsCSSValue::DoReset()
|
|||
mValue.mString->Release();
|
||||
} else if (IsFloatColorUnit()) {
|
||||
mValue.mFloatColor->Release();
|
||||
} else if (eCSSUnit_ComplexColor == mUnit) {
|
||||
mValue.mComplexColor->Release();
|
||||
} else if (UnitHasArrayValue()) {
|
||||
mValue.mArray->Release();
|
||||
} else if (eCSSUnit_URL == mUnit) {
|
||||
|
@ -485,6 +494,14 @@ nsCSSValue::SetRGBAColorValue(const RGBAColorData& aValue)
|
|||
aValue.mA, eCSSUnit_PercentageRGBAColor);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSValue::SetComplexColorValue(already_AddRefed<ComplexColorValue> aValue)
|
||||
{
|
||||
Reset();
|
||||
mUnit = eCSSUnit_ComplexColor;
|
||||
mValue.mComplexColor = aValue.take();
|
||||
}
|
||||
|
||||
void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
|
||||
{
|
||||
Reset();
|
||||
|
@ -1573,6 +1590,18 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
|
|||
mValue.mFloatColor->AppendToString(unit, aResult);
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_ComplexColor == unit) {
|
||||
StyleComplexColor color = GetStyleComplexColorValue();
|
||||
nsCSSValue serializable;
|
||||
if (color.IsCurrentColor()) {
|
||||
serializable.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
|
||||
} else if (color.IsNumericColor()) {
|
||||
serializable.SetColorValue(color.mColor);
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Cannot serialize a complex color");
|
||||
}
|
||||
serializable.AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
|
||||
aResult.AppendLiteral("url(");
|
||||
nsStyleUtil::AppendEscapedCSSString(
|
||||
|
@ -1869,6 +1898,7 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
|
|||
case eCSSUnit_PercentageRGBAColor: break;
|
||||
case eCSSUnit_HSLColor: break;
|
||||
case eCSSUnit_HSLAColor: break;
|
||||
case eCSSUnit_ComplexColor: break;
|
||||
case eCSSUnit_Percent: aResult.Append(char16_t('%')); break;
|
||||
case eCSSUnit_Number: break;
|
||||
case eCSSUnit_Gradient: break;
|
||||
|
@ -2056,6 +2086,11 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
|||
n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
|
||||
break;
|
||||
|
||||
// Complex Color
|
||||
case eCSSUnit_ComplexColor:
|
||||
n += mValue.mComplexColor->SizeOfIncludingThis(aMallocSizeOf);
|
||||
break;
|
||||
|
||||
// Float: nothing extra to measure.
|
||||
case eCSSUnit_Percent:
|
||||
case eCSSUnit_Number:
|
||||
|
@ -2784,6 +2819,17 @@ css::ImageValue::~ImageValue()
|
|||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
css::ComplexColorValue::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
nsCSSValueGradientStop::nsCSSValueGradientStop()
|
||||
: mLocation(eCSSUnit_None),
|
||||
mColor(eCSSUnit_Null),
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/SheetType.h"
|
||||
#include "mozilla/StyleComplexColor.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
|
@ -345,6 +346,56 @@ struct RGBAColorData
|
|||
}
|
||||
};
|
||||
|
||||
struct ComplexColorData
|
||||
{
|
||||
RGBAColorData mColor;
|
||||
float mForegroundRatio;
|
||||
|
||||
ComplexColorData() = default;
|
||||
ComplexColorData(const RGBAColorData& aColor, float aForegroundRatio)
|
||||
: mColor(aColor), mForegroundRatio(aForegroundRatio) {}
|
||||
ComplexColorData(nscolor aColor, float aForegroundRatio)
|
||||
: mColor(aColor), mForegroundRatio(aForegroundRatio) {}
|
||||
explicit ComplexColorData(const StyleComplexColor& aColor)
|
||||
: mColor(aColor.mColor)
|
||||
, mForegroundRatio(aColor.mForegroundRatio * (1.0f / 255.0f)) {}
|
||||
|
||||
bool operator==(const ComplexColorData& aOther) const
|
||||
{
|
||||
return mForegroundRatio == aOther.mForegroundRatio &&
|
||||
(IsCurrentColor() || mColor == aOther.mColor);
|
||||
}
|
||||
bool operator!=(const ComplexColorData& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
bool IsCurrentColor() const { return mForegroundRatio >= 1.0f; }
|
||||
bool IsNumericColor() const { return mForegroundRatio <= 0.0f; }
|
||||
|
||||
StyleComplexColor ToComplexColor() const
|
||||
{
|
||||
return StyleComplexColor(
|
||||
mColor.ToColor(), ClampColor(mForegroundRatio * 255.0f));
|
||||
}
|
||||
};
|
||||
|
||||
struct ComplexColorValue final : public ComplexColorData
|
||||
{
|
||||
// Just redirect any parameter to the data struct.
|
||||
template<typename... Args>
|
||||
explicit ComplexColorValue(Args&&... aArgs)
|
||||
: ComplexColorData(Forward<Args>(aArgs)...) {}
|
||||
ComplexColorValue(const ComplexColorValue&) = delete;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(ComplexColorValue)
|
||||
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
~ComplexColorValue() {}
|
||||
};
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -439,6 +490,7 @@ enum nsCSSUnit {
|
|||
// allowed.
|
||||
eCSSUnit_HSLColor = 89, // (nsCSSValueFloatColor*)
|
||||
eCSSUnit_HSLAColor = 90, // (nsCSSValueFloatColor*)
|
||||
eCSSUnit_ComplexColor = 91, // (ComplexColorValue*)
|
||||
|
||||
eCSSUnit_Percent = 100, // (float) 1.0 == 100%) value is percentage of something
|
||||
eCSSUnit_Number = 101, // (float) value is numeric (usually multiplier, different behavior than percent)
|
||||
|
@ -687,6 +739,11 @@ public:
|
|||
|
||||
nscolor GetColorValue() const;
|
||||
bool IsNonTransparentColor() const;
|
||||
mozilla::StyleComplexColor GetStyleComplexColorValue() const
|
||||
{
|
||||
MOZ_ASSERT(mUnit == eCSSUnit_ComplexColor);
|
||||
return mValue.mComplexColor->ToComplexColor();
|
||||
}
|
||||
|
||||
Array* GetArrayValue() const
|
||||
{
|
||||
|
@ -818,6 +875,8 @@ public:
|
|||
float aComponent3,
|
||||
float aAlpha, nsCSSUnit aUnit);
|
||||
void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue);
|
||||
void SetComplexColorValue(
|
||||
already_AddRefed<mozilla::css::ComplexColorValue> aValue);
|
||||
void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
|
||||
void SetURLValue(mozilla::css::URLValue* aURI);
|
||||
void SetImageValue(mozilla::css::ImageValue* aImage);
|
||||
|
@ -925,6 +984,7 @@ protected:
|
|||
nsCSSValuePairList* mPairListDependent;
|
||||
nsCSSValueFloatColor* MOZ_OWNING_REF mFloatColor;
|
||||
mozilla::css::FontFamilyListRefCnt* MOZ_OWNING_REF mFontFamilyList;
|
||||
mozilla::css::ComplexColorValue* MOZ_OWNING_REF mComplexColor;
|
||||
} mValue;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче