Bug 1305325 - Part 2: Define neutral values for each CSS property. r?birtles draft
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Fri, 21 Oct 2016 05:46:24 +0900
changeset 427786 5d3715c285ec83dd966f9aace24b5148f5eb0aab
parent 427785 1fa7ce8acbfdb561f2cfeb5396a26a158b7adf6d
child 427787 44db51bbe77a99c064b179de3bfedf9a552dd6c2
push id33113
push userbmo:hiikezoe@mozilla-japan.org
push dateThu, 20 Oct 2016 21:36:11 +0000
reviewersbirtles
bugs1305325
milestone52.0a1
Bug 1305325 - Part 2: Define neutral values for each CSS property. r?birtles Neutral value is zero element in additive operation space for each property. For properties that are unable to define neutral value, we will handle uninitialized StyleAnimationValue as the neutral value. MozReview-Commit-ID: Ye4QTcGoYl
layout/style/StyleAnimationValue.cpp
layout/style/StyleAnimationValue.h
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -4794,8 +4794,194 @@ StyleAnimationValue::operator==(const St
                         aOther.GetStringBufferValue()) == 0);
     case eUnit_ComplexColor:
       return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
   }
 
   NS_NOTREACHED("incomplete case");
   return false;
 }
+
+/* static */ StyleAnimationValue
+StyleAnimationValue::NeutralValue(nsCSSPropertyID aProperty)
+{
+  StyleAnimationValue result;
+
+  MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
+             "bad property");
+  nsStyleAnimType animType = nsCSSProps::kAnimTypeTable[aProperty];
+  switch (animType) {
+    case eStyleAnimType_Custom:
+      switch (aProperty) {
+        case eCSSProperty_border_bottom_width:
+        case eCSSProperty_border_left_width:
+        case eCSSProperty_border_right_width:
+        case eCSSProperty_border_top_width:
+        case eCSSProperty_column_rule_width:
+          result.SetCoordValue(0);
+          break;
+
+        case eCSSProperty_column_count:
+        case eCSSProperty_order:
+        case eCSSProperty_font_weight:
+          result.SetIntValue(0, Unit::eUnit_Integer);
+          break;
+
+        case eCSSProperty_border_spacing: {
+          auto value = MakeUnique<nsCSSValuePair>();
+          nscoordToCSSValue(0, value->mXValue);
+          nscoordToCSSValue(0, value->mYValue);
+          result.SetAndAdoptCSSValuePairValue(value.release(),
+                                              Unit::eUnit_CSSValuePair);
+          break;
+        }
+
+        case eCSSProperty_transform_origin: {
+          auto value = MakeUnique<nsCSSValueTriplet>();
+          nscoordToCSSValue(0, value->mXValue);
+          nscoordToCSSValue(0, value->mYValue);
+          nscoordToCSSValue(0, value->mZValue);
+          result.SetAndAdoptCSSValueTripletValue(value.release(),
+                                                 Unit::eUnit_CSSValueTriplet);
+          break;
+        }
+
+        case eCSSProperty_perspective_origin: {
+          auto value = MakeUnique<nsCSSValuePair>();
+          nscoordToCSSValue(0, value->mXValue);
+          nscoordToCSSValue(0, value->mYValue);
+          result.SetAndAdoptCSSValuePairValue(value.release(),
+                                              Unit::eUnit_CSSValuePair);
+          break;
+        }
+
+        case eCSSProperty_image_region:
+        case eCSSProperty_clip: {
+          nsCSSRect *vrect = new nsCSSRect;
+          nscoordToCSSValue(0, vrect->mLeft);
+          nscoordToCSSValue(0, vrect->mTop);
+          nscoordToCSSValue(0, vrect->mRight);
+          nscoordToCSSValue(0, vrect->mBottom);
+          result.SetAndAdoptCSSRectValue(vrect, Unit::eUnit_CSSRect);
+          break;
+        }
+
+        case eCSSProperty_object_position: {
+          // object-position: 0px 0px
+          auto value = MakeUnique<nsCSSValue>();
+          SetPositionValue(Position(), *value);
+          result.SetAndAdoptCSSValueValue(value.release(),
+                                          Unit::eUnit_ObjectPosition);
+          break;
+        }
+
+#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
+        case eCSSProperty_mask_position_x:
+        case eCSSProperty_mask_position_y:
+#endif
+        case eCSSProperty_background_position_x:
+        case eCSSProperty_background_position_y: {
+          // background-position-x: 0px or background-position-y: 0px
+          auto valueList = MakeUnique<nsCSSValueList>();
+          SetPositionCoordValue(Position::Coord(), valueList->mValue);
+          result.SetAndAdoptCSSValueListValue(
+            valueList.release(), Unit::eUnit_BackgroundPositionCoord);
+          break;
+        }
+
+#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
+        case eCSSProperty_mask_size:
+#endif
+        case eCSSProperty_background_size: {
+          // background-size: 0% 0%
+          auto value = MakeUnique<nsCSSValuePairList>();
+          value->mXValue.SetPercentValue(0);
+          value->mYValue.SetPercentValue(0);
+          result.SetAndAdoptCSSValuePairListValue(value.release());
+          break;
+        }
+
+        case eCSSProperty_transform: {
+          // transform: matrix3d(1, 0, 0, 0,
+          //                     0, 1, 0, 0,
+          //                     0, 0, 1, 0,
+          //                     0, 0, 0, 1)
+          nsAutoPtr<nsCSSValueList> value;
+          nsCSSValueList **tail = getter_Transfers(value);
+          RefPtr<nsCSSValue::Array> arr =
+            AppendTransformFunction(eCSSKeyword_matrix3d, tail);
+          // FIXME: Use nsStyleTransformMatrix::SetIdentityMatrix.
+          arr->Item(1).SetFloatValue(1, eCSSUnit_Number);
+          arr->Item(2).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(3).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(4).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(5).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(6).SetFloatValue(1, eCSSUnit_Number);
+          arr->Item(7).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(8).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(9).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(10).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(11).SetFloatValue(1, eCSSUnit_Number);
+          arr->Item(12).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(13).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(14).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(15).SetFloatValue(0, eCSSUnit_Number);
+          arr->Item(16).SetFloatValue(1, eCSSUnit_Number);
+          result.SetTransformValue(new nsCSSValueSharedList(value.forget()));
+          break;
+        }
+
+        case eCSSProperty_filter:
+          // Unfortunately we can't define neutral values for url() filter
+          // functions so that we can't define any neutral values for any filter
+          // property until we know underlying values.
+        case eCSSProperty_clip_path:
+        case eCSSProperty_font_stretch:
+        case eCSSProperty_stroke_dasharray:
+          // Can't define neutral value.
+          break;
+
+        default:
+          MOZ_ASSERT_UNREACHABLE("missing property implementation");
+          break;
+      }
+      break;
+    case eStyleAnimType_Coord:
+    case eStyleAnimType_Sides_Top:
+    case eStyleAnimType_Sides_Right:
+    case eStyleAnimType_Sides_Bottom:
+    case eStyleAnimType_Sides_Left:
+    case eStyleAnimType_nscoord:
+      result.SetCoordValue(0);
+      break;
+    case eStyleAnimType_Corner_TopLeft:
+    case eStyleAnimType_Corner_TopRight:
+    case eStyleAnimType_Corner_BottomRight:
+    case eStyleAnimType_Corner_BottomLeft: {
+      auto value = MakeUnique<nsCSSValuePair>();
+      nscoordToCSSValue(0, value->mXValue);
+      nscoordToCSSValue(0, value->mYValue);
+      result.SetAndAdoptCSSValuePairValue(value.release(),
+                                          Unit::eUnit_CSSValuePair);
+      break;
+    }
+    case eStyleAnimType_float:
+      result.SetFloatValue(0.0);
+      break;
+    case eStyleAnimType_Color:
+    case eStyleAnimType_ComplexColor:
+      result.SetColorValue(NS_RGBA(0, 0, 0, 0));
+      break;
+    case eStyleAnimType_PaintServer:
+    case eStyleAnimType_Shadow:
+    case eStyleAnimType_Discrete:
+      // In case of discrete type, paint server, shadow type, we can't define
+      // neutral value. So we handle eUnit_Null as neutral values for such
+      // properties.
+      break;
+    case eStyleAnimType_None:
+      MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(
+        "shouldn't specify non-animatable properties");
+      break;
+  }
+  return result;
+}
+
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -537,16 +537,21 @@ public:
     }
     return *this;
   }
 
   bool operator==(const StyleAnimationValue& aOther) const;
   bool operator!=(const StyleAnimationValue& aOther) const
     { return !(*this == aOther); }
 
+  // Create a neutral value for |aProperty|.
+  // Returns uninitialized StyleAnimationValue if neutral value is indefinable
+  // for |aProperty|, e.g. discrete type animation.
+  static StyleAnimationValue NeutralValue(nsCSSPropertyID aProperty);
+
 private:
   void FreeValue();
 
   static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
     return static_cast<char16_t*>(aBuffer->Data());
   }
 
   static bool IsIntUnit(Unit aUnit) {