Backed out 5 changesets (bug 1467622) for reftest failures on layout/reftests/svg/smil/style/anim-css-fill-1-from-by-curcol-hex.svg. CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Wed, 11 Jul 2018 09:37:26 +0300
changeset 425763 5a5c74e9ccc025350edeb6009e9071ee1f3e2891
parent 425762 476d6df5099909088d6101067e73b76b1d765aa4
child 425768 aff060ad3204234adae2d59b3776207c6687ebfc
child 425769 c40c74e6f3478a90f6756addb97de4fb1a64cb91
push id34264
push usershindli@mozilla.com
push dateWed, 11 Jul 2018 09:41:50 +0000
treeherdermozilla-central@5a5c74e9ccc0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1467622
milestone63.0a1
backs out8694fe928b04200f132a4c45c77b9d3e6353bf93
74533cad947919ef4c98b92971a1fcf65917ca34
e1dbee410e98251c8abb5de38b7c84c4751ac231
56142038cc7f63b68182c589d6dc38d40def3208
90cede21bad19e3817e723969ee6af4078037369
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 5 changesets (bug 1467622) for reftest failures on layout/reftests/svg/smil/style/anim-css-fill-1-from-by-curcol-hex.svg. CLOSED TREE Backed out changeset 8694fe928b04 (bug 1467622) Backed out changeset 74533cad9479 (bug 1467622) Backed out changeset e1dbee410e98 (bug 1467622) Backed out changeset 56142038cc7f (bug 1467622) Backed out changeset 90cede21bad1 (bug 1467622)
dom/smil/test/db_smilCSSPaced.js
layout/generic/nsImageFrame.cpp
layout/style/ComputedStyle.cpp
layout/style/ServoBindings.cpp
layout/style/StyleComplexColor.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/test_transitions_per_property.html
layout/svg/SVGImageContext.cpp
layout/svg/nsSVGUtils.cpp
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/helpers/animated_properties.mako.rs
servo/components/style/values/animated/color.rs
servo/components/style/values/computed/svg.rs
servo/components/style/values/generics/color.rs
servo/components/style/values/specified/svg.rs
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/svg/painting/OWNERS
testing/web-platform/tests/svg/painting/currentColor-override-pserver-fallback-ref.svg
testing/web-platform/tests/svg/painting/currentColor-override-pserver-fallback.svg
testing/web-platform/tests/svg/painting/currentColor-override-pserver-fill-ref.svg
testing/web-platform/tests/svg/painting/currentColor-override-pserver-fill.svg
testing/web-platform/tests/svg/painting/currentColor-override-pserver-stroke-ref.svg
testing/web-platform/tests/svg/painting/currentColor-override-pserver-stroke.svg
--- a/dom/smil/test/db_smilCSSPaced.js
+++ b/dom/smil/test/db_smilCSSPaced.js
@@ -23,53 +23,37 @@ var _pacedTestLists =
                           "rgb(20, 10, 8); " +
                           "rgb(20, 30, 4)",
                           { comp0:   "rgb(10, 10, 10)",
                             comp1_6: "rgb(15, 10, 9)",
                             comp1_3: "rgb(20, 10, 8)",
                             comp2_3: "rgb(20, 20, 6)",
                             comp1:   "rgb(20, 30, 4)"
                           }),
+    new AnimTestcasePaced("olive; " +        // rgb(128, 128, 0)
+                          "currentColor; " + // rgb(50, 50, 50)
+                          "rgb(206, 150, 206)",
+                          { comp0:   "rgb(128, 128, 0)",
+                            comp1_6: "rgb(89, 89, 25)",
+                            comp1_3: "rgb(50, 50, 50)",
+                            comp2_3: "rgb(128, 100, 128)",
+                            comp1:   "rgb(206, 150, 206)"
+                          }),
                           // Use the same RGB component values to make
                           // premultication effect easier to compute.
     new AnimTestcasePaced("rgba(20, 40, 60, 0.2); " +
                           "rgba(20, 40, 60, 0.4); " +
                           "rgba(20, 40, 60, 0.8)",
                           { comp0: "rgba(20, 40, 60, 0.2)",
                             comp1_6: "rgba(20, 40, 60, 0.3)",
                             comp1_3: "rgba(20, 40, 60, 0.4)",
                             comp2_3: "rgba(20, 40, 60, 0.6)",
                             comp1:   "rgba(20, 40, 60, 0.8)"
                           }),
   ],
-  currentColor_color: [
-    new AnimTestcasePaced("olive; " +        // rgb(128, 128, 0)
-                          "currentColor; " + // rgb(50, 50, 50)
-                          "rgb(206, 150, 206)",
-                          { comp0:   "rgb(128, 128, 0)",
-                            comp1_6: "rgb(89, 89, 25)",
-                            comp1_3: "rgb(50, 50, 50)",
-                            comp2_3: "rgb(128, 100, 128)",
-                            comp1:   "rgb(206, 150, 206)"
-                          }),
-  ],
-  currentColor_fill: [
-                          // Bug 1467622 changed the distance calculation
-                          // involving currentColor, comp values below
-                          // are no longer evenly spaced.
-    new AnimTestcasePaced("olive; " +        // rgb(128, 128, 0)
-                          "currentColor; " + // rgb(50, 50, 50)
-                          "rgb(206, 150, 206)",
-                          { comp0:   "rgb(128, 128, 0)",
-                            comp1_6: "rgb(99, 99, 18)",
-                            comp1_3: "rgb(71, 71, 37)",
-                            comp2_3: "rgb(111, 89, 111)",
-                            comp1:   "rgb(206, 150, 206)"
-                          }),
-  ],
   paintServer : [
     // Sanity check: These aren't interpolatable -- they should end up
     // ignoring the calcMode="paced" and falling into discrete-mode.
     new AnimTestcasePaced("url(#gradA); url(#gradB)",
           {
             comp0:   "url(\"" + document.URL + "#gradA\") rgb(0, 0, 0)",
             comp1_6: "url(\"" + document.URL + "#gradA\") rgb(0, 0, 0)",
             comp1_3: "url(\"" + document.URL + "#gradA\") rgb(0, 0, 0)",
@@ -221,25 +205,22 @@ var _pacedTestLists =
                           }),
   ],
 };
 
 // TODO: test more properties here.
 var gPacedBundles =
 [
   new TestcaseBundle(gPropList.clip,  _pacedTestLists.rect),
-  new TestcaseBundle(gPropList.color,
-                     [].concat(_pacedTestLists.color,
-                               _pacedTestLists.currentColor_color)),
+  new TestcaseBundle(gPropList.color, _pacedTestLists.color),
   new TestcaseBundle(gPropList.direction, [
     new AnimTestcasePaced("rtl; ltr; rtl")
   ]),
   new TestcaseBundle(gPropList.fill,
                      [].concat(_pacedTestLists.color,
-                               _pacedTestLists.currentColor_fill,
                                _pacedTestLists.paintServer)),
   new TestcaseBundle(gPropList.font_size,
                      [].concat(_pacedTestLists.lengthNoUnits,
                                _pacedTestLists.lengthPx, [
     new AnimTestcasePaced("20%; 24%; 16%",
                           { comp0:   "10px",
                             comp1_6: "11px",
                             comp1_3: "12px",
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1342,17 +1342,17 @@ nsImageFrame::DisplayAltText(nsPresConte
   }
 }
 
 struct nsRecessedBorder : public nsStyleBorder {
   nsRecessedBorder(nscoord aBorderWidth, nsPresContext* aPresContext)
     : nsStyleBorder(aPresContext)
   {
     NS_FOR_CSS_SIDES(side) {
-      BorderColorFor(side) = StyleComplexColor::Black();
+      BorderColorFor(side) = StyleComplexColor::FromColor(NS_RGB(0, 0, 0));
       mBorder.Side(side) = aBorderWidth;
       // Note: use SetBorderStyle here because we want to affect
       // mComputedBorder
       SetBorderStyle(side, NS_STYLE_BORDER_STYLE_INSET);
     }
   }
 };
 
--- a/layout/style/ComputedStyle.cpp
+++ b/layout/style/ComputedStyle.cpp
@@ -312,17 +312,17 @@ ExtractColor(ComputedStyle* aStyle, cons
 {
   return aColor.CalcColor(aStyle);
 }
 
 static nscolor
 ExtractColor(ComputedStyle* aStyle, const nsStyleSVGPaint& aPaintServer)
 {
   return aPaintServer.Type() == eStyleSVGPaintType_Color
-    ? aPaintServer.GetColor(aStyle) : NS_RGBA(0, 0, 0, 0);
+    ? aPaintServer.GetColor() : NS_RGBA(0, 0, 0, 0);
 }
 
 #define STYLE_FIELD(struct_, field_) aField == &struct_::field_ ||
 #define STYLE_STRUCT(name_, fields_)                                          \
   template<> nscolor                                                          \
   ComputedStyle::GetVisitedDependentColor(                                   \
     decltype(nsStyle##name_::MOZ_ARG_1 fields_) nsStyle##name_::* aField)     \
   {                                                                           \
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1634,17 +1634,17 @@ Gecko_CreateGradient(uint8_t aShape,
   result->mAngle.SetNoneValue();
   result->mBgPosX.SetNoneValue();
   result->mBgPosY.SetNoneValue();
   result->mRadiusX.SetNoneValue();
   result->mRadiusY.SetNoneValue();
 
   nsStyleGradientStop dummyStop = {
     nsStyleCoord(eStyleUnit_None),
-    StyleComplexColor::Black(),
+    StyleComplexColor::FromColor(NS_RGB(0, 0, 0)),
     0
   };
 
   for (uint32_t i = 0; i < aStopCount; i++) {
     result->mStops.AppendElement(dummyStop);
   }
 
   return result;
--- a/layout/style/StyleComplexColor.h
+++ b/layout/style/StyleComplexColor.h
@@ -34,26 +34,16 @@ public:
   }
   static StyleComplexColor CurrentColor() {
     return {NS_RGBA(0, 0, 0, 0), 1, eForeground};
   }
   static StyleComplexColor Auto() {
     return {NS_RGBA(0, 0, 0, 0), 1, eAuto};
   }
 
-  static StyleComplexColor Black() {
-    return StyleComplexColor::FromColor(NS_RGB(0, 0, 0));
-  }
-  static StyleComplexColor White() {
-    return StyleComplexColor::FromColor(NS_RGB(255, 255, 255));
-  }
-  static StyleComplexColor Transparent() {
-    return StyleComplexColor::FromColor(NS_RGBA(0, 0, 0, 0));
-  }
-
   bool IsAuto() const { return mTag == eAuto; }
   bool IsCurrentColor() const { return mTag == eForeground; }
 
   bool operator==(const StyleComplexColor& aOther) const {
     if (mTag != aOther.mTag) {
       return false;
     }
 
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4657,17 +4657,17 @@ nsComputedDOMStyle::GetFrameBoundsHeight
   return true;
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::GetFallbackValue(const nsStyleSVGPaint* aPaint)
 {
   RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
   if (aPaint->GetFallbackType() == eStyleSVGFallbackType_Color) {
-    SetToRGBAColor(fallback, aPaint->GetFallbackColor(mComputedStyle));
+    SetToRGBAColor(fallback, aPaint->GetFallbackColor());
   } else {
     fallback->SetIdent(eCSSKeyword_none);
   }
   return fallback.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::GetSVGPaintFor(bool aFill)
@@ -4679,17 +4679,17 @@ nsComputedDOMStyle::GetSVGPaintFor(bool 
 
   nsAutoString paintString;
 
   switch (paint->Type()) {
     case eStyleSVGPaintType_None:
       val->SetIdent(eCSSKeyword_none);
       break;
     case eStyleSVGPaintType_Color:
-      SetToRGBAColor(val, paint->GetColor(mComputedStyle));
+      SetToRGBAColor(val, paint->GetColor());
       break;
     case eStyleSVGPaintType_Server: {
       SetValueToURLValue(paint->GetPaintServer(), val);
       if (paint->GetFallbackType() != eStyleSVGFallbackType_NotSet) {
         RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
         RefPtr<CSSValue> fallback = GetFallbackValue(paint);
         valueList->AppendCSSValue(val.forget());
         valueList->AppendCSSValue(fallback.forget());
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1225,19 +1225,19 @@ nsStyleFilter::SetDropShadow(nsCSSShadow
   mType = NS_STYLE_FILTER_DROP_SHADOW;
 }
 
 // --------------------
 // nsStyleSVGReset
 //
 nsStyleSVGReset::nsStyleSVGReset(const nsPresContext* aContext)
   : mMask(nsStyleImageLayers::LayerType::Mask)
-  , mStopColor(StyleComplexColor::Black())
-  , mFloodColor(StyleComplexColor::Black())
-  , mLightingColor(StyleComplexColor::White())
+  , mStopColor(StyleComplexColor::FromColor(NS_RGB(0, 0, 0)))
+  , mFloodColor(StyleComplexColor::FromColor(NS_RGB(0, 0, 0)))
+  , mLightingColor(StyleComplexColor::FromColor(NS_RGB(255, 255, 255)))
   , mStopOpacity(1.0f)
   , mFloodOpacity(1.0f)
   , mDominantBaseline(NS_STYLE_DOMINANT_BASELINE_AUTO)
   , mVectorEffect(NS_STYLE_VECTOR_EFFECT_NONE)
   , mMaskType(NS_STYLE_MASK_TYPE_LUMINANCE)
 {
   MOZ_COUNT_CTOR(nsStyleSVGReset);
 }
@@ -1335,24 +1335,24 @@ nsStyleSVGReset::HasMask() const
     }
   }
 
   return false;
 }
 
 // nsStyleSVGPaint implementation
 nsStyleSVGPaint::nsStyleSVGPaint(nsStyleSVGPaintType aType)
-  : mPaint(StyleComplexColor::Black())
-  , mType(aType)
+  : mType(aType)
   , mFallbackType(eStyleSVGFallbackType_NotSet)
-  , mFallbackColor(StyleComplexColor::Black())
+  , mFallbackColor(NS_RGB(0, 0, 0))
 {
   MOZ_ASSERT(aType == nsStyleSVGPaintType(0) ||
              aType == eStyleSVGPaintType_None ||
              aType == eStyleSVGPaintType_Color);
+  mPaint.mColor = NS_RGB(0, 0, 0);
 }
 
 nsStyleSVGPaint::nsStyleSVGPaint(const nsStyleSVGPaint& aSource)
   : nsStyleSVGPaint(nsStyleSVGPaintType(0))
 {
   Assign(aSource);
 }
 
@@ -1363,26 +1363,26 @@ nsStyleSVGPaint::~nsStyleSVGPaint()
 
 void
 nsStyleSVGPaint::Reset()
 {
   switch (mType) {
     case eStyleSVGPaintType_None:
       break;
     case eStyleSVGPaintType_Color:
-      mPaint.mColor = StyleComplexColor::Black();
+      mPaint.mColor = NS_RGB(0, 0, 0);
       break;
     case eStyleSVGPaintType_Server:
       mPaint.mPaintServer->Release();
       mPaint.mPaintServer = nullptr;
       MOZ_FALLTHROUGH;
     case eStyleSVGPaintType_ContextFill:
     case eStyleSVGPaintType_ContextStroke:
       mFallbackType = eStyleSVGFallbackType_NotSet;
-      mFallbackColor = StyleComplexColor::Black();
+      mFallbackColor = NS_RGB(0, 0, 0);
       break;
   }
   mType = nsStyleSVGPaintType(0);
 }
 
 nsStyleSVGPaint&
 nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther)
 {
@@ -1424,38 +1424,38 @@ nsStyleSVGPaint::SetNone()
 {
   Reset();
   mType = eStyleSVGPaintType_None;
 }
 
 void
 nsStyleSVGPaint::SetContextValue(nsStyleSVGPaintType aType,
                                  nsStyleSVGFallbackType aFallbackType,
-                                 StyleComplexColor aFallbackColor)
+                                 nscolor aFallbackColor)
 {
   MOZ_ASSERT(aType == eStyleSVGPaintType_ContextFill ||
              aType == eStyleSVGPaintType_ContextStroke);
   Reset();
   mType = aType;
   mFallbackType = aFallbackType;
   mFallbackColor = aFallbackColor;
 }
 
 void
-nsStyleSVGPaint::SetColor(StyleComplexColor aColor)
+nsStyleSVGPaint::SetColor(nscolor aColor)
 {
   Reset();
   mType = eStyleSVGPaintType_Color;
   mPaint.mColor = aColor;
 }
 
 void
 nsStyleSVGPaint::SetPaintServer(css::URLValue* aPaintServer,
                                 nsStyleSVGFallbackType aFallbackType,
-                                StyleComplexColor aFallbackColor)
+                                nscolor aFallbackColor)
 {
   MOZ_ASSERT(aPaintServer);
   Reset();
   mType = eStyleSVGPaintType_Server;
   mPaint.mPaintServer = aPaintServer;
   mPaint.mPaintServer->AddRef();
   mFallbackType = aFallbackType;
   mFallbackColor = aFallbackColor;
@@ -3281,17 +3281,17 @@ nsStyleImageLayers::Layer::CalcDifferenc
 }
 
 // --------------------
 // nsStyleBackground
 //
 
 nsStyleBackground::nsStyleBackground(const nsPresContext* aContext)
   : mImage(nsStyleImageLayers::LayerType::Background)
-  , mBackgroundColor(StyleComplexColor::Transparent())
+  , mBackgroundColor(StyleComplexColor::FromColor(NS_RGBA(0, 0, 0, 0)))
 {
   MOZ_COUNT_CTOR(nsStyleBackground);
 }
 
 nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
   : mImage(aSource.mImage)
   , mBackgroundColor(aSource.mBackgroundColor)
 {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2866,71 +2866,68 @@ public:
   nsStyleSVGPaint(const nsStyleSVGPaint& aSource);
   ~nsStyleSVGPaint();
 
   nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
 
   nsStyleSVGPaintType Type() const { return mType; }
 
   void SetNone();
-  void SetColor(mozilla::StyleComplexColor aColor);
+  void SetColor(nscolor aColor);
   void SetPaintServer(mozilla::css::URLValue* aPaintServer,
                       nsStyleSVGFallbackType aFallbackType,
-                      mozilla::StyleComplexColor aFallbackColor);
+                      nscolor aFallbackColor);
   void SetPaintServer(mozilla::css::URLValue* aPaintServer) {
     SetPaintServer(aPaintServer, eStyleSVGFallbackType_NotSet,
-                   mozilla::StyleComplexColor::Black());
+                   NS_RGB(0, 0, 0));
   }
   void SetContextValue(nsStyleSVGPaintType aType,
                        nsStyleSVGFallbackType aFallbackType,
-                       mozilla::StyleComplexColor aFallbackColor);
+                       nscolor aFallbackColor);
   void SetContextValue(nsStyleSVGPaintType aType) {
-    SetContextValue(aType, eStyleSVGFallbackType_NotSet,
-                    mozilla::StyleComplexColor::Black());
+    SetContextValue(aType, eStyleSVGFallbackType_NotSet, NS_RGB(0, 0, 0));
   }
 
-  nscolor GetColor(mozilla::ComputedStyle* aComputedStyle) const {
+  nscolor GetColor() const {
     MOZ_ASSERT(mType == eStyleSVGPaintType_Color);
-    return mPaint.mColor.CalcColor(aComputedStyle);
+    return mPaint.mColor;
   }
 
   mozilla::css::URLValue* GetPaintServer() const {
     MOZ_ASSERT(mType == eStyleSVGPaintType_Server);
     return mPaint.mPaintServer;
   }
 
   nsStyleSVGFallbackType GetFallbackType() const {
     return mFallbackType;
   }
 
-  nscolor GetFallbackColor(mozilla::ComputedStyle* aComputedStyle) const {
+  nscolor GetFallbackColor() const {
     MOZ_ASSERT(mType == eStyleSVGPaintType_Server ||
                mType == eStyleSVGPaintType_ContextFill ||
                mType == eStyleSVGPaintType_ContextStroke);
-    return mFallbackColor.CalcColor(aComputedStyle);
+    return mFallbackColor;
   }
 
   bool operator==(const nsStyleSVGPaint& aOther) const;
   bool operator!=(const nsStyleSVGPaint& aOther) const {
     return !(*this == aOther);
   }
 
 private:
   void Reset();
   void Assign(const nsStyleSVGPaint& aOther);
 
-  union ColorOrPaintServer {
-    mozilla::StyleComplexColor mColor;
+  union {
+    nscolor mColor;
     mozilla::css::URLValue* mPaintServer;
-    explicit ColorOrPaintServer(mozilla::StyleComplexColor c) : mColor(c) {}
-  };
-  ColorOrPaintServer mPaint;
+  } mPaint;
   nsStyleSVGPaintType mType;
   nsStyleSVGFallbackType mFallbackType;
-  mozilla::StyleComplexColor mFallbackColor;
+  nscolor mFallbackColor;
 };
 
 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG
 {
   explicit nsStyleSVG(const nsPresContext* aContext);
   nsStyleSVG(const nsStyleSVG& aSource);
   ~nsStyleSVG();
   void FinishStyle(nsPresContext*, const nsStyleSVG*) {}
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -66,28 +66,28 @@ var supported_properties = {
     "border-top-right-radius": [ test_radius_transition ],
     "-moz-box-flex": [ test_float_zeroToOne_transition,
                        test_float_aboveOne_transition,
                        test_float_zeroToOne_clamped ],
     "box-shadow": [ test_shadow_transition ],
     "column-count": [ test_pos_integer_or_auto_transition,
                       test_integer_at_least_one_clamping ],
     "column-rule-color": [ test_color_transition,
-                           test_currentcolor_transition ],
+                           test_true_currentcolor_transition ],
     "column-rule-width": [ test_length_transition,
                            test_length_clamped ],
     "column-width": [ test_length_transition,
                       test_length_clamped ],
     "-moz-image-region": [ test_rect_transition ],
     "-moz-outline-radius-bottomleft": [ test_radius_transition ],
     "-moz-outline-radius-bottomright": [ test_radius_transition ],
     "-moz-outline-radius-topleft": [ test_radius_transition ],
     "-moz-outline-radius-topright": [ test_radius_transition ],
     "background-color": [ test_color_transition,
-                          test_currentcolor_transition ],
+                          test_true_currentcolor_transition ],
     "background-position": [ test_background_position_transition,
                              test_length_percent_pair_unclamped ],
     "background-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.
@@ -97,38 +97,38 @@ var supported_properties = {
                                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 */ ],
     "background-size": [ test_background_size_transition,
                          test_length_percent_pair_clamped ],
     "border-bottom-color": [ test_color_transition,
-                             test_currentcolor_transition ],
+                             test_true_currentcolor_transition ],
     "border-bottom-width": [ test_length_transition,
                              test_length_clamped ],
     "border-left-color": [ test_color_transition,
-                           test_currentcolor_transition ],
+                           test_true_currentcolor_transition ],
     "border-left-width": [ test_length_transition,
                            test_length_clamped ],
     "border-right-color": [ test_color_transition,
-                            test_currentcolor_transition ],
+                            test_true_currentcolor_transition ],
     "border-right-width": [ test_length_transition,
                             test_length_clamped ],
     "border-spacing": [ test_length_pair_transition,
                         test_length_pair_transition_clamped ],
     "border-top-color": [ test_color_transition,
-                          test_currentcolor_transition ],
+                          test_true_currentcolor_transition ],
     "border-top-width": [ test_length_transition,
                            test_length_clamped ],
     "bottom": [ test_length_transition, test_percent_transition,
                 test_length_percent_calc_transition,
                 test_length_unclamped, test_percent_unclamped ],
     "caret-color": [ test_color_transition,
-                     test_currentcolor_transition,
+                     test_true_currentcolor_transition,
                      test_auto_color_transition ],
     "clip": [ test_rect_transition ],
     "clip-path": [ test_basic_shape_or_url_transition ],
     "color": [ test_color_transition,
                test_currentcolor_transition ],
     "fill": [ test_color_transition,
               test_currentcolor_transition ],
     "fill-opacity" : [ test_float_zeroToOne_transition,
@@ -139,17 +139,17 @@ var supported_properties = {
     "flex-basis": [ test_length_transition, test_percent_transition,
                     test_length_clamped, test_percent_clamped,
                     test_flex_basis_content_transition ],
     "flex-grow": [ test_float_zeroToOne_transition,
                    test_float_aboveOne_transition ],
     "flex-shrink": [ test_float_zeroToOne_transition,
                      test_float_aboveOne_transition ],
     "flood-color": [ test_color_transition,
-                     test_currentcolor_transition ],
+                     test_true_currentcolor_transition ],
     "flood-opacity" : [ test_float_zeroToOne_transition,
                         // opacity is clamped in computed style
                         // (not parsing/interpolation)
                         test_float_zeroToOne_clamped ],
     "font-size": [ test_length_transition, test_percent_transition,
                    test_length_percent_calc_transition,
                    test_length_clamped, test_percent_clamped ],
     "font-size-adjust": [ test_float_zeroToOne_transition,
@@ -163,17 +163,17 @@ var supported_properties = {
     "height": [ test_length_transition, test_percent_transition,
                 test_length_percent_calc_transition,
                 test_length_clamped, test_percent_clamped ],
     "left": [ test_length_transition, test_percent_transition,
               test_length_percent_calc_transition,
               test_length_unclamped, test_percent_unclamped ],
     "letter-spacing": [ test_length_transition, test_length_unclamped ],
     "lighting-color": [ test_color_transition,
-                        test_currentcolor_transition ],
+                        test_true_currentcolor_transition ],
     // NOTE: when calc() is supported on 'line-height', we should add
     // test_length_percent_calc_transition.
     "line-height": [ test_length_transition, test_percent_transition,
                      test_length_clamped, test_percent_clamped ],
     "margin-bottom": [ test_length_transition, test_percent_transition,
                        test_length_percent_calc_transition,
                        test_length_unclamped, test_percent_unclamped ],
     "margin-left": [ test_length_transition, test_percent_transition,
@@ -213,17 +213,17 @@ var supported_properties = {
                    test_length_clamped, test_percent_clamped ],
     "object-position": [ test_background_position_transition ],
     "opacity" : [ test_float_zeroToOne_transition,
                   // opacity is clamped in computed style
                   // (not parsing/interpolation)
                   test_float_zeroToOne_clamped ],
     "order": [ test_integer_transition ],
     "outline-color": [ test_color_transition,
-                       test_currentcolor_transition ],
+                       test_true_currentcolor_transition ],
     "outline-offset": [ test_length_transition, test_length_unclamped ],
     "outline-width": [ test_length_transition, test_length_clamped ],
     "padding-bottom": [ test_length_transition, test_percent_transition,
                         test_length_percent_calc_transition,
                         test_length_clamped, test_percent_clamped ],
     "padding-left": [ test_length_transition, test_percent_transition,
                       test_length_percent_calc_transition,
                       test_length_clamped, test_percent_clamped ],
@@ -236,17 +236,17 @@ var supported_properties = {
     "perspective": [ test_length_transition ],
     "perspective-origin": [ test_length_pair_transition,
                             test_length_percent_pair_transition,
                             test_length_percent_pair_unclamped ],
     "right": [ test_length_transition, test_percent_transition,
                test_length_percent_calc_transition,
                test_length_unclamped, test_percent_unclamped ],
     "stop-color": [ test_color_transition,
-                    test_currentcolor_transition ],
+                    test_true_currentcolor_transition ],
     "stop-opacity" : [ test_float_zeroToOne_transition,
                        // opacity is clamped in computed style
                        // (not parsing/interpolation)
                        test_float_zeroToOne_clamped ],
     "stroke": [ test_color_transition,
                 test_currentcolor_transition ],
     "stroke-dasharray": [ test_dasharray_transition ],
     // NOTE: when calc() is supported on 'stroke-dashoffset', we should
@@ -261,21 +261,21 @@ var supported_properties = {
                          test_float_zeroToOne_clamped ],
     // NOTE: when calc() is supported on 'stroke-width', we should add
     // test_length_percent_calc_transition.
     "stroke-width": [ test_length_transition_svg, test_percent_transition,
                       test_length_clamped_svg, test_percent_clamped ],
     "-moz-tab-size": [ test_float_zeroToOne_transition,
                        test_float_aboveOne_transition, test_length_clamped ],
     "text-decoration": [ test_color_shorthand_transition,
-                         test_currentcolor_shorthand_transition ],
+                         test_true_currentcolor_shorthand_transition ],
     "text-decoration-color": [ test_color_transition,
-                               test_currentcolor_transition ],
+                               test_true_currentcolor_transition ],
     "text-emphasis-color": [ test_color_transition,
-                             test_currentcolor_transition ],
+                             test_true_currentcolor_transition ],
     "text-indent": [ test_length_transition, test_percent_transition,
                      test_length_unclamped, test_percent_unclamped ],
     "text-shadow": [ test_shadow_transition ],
     "top": [ test_length_transition, test_percent_transition,
              test_length_percent_calc_transition,
              test_length_unclamped, test_percent_unclamped ],
     "transform": [ test_transform_transition ],
     "transform-origin": [ test_length_pair_transition,
@@ -285,19 +285,19 @@ var supported_properties = {
                         test_length_unclamped, test_percent_unclamped ],
     "visibility": [ test_visibility_transition ],
     "width": [ test_length_transition, test_percent_transition,
                test_length_percent_calc_transition,
                test_length_clamped, test_percent_clamped ],
     "word-spacing": [ test_length_transition, test_length_unclamped ],
     "z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ],
     "-webkit-text-fill-color": [ test_color_transition,
-                                 test_currentcolor_transition ],
+                                 test_true_currentcolor_transition ],
     "-webkit-text-stroke-color": [ test_color_transition,
-                                   test_currentcolor_transition ]
+                                   test_true_currentcolor_transition ]
 };
 
 if (SpecialPowers.getBoolPref("layout.css.shape-outside.enabled")) {
   supported_properties["shape-image-threshold"] =
     [ test_float_zeroToOne_transition,
       // shape-image-threshold (like opacity) is clamped in computed style
       // (not parsing/interpolation)
       test_float_zeroToOne_clamped ];
@@ -318,22 +318,22 @@ if (IsCSSPropertyPrefEnabled("layout.css
   supported_properties["rotate"] = [ test_rotate_transition ];
   supported_properties["scale"] = [ test_scale_transition ];
   supported_properties["translate"] = [ test_translate_transition ];
 }
 
 if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-colors.enabled")) {
   supported_properties["scrollbar-face-color"] = [
     test_color_transition,
-    test_currentcolor_transition,
+    test_true_currentcolor_transition,
     test_auto_color_transition,
   ];
   supported_properties["scrollbar-track-color"] = [
     test_color_transition,
-    test_currentcolor_transition,
+    test_true_currentcolor_transition,
     test_auto_color_transition,
   ];
 }
 
 var div = document.getElementById("display");
 var OMTAdiv = document.getElementById("transformTest");
 var cs = getComputedStyle(div, "");
 var OMTACs = getComputedStyle(OMTAdiv, "");
@@ -1396,58 +1396,74 @@ function test_color_transition(prop, get
   is(vals[2], "255",
      "color-valued property " + prop + ": clamping of above-range (green)");
   is(vals[3], "0",
      "color-valued property " + prop + ": clamping of negatives (blue)");
   div.style.setProperty("transition-timing-function", "linear", "");
 }
 
 function test_currentcolor_transition(prop, get_color=(x => x), is_shorthand=false) {
+  div.style.setProperty("transition-property", "none", "");
+  div.style.setProperty(prop, "rgb(128, 64, 0)", "");
+  (prop == "color" ? div.parentNode : div).style.
+    setProperty("color", "rgb(0, 0, 128)", "");
+  is(get_color(cs.getPropertyValue(prop)), "rgb(128, 64, 0)",
+     "color-valued property " + prop + ": computed value before transition");
+  div.style.setProperty("transition-property", prop, "");
+  div.style.setProperty(prop, "currentColor", "");
+  is(get_color(cs.getPropertyValue(prop)), "rgb(96, 48, 32)",
+     "color-valued property " + prop + ": interpolation of currentColor");
+
+  if (!is_shorthand) {
+    check_distance(prop, "rgb(128, 64, 0)", "rgb(96, 48, 32)",
+                         "currentColor");
+  }
+
+  (prop == "color" ? div.parentNode : div).style.removeProperty("color");
+}
+
+function test_true_currentcolor_transition(prop, get_color=(x => x), is_shorthand=false) {
   const msg_prefix = `color-valued property ${prop}: `;
   div.style.setProperty("transition-property", "none", "");
-  (prop == "color" ? div.parentNode : div).style.
-    setProperty("color", "rgb(128, 0, 0)", "");
+  div.style.setProperty("color", "rgb(128, 0, 0)", "");
   div.style.setProperty(prop, "rgb(0, 0, 128)", "");
   is(get_color(cs.getPropertyValue(prop)), "rgb(0, 0, 128)",
      msg_prefix + "computed value before transition");
   div.style.setProperty("transition-property", prop, "");
   div.style.setProperty(prop, "currentcolor", "");
   is(get_color(cs.getPropertyValue(prop)), "rgb(32, 0, 96)",
      msg_prefix + "interpolation of rgb color and currentcolor");
 
-  if (prop != "color") {
-    div.style.setProperty("transition-property", "none", "");
-    div.style.setProperty("color", "rgb(128, 0, 0)", "");
-    div.style.setProperty(prop, "rgb(0, 0, 128)", "");
-    is(get_color(cs.getPropertyValue(prop)), "rgb(0, 0, 128)",
-       msg_prefix + "computed value before transition");
-    div.style.setProperty("transition-property", `color, ${prop}`, "");
-    div.style.setProperty("color", "rgb(0, 128, 0)", "");
-    div.style.setProperty(prop, "currentcolor", "");
-    is(cs.getPropertyValue("color"), "rgb(96, 32, 0)",
-       "interpolation of rgb color property");
-    is(get_color(cs.getPropertyValue(prop)), "rgb(24, 8, 96)",
-       msg_prefix + "interpolation of rgb color and interpolated currentcolor");
-  }
+  div.style.setProperty("transition-property", "none", "");
+  div.style.setProperty("color", "rgb(128, 0, 0)", "");
+  div.style.setProperty(prop, "rgb(0, 0, 128)", "");
+  is(get_color(cs.getPropertyValue(prop)), "rgb(0, 0, 128)",
+     msg_prefix + "computed value before transition");
+  div.style.setProperty("transition-property", `color, ${prop}`, "");
+  div.style.setProperty("color", "rgb(0, 128, 0)", "");
+  div.style.setProperty(prop, "currentcolor", "");
+  is(cs.getPropertyValue("color"), "rgb(96, 32, 0)",
+     "interpolation of rgb color property");
+  is(get_color(cs.getPropertyValue(prop)), "rgb(24, 8, 96)",
+     msg_prefix + "interpolation of rgb color and interpolated currentcolor");
 
   div.style.setProperty("transition-property", "none", "");
-  (prop == "color" ? div.parentNode : div).style.
-    setProperty("color", "rgba(128, 0, 0, 0.6)", "");
+  div.style.setProperty("color", "rgba(128, 0, 0, 0.6)", "");
   div.style.setProperty(prop, "rgba(0, 0, 128, 0.8)", "");
   is(get_color(cs.getPropertyValue(prop)), "rgba(0, 0, 128, 0.8)",
      msg_prefix + "computed value before transition");
   div.style.setProperty("transition-property", prop, "");
   div.style.setProperty(prop, "currentcolor", "");
   is(get_color(cs.getPropertyValue(prop)), "rgba(26, 0, 102, 0.75)",
      msg_prefix + "interpolation of rgba color and currentcolor");
 
   // It is not possible to check distance, because there is a hidden
   // dimension for ratio of currentcolor.
 
-  (prop == "color" ? div.parentNode : div).style.removeProperty("color");
+  div.style.removeProperty("color");
 }
 
 function test_auto_color_transition(prop, get_color=(x => x), is_shorthand=false) {
   const msg_prefix = `color-valued property ${prop}: `;
   const test_color = "rgb(51, 102, 153)";
   div.style.setProperty("transition-property", "none", "");
   div.style.setProperty(prop, "auto", "");
   let used_value_of_auto = get_color(cs.getPropertyValue(prop));
@@ -1469,16 +1485,20 @@ function get_color_from_shorthand_value(
 function test_color_shorthand_transition(prop) {
   test_color_transition(prop, get_color_from_shorthand_value, true);
 }
 
 function test_currentcolor_shorthand_transition(prop) {
   test_currentcolor_transition(prop, get_color_from_shorthand_value, true);
 }
 
+function test_true_currentcolor_shorthand_transition(prop) {
+  test_true_currentcolor_transition(prop, get_color_from_shorthand_value, true);
+}
+
 function test_shape_or_url_equals(computedValStr, expected)
 {
   // Check simple case "none"
   if (computedValStr == "none" && computedValStr == expected[0]) {
     return true;
   }
   // We will update the expected list in this function for checking the result,
   // so we clone it first to avoid affecting the input parameter.
--- a/layout/svg/SVGImageContext.cpp
+++ b/layout/svg/SVGImageContext.cpp
@@ -48,22 +48,22 @@ SVGImageContext::MaybeStoreContextPaint(
 
   bool haveContextPaint = false;
 
   RefPtr<SVGEmbeddingContextPaint> contextPaint = new SVGEmbeddingContextPaint();
 
   if ((style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_FILL) &&
       style->mFill.Type() == eStyleSVGPaintType_Color) {
     haveContextPaint = true;
-    contextPaint->SetFill(style->mFill.GetColor(aFromComputedStyle));
+    contextPaint->SetFill(style->mFill.GetColor());
   }
   if ((style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_STROKE) &&
       style->mStroke.Type() == eStyleSVGPaintType_Color) {
     haveContextPaint = true;
-    contextPaint->SetStroke(style->mStroke.GetColor(aFromComputedStyle));
+    contextPaint->SetStroke(style->mStroke.GetColor());
   }
   if (style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_FILL_OPACITY) {
     haveContextPaint = true;
     contextPaint->SetFillOpacity(style->mFillOpacity);
   }
   if (style->mContextPropsBits & NS_STYLE_CONTEXT_PROPERTY_STROKE_OPACITY) {
     haveContextPaint = true;
     contextPaint->SetStrokeOpacity(style->mStrokeOpacity);
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1434,39 +1434,39 @@ nsSVGUtils::GetFallbackOrPaintColor(Comp
 {
   const nsStyleSVGPaint &paint = aComputedStyle->StyleSVG()->*aFillOrStroke;
   ComputedStyle *styleIfVisited = aComputedStyle->GetStyleIfVisited();
   nscolor color;
   switch (paint.Type()) {
     case eStyleSVGPaintType_Server:
     case eStyleSVGPaintType_ContextStroke:
       color = paint.GetFallbackType() == eStyleSVGFallbackType_Color ?
-                paint.GetFallbackColor(aComputedStyle) : NS_RGBA(0, 0, 0, 0);
+                paint.GetFallbackColor() : NS_RGBA(0, 0, 0, 0);
       break;
     case eStyleSVGPaintType_ContextFill:
       color = paint.GetFallbackType() == eStyleSVGFallbackType_Color ?
-                paint.GetFallbackColor(aComputedStyle) : NS_RGB(0, 0, 0);
+                paint.GetFallbackColor() : NS_RGB(0, 0, 0);
       break;
     default:
-      color = paint.GetColor(aComputedStyle);
+      color = paint.GetColor();
       break;
   }
   if (styleIfVisited) {
     const nsStyleSVGPaint &paintIfVisited =
       styleIfVisited->StyleSVG()->*aFillOrStroke;
     // To prevent Web content from detecting if a user has visited a URL
     // (via URL loading triggered by paint servers or performance
     // differences between paint servers or between a paint server and a
     // color), we do not allow whether links are visited to change which
     // paint server is used or switch between paint servers and simple
     // colors.  A :visited style may only override a simple color with
     // another simple color.
     if (paintIfVisited.Type() == eStyleSVGPaintType_Color &&
         paint.Type() == eStyleSVGPaintType_Color) {
-      nscolor colors[2] = { color, paintIfVisited.GetColor(aComputedStyle) };
+      nscolor colors[2] = { color, paintIfVisited.GetColor() };
       return ComputedStyle::CombineVisitedColors(
                colors, aComputedStyle->RelevantLinkVisited());
     }
   }
   return color;
 }
 
 /* static */ void
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -663,24 +663,24 @@ def set_gecko_property(ffi_name, expr):
             SVGPaintKind::PaintServer(url) => {
                 unsafe {
                     bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.0.url_value.get());
                 }
             }
             SVGPaintKind::Color(color) => {
                 paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
                 unsafe {
-                    *paint.mPaint.mColor.as_mut() = color.into();
+                    *paint.mPaint.mColor.as_mut() = convert_rgba_to_nscolor(&color);
                 }
             }
         }
 
         paint.mFallbackType = match fallback {
             Some(Either::First(color)) => {
-                paint.mFallbackColor = color.into();
+                paint.mFallbackColor = convert_rgba_to_nscolor(&color);
                 nsStyleSVGFallbackType::eStyleSVGFallbackType_Color
             },
             Some(Either::Second(_)) => {
                 nsStyleSVGFallbackType::eStyleSVGFallbackType_None
             },
             None => nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet
         };
     }
@@ -705,17 +705,17 @@ def set_gecko_property(ffi_name, expr):
         use values::computed::url::ComputedUrl;
         use values::generics::svg::{SVGPaint, SVGPaintKind};
         use self::structs::nsStyleSVGPaintType;
         use self::structs::nsStyleSVGFallbackType;
         let ref paint = ${get_gecko_property(gecko_ffi_name)};
 
         let fallback = match paint.mFallbackType {
             nsStyleSVGFallbackType::eStyleSVGFallbackType_Color => {
-                Some(Either::First(paint.mFallbackColor.into()))
+                Some(Either::First(convert_nscolor_to_rgba(paint.mFallbackColor)))
             },
             nsStyleSVGFallbackType::eStyleSVGFallbackType_None => {
                 Some(Either::Second(None_))
             },
             nsStyleSVGFallbackType::eStyleSVGFallbackType_NotSet => None,
         };
 
         let kind = match paint.mType {
@@ -724,18 +724,17 @@ def set_gecko_property(ffi_name, expr):
             nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke => SVGPaintKind::ContextStroke,
             nsStyleSVGPaintType::eStyleSVGPaintType_Server => {
                 SVGPaintKind::PaintServer(unsafe {
                     let url = RefPtr::new(*paint.mPaint.mPaintServer.as_ref());
                     ComputedUrl::from_url_value(url)
                 })
             }
             nsStyleSVGPaintType::eStyleSVGPaintType_Color => {
-                let col = unsafe { *paint.mPaint.mColor.as_ref() };
-                SVGPaintKind::Color(col.into())
+                unsafe { SVGPaintKind::Color(convert_nscolor_to_rgba(*paint.mPaint.mColor.as_ref())) }
             }
         };
         SVGPaint {
             kind: kind,
             fallback: fallback,
         }
     }
 </%def>
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -24,17 +24,17 @@ use properties::{LonghandId, ShorthandId
 use servo_arc::Arc;
 use smallvec::SmallVec;
 use std::{cmp, ptr};
 use std::mem::{self, ManuallyDrop};
 use hash::FnvHashMap;
 use super::ComputedValues;
 use values::CSSFloat;
 use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
-use values::animated::color::Color as AnimatedColor;
+use values::animated::color::RGBA as AnimatedRGBA;
 use values::animated::effects::Filter as AnimatedFilter;
 #[cfg(feature = "gecko")] use values::computed::TransitionProperty;
 use values::computed::{Angle, CalcLengthOrPercentage};
 use values::computed::{ClipRect, Context};
 use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
 use values::computed::{LengthOrPercentageOrNone, MaxLength};
 use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage};
 use values::computed::length::NonNegativeLengthOrPercentage;
@@ -2669,20 +2669,20 @@ impl ComputeSquaredDistance for Computed
             return matrix1.compute_squared_distance(&matrix2);
         }
 
         squared_dist
     }
 }
 
 /// Animated SVGPaint
-pub type IntermediateSVGPaint = SVGPaint<AnimatedColor, ComputedUrl>;
+pub type IntermediateSVGPaint = SVGPaint<AnimatedRGBA, ComputedUrl>;
 
 /// Animated SVGPaintKind
-pub type IntermediateSVGPaintKind = SVGPaintKind<AnimatedColor, ComputedUrl>;
+pub type IntermediateSVGPaintKind = SVGPaintKind<AnimatedRGBA, ComputedUrl>;
 
 impl ToAnimatedZero for IntermediateSVGPaint {
     #[inline]
     fn to_animated_zero(&self) -> Result<Self, ()> {
         Ok(IntermediateSVGPaint {
             kind: self.kind.to_animated_zero()?,
             fallback: self.fallback.and_then(|v| v.to_animated_zero().ok()),
         })
--- a/servo/components/style/values/animated/color.rs
+++ b/servo/components/style/values/animated/color.rs
@@ -121,113 +121,61 @@ impl Animate for Color {
     fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
         use self::GenericColor::*;
 
         // Common cases are interpolating between two numeric colors,
         // two currentcolors, and a numeric color and a currentcolor.
         let (this_weight, other_weight) = procedure.weights();
 
         Ok(match (*self, *other, procedure) {
-            // Any interpolation of currentcolor with currentcolor returns currentcolor.
-            (Foreground, Foreground, Procedure::Interpolate { .. }) => Foreground,
+            // Any interpolation of currentColor with currentColor returns currentColor.
+            (Foreground, Foreground, Procedure::Interpolate { .. }) => Color::currentcolor(),
             // Animating two numeric colors.
             (Numeric(c1), Numeric(c2), _) => Numeric(c1.animate(&c2, procedure)?),
-            // Combinations of numeric color and currentcolor
+            // Combinations of numeric color and currentColor
             (Foreground, Numeric(color), _) => Self::with_ratios(
                 color,
                 ComplexColorRatios {
                     bg: other_weight as f32,
                     fg: this_weight as f32,
                 },
             ),
             (Numeric(color), Foreground, _) => Self::with_ratios(
                 color,
                 ComplexColorRatios {
                     bg: this_weight as f32,
                     fg: other_weight as f32,
                 },
             ),
 
-            // Any other animation of currentcolor with currentcolor.
+            // Any other animation of currentColor with currentColor.
             (Foreground, Foreground, _) => Self::with_ratios(
                 RGBA::transparent(),
                 ComplexColorRatios {
                     bg: 0.,
                     fg: (this_weight + other_weight) as f32,
                 },
             ),
 
             // Defer to complex calculations
             _ => {
-                // Compute the "scaled" contribution for `color`.
-                fn scaled_rgba(color: &Color) -> RGBA {
-                    match *color {
-                        GenericColor::Numeric(color) => color,
-                        GenericColor::Foreground => RGBA::transparent(),
-                        GenericColor::Complex(color, ratios) => RGBA {
-                            red: color.red * ratios.bg,
-                            green: color.green * ratios.bg,
-                            blue: color.blue * ratios.bg,
-                            alpha: color.alpha * ratios.bg,
-                        },
-                    }
-                }
+                // For interpolating between two complex colors, we need to
+                // generate colors with effective alpha value.
+                let self_color = self.effective_intermediate_rgba();
+                let other_color = other.effective_intermediate_rgba();
+                let color = self_color.animate(&other_color, procedure)?;
+                // Then we compute the final background ratio, and derive
+                // the final alpha value from the effective alpha value.
+                let self_ratios = self.effective_ratios();
+                let other_ratios = other.effective_ratios();
+                let ratios = self_ratios.animate(&other_ratios, procedure)?;
+                let alpha = color.alpha / ratios.bg;
+                let color = RGBA { alpha, ..color };
 
-                // Each `Color`, represents a complex combination of foreground color and
-                // background color where fg and bg represent the overall
-                // contributions. ie:
-                //
-                //    color = { bg * mColor, fg * foreground }
-                //          =   { bg_color , fg_color }
-                //          =     bg_color + fg_color
-                //
-                // where `foreground` is `currentcolor`, and `bg_color`,
-                // `fg_color` are the scaled background and foreground
-                // contributions.
-                //
-                // Each operation, lerp, addition, or accumulate, can be
-                // represented as a scaled-addition each complex color. ie:
-                //
-                //    p * col1 + q * col2
-                //
-                // where p = (1 - a), q = a for lerp(a), p = 1, q = 1 for
-                // addition, etc.
-                //
-                // Therefore:
-                //
-                //    col1 op col2
-                //    = p * col1 + q * col2
-                //    = p * { bg_color1, fg_color1 } + q * { bg_color2, fg_color2 }
-                //    = p * (bg_color1 + fg_color1) + q * (bg_color2 + fg_color2)
-                //    = p * bg_color1 + p * fg_color1 + q * bg_color2 + p * fg_color2
-                //    = (p * bg_color1 + q * bg_color2) + (p * fg_color1 + q * fg_color2)
-                //    = (bg_color1 op bg_color2) + (fg_color1 op fg_color2)
-                //
-                // fg_color1 op fg_color2 is equivalent to (fg1 op fg2) * foreground,
-                // so the final color is:
-                //
-                //    = { bg_color, fg_color }
-                //    = { 1 * (bg_color1 op bg_color2), (fg1 op fg2) * foreground }
-
-                // To perform the operation on two complex colors, we need to
-                // generate the scaled contributions of each background color
-                // component.
-                let bg_color1 = scaled_rgba(self);
-                let bg_color2 = scaled_rgba(other);
-                // Perform bg_color1 op bg_color2
-                let bg_color = bg_color1.animate(&bg_color2, procedure)?;
-
-                // Calculate the final foreground color ratios; perform
-                // animation on effective fg ratios.
-                let ComplexColorRatios { fg: fg1, .. } = self.effective_ratios();
-                let ComplexColorRatios { fg: fg2, .. } = other.effective_ratios();
-                // Perform fg1 op fg2
-                let fg = fg1.animate(&fg2, procedure)?;
-
-                Self::with_ratios(bg_color, ComplexColorRatios { bg: 1., fg })
+                Self::with_ratios(color, ratios)
             }
         })
     }
 }
 
 impl ComputeSquaredDistance for Color {
     #[inline]
     fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
--- a/servo/components/style/values/computed/svg.rs
+++ b/servo/components/style/values/computed/svg.rs
@@ -4,42 +4,41 @@
 
 //! Computed types for SVG properties.
 
 use app_units::Au;
 use values::RGBA;
 use values::computed::{LengthOrPercentage, NonNegativeLength};
 use values::computed::{NonNegativeLengthOrPercentage, NonNegativeNumber, Number};
 use values::computed::Opacity;
-use values::computed::color::Color;
 use values::computed::url::ComputedUrl;
 use values::generics::svg as generic;
 
 pub use values::specified::SVGPaintOrder;
 
 pub use values::specified::MozContextProperties;
 
 /// Computed SVG Paint value
-pub type SVGPaint = generic::SVGPaint<Color, ComputedUrl>;
+pub type SVGPaint = generic::SVGPaint<RGBA, ComputedUrl>;
 /// Computed SVG Paint Kind value
-pub type SVGPaintKind = generic::SVGPaintKind<Color, ComputedUrl>;
+pub type SVGPaintKind = generic::SVGPaintKind<RGBA, ComputedUrl>;
 
 impl Default for SVGPaint {
     fn default() -> Self {
         SVGPaint {
             kind: generic::SVGPaintKind::None,
             fallback: None,
         }
     }
 }
 
 impl SVGPaint {
     /// Opaque black color
     pub fn black() -> Self {
-        let rgba = RGBA::from_floats(0., 0., 0., 1.).into();
+        let rgba = RGBA::from_floats(0., 0., 0., 1.);
         SVGPaint {
             kind: generic::SVGPaintKind::Color(rgba),
             fallback: None,
         }
     }
 }
 
 /// A value of <length> | <percentage> | <number> for stroke-dashoffset.
--- a/servo/components/style/values/generics/color.rs
+++ b/servo/components/style/values/generics/color.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Generic types for color properties.
 
 /// Ratios representing the contribution of color and currentcolor to
 /// the final color value.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)]
+#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)]
 pub struct ComplexColorRatios {
     /// Numeric color contribution.
     pub bg: f32,
     /// Foreground color, aka currentcolor, contribution.
     pub fg: f32,
 }
 
 impl ComplexColorRatios {
--- a/servo/components/style/values/specified/svg.rs
+++ b/servo/components/style/values/specified/svg.rs
@@ -8,24 +8,24 @@ use cssparser::Parser;
 use parser::{Parse, ParserContext};
 use std::fmt::{self, Write};
 use style_traits::{CommaWithSpace, CssWriter, ParseError, Separator};
 use style_traits::{StyleParseErrorKind, ToCss};
 use values::CustomIdent;
 use values::generics::svg as generic;
 use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber};
 use values::specified::{Number, Opacity};
-use values::specified::color::Color;
+use values::specified::color::RGBAColor;
 use values::specified::url::SpecifiedUrl;
 
 /// Specified SVG Paint value
-pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>;
+pub type SVGPaint = generic::SVGPaint<RGBAColor, SpecifiedUrl>;
 
 /// Specified SVG Paint Kind value
-pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>;
+pub type SVGPaintKind = generic::SVGPaintKind<RGBAColor, SpecifiedUrl>;
 
 #[cfg(feature = "gecko")]
 fn is_context_value_enabled() -> bool {
     // The prefs can only be mutated on the main thread, so it is safe
     // to read whenever we are on the main thread or the main thread is
     // blocked.
     use gecko_bindings::structs::mozilla;
     unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled }
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -183966,52 +183966,16 @@
       [
        "/svg/linking/reftests/use-descendant-combinator-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
-   "svg/painting/currentColor-override-pserver-fallback.svg": [
-    [
-     "/svg/painting/currentColor-override-pserver-fallback.svg",
-     [
-      [
-       "/svg/painting/currentColor-override-pserver-fallback-ref.svg",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "svg/painting/currentColor-override-pserver-fill.svg": [
-    [
-     "/svg/painting/currentColor-override-pserver-fill.svg",
-     [
-      [
-       "/svg/painting/currentColor-override-pserver-fill-ref.svg",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "svg/painting/currentColor-override-pserver-stroke.svg": [
-    [
-     "/svg/painting/currentColor-override-pserver-stroke.svg",
-     [
-      [
-       "/svg/painting/currentColor-override-pserver-stroke-ref.svg",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "svg/path/bearing/absolute.svg": [
     [
      "/svg/path/bearing/absolute.svg",
      [
       [
        "/svg/path/bearing/absolute-ref.svg",
        "=="
       ]
@@ -297269,36 +297233,16 @@
      {}
     ]
    ],
    "svg/linking/scripted/testcommon.js": [
     [
      {}
     ]
    ],
-   "svg/painting/OWNERS": [
-    [
-     {}
-    ]
-   ],
-   "svg/painting/currentColor-override-pserver-fallback-ref.svg": [
-    [
-     {}
-    ]
-   ],
-   "svg/painting/currentColor-override-pserver-fill-ref.svg": [
-    [
-     {}
-    ]
-   ],
-   "svg/painting/currentColor-override-pserver-stroke-ref.svg": [
-    [
-     {}
-    ]
-   ],
    "svg/path/bearing/absolute-ref.svg": [
     [
      {}
     ]
    ],
    "svg/path/bearing/relative-ref.svg": [
     [
      {}
@@ -573596,20 +573540,16 @@
   "html/dom/elements/semantics-0/.gitkeep": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "html/dom/elements/the-innertext-idl-attribute/OWNERS": [
    "3a52efa37cb05c353bb8ce78146c42db6a238b74",
    "support"
   ],
-  "html/dom/elements/the-innertext-idl-attribute/dynamic-getter.html": [
-   "90be7a0dddb948a2734c6a502f775446676a5cf2",
-   "testharness"
-  ],
   "html/dom/elements/the-innertext-idl-attribute/getter-tests.js": [
    "42f3e48763297d3360c1074a7c2b706a6f539d37",
    "support"
   ],
   "html/dom/elements/the-innertext-idl-attribute/getter.html": [
    "bfcd91955e1645278f7825d472bcce03dbc8f773",
    "testharness"
   ],
@@ -616556,44 +616496,16 @@
   "svg/linking/scripted/testScripts/externalScript2.js": [
    "6360f077307c4d532d06105ef2830876eb8642ee",
    "support"
   ],
   "svg/linking/scripted/testcommon.js": [
    "1367de727c679521d6b7237b97b86c5516e9363c",
    "support"
   ],
-  "svg/painting/OWNERS": [
-   "793bbbcd7b50cd21b5ba5895ab97fa8ae23522d2",
-   "support"
-  ],
-  "svg/painting/currentColor-override-pserver-fallback-ref.svg": [
-   "ecfd31db61525a01eeb7d40e9d46d88508096fb6",
-   "support"
-  ],
-  "svg/painting/currentColor-override-pserver-fallback.svg": [
-   "5ebc8cafe14d0cab8db3a47878c6f299ed4c0645",
-   "reftest"
-  ],
-  "svg/painting/currentColor-override-pserver-fill-ref.svg": [
-   "6a534c27b80b2e2a28611243da3aa35662d0fb27",
-   "support"
-  ],
-  "svg/painting/currentColor-override-pserver-fill.svg": [
-   "9fa970bd0f2e2d059094408b0f7a42d430b938f2",
-   "reftest"
-  ],
-  "svg/painting/currentColor-override-pserver-stroke-ref.svg": [
-   "9aa1ab0d77e12ae86ad2d10c9e38d93eda9a89e5",
-   "support"
-  ],
-  "svg/painting/currentColor-override-pserver-stroke.svg": [
-   "d8e578f5422229b37676ecdc7146488ac0865eaf",
-   "reftest"
-  ],
   "svg/path/bearing/absolute-ref.svg": [
    "6ad5320a05fcc31fd2af98d2bbd0bd6fbc558daa",
    "support"
   ],
   "svg/path/bearing/absolute.svg": [
    "e1c8d4bca5ab9519936a96521006baa176296c27",
    "reftest"
   ],
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/OWNERS
+++ /dev/null
@@ -1,1 +0,0 @@
-@kamidphish
\ No newline at end of file
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-fallback-ref.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <!-- pattern inherits fill color via currentcolor -->
-  <circle stroke="black" fill="limegreen" cx="50" cy="50" r="40" />
-</svg>
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-fallback.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <metadata>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="author" title="Dan Glastonbury" href="mailto:dglastonbury@mozilla.com"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/pservers.html"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="currentColor-override-pserver-fallback-ref.svg"/>
-    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="missing pattern fallback inherits fill color via currentcolor."/>
-  </metadata>
-
-  <g fill="url(#NotFound) currentcolor" color="red">
-    <circle color="limegreen" stroke="black" cx="50" cy="50" r="40" />
-  </g>
-</svg>
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-fill-ref.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <!-- pattern inherits fill color via currentcolor -->
-  <defs>
-    <pattern id="MyPattern" patternUnits="userSpaceOnUse"
-             x="5" y ="5" width="10" height="10">
-      <circle fill="limegreen" cx="5" cy="5" r="5" />
-    </pattern>
-  </defs>
-
-  <circle color="blue" stroke="black" fill="url(#MyPattern)" cx="50" cy="50" r="40" />
-</svg>
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-fill.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <metadata>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="author" title="Dan Glastonbury" href="mailto:dglastonbury@mozilla.com"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/pservers.html"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="currentColor-override-pserver-fill-ref.svg"/>
-    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="pattern inherits fill color via currentcolor."/>
-  </metadata>
-
-  <defs>
-    <pattern id="MyPattern" patternUnits="userSpaceOnUse"
-             x="5" y ="5" width="10" height="10" color="red" fill="currentcolor">
-      <circle color="limegreen" fill="inherit" cx="5" cy="5" r="5" />
-    </pattern>
-  </defs>
-
-  <circle stroke="black" fill="url(#MyPattern)" cx="50" cy="50" r="40" />
-</svg>
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-stroke-ref.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <!-- pattern inherits fill color via currentcolor -->
-  <defs>
-    <pattern id="MyPattern" patternUnits="userSpaceOnUse"
-             x="5" y ="5" width="10" height="10">
-      <circle stroke="limegreen" stroke-width="5%" cx="5" cy="5" r="5" />
-    </pattern>
-  </defs>
-
-  <circle stroke="black" fill="url(#MyPattern)" cx="50" cy="50" r="40" />
-</svg>
deleted file mode 100644
--- a/testing/web-platform/tests/svg/painting/currentColor-override-pserver-stroke.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg">
-  <metadata>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="author" title="Dan Glastonbury" href="mailto:dglastonbury@mozilla.com"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="help" href="https://www.w3.org/TR/SVG2/pservers.html"/>
-    <link xmlns="http://www.w3.org/1999/xhtml" rel="match" href="currentColor-override-pserver-stroke-ref.svg"/>
-    <meta xmlns="http://www.w3.org/1999/xhtml" name="assert" content="pattern inherits stroke color via currentcolor."/>
-  </metadata>
-
-  <defs>
-    <pattern id="MyPattern" patternUnits="userSpaceOnUse"
-             x="5" y ="5" width="10" height="10" color="red" stroke="currentcolor">
-      <circle color="limegreen" stroke="inherit" stroke-width="5%" cx="5" cy="5" r="5" />
-    </pattern>
-  </defs>
-
-  <circle stroke="black" fill="url(#MyPattern)" cx="50" cy="50" r="40" />
-</svg>