Bug 1312379 part 3 - [css-align][css-tables] Add methods for CSS Alignment first/last baseline of the table container. r=dholbert a=cbook
☠☠ backed out by 7af89361ca4a ☠ ☠
authorMats Palmgren <mats@mozilla.com>
Thu, 22 Dec 2016 16:08:42 +0100
changeset 353178 e341f4fa167cae19c0a81660f6ffae628061c519
parent 353177 2973e5aa9d5cf9e6e147aea4cec33a2a80a5f124
child 353179 c1e8046838571461c7bcca048ff88a96a6be0138
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, cbook
bugs1312379
milestone52.0a2
Bug 1312379 part 3 - [css-align][css-tables] Add methods for CSS Alignment first/last baseline of the table container. r=dholbert a=cbook
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
layout/tables/nsTableWrapperFrame.h
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3774,45 +3774,64 @@ nsTableFrame::GetRowSpacing(int32_t aSta
   NS_ASSERTION(aStartRowIndex <= aEndRowIndex,
                "End index must not be less than start index");
   // Only one possible value so just multiply it out. Tables where index
   // matters will override this function
   return GetRowSpacing() * (aEndRowIndex - aStartRowIndex);
 }
 
 /* virtual */ nscoord
-nsTableFrame::GetLogicalBaseline(WritingMode aWritingMode) const
-{
-  nscoord ascent = 0;
+nsTableFrame::GetLogicalBaseline(WritingMode aWM) const
+{
+  nscoord baseline;
+  if (!GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::eFirst, &baseline)) {
+    baseline = BSize(aWM);
+  }
+  return baseline;
+}
+
+/* virtual */ bool
+nsTableFrame::GetNaturalBaselineBOffset(WritingMode aWM,
+                                        BaselineSharingGroup aBaselineGroup,
+                                        nscoord*             aBaseline) const
+{
   RowGroupArray orderedRowGroups;
   OrderRowGroups(orderedRowGroups);
-  nsTableRowFrame* firstRow = nullptr;
   // XXX not sure if this should be the size of the containing block instead.
   nsSize containerSize = mRect.Size();
-  for (uint32_t rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
-    nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
-    if (rgFrame->GetRowCount()) {
-      firstRow = rgFrame->GetFirstRow();
-
-      nscoord rgNormalBStart =
-        LogicalRect(aWritingMode, rgFrame->GetNormalRect(), containerSize)
-        .Origin(aWritingMode).B(aWritingMode);
-      nscoord firstRowNormalBStart =
-        LogicalRect(aWritingMode, firstRow->GetNormalRect(), containerSize)
-        .Origin(aWritingMode).B(aWritingMode);
-
-      ascent = rgNormalBStart + firstRowNormalBStart +
-               firstRow->GetRowBaseline(aWritingMode);
-      break;
-    }
-  }
-  if (!firstRow)
-    ascent = BSize(aWritingMode);
-  return ascent;
-}
+  auto TableBaseline = [aWM, containerSize] (nsTableRowGroupFrame* aRowGroup,
+                                             nsTableRowFrame* aRow) {
+    nscoord rgBStart = LogicalRect(aWM, aRowGroup->GetNormalRect(),
+                                   containerSize).BStart(aWM);
+    nscoord rowBStart = LogicalRect(aWM, aRow->GetNormalRect(),
+                                    containerSize).BStart(aWM);
+    return rgBStart + rowBStart + aRow->GetRowBaseline(aWM);
+  };
+  if (aBaselineGroup == BaselineSharingGroup::eFirst) {
+    for (uint32_t rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
+      nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
+      nsTableRowFrame* row = rgFrame->GetFirstRow();
+      if (row) {
+        *aBaseline = TableBaseline(rgFrame, row);
+        return true;
+      }
+    }
+  } else {
+    for (uint32_t rgIndex = orderedRowGroups.Length(); rgIndex-- > 0;) {
+      nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
+      nsTableRowFrame* row = rgFrame->GetLastRow();
+      if (row) {
+        *aBaseline = BSize(aWM) - TableBaseline(rgFrame, row);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 /* ----- global methods ----- */
 
 nsTableFrame*
 NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableFrame(aContext);
 }
 
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -467,16 +467,20 @@ private:
   /* For the base implementation of nsTableFrame, cell spacing does not depend
    * on row/column indexing.
    */
   nscoord GetColSpacing();
   nscoord GetRowSpacing();
 
 public:
   virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
+  bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
+                                 BaselineSharingGroup aBaselineGroup,
+                                 nscoord*             aBaseline) const override;
+
   /** return the row span of a cell, taking into account row span magic at the bottom
     * of a table. The row span equals the number of rows spanned by aCell starting at
     * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
     * index in which aCell originates.
     *
     * @param aStartRowIndex the cell
     * @param aCell          the cell
     *
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -502,17 +502,29 @@ nsTableRowGroupFrame::ReflowChildren(nsP
     }
   }
 }
 
 nsTableRowFrame*
 nsTableRowGroupFrame::GetFirstRow()
 {
   for (nsIFrame* childFrame : mFrames) {
-    nsTableRowFrame *rowFrame = do_QueryFrame(childFrame);
+    nsTableRowFrame* rowFrame = do_QueryFrame(childFrame);
+    if (rowFrame) {
+      return rowFrame;
+    }
+  }
+  return nullptr;
+}
+
+nsTableRowFrame*
+nsTableRowGroupFrame::GetLastRow()
+{
+  for (auto iter = mFrames.rbegin(), end = mFrames.rend(); iter != end; ++iter) {
+    nsTableRowFrame* rowFrame = do_QueryFrame(*iter);
     if (rowFrame) {
       return rowFrame;
     }
   }
   return nullptr;
 }
 
 
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -98,16 +98,17 @@ public:
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::tableRowGroupFrame
    */
   virtual nsIAtom* GetType() const override;
 
   nsTableRowFrame* GetFirstRow();
+  nsTableRowFrame* GetLastRow();
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
   virtual mozilla::WritingMode GetWritingMode() const override
     { return GetTableFrame()->GetWritingMode(); }
 
--- a/layout/tables/nsTableWrapperFrame.h
+++ b/layout/tables/nsTableWrapperFrame.h
@@ -63,16 +63,35 @@ public:
                                 const nsDisplayListSet& aLists) override;
 
   void BuildDisplayListForInnerTable(nsDisplayListBuilder*   aBuilder,
                                      const nsRect&           aDirtyRect,
                                      const nsDisplayListSet& aLists);
 
   virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
 
+  bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM,
+                                 BaselineSharingGroup aBaselineGroup,
+                                 nscoord*             aBaseline) const override
+  {
+    auto innerTable = InnerTableFrame();
+    nscoord offset;
+    if (innerTable->GetNaturalBaselineBOffset(aWM, aBaselineGroup, &offset)) {
+      auto bStart = innerTable->BStart(aWM, mRect.Size());
+      if (aBaselineGroup == BaselineSharingGroup::eFirst) {
+        *aBaseline = offset + bStart;
+      } else {
+        auto bEnd = bStart + innerTable->BSize(aWM);
+        *aBaseline = BSize(aWM) - (bEnd - offset);
+      }
+      return true;
+    }
+    return false;
+  }
+
   virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
 
   virtual mozilla::LogicalSize
   ComputeAutoSize(nsRenderingContext*         aRenderingContext,
                   mozilla::WritingMode        aWM,
                   const mozilla::LogicalSize& aCBSize,
                   nscoord                     aAvailableISize,