Bug 1299741 part 9 - Add support for storing complex color in nsCSSValue and StyleAnimationValue. r?dbaron draft
authorXidorn Quan <me@upsuper.org>
Thu, 01 Sep 2016 23:56:12 +1000
changeset 408670 76a77d64f09e0c2af4d546854e298d19b32368c6
parent 408669 c3064df6201201cf0de34e456baee3c9d7688139
child 408671 9284f02c8fc63cb3e6003880246538481bce0d7e
push id28268
push userxquan@mozilla.com
push dateThu, 01 Sep 2016 14:08:08 +0000
reviewersdbaron
bugs1299741
milestone51.0a1
Bug 1299741 part 9 - Add support for storing complex color in nsCSSValue and StyleAnimationValue. r?dbaron MozReview-Commit-ID: C9qQ1dvlJBs
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -3082,16 +3082,21 @@ StyleAnimationValue::UncomputeValue(nsCS
       break;
     case eUnit_Color:
       // colors can be alone, or part of a paint server
       aSpecifiedValue.SetColorValue(aComputedValue.GetColorValue());
       break;
     case eUnit_CurrentColor:
       aSpecifiedValue.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
       break;
+    case eUnit_ComplexColor: {
+      StyleComplexColor color = aComputedValue.GetComplexColorValue();
+      aSpecifiedValue.SetComplexColorValue(color);
+      break;
+    }
     case eUnit_Calc:
     case eUnit_ObjectPosition:
     case eUnit_URL:
     case eUnit_DiscreteCSSValue: {
       nsCSSValue* val = aComputedValue.GetCSSValueValue();
       // Sanity-check that the underlying unit in the nsCSSValue is what we
       // expect for our StyleAnimationValue::Unit:
       MOZ_ASSERT((unit == eUnit_Calc && val->GetUnit() == eCSSUnit_Calc) ||
@@ -4326,16 +4331,17 @@ StyleAnimationValue::operator=(const Sty
 {
   if (this == &aOther) {
     return *this;
   }
 
   FreeValue();
 
   mUnit = aOther.mUnit;
+  mExtra = aOther.mExtra;
   switch (mUnit) {
     case eUnit_Null:
     case eUnit_Normal:
     case eUnit_Auto:
     case eUnit_None:
     case eUnit_CurrentColor:
       break;
     case eUnit_Enumerated:
@@ -4347,16 +4353,17 @@ StyleAnimationValue::operator=(const Sty
       mValue.mCoord = aOther.mValue.mCoord;
       break;
     case eUnit_Percent:
     case eUnit_Float:
       mValue.mFloat = aOther.mValue.mFloat;
       MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
       break;
     case eUnit_Color:
+    case eUnit_ComplexColor:
       mValue.mColor = aOther.mValue.mColor;
       break;
     case eUnit_Calc:
     case eUnit_ObjectPosition:
     case eUnit_URL:
     case eUnit_DiscreteCSSValue:
       MOZ_ASSERT(IsCSSValueUnit(mUnit),
                  "This clause is for handling nsCSSValue-backed units");
@@ -4482,16 +4489,25 @@ StyleAnimationValue::SetColorValue(nscol
 void
 StyleAnimationValue::SetCurrentColorValue()
 {
   FreeValue();
   mUnit = eUnit_CurrentColor;
 }
 
 void
+StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aValue)
+{
+  FreeValue();
+  mUnit = eUnit_ComplexColor;
+  mValue.mColor = aValue.mColor;
+  mExtra = aValue.mForegroundRatio;
+}
+
+void
 StyleAnimationValue::SetUnparsedStringValue(const nsString& aString)
 {
   FreeValue();
   mUnit = eUnit_UnparsedString;
   mValue.mString = nsCSSValue::BufferFromString(aString).take();
 }
 
 void
@@ -4627,16 +4643,18 @@ StyleAnimationValue::operator==(const St
       return mValue.mInt == aOther.mValue.mInt;
     case eUnit_Coord:
       return mValue.mCoord == aOther.mValue.mCoord;
     case eUnit_Percent:
     case eUnit_Float:
       return mValue.mFloat == aOther.mValue.mFloat;
     case eUnit_Color:
       return mValue.mColor == aOther.mValue.mColor;
+    case eUnit_ComplexColor:
+      return mValue.mColor == aOther.mValue.mColor && mExtra == aOther.mExtra;
     case eUnit_Calc:
     case eUnit_ObjectPosition:
     case eUnit_URL:
     case eUnit_DiscreteCSSValue:
       MOZ_ASSERT(IsCSSValueUnit(mUnit),
                  "This clause is for handling nsCSSValue-backed units");
       return *mValue.mCSSValue == *aOther.mValue.mCSSValue;
     case eUnit_CSSValuePair:
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -278,16 +278,17 @@ public:
     eUnit_Visibility, // special case for transitions (which converts
                       // Enumerated to Visibility as needed)
     eUnit_Integer,
     eUnit_Coord,
     eUnit_Percent,
     eUnit_Float,
     eUnit_Color,
     eUnit_CurrentColor,
+    eUnit_ComplexColor, // nscolor & ratio in extra
     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
                           // 4-entry nsCSSValue::Array
     eUnit_URL, // nsCSSValue* (never null), always with a css::URLValue
     eUnit_DiscreteCSSValue, // nsCSSValue* (never null)
     eUnit_CSSValuePair, // nsCSSValuePair* (never null)
     eUnit_CSSValueTriplet, // nsCSSValueTriplet* (never null)
@@ -348,16 +349,20 @@ public:
   float GetFloatValue() const {
     NS_ASSERTION(mUnit == eUnit_Float, "unit mismatch");
     return mValue.mFloat;
   }
   nscolor GetColorValue() const {
     NS_ASSERTION(mUnit == eUnit_Color, "unit mismatch");
     return mValue.mColor;
   }
+  StyleComplexColor GetComplexColorValue() const {
+    MOZ_ASSERT(mUnit == eUnit_ComplexColor, "unit mismatch");
+    return StyleComplexColor(mValue.mColor, mExtra);
+  }
   nsCSSValue* GetCSSValueValue() const {
     NS_ASSERTION(IsCSSValueUnit(mUnit), "unit mismatch");
     return mValue.mCSSValue;
   }
   nsCSSValuePair* GetCSSValuePairValue() const {
     NS_ASSERTION(IsCSSValuePairUnit(mUnit), "unit mismatch");
     return mValue.mCSSValuePair;
   }
@@ -417,16 +422,17 @@ public:
     NS_ASSERTION(aUnit == eUnit_Null || aUnit == eUnit_Normal ||
                  aUnit == eUnit_Auto || aUnit == eUnit_None,
                  "must be valueless unit");
   }
   StyleAnimationValue(const StyleAnimationValue& aOther)
     : mUnit(eUnit_Null) { *this = aOther; }
   StyleAnimationValue(StyleAnimationValue&& aOther)
     : mUnit(aOther.mUnit)
+    , mExtra(aOther.mExtra)
     , mValue(aOther.mValue)
   {
     aOther.mUnit = eUnit_Null;
   }
   enum IntegerConstructorType { IntegerConstructor };
   StyleAnimationValue(int32_t aInt, Unit aUnit, IntegerConstructorType);
   enum CoordConstructorType { CoordConstructor };
   StyleAnimationValue(nscoord aLength, CoordConstructorType);
@@ -451,16 +457,17 @@ public:
                   "aValue must be an enum that fits within mValue.mInt");
     SetIntValue(static_cast<int32_t>(aInt), aUnit);
   }
   void SetCoordValue(nscoord aCoord);
   void SetPercentValue(float aPercent);
   void SetFloatValue(float aFloat);
   void SetColorValue(nscolor aColor);
   void SetCurrentColorValue();
+  void SetComplexColorValue(const StyleComplexColor& aValue);
   void SetUnparsedStringValue(const nsString& aString);
   void SetCSSValueArrayValue(nsCSSValue::Array* aValue, Unit aUnit);
 
   // These setters take ownership of |aValue|, and are therefore named
   // "SetAndAdopt*".
   void SetAndAdoptCSSValueValue(nsCSSValue *aValue, Unit aUnit);
   void SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValue, Unit aUnit);
   void SetAndAdoptCSSValueTripletValue(nsCSSValueTriplet *aValue, Unit aUnit);
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -134,32 +134,33 @@ nsCSSValue::nsCSSValue(css::FontFamilyLi
   : mUnit(eCSSUnit_FontFamilyList)
 {
   mValue.mFontFamilyList = aValue;
   mValue.mFontFamilyList->AddRef();
 }
 
 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
   : mUnit(aCopy.mUnit)
+  , mExtra(aCopy.mExtra)
 {
   if (mUnit <= eCSSUnit_DummyInherit) {
     // nothing to do, but put this important case first
   }
   else if (eCSSUnit_Percent <= mUnit) {
     mValue.mFloat = aCopy.mValue.mFloat;
     MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
   }
   else if (UnitHasStringValue()) {
     mValue.mString = aCopy.mValue.mString;
     mValue.mString->AddRef();
   }
   else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
     mValue.mInt = aCopy.mValue.mInt;
   }
-  else if (IsIntegerColorUnit()) {
+  else if (IsIntegerColorUnit() || eCSSUnit_ComplexColor == mUnit) {
     mValue.mColor = aCopy.mValue.mColor;
   }
   else if (IsFloatColorUnit()) {
     mValue.mFloatColor = aCopy.mValue.mFloatColor;
     mValue.mFloatColor->AddRef();
   }
   else if (UnitHasArrayValue()) {
     mValue.mArray = aCopy.mValue.mArray;
@@ -235,16 +236,17 @@ nsCSSValue& nsCSSValue::operator=(const 
 
 nsCSSValue&
 nsCSSValue::operator=(nsCSSValue&& aOther)
 {
   MOZ_ASSERT(this != &aOther, "Self assigment with rvalue reference");
 
   Reset();
   mUnit = aOther.mUnit;
+  mExtra = aOther.mExtra;
   mValue = aOther.mValue;
   aOther.mUnit = eCSSUnit_Null;
 
   return *this;
 }
 
 bool nsCSSValue::operator==(const nsCSSValue& aOther) const
 {
@@ -266,16 +268,19 @@ bool nsCSSValue::operator==(const nsCSSV
       return mValue.mInt == aOther.mValue.mInt;
     }
     else if (IsIntegerColorUnit()) {
       return mValue.mColor == aOther.mValue.mColor;
     }
     else if (IsFloatColorUnit()) {
       return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
     }
+    else if (eCSSUnit_ComplexColor == mUnit) {
+      return mValue.mColor == aOther.mValue.mColor && mExtra == aOther.mExtra;
+    }
     else if (UnitHasArrayValue()) {
       return *mValue.mArray == *aOther.mValue.mArray;
     }
     else if (eCSSUnit_URL == mUnit) {
       return *mValue.mURL == *aOther.mValue.mURL;
     }
     else if (eCSSUnit_Image == mUnit) {
       return *mValue.mImage == *aOther.mValue.mImage;
@@ -472,16 +477,24 @@ void nsCSSValue::SetFloatColorValue(floa
   Reset();
   mUnit = aUnit;
   MOZ_ASSERT(IsFloatColorUnit(), "bad unit");
   mValue.mFloatColor =
     new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha);
   mValue.mFloatColor->AddRef();
 }
 
+void nsCSSValue::SetComplexColorValue(const StyleComplexColor& aColor)
+{
+  Reset();
+  mUnit = eCSSUnit_ComplexColor;
+  mValue.mColor = aColor.mColor;
+  mExtra = aColor.mForegroundRatio;
+}
+
 void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
 {
   Reset();
   mUnit = aUnit;
   MOZ_ASSERT(UnitHasArrayValue(), "bad unit");
   mValue.mArray = aValue;
   mValue.mArray->AddRef();
 }
@@ -1559,16 +1572,28 @@ nsCSSValue::AppendToString(nsCSSProperty
       if (eCSSUnit_ShortHexColorAlpha == unit) {
         aResult.AppendInt(NS_GET_A(color) / 0x11, 16);
       }
     } else {
       MOZ_ASSERT(IsFloatColorUnit());
       mValue.mFloatColor->AppendToString(unit, aResult);
     }
   }
+  else if (eCSSUnit_ComplexColor == unit) {
+    StyleComplexColor color = GetComplexColorValue();
+    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(
       nsDependentString(GetOriginalURLValue()), aResult);
     aResult.Append(')');
   }
   else if (eCSSUnit_Element == unit) {
     aResult.AppendLiteral("-moz-element(#");
@@ -2032,16 +2057,17 @@ nsCSSValue::SizeOfExcludingThis(mozilla:
 
     // Integer Color: nothing extra to measure.
     case eCSSUnit_RGBColor:
     case eCSSUnit_RGBAColor:
     case eCSSUnit_HexColor:
     case eCSSUnit_ShortHexColor:
     case eCSSUnit_HexColorAlpha:
     case eCSSUnit_ShortHexColorAlpha:
+    case eCSSUnit_ComplexColor:
       break;
 
     // Float Color
     case eCSSUnit_PercentageRGBColor:
     case eCSSUnit_PercentageRGBAColor:
     case eCSSUnit_HSLColor:
     case eCSSUnit_HSLAColor:
       n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -8,16 +8,17 @@
 #ifndef nsCSSValue_h___
 #define nsCSSValue_h___
 
 #include <type_traits>
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/SheetType.h"
+#include "mozilla/StyleComplexColor.h"
 #include "mozilla/UniquePtr.h"
 
 #include "nsIPrincipal.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsCSSKeywords.h"
 #include "nsCSSPropertyID.h"
 #include "nsCSSProps.h"
@@ -377,16 +378,17 @@ enum nsCSSUnit : uint16_t {
   eCSSUnit_HexColor            = 83,   // (nscolor) an opaque RGBA value specified as #rrggbb
   eCSSUnit_ShortHexColor       = 84,   // (nscolor) an opaque RGBA value specified as #rgb
   eCSSUnit_HexColorAlpha       = 85,   // (nscolor) an opaque RGBA value specified as #rrggbbaa
   eCSSUnit_ShortHexColorAlpha  = 86,   // (nscolor) an opaque RGBA value specified as #rgba
   eCSSUnit_PercentageRGBColor  = 87,   // (nsCSSValueFloatColor*)
   eCSSUnit_PercentageRGBAColor = 88,   // (nsCSSValueFloatColor*)
   eCSSUnit_HSLColor            = 89,   // (nsCSSValueFloatColor*)
   eCSSUnit_HSLAColor           = 90,   // (nsCSSValueFloatColor*)
+  eCSSUnit_ComplexColor        = 91,   // (nscolor + extra) RGBA value with ratio in extra
 
   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)
 
   // Physical length units
   eCSSUnit_PhysicalMillimeter = 200,   // (float) 1/25.4 inch
 
   // Length units - relative
@@ -468,16 +470,17 @@ public:
   explicit nsCSSValue(mozilla::css::ImageValue* aValue);
   explicit nsCSSValue(nsCSSValueGradient* aValue);
   explicit nsCSSValue(nsCSSValueTokenStream* aValue);
   explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
   explicit nsCSSValue(mozilla::css::FontFamilyListRefCnt* aValue);
   nsCSSValue(const nsCSSValue& aCopy);
   nsCSSValue(nsCSSValue&& aOther)
     : mUnit(aOther.mUnit)
+    , mExtra(aOther.mExtra)
     , mValue(aOther.mValue)
   {
     aOther.mUnit = eCSSUnit_Null;
   }
   ~nsCSSValue() { Reset(); }
 
   nsCSSValue&  operator=(const nsCSSValue& aCopy);
   nsCSSValue&  operator=(nsCSSValue&& aCopy);
@@ -626,16 +629,22 @@ public:
   {
     MOZ_ASSERT(UnitHasStringValue(), "not a string value");
     return GetBufferValue(mValue.mString);
   }
 
   nscolor GetColorValue() const;
   bool IsNonTransparentColor() const;
 
+  mozilla::StyleComplexColor GetComplexColorValue() const
+  {
+    MOZ_ASSERT(mUnit == eCSSUnit_ComplexColor, "unit mismatch");
+    return mozilla::StyleComplexColor(mValue.mColor, mExtra);
+  }
+
   Array* GetArrayValue() const
   {
     MOZ_ASSERT(UnitHasArrayValue(), "not an array value");
     return mValue.mArray;
   }
 
   nsIURI* GetURLValue() const
   {
@@ -749,16 +758,17 @@ public:
   void SetFloatValue(float aValue, nsCSSUnit aUnit);
   void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
   void SetColorValue(nscolor aValue);
   void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
   void SetFloatColorValue(float aComponent1,
                           float aComponent2,
                           float aComponent3,
                           float aAlpha, nsCSSUnit aUnit);
+  void SetComplexColorValue(const mozilla::StyleComplexColor& aColor);
   void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
   void SetURLValue(mozilla::css::URLValue* aURI);
   void SetImageValue(mozilla::css::ImageValue* aImage);
   void SetGradientValue(nsCSSValueGradient* aGradient);
   void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
   void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
   void SetFontFamilyListValue(mozilla::css::FontFamilyListRefCnt* aFontListValue);
   void SetPairValue(const nsCSSValuePair* aPair);