Bug 1415670 Part 2: Calculate negativeNumber for each GridLine. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 08 Nov 2017 14:06:51 -0800
changeset 707903 6c530e38bea4f57197990de1d721fc777eceb1d8
parent 707902 d426b41b25040ee6fe28719e2bf91b9023d48946
child 707904 ad5da451b74968cc8cfb5c41b9f620e597bf07e8
push id92240
push userbwerth@mozilla.com
push dateTue, 05 Dec 2017 22:58:46 +0000
bugs1415670
milestone59.0a1
Bug 1415670 Part 2: Calculate negativeNumber for each GridLine. MozReview-Commit-ID: D56jk7MbeIa
dom/grid/GridLine.cpp
dom/grid/GridLine.h
dom/grid/GridLines.cpp
dom/grid/GridLines.h
--- a/dom/grid/GridLine.cpp
+++ b/dom/grid/GridLine.cpp
@@ -68,27 +68,29 @@ uint32_t
 GridLine::Number() const
 {
   return mNumber;
 }
 
 int32_t
 GridLine::NegativeNumber() const
 {
-  return 0;
+  return mNegativeNumber;
 }
 
 void
 GridLine::SetLineValues(const nsTArray<nsString>& aNames,
                         double aStart,
                         double aBreadth,
                         uint32_t aNumber,
+                        int32_t aNegativeNumber,
                         GridDeclaration aType)
 {
   mNames = aNames;
   mStart = aStart;
   mBreadth = aBreadth;
   mNumber = aNumber;
+  mNegativeNumber = aNegativeNumber;
   mType = aType;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/grid/GridLine.h
+++ b/dom/grid/GridLine.h
@@ -43,23 +43,25 @@ public:
   GridDeclaration Type() const;
   uint32_t Number() const;
   int32_t NegativeNumber() const;
 
   void SetLineValues(const nsTArray<nsString>& aNames,
                      double aStart,
                      double aBreadth,
                      uint32_t aNumber,
+                     int32_t aNegativeNumber,
                      GridDeclaration aType);
 
 protected:
   RefPtr<GridLines> mParent;
   nsTArray<nsString> mNames;
   double mStart;
   double mBreadth;
   GridDeclaration mType;
   uint32_t mNumber;
+  int32_t mNegativeNumber;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_GridLine_h */
--- a/dom/grid/GridLines.cpp
+++ b/dom/grid/GridLines.cpp
@@ -70,28 +70,44 @@ GridLines::SetLineInfo(const ComputedGri
 {
   MOZ_ASSERT(aLineInfo);
   mLines.Clear();
 
   if (!aTrackInfo) {
     return;
   }
 
-  uint32_t trackCount = aTrackInfo->mEndFragmentTrack -
-                        aTrackInfo->mStartFragmentTrack;
+  uint32_t lineCount = aTrackInfo->mEndFragmentTrack -
+                       aTrackInfo->mStartFragmentTrack +
+                       1;
 
   // If there is at least one track, line count is one more
   // than the number of tracks.
-  if (trackCount > 0) {
+  if (lineCount > 0) {
     nscoord lastTrackEdge = 0;
     nscoord startOfNextTrack;
     uint32_t repeatIndex = 0;
     uint32_t numRepeatTracks = aTrackInfo->mRemovedRepeatTracks.Length();
     uint32_t numAddedLines = 0;
 
+    // For the calculation of negative line numbers, we need to know
+    // the total number of leading implicit and explicit tracks.
+    // This might be different from the number of tracks sizes in
+    // aTrackInfo, because some of those tracks may be auto-fits that
+    // have been removed.
+    uint32_t leadingTrackCount = aTrackInfo->mNumLeadingImplicitTracks +
+                                 aTrackInfo->mNumExplicitTracks;
+    if (numRepeatTracks > 0) {
+      for (auto& removedTrack : aTrackInfo->mRemovedRepeatTracks) {
+        if (removedTrack) {
+          ++leadingTrackCount;
+        }
+      }
+    }
+
     for (uint32_t i = aTrackInfo->mStartFragmentTrack;
          i < aTrackInfo->mEndFragmentTrack + 1;
          i++) {
       // Since line indexes are 1-based, calculate a 1-based value
       // for this track to simplify some calculations.
       const uint32_t line1Index = i + 1;
 
       startOfNextTrack = (i < aTrackInfo->mEndFragmentTrack) ?
@@ -132,60 +148,66 @@ GridLines::SetLineInfo(const ComputedGri
       if (i >= (aTrackInfo->mRepeatFirstTrack +
                 aTrackInfo->mNumLeadingImplicitTracks) &&
           repeatIndex < numRepeatTracks) {
         numAddedLines += AppendRemovedAutoFits(aTrackInfo,
                                                aLineInfo,
                                                lastTrackEdge,
                                                repeatIndex,
                                                numRepeatTracks,
+                                               leadingTrackCount,
                                                lineNames);
       }
 
       RefPtr<GridLine> line = new GridLine(this);
       mLines.AppendElement(line);
       MOZ_ASSERT(line1Index > 0, "line1Index must be positive.");
       bool isBeforeFirstExplicit =
         (line1Index <= aTrackInfo->mNumLeadingImplicitTracks);
+      bool isAfterLastExplicit = line1Index > (leadingTrackCount + 1);
       // Calculate an actionable line number for this line, that could be used
       // in a css grid property to align a grid item or area at that line.
       // For implicit lines that appear before line 1, report a number of 0.
       // We can't report negative indexes, because those have a different
       // meaning in the css grid spec (negative indexes are negative-1-based
       // from the end of the grid decreasing towards the front).
       uint32_t lineNumber = isBeforeFirstExplicit ? 0 :
-        (line1Index - aTrackInfo->mNumLeadingImplicitTracks + numAddedLines);
+        (line1Index + numAddedLines - aTrackInfo->mNumLeadingImplicitTracks);
+
+      // The negativeNumber is counted back from the leadingTrackCount.
+      int32_t lineNegativeNumber = isAfterLastExplicit ? 0 :
+        (line1Index + numAddedLines - (leadingTrackCount + 2));
       GridDeclaration lineType =
-        (isBeforeFirstExplicit ||
-         line1Index > (aTrackInfo->mNumLeadingImplicitTracks +
-                       aTrackInfo->mNumExplicitTracks + 1))
+        (isBeforeFirstExplicit || isAfterLastExplicit)
          ? GridDeclaration::Implicit
          : GridDeclaration::Explicit;
       line->SetLineValues(
         lineNames,
         nsPresContext::AppUnitsToDoubleCSSPixels(lastTrackEdge),
         nsPresContext::AppUnitsToDoubleCSSPixels(startOfNextTrack -
                                                  lastTrackEdge),
         lineNumber,
+        lineNegativeNumber,
         lineType
       );
 
       if (i < aTrackInfo->mEndFragmentTrack) {
         lastTrackEdge = aTrackInfo->mPositions[i] + aTrackInfo->mSizes[i];
       }
     }
   }
 }
 
 uint32_t
 GridLines::AppendRemovedAutoFits(const ComputedGridTrackInfo* aTrackInfo,
                                  const ComputedGridLineInfo* aLineInfo,
                                  nscoord aLastTrackEdge,
                                  uint32_t& aRepeatIndex,
                                  uint32_t aNumRepeatTracks,
+                                 uint32_t aNumLeadingTracks,
                                  nsTArray<nsString>& aLineNames)
 {
   // Check to see if lineNames contains ALL of the before line names.
   bool alreadyHasBeforeLineNames = true;
   for (const auto& beforeName : aLineInfo->mNamesBefore) {
     if (!aLineNames.Contains(beforeName)) {
       alreadyHasBeforeLineNames = false;
       break;
@@ -220,23 +242,39 @@ GridLines::AppendRemovedAutoFits(const C
     // If this is the second or later time through, or didn't already
     // have before names, add them.
     if (linesAdded > 0 || !alreadyHasBeforeLineNames) {
       aLineNames.AppendElements(aLineInfo->mNamesBefore);
     }
 
     RefPtr<GridLine> line = new GridLine(this);
     mLines.AppendElement(line);
+
+    // Time to calculate the line numbers. For the positive numbers
+    // we count with a 1-based index from mRepeatFirstTrack. Although
+    // this number is the index of the first repeat track AFTER all
+    // the leading implicit tracks, that's still what we want since
+    // all those leading implicit tracks have line number 0.
     uint32_t lineNumber = aTrackInfo->mRepeatFirstTrack +
                           aRepeatIndex + 1;
+
+    // The negative number does have to account for the leading
+    // implicit tracks. We've been passed aNumLeadingTracks which is
+    // the total of the leading implicit tracks plus the explicit
+    // tracks. So all we have to do is subtract that number plus one
+    // from the 0-based index of this track.
+    int32_t lineNegativeNumber = (aTrackInfo->mNumLeadingImplicitTracks +
+                                  aTrackInfo->mRepeatFirstTrack +
+                                  aRepeatIndex) - (aNumLeadingTracks + 1);
     line->SetLineValues(
       aLineNames,
       nsPresContext::AppUnitsToDoubleCSSPixels(aLastTrackEdge),
       nsPresContext::AppUnitsToDoubleCSSPixels(0),
       lineNumber,
+      lineNegativeNumber,
       GridDeclaration::Explicit
     );
 
     // No matter what, the next line should have the after names associated
     // with it. If we go through the loop again, the before names will also
     // be added.
     aLineNames = aLineInfo->mNamesAfter;
     aRepeatIndex++;
--- a/dom/grid/GridLines.h
+++ b/dom/grid/GridLines.h
@@ -45,16 +45,17 @@ public:
                    bool aIsRow);
 
 protected:
   uint32_t AppendRemovedAutoFits(const ComputedGridTrackInfo* aTrackInfo,
                                  const ComputedGridLineInfo* aLineInfo,
                                  nscoord aLastTrackEdge,
                                  uint32_t& aRepeatIndex,
                                  uint32_t aNumRepeatTracks,
+                                 uint32_t aNumLeadingTracks,
                                  nsTArray<nsString>& aLineNames);
 
   RefPtr<GridDimension> mParent;
   nsTArray<RefPtr<GridLine>> mLines;
 };
 
 } // namespace dom
 } // namespace mozilla