Bug 1551991 - Remove nsCSSValue usage for range checks in CounterStyleRule. r=jwatt
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 16 May 2019 23:05:38 +0000
changeset 474266 f06a39190b3d96439f9a1bd4e340f360244a4711
parent 474265 76ba2ec949d32634e2dd9ea5ba0a91170bda89a5
child 474267 80046630ae827214930d393824be223a68fe6805
push id36027
push usershindli@mozilla.com
push dateFri, 17 May 2019 16:24:38 +0000
treeherdermozilla-central@c94c54aff466 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1551991
milestone68.0a1
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
Bug 1551991 - Remove nsCSSValue usage for range checks in CounterStyleRule. r=jwatt Depends on D31317 Differential Revision: https://phabricator.services.mozilla.com/D31318
layout/style/CounterStyleManager.cpp
servo/ports/geckolib/glue.rs
--- a/layout/style/CounterStyleManager.cpp
+++ b/layout/style/CounterStyleManager.cpp
@@ -1178,33 +1178,31 @@ void CustomCounterStyle::GetNegative(Neg
 
 static inline bool IsRangeValueInfinite(const nsCSSValue& aValue) {
   return aValue.GetUnit() == eCSSUnit_Enumerated &&
          aValue.GetIntValue() == NS_STYLE_COUNTER_RANGE_INFINITE;
 }
 
 /* virtual */
 bool CustomCounterStyle::IsOrdinalInRange(CounterValue aOrdinal) {
-  nsCSSValue value = GetDesc(eCSSCounterDesc_Range);
-  if (value.GetUnit() == eCSSUnit_PairList) {
-    for (const nsCSSValuePairList* item = value.GetPairListValue();
-         item != nullptr; item = item->mNext) {
-      const nsCSSValue& lowerBound = item->mXValue;
-      const nsCSSValue& upperBound = item->mYValue;
-      if ((IsRangeValueInfinite(lowerBound) ||
-           aOrdinal >= lowerBound.GetIntValue()) &&
-          (IsRangeValueInfinite(upperBound) ||
-           aOrdinal <= upperBound.GetIntValue())) {
-        return true;
+  auto inRange = Servo_CounterStyleRule_IsInRange(mRule, aOrdinal);
+  switch (inRange) {
+    case StyleIsOrdinalInRange::InRange:
+      return true;
+    case StyleIsOrdinalInRange::NotInRange:
+      return false;
+    case StyleIsOrdinalInRange::NoOrdinalSpecified:
+      if (IsExtendsSystem()) {
+        return GetExtends()->IsOrdinalInRange(aOrdinal);
       }
-    }
-    return false;
-  } else if (IsExtendsSystem() && value.GetUnit() == eCSSUnit_None) {
-    // Only use the range of extended style when 'range' is not specified.
-    return GetExtends()->IsOrdinalInRange(aOrdinal);
+      break;
+    case StyleIsOrdinalInRange::Auto:
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("Unkown result from IsInRange?");
   }
   return IsOrdinalInAutoRange(aOrdinal);
 }
 
 /* virtual */
 bool CustomCounterStyle::IsOrdinalInAutoRange(CounterValue aOrdinal) {
   switch (mSystem) {
     case NS_STYLE_COUNTER_SYSTEM_CYCLIC:
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3027,16 +3027,64 @@ pub unsafe extern "C" fn Servo_CounterSt
         *suffix = match negative.1 {
             Some(ref s) => symbol_to_string(s),
             None => nsString::new(),
         };
         true
     })
 }
 
+#[repr(u8)]
+pub enum IsOrdinalInRange {
+    Auto,
+    InRange,
+    NotInRange,
+    NoOrdinalSpecified,
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_CounterStyleRule_IsInRange(
+    rule: &RawServoCounterStyleRule,
+    ordinal: i32,
+) -> IsOrdinalInRange {
+    use style::counter_style::CounterBound;
+    read_locked_arc(rule, |rule: &CounterStyleRule| {
+        let range = match rule.range() {
+            Some(r) => r,
+            None => return IsOrdinalInRange::NoOrdinalSpecified,
+        };
+
+        if range.0.is_empty() {
+            return IsOrdinalInRange::Auto;
+        }
+
+        let in_range = range.0.iter().any(|r| {
+            if let CounterBound::Integer(start) = r.start {
+                if start.value() > ordinal {
+                    return false;
+                }
+            }
+
+            if let CounterBound::Integer(end) = r.end {
+                if end.value() < ordinal {
+                    return false;
+                }
+            }
+
+            true
+        });
+
+        if in_range {
+            IsOrdinalInRange::InRange
+        } else {
+            IsOrdinalInRange::NotInRange
+        }
+    })
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn Servo_CounterStyleRule_GetSystem(
     rule: &RawServoCounterStyleRule,
 ) -> u8 {
     use style::counter_style::System;
     read_locked_arc(rule, |rule: &CounterStyleRule| {
         match *rule.resolved_system() {
             System::Cyclic => structs::NS_STYLE_COUNTER_SYSTEM_CYCLIC,