| OLD | NEW | 
|     1 /* |     1 /* | 
|     2  * Copyright (C) 1997 Martin Jones (mjones@kde.org) |     2  * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 
|     3  *           (C) 1997 Torben Weis (weis@kde.org) |     3  *           (C) 1997 Torben Weis (weis@kde.org) | 
|     4  *           (C) 1998 Waldo Bastian (bastian@kde.org) |     4  *           (C) 1998 Waldo Bastian (bastian@kde.org) | 
|     5  *           (C) 1999 Lars Knoll (knoll@kde.org) |     5  *           (C) 1999 Lars Knoll (knoll@kde.org) | 
|     6  *           (C) 1999 Antti Koivisto (koivisto@kde.org) |     6  *           (C) 1999 Antti Koivisto (koivisto@kde.org) | 
|     7  * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. All r
      ights reserved. |     7  * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. | 
 |     8  *               All rights reserved. | 
|     8  * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |     9  * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 
|     9  * |    10  * | 
|    10  * This library is free software; you can redistribute it and/or |    11  * This library is free software; you can redistribute it and/or | 
|    11  * modify it under the terms of the GNU Library General Public |    12  * modify it under the terms of the GNU Library General Public | 
|    12  * License as published by the Free Software Foundation; either |    13  * License as published by the Free Software Foundation; either | 
|    13  * version 2 of the License, or (at your option) any later version. |    14  * version 2 of the License, or (at your option) any later version. | 
|    14  * |    15  * | 
|    15  * This library is distributed in the hope that it will be useful, |    16  * This library is distributed in the hope that it will be useful, | 
|    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of |    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|    34 #include "core/layout/SubtreeLayoutScope.h" |    35 #include "core/layout/SubtreeLayoutScope.h" | 
|    35 #include "core/paint/TableSectionPainter.h" |    36 #include "core/paint/TableSectionPainter.h" | 
|    36 #include "wtf/HashSet.h" |    37 #include "wtf/HashSet.h" | 
|    37 #include <algorithm> |    38 #include <algorithm> | 
|    38 #include <limits> |    39 #include <limits> | 
|    39  |    40  | 
|    40 namespace blink { |    41 namespace blink { | 
|    41  |    42  | 
|    42 using namespace HTMLNames; |    43 using namespace HTMLNames; | 
|    43  |    44  | 
|    44 // This variable is used to balance the memory consumption vs the paint invalida
      tion time on big tables. |    45 // This variable is used to balance the memory consumption vs the paint | 
 |    46 // invalidation time on big tables. | 
|    45 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; |    47 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; | 
|    46  |    48  | 
|    47 static inline void setRowLogicalHeightToRowStyleLogicalHeight( |    49 static inline void setRowLogicalHeightToRowStyleLogicalHeight( | 
|    48     LayoutTableSection::RowStruct& row) { |    50     LayoutTableSection::RowStruct& row) { | 
|    49   ASSERT(row.rowLayoutObject); |    51   ASSERT(row.rowLayoutObject); | 
|    50   row.logicalHeight = row.rowLayoutObject->style()->logicalHeight(); |    52   row.logicalHeight = row.rowLayoutObject->style()->logicalHeight(); | 
|    51 } |    53 } | 
|    52  |    54  | 
|    53 static inline void updateLogicalHeightForCell( |    55 static inline void updateLogicalHeightForCell( | 
|    54     LayoutTableSection::RowStruct& row, |    56     LayoutTableSection::RowStruct& row, | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   161  |   163  | 
|   162     if (beforeChild && !beforeChild->isAnonymous() && |   164     if (beforeChild && !beforeChild->isAnonymous() && | 
|   163         beforeChild->parent() == this) { |   165         beforeChild->parent() == this) { | 
|   164       LayoutObject* row = beforeChild->previousSibling(); |   166       LayoutObject* row = beforeChild->previousSibling(); | 
|   165       if (row && row->isTableRow() && row->isAnonymous()) { |   167       if (row && row->isTableRow() && row->isAnonymous()) { | 
|   166         row->addChild(child); |   168         row->addChild(child); | 
|   167         return; |   169         return; | 
|   168       } |   170       } | 
|   169     } |   171     } | 
|   170  |   172  | 
|   171     // If beforeChild is inside an anonymous cell/row, insert into the cell or i
      nto |   173     // If beforeChild is inside an anonymous cell/row, insert into the cell or | 
|   172     // the anonymous row containing it, if there is one. |   174     // into the anonymous row containing it, if there is one. | 
|   173     LayoutObject* lastBox = last; |   175     LayoutObject* lastBox = last; | 
|   174     while (lastBox && lastBox->parent()->isAnonymous() && |   176     while (lastBox && lastBox->parent()->isAnonymous() && | 
|   175            !lastBox->isTableRow()) |   177            !lastBox->isTableRow()) | 
|   176       lastBox = lastBox->parent(); |   178       lastBox = lastBox->parent(); | 
|   177     if (lastBox && lastBox->isAnonymous() && |   179     if (lastBox && lastBox->isAnonymous() && | 
|   178         !lastBox->isBeforeOrAfterContent()) { |   180         !lastBox->isBeforeOrAfterContent()) { | 
|   179       lastBox->addChild(child, beforeChild); |   181       lastBox->addChild(child, beforeChild); | 
|   180       return; |   182       return; | 
|   181     } |   183     } | 
|   182  |   184  | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   242     for (; row && row != previousCell->row(); row = row->previousRow()) { |   244     for (; row && row != previousCell->row(); row = row->previousRow()) { | 
|   243     } |   245     } | 
|   244     ASSERT(row == previousCell->row()); |   246     ASSERT(row == previousCell->row()); | 
|   245  |   247  | 
|   246     previousCell = currentCell; |   248     previousCell = currentCell; | 
|   247   } |   249   } | 
|   248 #endif  // NDEBUG |   250 #endif  // NDEBUG | 
|   249 } |   251 } | 
|   250  |   252  | 
|   251 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { |   253 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { | 
|   252   // We don't insert the cell if we need cell recalc as our internal columns' re
      presentation |   254   // We don't insert the cell if we need cell recalc as our internal columns' | 
|   253   // will have drifted from the table's representation. Also recalcCells will ca
      ll addCell |   255   // representation will have drifted from the table's representation. Also | 
|   254   // at a later time after sync'ing our columns' with the table's. |   256   // recalcCells will call addCell at a later time after sync'ing our columns' | 
 |   257   // with the table's. | 
|   255   if (needsCellRecalc()) |   258   if (needsCellRecalc()) | 
|   256     return; |   259     return; | 
|   257  |   260  | 
|   258   unsigned rSpan = cell->rowSpan(); |   261   unsigned rSpan = cell->rowSpan(); | 
|   259   unsigned cSpan = cell->colSpan(); |   262   unsigned cSpan = cell->colSpan(); | 
|   260   const Vector<LayoutTable::ColumnStruct>& columns = |   263   const Vector<LayoutTable::ColumnStruct>& columns = | 
|   261       table()->effectiveColumns(); |   264       table()->effectiveColumns(); | 
|   262   unsigned nCols = columns.size(); |   265   unsigned nCols = columns.size(); | 
|   263   unsigned insertionRow = row->rowIndex(); |   266   unsigned insertionRow = row->rowIndex(); | 
|   264  |   267  | 
|   265   // ### mozilla still seems to do the old HTML way, even for strict DTD |   268   // ### mozilla still seems to do the old HTML way, even for strict DTD | 
|   266   // (see the annotation on table cell layouting in the CSS specs and the testca
      se below: |   269   // (see the annotation on table cell layouting in the CSS specs and the | 
 |   270   // testcase below: | 
|   267   // <TABLE border> |   271   // <TABLE border> | 
|   268   // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 |   272   // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 | 
|   269   // <TR><TD colspan="2">5 |   273   // <TR><TD colspan="2">5 | 
|   270   // </TABLE> |   274   // </TABLE> | 
|   271   while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() || |   275   while (m_cCol < nCols && (cellAt(insertionRow, m_cCol).hasCells() || | 
|   272                             cellAt(insertionRow, m_cCol).inColSpan)) |   276                             cellAt(insertionRow, m_cCol).inColSpan)) | 
|   273     m_cCol++; |   277     m_cCol++; | 
|   274  |   278  | 
|   275   updateLogicalHeightForCell(m_grid[insertionRow], cell); |   279   updateLogicalHeightForCell(m_grid[insertionRow], cell); | 
|   276  |   280  | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   347                                         m_rowPos[actualRow] - |   351                                         m_rowPos[actualRow] - | 
|   348                                         borderSpacingForRow(actualRow); |   352                                         borderSpacingForRow(actualRow); | 
|   349     if (!spanningRowsHeight.rowHeight[row]) |   353     if (!spanningRowsHeight.rowHeight[row]) | 
|   350       spanningRowsHeight.isAnyRowWithOnlySpanningCells |= |   354       spanningRowsHeight.isAnyRowWithOnlySpanningCells |= | 
|   351           rowHasOnlySpanningCells(actualRow); |   355           rowHasOnlySpanningCells(actualRow); | 
|   352  |   356  | 
|   353     spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row]; |   357     spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row]; | 
|   354     spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= |   358     spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= | 
|   355         borderSpacingForRow(actualRow); |   359         borderSpacingForRow(actualRow); | 
|   356   } |   360   } | 
|   357   // We don't span the following row so its border-spacing (if any) should be in
      cluded. |   361   // We don't span the following row so its border-spacing (if any) should be | 
 |   362   // included. | 
|   358   spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += |   363   spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += | 
|   359       borderSpacingForRow(rowIndex + rowSpan - 1); |   364       borderSpacingForRow(rowIndex + rowSpan - 1); | 
|   360 } |   365 } | 
|   361  |   366  | 
|   362 void LayoutTableSection::distributeExtraRowSpanHeightToPercentRows( |   367 void LayoutTableSection::distributeExtraRowSpanHeightToPercentRows( | 
|   363     LayoutTableCell* cell, |   368     LayoutTableCell* cell, | 
|   364     float totalPercent, |   369     float totalPercent, | 
|   365     int& extraRowSpanningHeight, |   370     int& extraRowSpanningHeight, | 
|   366     Vector<int>& rowsHeight) { |   371     Vector<int>& rowsHeight) { | 
|   367   if (!extraRowSpanningHeight || !totalPercent) |   372   if (!extraRowSpanningHeight || !totalPercent) | 
|   368     return; |   373     return; | 
|   369  |   374  | 
|   370   const unsigned rowSpan = cell->rowSpan(); |   375   const unsigned rowSpan = cell->rowSpan(); | 
|   371   const unsigned rowIndex = cell->rowIndex(); |   376   const unsigned rowIndex = cell->rowIndex(); | 
|   372   float percent = std::min(totalPercent, 100.0f); |   377   float percent = std::min(totalPercent, 100.0f); | 
|   373   const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight; |   378   const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight; | 
|   374  |   379  | 
|   375   // Our algorithm matches Firefox. Extra spanning height would be distributed O
      nly in first percent height rows |   380   // Our algorithm matches Firefox. Extra spanning height would be distributed | 
|   376   // those total percent is 100. Other percent rows would be uneffected even ext
      ra spanning height is remain. |   381   // Only in first percent height rows those total percent is 100. Other percent | 
 |   382   // rows would be uneffected even extra spanning height is remain. | 
|   377   int accumulatedPositionIncrease = 0; |   383   int accumulatedPositionIncrease = 0; | 
|   378   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { |   384   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { | 
|   379     if (percent > 0 && extraRowSpanningHeight > 0) { |   385     if (percent > 0 && extraRowSpanningHeight > 0) { | 
|   380       // TODO(alancutter): Make this work correctly for calc lengths. |   386       // TODO(alancutter): Make this work correctly for calc lengths. | 
|   381       if (m_grid[row].logicalHeight.isPercent()) { |   387       if (m_grid[row].logicalHeight.isPercent()) { | 
|   382         int toAdd = |   388         int toAdd = | 
|   383             (tableHeight * |   389             (tableHeight * | 
|   384              std::min(m_grid[row].logicalHeight.percent(), percent) / 100) - |   390              std::min(m_grid[row].logicalHeight.percent(), percent) / 100) - | 
|   385             rowsHeight[row - rowIndex]; |   391             rowsHeight[row - rowIndex]; | 
|   386  |   392  | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   397 static void updatePositionIncreasedWithRowHeight( |   403 static void updatePositionIncreasedWithRowHeight( | 
|   398     int extraHeight, |   404     int extraHeight, | 
|   399     float rowHeight, |   405     float rowHeight, | 
|   400     float totalHeight, |   406     float totalHeight, | 
|   401     int& accumulatedPositionIncrease, |   407     int& accumulatedPositionIncrease, | 
|   402     double& remainder) { |   408     double& remainder) { | 
|   403   // Without the cast we lose enough precision to cause heights to miss pixels |   409   // Without the cast we lose enough precision to cause heights to miss pixels | 
|   404   // (and trigger asserts) in some layout tests. |   410   // (and trigger asserts) in some layout tests. | 
|   405   double proportionalPositionIncrease = |   411   double proportionalPositionIncrease = | 
|   406       remainder + (extraHeight * double(rowHeight)) / totalHeight; |   412       remainder + (extraHeight * double(rowHeight)) / totalHeight; | 
|   407   // The epsilon is to push any values that are close to a whole number but aren
      't due to floating point imprecision. |   413   // The epsilon is to push any values that are close to a whole number but | 
|   408   // The epsilons are not accumulated, any that aren't necessary are lost in the
       cast to int. |   414   // aren't due to floating point imprecision. The epsilons are not accumulated, | 
 |   415   // any that aren't necessary are lost in the cast to int. | 
|   409   int positionIncreaseInt = proportionalPositionIncrease + 0.000001; |   416   int positionIncreaseInt = proportionalPositionIncrease + 0.000001; | 
|   410   accumulatedPositionIncrease += positionIncreaseInt; |   417   accumulatedPositionIncrease += positionIncreaseInt; | 
|   411   remainder = proportionalPositionIncrease - positionIncreaseInt; |   418   remainder = proportionalPositionIncrease - positionIncreaseInt; | 
|   412 } |   419 } | 
|   413  |   420  | 
|   414 // This is mainly used to distribute whole extra rowspanning height in percent r
      ows when all spanning rows are |   421 // This is mainly used to distribute whole extra rowspanning height in percent | 
|   415 // percent rows. |   422 // rows when all spanning rows are percent rows. | 
|   416 // Distributing whole extra rowspanning height in percent rows based on the rati
      os of percent because this method works |   423 // Distributing whole extra rowspanning height in percent rows based on the | 
|   417 // same as percent distribution when only percent rows are present and percent i
      s 100. Also works perfectly fine when |   424 // ratios of percent because this method works same as percent distribution when | 
|   418 // percent is not equal to 100. |   425 // only percent rows are present and percent is 100. Also works perfectly fine | 
 |   426 // when percent is not equal to 100. | 
|   419 void LayoutTableSection::distributeWholeExtraRowSpanHeightToPercentRows( |   427 void LayoutTableSection::distributeWholeExtraRowSpanHeightToPercentRows( | 
|   420     LayoutTableCell* cell, |   428     LayoutTableCell* cell, | 
|   421     float totalPercent, |   429     float totalPercent, | 
|   422     int& extraRowSpanningHeight, |   430     int& extraRowSpanningHeight, | 
|   423     Vector<int>& rowsHeight) { |   431     Vector<int>& rowsHeight) { | 
|   424   if (!extraRowSpanningHeight || !totalPercent) |   432   if (!extraRowSpanningHeight || !totalPercent) | 
|   425     return; |   433     return; | 
|   426  |   434  | 
|   427   const unsigned rowSpan = cell->rowSpan(); |   435   const unsigned rowSpan = cell->rowSpan(); | 
|   428   const unsigned rowIndex = cell->rowIndex(); |   436   const unsigned rowIndex = cell->rowIndex(); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   450     int& extraRowSpanningHeight, |   458     int& extraRowSpanningHeight, | 
|   451     Vector<int>& rowsHeight) { |   459     Vector<int>& rowsHeight) { | 
|   452   if (!extraRowSpanningHeight || !totalAutoRowsHeight) |   460   if (!extraRowSpanningHeight || !totalAutoRowsHeight) | 
|   453     return; |   461     return; | 
|   454  |   462  | 
|   455   const unsigned rowSpan = cell->rowSpan(); |   463   const unsigned rowSpan = cell->rowSpan(); | 
|   456   const unsigned rowIndex = cell->rowIndex(); |   464   const unsigned rowIndex = cell->rowIndex(); | 
|   457   int accumulatedPositionIncrease = 0; |   465   int accumulatedPositionIncrease = 0; | 
|   458   double remainder = 0; |   466   double remainder = 0; | 
|   459  |   467  | 
|   460   // Aspect ratios of auto rows should not change otherwise table may look diffe
      rent than user expected. |   468   // Aspect ratios of auto rows should not change otherwise table may look | 
|   461   // So extra height distributed in auto spanning rows based on their weight in 
      spanning cell. |   469   // different than user expected. So extra height distributed in auto spanning | 
 |   470   // rows based on their weight in spanning cell. | 
|   462   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { |   471   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { | 
|   463     if (m_grid[row].logicalHeight.isAuto()) { |   472     if (m_grid[row].logicalHeight.isAuto()) { | 
|   464       updatePositionIncreasedWithRowHeight( |   473       updatePositionIncreasedWithRowHeight( | 
|   465           extraRowSpanningHeight, rowsHeight[row - rowIndex], |   474           extraRowSpanningHeight, rowsHeight[row - rowIndex], | 
|   466           totalAutoRowsHeight, accumulatedPositionIncrease, remainder); |   475           totalAutoRowsHeight, accumulatedPositionIncrease, remainder); | 
|   467     } |   476     } | 
|   468     m_rowPos[row + 1] += accumulatedPositionIncrease; |   477     m_rowPos[row + 1] += accumulatedPositionIncrease; | 
|   469   } |   478   } | 
|   470  |   479  | 
|   471   DCHECK(!round(remainder)) << "remainder was " << remainder; |   480   DCHECK(!round(remainder)) << "remainder was " << remainder; | 
|   472  |   481  | 
|   473   extraRowSpanningHeight -= accumulatedPositionIncrease; |   482   extraRowSpanningHeight -= accumulatedPositionIncrease; | 
|   474 } |   483 } | 
|   475  |   484  | 
|   476 void LayoutTableSection::distributeExtraRowSpanHeightToRemainingRows( |   485 void LayoutTableSection::distributeExtraRowSpanHeightToRemainingRows( | 
|   477     LayoutTableCell* cell, |   486     LayoutTableCell* cell, | 
|   478     int totalRemainingRowsHeight, |   487     int totalRemainingRowsHeight, | 
|   479     int& extraRowSpanningHeight, |   488     int& extraRowSpanningHeight, | 
|   480     Vector<int>& rowsHeight) { |   489     Vector<int>& rowsHeight) { | 
|   481   if (!extraRowSpanningHeight || !totalRemainingRowsHeight) |   490   if (!extraRowSpanningHeight || !totalRemainingRowsHeight) | 
|   482     return; |   491     return; | 
|   483  |   492  | 
|   484   const unsigned rowSpan = cell->rowSpan(); |   493   const unsigned rowSpan = cell->rowSpan(); | 
|   485   const unsigned rowIndex = cell->rowIndex(); |   494   const unsigned rowIndex = cell->rowIndex(); | 
|   486   int accumulatedPositionIncrease = 0; |   495   int accumulatedPositionIncrease = 0; | 
|   487   double remainder = 0; |   496   double remainder = 0; | 
|   488  |   497  | 
|   489   // Aspect ratios of the rows should not change otherwise table may look differ
      ent than user expected. |   498   // Aspect ratios of the rows should not change otherwise table may look | 
|   490   // So extra height distribution in remaining spanning rows based on their weig
      ht in spanning cell. |   499   // different than user expected. So extra height distribution in remaining | 
 |   500   // spanning rows based on their weight in spanning cell. | 
|   491   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { |   501   for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { | 
|   492     if (!m_grid[row].logicalHeight.isPercentOrCalc()) { |   502     if (!m_grid[row].logicalHeight.isPercentOrCalc()) { | 
|   493       updatePositionIncreasedWithRowHeight( |   503       updatePositionIncreasedWithRowHeight( | 
|   494           extraRowSpanningHeight, rowsHeight[row - rowIndex], |   504           extraRowSpanningHeight, rowsHeight[row - rowIndex], | 
|   495           totalRemainingRowsHeight, accumulatedPositionIncrease, remainder); |   505           totalRemainingRowsHeight, accumulatedPositionIncrease, remainder); | 
|   496     } |   506     } | 
|   497     m_rowPos[row + 1] += accumulatedPositionIncrease; |   507     m_rowPos[row + 1] += accumulatedPositionIncrease; | 
|   498   } |   508   } | 
|   499  |   509  | 
|   500   DCHECK(!round(remainder)) << "remainder was " << remainder; |   510   DCHECK(!round(remainder)) << "remainder was " << remainder; | 
|   501  |   511  | 
|   502   extraRowSpanningHeight -= accumulatedPositionIncrease; |   512   extraRowSpanningHeight -= accumulatedPositionIncrease; | 
|   503 } |   513 } | 
|   504  |   514  | 
|   505 static bool cellIsFullyIncludedInOtherCell(const LayoutTableCell* cell1, |   515 static bool cellIsFullyIncludedInOtherCell(const LayoutTableCell* cell1, | 
|   506                                            const LayoutTableCell* cell2) { |   516                                            const LayoutTableCell* cell2) { | 
|   507   return (cell1->rowIndex() >= cell2->rowIndex() && |   517   return (cell1->rowIndex() >= cell2->rowIndex() && | 
|   508           (cell1->rowIndex() + cell1->rowSpan()) <= |   518           (cell1->rowIndex() + cell1->rowSpan()) <= | 
|   509               (cell2->rowIndex() + cell2->rowSpan())); |   519               (cell2->rowIndex() + cell2->rowSpan())); | 
|   510 } |   520 } | 
|   511  |   521  | 
|   512 // To avoid unneeded extra height distributions, we apply the following sorting 
      algorithm: |   522 // To avoid unneeded extra height distributions, we apply the following sorting | 
 |   523 // algorithm: | 
|   513 static bool compareRowSpanCellsInHeightDistributionOrder( |   524 static bool compareRowSpanCellsInHeightDistributionOrder( | 
|   514     const LayoutTableCell* cell1, |   525     const LayoutTableCell* cell1, | 
|   515     const LayoutTableCell* cell2) { |   526     const LayoutTableCell* cell2) { | 
|   516   // Sorting bigger height cell first if cells are at same index with same span 
      because we will skip smaller |   527   // Sorting bigger height cell first if cells are at same index with same span | 
|   517   // height cell to distribute it's extra height. |   528   // because we will skip smaller height cell to distribute it's extra height. | 
|   518   if (cell1->rowIndex() == cell2->rowIndex() && |   529   if (cell1->rowIndex() == cell2->rowIndex() && | 
|   519       cell1->rowSpan() == cell2->rowSpan()) |   530       cell1->rowSpan() == cell2->rowSpan()) | 
|   520     return (cell1->logicalHeightForRowSizing() > |   531     return (cell1->logicalHeightForRowSizing() > | 
|   521             cell2->logicalHeightForRowSizing()); |   532             cell2->logicalHeightForRowSizing()); | 
|   522   // Sorting inner most cell first because if inner spanning cell'e extra height
       is distributed then outer |   533   // Sorting inner most cell first because if inner spanning cell'e extra height | 
|   523   // spanning cell's extra height will adjust accordingly. In reverse order, the
      re is more chances that outer |   534   // is distributed then outer spanning cell's extra height will adjust | 
|   524   // spanning cell's height will exceed than defined by user. |   535   // accordingly. In reverse order, there is more chances that outer spanning | 
 |   536   // cell's height will exceed than defined by user. | 
|   525   if (cellIsFullyIncludedInOtherCell(cell1, cell2)) |   537   if (cellIsFullyIncludedInOtherCell(cell1, cell2)) | 
|   526     return true; |   538     return true; | 
|   527   // Sorting lower row index first because first we need to apply the extra heig
      ht of spanning cell which |   539   // Sorting lower row index first because first we need to apply the extra | 
|   528   // comes first in the table so lower rows's position would increment in sequen
      ce. |   540   // height of spanning cell which comes first in the table so lower rows's | 
 |   541   // position would increment in sequence. | 
|   529   if (!cellIsFullyIncludedInOtherCell(cell2, cell1)) |   542   if (!cellIsFullyIncludedInOtherCell(cell2, cell1)) | 
|   530     return (cell1->rowIndex() < cell2->rowIndex()); |   543     return (cell1->rowIndex() < cell2->rowIndex()); | 
|   531  |   544  | 
|   532   return false; |   545   return false; | 
|   533 } |   546 } | 
|   534  |   547  | 
|   535 unsigned LayoutTableSection::calcRowHeightHavingOnlySpanningCells( |   548 unsigned LayoutTableSection::calcRowHeightHavingOnlySpanningCells( | 
|   536     unsigned row, |   549     unsigned row, | 
|   537     int& accumulatedCellPositionIncrease, |   550     int& accumulatedCellPositionIncrease, | 
|   538     unsigned rowToApplyExtraHeight, |   551     unsigned rowToApplyExtraHeight, | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   554       continue; |   567       continue; | 
|   555  |   568  | 
|   556     LayoutTableCell* cell = rowSpanCell.cells[0]; |   569     LayoutTableCell* cell = rowSpanCell.cells[0]; | 
|   557  |   570  | 
|   558     if (cell->rowSpan() < 2) |   571     if (cell->rowSpan() < 2) | 
|   559       continue; |   572       continue; | 
|   560  |   573  | 
|   561     const unsigned cellRowIndex = cell->rowIndex(); |   574     const unsigned cellRowIndex = cell->rowIndex(); | 
|   562     const unsigned cellRowSpan = cell->rowSpan(); |   575     const unsigned cellRowSpan = cell->rowSpan(); | 
|   563  |   576  | 
|   564     // As we are going from the top of the table to the bottom to calculate the 
      row |   577     // As we are going from the top of the table to the bottom to calculate the | 
|   565     // heights for rows that only contain spanning cells and all previous rows a
      re |   578     // row heights for rows that only contain spanning cells and all previous | 
|   566     // processed we only need to find the number of rows with spanning cells fro
      m the |   579     // rows are processed we only need to find the number of rows with spanning | 
|   567     // current cell to the end of the current cells spanning height. |   580     // cells from the current cell to the end of the current cells spanning | 
 |   581     // height. | 
|   568     unsigned startRowForSpanningCellCount = std::max(cellRowIndex, row); |   582     unsigned startRowForSpanningCellCount = std::max(cellRowIndex, row); | 
|   569     unsigned endRow = cellRowIndex + cellRowSpan; |   583     unsigned endRow = cellRowIndex + cellRowSpan; | 
|   570     unsigned spanningCellsRowsCountHavingZeroHeight = |   584     unsigned spanningCellsRowsCountHavingZeroHeight = | 
|   571         rowsCountWithOnlySpanningCells[endRow - 1]; |   585         rowsCountWithOnlySpanningCells[endRow - 1]; | 
|   572  |   586  | 
|   573     if (startRowForSpanningCellCount) |   587     if (startRowForSpanningCellCount) | 
|   574       spanningCellsRowsCountHavingZeroHeight -= |   588       spanningCellsRowsCountHavingZeroHeight -= | 
|   575           rowsCountWithOnlySpanningCells[startRowForSpanningCellCount - 1]; |   589           rowsCountWithOnlySpanningCells[startRowForSpanningCellCount - 1]; | 
|   576  |   590  | 
|   577     int totalRowspanCellHeight = (m_rowPos[endRow] - m_rowPos[cellRowIndex]) - |   591     int totalRowspanCellHeight = (m_rowPos[endRow] - m_rowPos[cellRowIndex]) - | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   615           actualRow, accumulatedPositionIncrease, rowIndex + rowSpan, |   629           actualRow, accumulatedPositionIncrease, rowIndex + rowSpan, | 
|   616           extraHeightToPropagate, rowsCountWithOnlySpanningCells); |   630           extraHeightToPropagate, rowsCountWithOnlySpanningCells); | 
|   617       accumulatedPositionIncrease += spanningRowsHeight.rowHeight[row]; |   631       accumulatedPositionIncrease += spanningRowsHeight.rowHeight[row]; | 
|   618     } |   632     } | 
|   619     m_rowPos[actualRow + 1] += accumulatedPositionIncrease; |   633     m_rowPos[actualRow + 1] += accumulatedPositionIncrease; | 
|   620   } |   634   } | 
|   621  |   635  | 
|   622   spanningRowsHeight.totalRowsHeight += accumulatedPositionIncrease; |   636   spanningRowsHeight.totalRowsHeight += accumulatedPositionIncrease; | 
|   623 } |   637 } | 
|   624  |   638  | 
|   625 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on t
      he ratio of row's height if |   639 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on | 
|   626 // 1. RowSpan cell height is greater than the total height of rows in rowSpan ce
      ll |   640 // the ratio of row's height if 1 RowSpan cell height is greater than the total | 
 |   641 // height of rows in rowSpan cell. | 
|   627 void LayoutTableSection::distributeRowSpanHeightToRows( |   642 void LayoutTableSection::distributeRowSpanHeightToRows( | 
|   628     SpanningLayoutTableCells& rowSpanCells) { |   643     SpanningLayoutTableCells& rowSpanCells) { | 
|   629   ASSERT(rowSpanCells.size()); |   644   ASSERT(rowSpanCells.size()); | 
|   630  |   645  | 
|   631   // 'rowSpanCells' list is already sorted based on the cells rowIndex in ascend
      ing order |   646   // 'rowSpanCells' list is already sorted based on the cells rowIndex in | 
 |   647   // ascending order | 
|   632   // Arrange row spanning cell in the order in which we need to process first. |   648   // Arrange row spanning cell in the order in which we need to process first. | 
|   633   std::sort(rowSpanCells.begin(), rowSpanCells.end(), |   649   std::sort(rowSpanCells.begin(), rowSpanCells.end(), | 
|   634             compareRowSpanCellsInHeightDistributionOrder); |   650             compareRowSpanCellsInHeightDistributionOrder); | 
|   635  |   651  | 
|   636   unsigned extraHeightToPropagate = 0; |   652   unsigned extraHeightToPropagate = 0; | 
|   637   unsigned lastRowIndex = 0; |   653   unsigned lastRowIndex = 0; | 
|   638   unsigned lastRowSpan = 0; |   654   unsigned lastRowSpan = 0; | 
|   639  |   655  | 
|   640   Vector<int> rowsCountWithOnlySpanningCells; |   656   Vector<int> rowsCountWithOnlySpanningCells; | 
|   641  |   657  | 
|   642   // At this stage, Height of the rows are zero for the one containing only span
      ning cells. |   658   // At this stage, Height of the rows are zero for the one containing only | 
 |   659   // spanning cells. | 
|   643   int count = 0; |   660   int count = 0; | 
|   644   for (unsigned row = 0; row < m_grid.size(); row++) { |   661   for (unsigned row = 0; row < m_grid.size(); row++) { | 
|   645     if (rowHasOnlySpanningCells(row)) |   662     if (rowHasOnlySpanningCells(row)) | 
|   646       count++; |   663       count++; | 
|   647     rowsCountWithOnlySpanningCells.append(count); |   664     rowsCountWithOnlySpanningCells.append(count); | 
|   648   } |   665   } | 
|   649  |   666  | 
|   650   for (unsigned i = 0; i < rowSpanCells.size(); i++) { |   667   for (unsigned i = 0; i < rowSpanCells.size(); i++) { | 
|   651     LayoutTableCell* cell = rowSpanCells[i]; |   668     LayoutTableCell* cell = rowSpanCells[i]; | 
|   652  |   669  | 
|   653     unsigned rowIndex = cell->rowIndex(); |   670     unsigned rowIndex = cell->rowIndex(); | 
|   654  |   671  | 
|   655     unsigned rowSpan = cell->rowSpan(); |   672     unsigned rowSpan = cell->rowSpan(); | 
|   656  |   673  | 
|   657     unsigned spanningCellEndIndex = rowIndex + rowSpan; |   674     unsigned spanningCellEndIndex = rowIndex + rowSpan; | 
|   658     unsigned lastSpanningCellEndIndex = lastRowIndex + lastRowSpan; |   675     unsigned lastSpanningCellEndIndex = lastRowIndex + lastRowSpan; | 
|   659  |   676  | 
|   660     // Only the highest spanning cell will distribute its extra height in a row 
      if more than one spanning cell |   677     // Only the highest spanning cell will distribute its extra height in a row | 
|   661     // is present at the same level. |   678     // if more than one spanning cell is present at the same level. | 
|   662     if (rowIndex == lastRowIndex && rowSpan == lastRowSpan) |   679     if (rowIndex == lastRowIndex && rowSpan == lastRowSpan) | 
|   663       continue; |   680       continue; | 
|   664  |   681  | 
|   665     int originalBeforePosition = m_rowPos[spanningCellEndIndex]; |   682     int originalBeforePosition = m_rowPos[spanningCellEndIndex]; | 
|   666  |   683  | 
|   667     // When 2 spanning cells are ending at same row index then while extra heigh
      t distribution of first spanning |   684     // When 2 spanning cells are ending at same row index then while extra | 
|   668     // cell updates position of the last row so getting the original position of
       the last row in second spanning |   685     // height distribution of first spanning cell updates position of the last | 
 |   686     // row so getting the original position of the last row in second spanning | 
|   669     // cell need to reduce the height changed by first spanning cell. |   687     // cell need to reduce the height changed by first spanning cell. | 
|   670     if (spanningCellEndIndex == lastSpanningCellEndIndex) |   688     if (spanningCellEndIndex == lastSpanningCellEndIndex) | 
|   671       originalBeforePosition -= extraHeightToPropagate; |   689       originalBeforePosition -= extraHeightToPropagate; | 
|   672  |   690  | 
|   673     if (extraHeightToPropagate) { |   691     if (extraHeightToPropagate) { | 
|   674       for (unsigned row = lastSpanningCellEndIndex + 1; |   692       for (unsigned row = lastSpanningCellEndIndex + 1; | 
|   675            row <= spanningCellEndIndex; row++) |   693            row <= spanningCellEndIndex; row++) | 
|   676         m_rowPos[row] += extraHeightToPropagate; |   694         m_rowPos[row] += extraHeightToPropagate; | 
|   677     } |   695     } | 
|   678  |   696  | 
|   679     lastRowIndex = rowIndex; |   697     lastRowIndex = rowIndex; | 
|   680     lastRowSpan = rowSpan; |   698     lastRowSpan = rowSpan; | 
|   681  |   699  | 
|   682     struct SpanningRowsHeight spanningRowsHeight; |   700     struct SpanningRowsHeight spanningRowsHeight; | 
|   683  |   701  | 
|   684     populateSpanningRowsHeightFromCell(cell, spanningRowsHeight); |   702     populateSpanningRowsHeightFromCell(cell, spanningRowsHeight); | 
|   685  |   703  | 
|   686     // Here we are handling only row(s) who have only rowspanning cells and do n
      ot have any empty cell. |   704     // Here we are handling only row(s) who have only rowspanning cells and do | 
 |   705     // not have any empty cell. | 
|   687     if (spanningRowsHeight.isAnyRowWithOnlySpanningCells) |   706     if (spanningRowsHeight.isAnyRowWithOnlySpanningCells) | 
|   688       updateRowsHeightHavingOnlySpanningCells(cell, spanningRowsHeight, |   707       updateRowsHeightHavingOnlySpanningCells(cell, spanningRowsHeight, | 
|   689                                               extraHeightToPropagate, |   708                                               extraHeightToPropagate, | 
|   690                                               rowsCountWithOnlySpanningCells); |   709                                               rowsCountWithOnlySpanningCells); | 
|   691  |   710  | 
|   692     // This code handle row(s) that have rowspanning cell(s) and at least one em
      pty cell. |   711     // This code handle row(s) that have rowspanning cell(s) and at least one | 
|   693     // Such rows are not handled below and end up having a height of 0. That wou
      ld mean |   712     // empty cell. Such rows are not handled below and end up having a height of | 
|   694     // content overlapping if one of their cells has any content. To avoid the p
      roblem, we |   713     // 0. That would mean content overlapping if one of their cells has any | 
|   695     // add all the remaining spanning cells' height to the last spanned row. |   714     // content. To avoid the problem, we add all the remaining spanning cells' | 
|   696     // This means that we could grow a row past its 'height' or break percentage
       spreading |   715     // height to the last spanned row. This means that we could grow a row past | 
|   697     // however this is better than overlapping content. |   716     // its 'height' or break percentage spreading however this is better than | 
 |   717     // overlapping content. | 
|   698     // FIXME: Is there a better algorithm? |   718     // FIXME: Is there a better algorithm? | 
|   699     if (!spanningRowsHeight.totalRowsHeight) { |   719     if (!spanningRowsHeight.totalRowsHeight) { | 
|   700       if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing) |   720       if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing) | 
|   701         m_rowPos[spanningCellEndIndex] += |   721         m_rowPos[spanningCellEndIndex] += | 
|   702             spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing + |   722             spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing + | 
|   703             borderSpacingForRow(spanningCellEndIndex - 1); |   723             borderSpacingForRow(spanningCellEndIndex - 1); | 
|   704  |   724  | 
|   705       extraHeightToPropagate = |   725       extraHeightToPropagate = | 
|   706           m_rowPos[spanningCellEndIndex] - originalBeforePosition; |   726           m_rowPos[spanningCellEndIndex] - originalBeforePosition; | 
|   707       continue; |   727       continue; | 
|   708     } |   728     } | 
|   709  |   729  | 
|   710     if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= |   730     if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= | 
|   711         spanningRowsHeight.totalRowsHeight) { |   731         spanningRowsHeight.totalRowsHeight) { | 
|   712       extraHeightToPropagate = |   732       extraHeightToPropagate = | 
|   713           m_rowPos[rowIndex + rowSpan] - originalBeforePosition; |   733           m_rowPos[rowIndex + rowSpan] - originalBeforePosition; | 
|   714       continue; |   734       continue; | 
|   715     } |   735     } | 
|   716  |   736  | 
|   717     // Below we are handling only row(s) who have at least one visible cell with
      out rowspan value. |   737     // Below we are handling only row(s) who have at least one visible cell | 
 |   738     // without rowspan value. | 
|   718     float totalPercent = 0; |   739     float totalPercent = 0; | 
|   719     int totalAutoRowsHeight = 0; |   740     int totalAutoRowsHeight = 0; | 
|   720     int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight; |   741     int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight; | 
|   721  |   742  | 
|   722     // FIXME: Inner spanning cell height should not change if it have fixed heig
      ht when it's parent spanning cell |   743     // FIXME: Inner spanning cell height should not change if it have fixed | 
|   723     // is distributing it's extra height in rows. |   744     // height when it's parent spanning cell is distributing it's extra height | 
 |   745     //in rows. | 
|   724  |   746  | 
|   725     // Calculate total percentage, total auto rows height and total rows height 
      except percent rows. |   747     // Calculate total percentage, total auto rows height and total rows height | 
 |   748     // except percent rows. | 
|   726     for (unsigned row = rowIndex; row < spanningCellEndIndex; row++) { |   749     for (unsigned row = rowIndex; row < spanningCellEndIndex; row++) { | 
|   727       // TODO(alancutter): Make this work correctly for calc lengths. |   750       // TODO(alancutter): Make this work correctly for calc lengths. | 
|   728       if (m_grid[row].logicalHeight.isPercent()) { |   751       if (m_grid[row].logicalHeight.isPercent()) { | 
|   729         totalPercent += m_grid[row].logicalHeight.percent(); |   752         totalPercent += m_grid[row].logicalHeight.percent(); | 
|   730         totalRemainingRowsHeight -= |   753         totalRemainingRowsHeight -= | 
|   731             spanningRowsHeight.rowHeight[row - rowIndex]; |   754             spanningRowsHeight.rowHeight[row - rowIndex]; | 
|   732       } else if (m_grid[row].logicalHeight.isAuto()) { |   755       } else if (m_grid[row].logicalHeight.isAuto()) { | 
|   733         totalAutoRowsHeight += spanningRowsHeight.rowHeight[row - rowIndex]; |   756         totalAutoRowsHeight += spanningRowsHeight.rowHeight[row - rowIndex]; | 
|   734       } |   757       } | 
|   735     } |   758     } | 
|   736  |   759  | 
|   737     int extraRowSpanningHeight = |   760     int extraRowSpanningHeight = | 
|   738         spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing - |   761         spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing - | 
|   739         spanningRowsHeight.totalRowsHeight; |   762         spanningRowsHeight.totalRowsHeight; | 
|   740  |   763  | 
|   741     if (totalPercent < 100 && !totalAutoRowsHeight && |   764     if (totalPercent < 100 && !totalAutoRowsHeight && | 
|   742         !totalRemainingRowsHeight) { |   765         !totalRemainingRowsHeight) { | 
|   743       // Distributing whole extra rowspanning height in percent row when only no
      n-percent rows height is 0. |   766       // Distributing whole extra rowspanning height in percent row when only | 
 |   767       // non-percent rows height is 0. | 
|   744       distributeWholeExtraRowSpanHeightToPercentRows( |   768       distributeWholeExtraRowSpanHeightToPercentRows( | 
|   745           cell, totalPercent, extraRowSpanningHeight, |   769           cell, totalPercent, extraRowSpanningHeight, | 
|   746           spanningRowsHeight.rowHeight); |   770           spanningRowsHeight.rowHeight); | 
|   747     } else { |   771     } else { | 
|   748       distributeExtraRowSpanHeightToPercentRows(cell, totalPercent, |   772       distributeExtraRowSpanHeightToPercentRows(cell, totalPercent, | 
|   749                                                 extraRowSpanningHeight, |   773                                                 extraRowSpanningHeight, | 
|   750                                                 spanningRowsHeight.rowHeight); |   774                                                 spanningRowsHeight.rowHeight); | 
|   751       distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, |   775       distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, | 
|   752                                              extraRowSpanningHeight, |   776                                              extraRowSpanningHeight, | 
|   753                                              spanningRowsHeight.rowHeight); |   777                                              spanningRowsHeight.rowHeight); | 
|   754       distributeExtraRowSpanHeightToRemainingRows( |   778       distributeExtraRowSpanHeightToRemainingRows( | 
|   755           cell, totalRemainingRowsHeight, extraRowSpanningHeight, |   779           cell, totalRemainingRowsHeight, extraRowSpanningHeight, | 
|   756           spanningRowsHeight.rowHeight); |   780           spanningRowsHeight.rowHeight); | 
|   757     } |   781     } | 
|   758  |   782  | 
|   759     ASSERT(!extraRowSpanningHeight); |   783     ASSERT(!extraRowSpanningHeight); | 
|   760  |   784  | 
|   761     // Getting total changed height in the table |   785     // Getting total changed height in the table | 
|   762     extraHeightToPropagate = |   786     extraHeightToPropagate = | 
|   763         m_rowPos[spanningCellEndIndex] - originalBeforePosition; |   787         m_rowPos[spanningCellEndIndex] - originalBeforePosition; | 
|   764   } |   788   } | 
|   765  |   789  | 
|   766   if (extraHeightToPropagate) { |   790   if (extraHeightToPropagate) { | 
|   767     // Apply changed height by rowSpan cells to rows present at the end of the t
      able |   791     // Apply changed height by rowSpan cells to rows present at the end of the | 
 |   792     // table | 
|   768     for (unsigned row = lastRowIndex + lastRowSpan + 1; row <= m_grid.size(); |   793     for (unsigned row = lastRowIndex + lastRowSpan + 1; row <= m_grid.size(); | 
|   769          row++) |   794          row++) | 
|   770       m_rowPos[row] += extraHeightToPropagate; |   795       m_rowPos[row] += extraHeightToPropagate; | 
|   771   } |   796   } | 
|   772 } |   797 } | 
|   773  |   798  | 
|   774 // Find out the baseline of the cell |   799 // Find out the baseline of the cell | 
|   775 // If the cell's baseline is more than the row's baseline then the cell's baseli
      ne become the row's baseline |   800 // If the cell's baseline is more than the row's baseline then the cell's | 
|   776 // and if the row's baseline goes out of the row's boundaries then adjust row he
      ight accordingly. |   801 // baseline become the row's baseline and if the row's baseline goes out of the | 
 |   802 // row's boundaries then adjust row height accordingly. | 
|   777 void LayoutTableSection::updateBaselineForCell(LayoutTableCell* cell, |   803 void LayoutTableSection::updateBaselineForCell(LayoutTableCell* cell, | 
|   778                                                unsigned row, |   804                                                unsigned row, | 
|   779                                                int& baselineDescent) { |   805                                                int& baselineDescent) { | 
|   780   if (!cell->isBaselineAligned()) |   806   if (!cell->isBaselineAligned()) | 
|   781     return; |   807     return; | 
|   782  |   808  | 
|   783   // Ignoring the intrinsic padding as it depends on knowing the row's baseline,
       which won't be accurate |   809   // Ignoring the intrinsic padding as it depends on knowing the row's baseline, | 
|   784   // until the end of this function. |   810   // which won't be accurate until the end of this function. | 
|   785   int baselinePosition = |   811   int baselinePosition = | 
|   786       cell->cellBaselinePosition() - cell->intrinsicPaddingBefore(); |   812       cell->cellBaselinePosition() - cell->intrinsicPaddingBefore(); | 
|   787   if (baselinePosition > |   813   if (baselinePosition > | 
|   788       cell->borderBefore() + |   814       cell->borderBefore() + | 
|   789           (cell->paddingBefore() - cell->intrinsicPaddingBefore())) { |   815           (cell->paddingBefore() - cell->intrinsicPaddingBefore())) { | 
|   790     m_grid[row].baseline = std::max(m_grid[row].baseline, baselinePosition); |   816     m_grid[row].baseline = std::max(m_grid[row].baseline, baselinePosition); | 
|   791  |   817  | 
|   792     int cellStartRowBaselineDescent = 0; |   818     int cellStartRowBaselineDescent = 0; | 
|   793     if (cell->rowSpan() == 1) { |   819     if (cell->rowSpan() == 1) { | 
|   794       baselineDescent = |   820       baselineDescent = | 
|   795           std::max(baselineDescent, |   821           std::max(baselineDescent, | 
|   796                    cell->logicalHeightForRowSizing() - baselinePosition); |   822                    cell->logicalHeightForRowSizing() - baselinePosition); | 
|   797       cellStartRowBaselineDescent = baselineDescent; |   823       cellStartRowBaselineDescent = baselineDescent; | 
|   798     } |   824     } | 
|   799     m_rowPos[row + 1] = |   825     m_rowPos[row + 1] = | 
|   800         std::max<int>(m_rowPos[row + 1], m_rowPos[row] + m_grid[row].baseline + |   826         std::max<int>(m_rowPos[row + 1], m_rowPos[row] + m_grid[row].baseline + | 
|   801                                              cellStartRowBaselineDescent); |   827                                              cellStartRowBaselineDescent); | 
|   802   } |   828   } | 
|   803 } |   829 } | 
|   804  |   830  | 
|   805 int LayoutTableSection::calcRowLogicalHeight() { |   831 int LayoutTableSection::calcRowLogicalHeight() { | 
|   806 #if ENABLE(ASSERT) |   832 #if ENABLE(ASSERT) | 
|   807   SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); |   833   SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); | 
|   808 #endif |   834 #endif | 
|   809  |   835  | 
|   810   ASSERT(!needsLayout()); |   836   ASSERT(!needsLayout()); | 
|   811  |   837  | 
|   812   LayoutTableCell* cell; |   838   LayoutTableCell* cell; | 
|   813  |   839  | 
|   814   // We may have to forcefully lay out cells here, in which case we need a layou
      t |   840   // We may have to forcefully lay out cells here, in which case we need a | 
|   815   // state. Technically, we should also push state for the row, but since rows d
      on't push a |   841   // layout state. Technically, we should also push state for the row, but since | 
|   816   // coordinate transform, that's not necessary. |   842   // rows don't push a coordinate transform, that's not necessary. | 
|   817   LayoutState state(*this, locationOffset()); |   843   LayoutState state(*this, locationOffset()); | 
|   818  |   844  | 
|   819   m_rowPos.resize(m_grid.size() + 1); |   845   m_rowPos.resize(m_grid.size() + 1); | 
|   820  |   846  | 
|   821   // We ignore the border-spacing on any non-top section as it is already includ
      ed in the previous section's last row position. |   847   // We ignore the border-spacing on any non-top section as it is already | 
 |   848   // included in the previous section's last row position. | 
|   822   if (this == table()->topSection()) |   849   if (this == table()->topSection()) | 
|   823     m_rowPos[0] = table()->vBorderSpacing(); |   850     m_rowPos[0] = table()->vBorderSpacing(); | 
|   824   else |   851   else | 
|   825     m_rowPos[0] = 0; |   852     m_rowPos[0] = 0; | 
|   826  |   853  | 
|   827   SpanningLayoutTableCells rowSpanCells; |   854   SpanningLayoutTableCells rowSpanCells; | 
|   828 #if ENABLE(ASSERT) |   855 #if ENABLE(ASSERT) | 
|   829   HashSet<const LayoutTableCell*> uniqueCells; |   856   HashSet<const LayoutTableCell*> uniqueCells; | 
|   830 #endif |   857 #endif | 
|   831  |   858  | 
|   832   for (unsigned r = 0; r < m_grid.size(); r++) { |   859   for (unsigned r = 0; r < m_grid.size(); r++) { | 
|   833     m_grid[r].baseline = -1; |   860     m_grid[r].baseline = -1; | 
|   834     int baselineDescent = 0; |   861     int baselineDescent = 0; | 
|   835  |   862  | 
|   836     if (m_grid[r].logicalHeight.isSpecified()) { |   863     if (m_grid[r].logicalHeight.isSpecified()) { | 
|   837       // Our base size is the biggest logical height from our cells' styles (exc
      luding row spanning cells). |   864       // Our base size is the biggest logical height from our cells' styles | 
 |   865       // (excluding row spanning cells). | 
|   838       m_rowPos[r + 1] = std::max( |   866       m_rowPos[r + 1] = std::max( | 
|   839           m_rowPos[r] + |   867           m_rowPos[r] + | 
|   840               minimumValueForLength(m_grid[r].logicalHeight, LayoutUnit()) |   868               minimumValueForLength(m_grid[r].logicalHeight, LayoutUnit()) | 
|   841                   .round(), |   869                   .round(), | 
|   842           0); |   870           0); | 
|   843     } else { |   871     } else { | 
|   844       // Non-specified lengths are ignored because the row already accounts for 
      the cells |   872       // Non-specified lengths are ignored because the row already accounts for | 
|   845       // intrinsic logical height. |   873       // the cells intrinsic logical height. | 
|   846       m_rowPos[r + 1] = std::max(m_rowPos[r], 0); |   874       m_rowPos[r + 1] = std::max(m_rowPos[r], 0); | 
|   847     } |   875     } | 
|   848  |   876  | 
|   849     Row& row = m_grid[r].row; |   877     Row& row = m_grid[r].row; | 
|   850     unsigned totalCols = row.size(); |   878     unsigned totalCols = row.size(); | 
|   851     LayoutTableCell* lastRowSpanCell = nullptr; |   879     LayoutTableCell* lastRowSpanCell = nullptr; | 
|   852  |   880  | 
|   853     for (unsigned c = 0; c < totalCols; c++) { |   881     for (unsigned c = 0; c < totalCols; c++) { | 
|   854       CellStruct& current = cellAt(r, c); |   882       CellStruct& current = cellAt(r, c); | 
|   855       for (unsigned i = 0; i < current.cells.size(); i++) { |   883       for (unsigned i = 0; i < current.cells.size(); i++) { | 
|   856         cell = current.cells[i]; |   884         cell = current.cells[i]; | 
|   857         if (current.inColSpan && cell->rowSpan() == 1) |   885         if (current.inColSpan && cell->rowSpan() == 1) | 
|   858           continue; |   886           continue; | 
|   859  |   887  | 
|   860         if (cell->rowSpan() > 1) { |   888         if (cell->rowSpan() > 1) { | 
|   861           // For row spanning cells, we only handle them for the first row they 
      span. This ensures we take their baseline into account. |   889           // For row spanning cells, we only handle them for the first row they | 
 |   890           // span. This ensures we take their baseline into account. | 
|   862           if (lastRowSpanCell != cell && cell->rowIndex() == r) { |   891           if (lastRowSpanCell != cell && cell->rowIndex() == r) { | 
|   863 #if ENABLE(ASSERT) |   892 #if ENABLE(ASSERT) | 
|   864             ASSERT(!uniqueCells.contains(cell)); |   893             ASSERT(!uniqueCells.contains(cell)); | 
|   865             uniqueCells.add(cell); |   894             uniqueCells.add(cell); | 
|   866 #endif |   895 #endif | 
|   867  |   896  | 
|   868             rowSpanCells.append(cell); |   897             rowSpanCells.append(cell); | 
|   869             lastRowSpanCell = cell; |   898             lastRowSpanCell = cell; | 
|   870           } |   899           } | 
|   871         } |   900         } | 
|   872  |   901  | 
|   873         if (cell->rowIndex() == r && cell->hasOverrideLogicalContentHeight()) { |   902         if (cell->rowIndex() == r && cell->hasOverrideLogicalContentHeight()) { | 
|   874           cell->clearIntrinsicPadding(); |   903           cell->clearIntrinsicPadding(); | 
|   875           cell->clearOverrideSize(); |   904           cell->clearOverrideSize(); | 
|   876           cell->forceChildLayout(); |   905           cell->forceChildLayout(); | 
|   877         } |   906         } | 
|   878  |   907  | 
|   879         if (cell->rowSpan() == 1) |   908         if (cell->rowSpan() == 1) | 
|   880           m_rowPos[r + 1] = std::max( |   909           m_rowPos[r + 1] = std::max( | 
|   881               m_rowPos[r + 1], m_rowPos[r] + cell->logicalHeightForRowSizing()); |   910               m_rowPos[r + 1], m_rowPos[r] + cell->logicalHeightForRowSizing()); | 
|   882  |   911  | 
|   883         // Find out the baseline. The baseline is set on the first row in a rowS
      pan. |   912         // Find out the baseline. The baseline is set on the first row in a | 
 |   913         // rowSpan. | 
|   884         if (cell->rowIndex() == r) |   914         if (cell->rowIndex() == r) | 
|   885           updateBaselineForCell(cell, r, baselineDescent); |   915           updateBaselineForCell(cell, r, baselineDescent); | 
|   886       } |   916       } | 
|   887     } |   917     } | 
|   888  |   918  | 
|   889     // Add the border-spacing to our final position. |   919     // Add the border-spacing to our final position. | 
|   890     m_rowPos[r + 1] += borderSpacingForRow(r); |   920     m_rowPos[r + 1] += borderSpacingForRow(r); | 
|   891     m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r]); |   921     m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r]); | 
|   892   } |   922   } | 
|   893  |   923  | 
|   894   if (!rowSpanCells.isEmpty()) |   924   if (!rowSpanCells.isEmpty()) | 
|   895     distributeRowSpanHeightToRows(rowSpanCells); |   925     distributeRowSpanHeightToRows(rowSpanCells); | 
|   896  |   926  | 
|   897   ASSERT(!needsLayout()); |   927   ASSERT(!needsLayout()); | 
|   898  |   928  | 
|   899   return m_rowPos[m_grid.size()]; |   929   return m_rowPos[m_grid.size()]; | 
|   900 } |   930 } | 
|   901  |   931  | 
|   902 void LayoutTableSection::layout() { |   932 void LayoutTableSection::layout() { | 
|   903   ASSERT(needsLayout()); |   933   ASSERT(needsLayout()); | 
|   904   LayoutAnalyzer::Scope analyzer(*this); |   934   LayoutAnalyzer::Scope analyzer(*this); | 
|   905   RELEASE_ASSERT(!needsCellRecalc()); |   935   RELEASE_ASSERT(!needsCellRecalc()); | 
|   906   ASSERT(!table()->needsSectionRecalc()); |   936   ASSERT(!table()->needsSectionRecalc()); | 
|   907  |   937  | 
|   908   // addChild may over-grow m_grid but we don't want to throw away the memory to
      o early as addChild |   938   // addChild may over-grow m_grid but we don't want to throw away the memory | 
|   909   // can be called in a loop (e.g during parsing). Doing it now ensures we have 
      a stable-enough structure. |   939   // too early as addChild can be called in a loop (e.g during parsing). Doing | 
 |   940   // it now ensures we have a stable-enough structure. | 
|   910   m_grid.shrinkToFit(); |   941   m_grid.shrinkToFit(); | 
|   911  |   942  | 
|   912   LayoutState state(*this, locationOffset()); |   943   LayoutState state(*this, locationOffset()); | 
|   913  |   944  | 
|   914   const Vector<int>& columnPos = table()->effectiveColumnPositions(); |   945   const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 
|   915  |   946  | 
|   916   SubtreeLayoutScope layouter(*this); |   947   SubtreeLayoutScope layouter(*this); | 
|   917   for (unsigned r = 0; r < m_grid.size(); ++r) { |   948   for (unsigned r = 0; r < m_grid.size(); ++r) { | 
|   918     Row& row = m_grid[r].row; |   949     Row& row = m_grid[r].row; | 
|   919     unsigned cols = row.size(); |   950     unsigned cols = row.size(); | 
|   920     // First, propagate our table layout's information to the cells. This will m
      ark the row as needing layout |   951     // First, propagate our table layout's information to the cells. This will | 
|   921     // if there was a column logical width change. |   952     // mark the row as needing layout if there was a column logical width | 
 |   953     // change. | 
|   922     for (unsigned startColumn = 0; startColumn < cols; ++startColumn) { |   954     for (unsigned startColumn = 0; startColumn < cols; ++startColumn) { | 
|   923       CellStruct& current = row[startColumn]; |   955       CellStruct& current = row[startColumn]; | 
|   924       LayoutTableCell* cell = current.primaryCell(); |   956       LayoutTableCell* cell = current.primaryCell(); | 
|   925       if (!cell || current.inColSpan) |   957       if (!cell || current.inColSpan) | 
|   926         continue; |   958         continue; | 
|   927  |   959  | 
|   928       unsigned endCol = startColumn; |   960       unsigned endCol = startColumn; | 
|   929       unsigned cspan = cell->colSpan(); |   961       unsigned cspan = cell->colSpan(); | 
|   930       while (cspan && endCol < cols) { |   962       while (cspan && endCol < cols) { | 
|   931         ASSERT(endCol < table()->effectiveColumns().size()); |   963         ASSERT(endCol < table()->effectiveColumns().size()); | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   980  |  1012  | 
|   981 void LayoutTableSection::distributeExtraLogicalHeightToAutoRows( |  1013 void LayoutTableSection::distributeExtraLogicalHeightToAutoRows( | 
|   982     int& extraLogicalHeight, |  1014     int& extraLogicalHeight, | 
|   983     unsigned autoRowsCount) { |  1015     unsigned autoRowsCount) { | 
|   984   if (!autoRowsCount) |  1016   if (!autoRowsCount) | 
|   985     return; |  1017     return; | 
|   986  |  1018  | 
|   987   int totalLogicalHeightAdded = 0; |  1019   int totalLogicalHeightAdded = 0; | 
|   988   for (unsigned r = 0; r < m_grid.size(); ++r) { |  1020   for (unsigned r = 0; r < m_grid.size(); ++r) { | 
|   989     if (autoRowsCount > 0 && m_grid[r].logicalHeight.isAuto()) { |  1021     if (autoRowsCount > 0 && m_grid[r].logicalHeight.isAuto()) { | 
|   990       // Recomputing |extraLogicalHeightForRow| guarantees that we properly ditr
      ibute round |extraLogicalHeight|. |  1022       // Recomputing |extraLogicalHeightForRow| guarantees that we properly | 
 |  1023       // ditribute round |extraLogicalHeight|. | 
|   991       int extraLogicalHeightForRow = extraLogicalHeight / autoRowsCount; |  1024       int extraLogicalHeightForRow = extraLogicalHeight / autoRowsCount; | 
|   992       totalLogicalHeightAdded += extraLogicalHeightForRow; |  1025       totalLogicalHeightAdded += extraLogicalHeightForRow; | 
|   993       extraLogicalHeight -= extraLogicalHeightForRow; |  1026       extraLogicalHeight -= extraLogicalHeightForRow; | 
|   994       --autoRowsCount; |  1027       --autoRowsCount; | 
|   995     } |  1028     } | 
|   996     m_rowPos[r + 1] += totalLogicalHeightAdded; |  1029     m_rowPos[r + 1] += totalLogicalHeightAdded; | 
|   997   } |  1030   } | 
|   998 } |  1031 } | 
|   999  |  1032  | 
|  1000 void LayoutTableSection::distributeRemainingExtraLogicalHeight( |  1033 void LayoutTableSection::distributeRemainingExtraLogicalHeight( | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1058  |  1091  | 
|  1059 void LayoutTableSection::layoutRows() { |  1092 void LayoutTableSection::layoutRows() { | 
|  1060 #if ENABLE(ASSERT) |  1093 #if ENABLE(ASSERT) | 
|  1061   SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); |  1094   SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); | 
|  1062 #endif |  1095 #endif | 
|  1063  |  1096  | 
|  1064   ASSERT(!needsLayout()); |  1097   ASSERT(!needsLayout()); | 
|  1065  |  1098  | 
|  1066   LayoutAnalyzer::Scope analyzer(*this); |  1099   LayoutAnalyzer::Scope analyzer(*this); | 
|  1067  |  1100  | 
|  1068   // FIXME: Changing the height without a layout can change the overflow so it s
      eems wrong. |  1101   // FIXME: Changing the height without a layout can change the overflow so it | 
 |  1102   // seems wrong. | 
|  1069  |  1103  | 
|  1070   unsigned totalRows = m_grid.size(); |  1104   unsigned totalRows = m_grid.size(); | 
|  1071  |  1105  | 
|  1072   // Set the width of our section now.  The rows will also be this width. |  1106   // Set the width of our section now.  The rows will also be this width. | 
|  1073   setLogicalWidth(table()->contentLogicalWidth()); |  1107   setLogicalWidth(table()->contentLogicalWidth()); | 
|  1074  |  1108  | 
|  1075   int vspacing = table()->vBorderSpacing(); |  1109   int vspacing = table()->vBorderSpacing(); | 
|  1076   unsigned nEffCols = table()->numEffectiveColumns(); |  1110   unsigned nEffCols = table()->numEffectiveColumns(); | 
|  1077   bool isPaginated = view()->layoutState()->isPaginated(); |  1111   bool isPaginated = view()->layoutState()->isPaginated(); | 
|  1078  |  1112  | 
|  1079   if (isPaginated) { |  1113   if (isPaginated) { | 
|  1080     LayoutTableSection* header = table()->header(); |  1114     LayoutTableSection* header = table()->header(); | 
|  1081     // If we're a table header nested inside a table cell then we want to repeat
       on each |  1115     // If we're a table header nested inside a table cell then we want to repeat | 
|  1082     // page, but below the header we're nested inside. Note we don't try to matc
      h the padding |  1116     // on each page, but below the header we're nested inside. Note we don't try | 
|  1083     // on the cell on each repeated header. |  1117     // to match the padding on the cell on each repeated header. | 
|  1084     if (header && header == this) |  1118     if (header && header == this) | 
|  1085       setOffsetForRepeatingHeader( |  1119       setOffsetForRepeatingHeader( | 
|  1086           view()->layoutState()->heightOffsetForTableHeaders()); |  1120           view()->layoutState()->heightOffsetForTableHeaders()); | 
|  1087   } |  1121   } | 
|  1088  |  1122  | 
|  1089   LayoutState state(*this, locationOffset()); |  1123   LayoutState state(*this, locationOffset()); | 
|  1090  |  1124  | 
|  1091   for (unsigned r = 0; r < totalRows; r++) { |  1125   for (unsigned r = 0; r < totalRows; r++) { | 
|  1092     // Set the row's x/y position and width/height. |  1126     // Set the row's x/y position and width/height. | 
|  1093     LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; |  1127     LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject; | 
|  1094     int paginationStrutOnRow = 0; |  1128     int paginationStrutOnRow = 0; | 
|  1095     if (rowLayoutObject) { |  1129     if (rowLayoutObject) { | 
|  1096       rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r])); |  1130       rowLayoutObject->setLogicalLocation(LayoutPoint(0, m_rowPos[r])); | 
|  1097       rowLayoutObject->setLogicalWidth(logicalWidth()); |  1131       rowLayoutObject->setLogicalWidth(logicalWidth()); | 
|  1098       rowLayoutObject->setLogicalHeight( |  1132       rowLayoutObject->setLogicalHeight( | 
|  1099           LayoutUnit(m_rowPos[r + 1] - m_rowPos[r] - vspacing)); |  1133           LayoutUnit(m_rowPos[r + 1] - m_rowPos[r] - vspacing)); | 
|  1100       rowLayoutObject->updateLayerTransformAfterLayout(); |  1134       rowLayoutObject->updateLayerTransformAfterLayout(); | 
|  1101       if (isPaginated) { |  1135       if (isPaginated) { | 
|  1102         paginationStrutOnRow = |  1136         paginationStrutOnRow = | 
|  1103             paginationStrutForRow(rowLayoutObject, LayoutUnit(m_rowPos[r])); |  1137             paginationStrutForRow(rowLayoutObject, LayoutUnit(m_rowPos[r])); | 
|  1104         rowLayoutObject->setPaginationStrut(LayoutUnit(paginationStrutOnRow)); |  1138         rowLayoutObject->setPaginationStrut(LayoutUnit(paginationStrutOnRow)); | 
|  1105         bool rowIsAtTopOfColumn = |  1139         bool rowIsAtTopOfColumn = | 
|  1106             state.heightOffsetForTableHeaders() && |  1140             state.heightOffsetForTableHeaders() && | 
|  1107             pageRemainingLogicalHeightForOffset(LayoutUnit(m_rowPos[r]), |  1141             pageRemainingLogicalHeightForOffset(LayoutUnit(m_rowPos[r]), | 
|  1108                                                 AssociateWithLatterPage) == |  1142                                                 AssociateWithLatterPage) == | 
|  1109                 pageLogicalHeightForOffset(LayoutUnit(m_rowPos[r])); |  1143                 pageLogicalHeightForOffset(LayoutUnit(m_rowPos[r])); | 
|  1110         if (paginationStrutOnRow || rowIsAtTopOfColumn) { |  1144         if (paginationStrutOnRow || rowIsAtTopOfColumn) { | 
|  1111           // If there isn't room for at least one content row on a page with a h
      eader group, then |  1145           // If there isn't room for at least one content row on a page with a | 
|  1112           // we won't repeat the header on each page. |  1146           // header group, then we won't repeat the header on each page. | 
|  1113           if (!r && table()->header() && |  1147           if (!r && table()->header() && | 
|  1114               table()->sectionAbove(this) == table()->header() && |  1148               table()->sectionAbove(this) == table()->header() && | 
|  1115               table()->header()->getPaginationBreakability() != AllowAnyBreaks) |  1149               table()->header()->getPaginationBreakability() != AllowAnyBreaks) | 
|  1116             state.setHeightOffsetForTableHeaders( |  1150             state.setHeightOffsetForTableHeaders( | 
|  1117                 state.heightOffsetForTableHeaders() - |  1151                 state.heightOffsetForTableHeaders() - | 
|  1118                 table()->header()->logicalHeight()); |  1152                 table()->header()->logicalHeight()); | 
|  1119           // If we have a header group we will paint it at the top of each page,
       move the rows |  1153           // If we have a header group we will paint it at the top of each page, | 
|  1120           // down to accomodate it. |  1154           // move the rows down to accomodate it. | 
|  1121           paginationStrutOnRow += state.heightOffsetForTableHeaders().toInt(); |  1155           paginationStrutOnRow += state.heightOffsetForTableHeaders().toInt(); | 
|  1122           for (unsigned rowIndex = r; rowIndex <= totalRows; rowIndex++) |  1156           for (unsigned rowIndex = r; rowIndex <= totalRows; rowIndex++) | 
|  1123             m_rowPos[rowIndex] += paginationStrutOnRow; |  1157             m_rowPos[rowIndex] += paginationStrutOnRow; | 
|  1124         } |  1158         } | 
|  1125       } |  1159       } | 
|  1126     } |  1160     } | 
|  1127  |  1161  | 
|  1128     int rowHeightIncreaseForPagination = INT_MIN; |  1162     int rowHeightIncreaseForPagination = INT_MIN; | 
|  1129  |  1163  | 
|  1130     for (unsigned c = 0; c < nEffCols; c++) { |  1164     for (unsigned c = 0; c < nEffCols; c++) { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  1148       setLogicalPositionForCell(cell, c); |  1182       setLogicalPositionForCell(cell, c); | 
|  1149  |  1183  | 
|  1150       if (!cell->needsLayout()) |  1184       if (!cell->needsLayout()) | 
|  1151         markChildForPaginationRelayoutIfNeeded(*cell, layouter); |  1185         markChildForPaginationRelayoutIfNeeded(*cell, layouter); | 
|  1152  |  1186  | 
|  1153       cell->layoutIfNeeded(); |  1187       cell->layoutIfNeeded(); | 
|  1154  |  1188  | 
|  1155       // FIXME: Make pagination work with vertical tables. |  1189       // FIXME: Make pagination work with vertical tables. | 
|  1156       if (view()->layoutState()->pageLogicalHeight() && |  1190       if (view()->layoutState()->pageLogicalHeight() && | 
|  1157           cell->logicalHeight() != rHeight) { |  1191           cell->logicalHeight() != rHeight) { | 
|  1158         // FIXME: Pagination might have made us change size. For now just shrink
       or grow the cell to fit without doing a relayout. |  1192         // FIXME: Pagination might have made us change size. For now just shrink | 
|  1159         // We'll also do a basic increase of the row height to accommodate the c
      ell if it's bigger, but this isn't quite right |  1193         // or grow the cell to fit without doing a relayout. | 
|  1160         // either. It's at least stable though and won't result in an infinite #
       of relayouts that may never stabilize. |  1194         // We'll also do a basic increase of the row height to accommodate the | 
 |  1195         // cell if it's bigger, but this isn't quite right either. It's at least | 
 |  1196         // stable though and won't result in an infinite # of relayouts that may | 
 |  1197         // never stabilize. | 
|  1161         LayoutUnit oldLogicalHeight = cell->logicalHeight(); |  1198         LayoutUnit oldLogicalHeight = cell->logicalHeight(); | 
|  1162         rowHeightIncreaseForPagination = |  1199         rowHeightIncreaseForPagination = | 
|  1163             std::max<int>(rowHeightIncreaseForPagination, |  1200             std::max<int>(rowHeightIncreaseForPagination, | 
|  1164                           (oldLogicalHeight - rHeight).toInt()); |  1201                           (oldLogicalHeight - rHeight).toInt()); | 
|  1165         cell->setLogicalHeight(LayoutUnit(rHeight)); |  1202         cell->setLogicalHeight(LayoutUnit(rHeight)); | 
|  1166         cell->computeOverflow(oldLogicalHeight, false); |  1203         cell->computeOverflow(oldLogicalHeight, false); | 
|  1167       } |  1204       } | 
|  1168  |  1205  | 
|  1169       LayoutSize childOffset(cell->location() - oldCellRect.location()); |  1206       LayoutSize childOffset(cell->location() - oldCellRect.location()); | 
|  1170       if (childOffset.width() || childOffset.height()) { |  1207       if (childOffset.width() || childOffset.height()) { | 
|  1171         // If the child moved, we have to issue paint invalidations to it as wel
      l as any floating/positioned |  1208         // If the child moved, we have to issue paint invalidations to it as | 
|  1172         // descendants. An exception is if we need a layout. In this case, we kn
      ow we're going to |  1209         // well as any floating/positioned descendants. An exception is if we | 
|  1173         // issue paint invalidations ourselves (and the child) anyway. |  1210         // need a layout. In this case, we know we're going to issue paint | 
 |  1211         // invalidations ourselves (and the child) anyway. | 
|  1174         if (!table()->selfNeedsLayout()) |  1212         if (!table()->selfNeedsLayout()) | 
|  1175           cell->setMayNeedPaintInvalidation(); |  1213           cell->setMayNeedPaintInvalidation(); | 
|  1176       } |  1214       } | 
|  1177     } |  1215     } | 
|  1178     if (rowHeightIncreaseForPagination > INT_MIN) { |  1216     if (rowHeightIncreaseForPagination > INT_MIN) { | 
|  1179       for (unsigned rowIndex = r + 1; rowIndex <= totalRows; rowIndex++) |  1217       for (unsigned rowIndex = r + 1; rowIndex <= totalRows; rowIndex++) | 
|  1180         m_rowPos[rowIndex] += rowHeightIncreaseForPagination; |  1218         m_rowPos[rowIndex] += rowHeightIncreaseForPagination; | 
|  1181       for (unsigned c = 0; c < nEffCols; ++c) { |  1219       for (unsigned c = 0; c < nEffCols; ++c) { | 
|  1182         Vector<LayoutTableCell*, 1>& cells = cellAt(r, c).cells; |  1220         Vector<LayoutTableCell*, 1>& cells = cellAt(r, c).cells; | 
|  1183         for (size_t i = 0; i < cells.size(); ++i) { |  1221         for (size_t i = 0; i < cells.size(); ++i) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  1195   ASSERT(!needsLayout()); |  1233   ASSERT(!needsLayout()); | 
|  1196  |  1234  | 
|  1197   setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); |  1235   setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); | 
|  1198  |  1236  | 
|  1199   computeOverflowFromCells(totalRows, nEffCols); |  1237   computeOverflowFromCells(totalRows, nEffCols); | 
|  1200 } |  1238 } | 
|  1201  |  1239  | 
|  1202 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, |  1240 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, | 
|  1203                                               LayoutUnit logicalOffset) const { |  1241                                               LayoutUnit logicalOffset) const { | 
|  1204   DCHECK(row); |  1242   DCHECK(row); | 
|  1205   // Even if the row allows us to break-inside, we will want to put a strut on t
      he row if we have a header |  1243   // Even if the row allows us to break-inside, we will want to put a strut on | 
|  1206   // group that wants to appear at the top of each page. |  1244   // the row if we have a header group that wants to appear at the top of each | 
 |  1245   // page. | 
|  1207   bool tableHeaderForcesStrut = |  1246   bool tableHeaderForcesStrut = | 
|  1208       table()->header() |  1247       table()->header() | 
|  1209           ? table()->header()->getPaginationBreakability() != AllowAnyBreaks |  1248           ? table()->header()->getPaginationBreakability() != AllowAnyBreaks | 
|  1210           : false; |  1249           : false; | 
|  1211   if (row->getPaginationBreakability() == AllowAnyBreaks && |  1250   if (row->getPaginationBreakability() == AllowAnyBreaks && | 
|  1212       !tableHeaderForcesStrut) |  1251       !tableHeaderForcesStrut) | 
|  1213     return 0; |  1252     return 0; | 
|  1214   LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |  1253   LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 
|  1215   if (!pageLogicalHeight) |  1254   if (!pageLogicalHeight) | 
|  1216     return 0; |  1255     return 0; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  1228   // repeating header. |  1267   // repeating header. | 
|  1229   if (offsetForBorderSpacing < 0) |  1268   if (offsetForBorderSpacing < 0) | 
|  1230     return offsetForBorderSpacing.toInt(); |  1269     return offsetForBorderSpacing.toInt(); | 
|  1231  |  1270  | 
|  1232   if (remainingLogicalHeight >= rowLogicalHeight) |  1271   if (remainingLogicalHeight >= rowLogicalHeight) | 
|  1233     return 0;  // It fits fine where it is. No need to break. |  1272     return 0;  // It fits fine where it is. No need to break. | 
|  1234   LayoutUnit paginationStrut = calculatePaginationStrutToFitContent( |  1273   LayoutUnit paginationStrut = calculatePaginationStrutToFitContent( | 
|  1235       logicalOffset, remainingLogicalHeight, rowLogicalHeight); |  1274       logicalOffset, remainingLogicalHeight, rowLogicalHeight); | 
|  1236   if (paginationStrut == remainingLogicalHeight && |  1275   if (paginationStrut == remainingLogicalHeight && | 
|  1237       remainingLogicalHeight == pageLogicalHeight) { |  1276       remainingLogicalHeight == pageLogicalHeight) { | 
|  1238     // Don't break if we were at the top of a page, and we failed to fit the con
      tent |  1277     // Don't break if we were at the top of a page, and we failed to fit the | 
|  1239     // completely. No point in leaving a page completely blank. |  1278     // content completely. No point in leaving a page completely blank. | 
|  1240     return 0; |  1279     return 0; | 
|  1241   } |  1280   } | 
|  1242   // Table layout parts only work on integers, so we have to round. Round up, to |  1281   // Table layout parts only work on integers, so we have to round. Round up, to | 
|  1243   // make sure that no fraction ever gets left behind in the previous |  1282   // make sure that no fraction ever gets left behind in the previous | 
|  1244   // fragmentainer. |  1283   // fragmentainer. | 
|  1245   return paginationStrut.ceil(); |  1284   return paginationStrut.ceil(); | 
|  1246 } |  1285 } | 
|  1247  |  1286  | 
|  1248 void LayoutTableSection::computeOverflowFromCells() { |  1287 void LayoutTableSection::computeOverflowFromCells() { | 
|  1249   unsigned totalRows = m_grid.size(); |  1288   unsigned totalRows = m_grid.size(); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  1275       if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) |  1314       if (r < totalRows - 1 && cell == primaryCellAt(r + 1, c)) | 
|  1276         continue; |  1315         continue; | 
|  1277       addOverflowFromChild(cell); |  1316       addOverflowFromChild(cell); | 
|  1278 #if ENABLE(ASSERT) |  1317 #if ENABLE(ASSERT) | 
|  1279       hasOverflowingCell |= cell->hasVisualOverflow(); |  1318       hasOverflowingCell |= cell->hasVisualOverflow(); | 
|  1280 #endif |  1319 #endif | 
|  1281       if (cell->hasVisualOverflow() && |  1320       if (cell->hasVisualOverflow() && | 
|  1282           !m_forceSlowPaintPathWithOverflowingCell) { |  1321           !m_forceSlowPaintPathWithOverflowingCell) { | 
|  1283         m_overflowingCells.add(cell); |  1322         m_overflowingCells.add(cell); | 
|  1284         if (m_overflowingCells.size() > maxAllowedOverflowingCellsCount) { |  1323         if (m_overflowingCells.size() > maxAllowedOverflowingCellsCount) { | 
|  1285           // We need to set m_forcesSlowPaintPath only if there is a least one o
      verflowing cells as the hit testing code rely on this information. |  1324           // We need to set m_forcesSlowPaintPath only if there is a least one | 
 |  1325           // overflowing cells as the hit testing code rely on this information. | 
|  1286           m_forceSlowPaintPathWithOverflowingCell = true; |  1326           m_forceSlowPaintPathWithOverflowingCell = true; | 
|  1287           // The slow path does not make any use of the overflowing cells info, 
      don't hold on to the memory. |  1327           // The slow path does not make any use of the overflowing cells info, | 
 |  1328           // don't hold on to the memory. | 
|  1288           m_overflowingCells.clear(); |  1329           m_overflowingCells.clear(); | 
|  1289         } |  1330         } | 
|  1290       } |  1331       } | 
|  1291     } |  1332     } | 
|  1292   } |  1333   } | 
|  1293  |  1334  | 
|  1294   ASSERT(hasOverflowingCell == this->hasOverflowingCell()); |  1335   ASSERT(hasOverflowingCell == this->hasOverflowingCell()); | 
|  1295 } |  1336 } | 
|  1296  |  1337  | 
|  1297 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { |  1338 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1359   if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) |  1400   if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) | 
|  1360     borderWidth = rb.width(); |  1401     borderWidth = rb.width(); | 
|  1361  |  1402  | 
|  1362   bool allHidden = true; |  1403   bool allHidden = true; | 
|  1363   for (unsigned c = 0; c < totalCols; c++) { |  1404   for (unsigned c = 0; c < totalCols; c++) { | 
|  1364     const CellStruct& current = |  1405     const CellStruct& current = | 
|  1365         cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c); |  1406         cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c); | 
|  1366     if (current.inColSpan || !current.hasCells()) |  1407     if (current.inColSpan || !current.hasCells()) | 
|  1367       continue; |  1408       continue; | 
|  1368     const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); |  1409     const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); | 
|  1369     const BorderValue& cb = |  1410     // FIXME: Make this work with perpendicular and flipped cells. | 
|  1370         side == BorderBefore |  1411     const BorderValue& cb = side == BorderBefore | 
|  1371             ? primaryCellStyle.borderBefore() |  1412                                 ? primaryCellStyle.borderBefore() | 
|  1372             : primaryCellStyle |  1413                                 : primaryCellStyle.borderAfter(); | 
|  1373                   .borderAfter();  // FIXME: Make this work with perpendicular a
      nd flipped cells. |  | 
|  1374     // FIXME: Don't repeat for the same col group |  1414     // FIXME: Don't repeat for the same col group | 
|  1375     LayoutTableCol* col = |  1415     LayoutTableCol* col = | 
|  1376         table()->colElementAtAbsoluteColumn(c).innermostColOrColGroup(); |  1416         table()->colElementAtAbsoluteColumn(c).innermostColOrColGroup(); | 
|  1377     if (col) { |  1417     if (col) { | 
|  1378       const BorderValue& gb = side == BorderBefore |  1418       const BorderValue& gb = side == BorderBefore | 
|  1379                                   ? col->style()->borderBefore() |  1419                                   ? col->style()->borderBefore() | 
|  1380                                   : col->style()->borderAfter(); |  1420                                   : col->style()->borderAfter(); | 
|  1381       if (gb.style() == BorderStyleHidden || cb.style() == BorderStyleHidden) |  1421       if (gb.style() == BorderStyleHidden || cb.style() == BorderStyleHidden) | 
|  1382         continue; |  1422         continue; | 
|  1383       allHidden = false; |  1423       allHidden = false; | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1430  |  1470  | 
|  1431   bool allHidden = true; |  1471   bool allHidden = true; | 
|  1432   for (unsigned r = 0; r < m_grid.size(); r++) { |  1472   for (unsigned r = 0; r < m_grid.size(); r++) { | 
|  1433     const CellStruct& current = cellAt(r, colIndex); |  1473     const CellStruct& current = cellAt(r, colIndex); | 
|  1434     if (!current.hasCells()) |  1474     if (!current.hasCells()) | 
|  1435       continue; |  1475       continue; | 
|  1436     // FIXME: Don't repeat for the same cell |  1476     // FIXME: Don't repeat for the same cell | 
|  1437     const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); |  1477     const ComputedStyle& primaryCellStyle = current.primaryCell()->styleRef(); | 
|  1438     const ComputedStyle& primaryCellParentStyle = |  1478     const ComputedStyle& primaryCellParentStyle = | 
|  1439         current.primaryCell()->parent()->styleRef(); |  1479         current.primaryCell()->parent()->styleRef(); | 
|  1440     const BorderValue& cb = |  1480     // FIXME: Make this work with perpendicular and flipped cells. | 
|  1441         side == BorderStart |  1481     const BorderValue& cb = side == BorderStart ? primaryCellStyle.borderStart() | 
|  1442             ? primaryCellStyle.borderStart() |  1482                                                 : primaryCellStyle.borderEnd(); | 
|  1443             : primaryCellStyle |  | 
|  1444                   .borderEnd();  // FIXME: Make this work with perpendicular and
       flipped cells. |  | 
|  1445     const BorderValue& rb = side == BorderStart |  1483     const BorderValue& rb = side == BorderStart | 
|  1446                                 ? primaryCellParentStyle.borderStart() |  1484                                 ? primaryCellParentStyle.borderStart() | 
|  1447                                 : primaryCellParentStyle.borderEnd(); |  1485                                 : primaryCellParentStyle.borderEnd(); | 
|  1448     if (cb.style() == BorderStyleHidden || rb.style() == BorderStyleHidden) |  1486     if (cb.style() == BorderStyleHidden || rb.style() == BorderStyleHidden) | 
|  1449       continue; |  1487       continue; | 
|  1450     allHidden = false; |  1488     allHidden = false; | 
|  1451     if (cb.style() > BorderStyleHidden && cb.width() > borderWidth) |  1489     if (cb.style() > BorderStyleHidden && cb.width() > borderWidth) | 
|  1452       borderWidth = cb.width(); |  1490       borderWidth = cb.width(); | 
|  1453     if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) |  1491     if (rb.style() > BorderStyleHidden && rb.width() > borderWidth) | 
|  1454       borderWidth = rb.width(); |  1492       borderWidth = rb.width(); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1499 LayoutRect LayoutTableSection::logicalRectForWritingModeAndDirection( |  1537 LayoutRect LayoutTableSection::logicalRectForWritingModeAndDirection( | 
|  1500     const LayoutRect& rect) const { |  1538     const LayoutRect& rect) const { | 
|  1501   LayoutRect tableAlignedRect(rect); |  1539   LayoutRect tableAlignedRect(rect); | 
|  1502  |  1540  | 
|  1503   flipForWritingMode(tableAlignedRect); |  1541   flipForWritingMode(tableAlignedRect); | 
|  1504  |  1542  | 
|  1505   if (!style()->isHorizontalWritingMode()) |  1543   if (!style()->isHorizontalWritingMode()) | 
|  1506     tableAlignedRect = tableAlignedRect.transposedRect(); |  1544     tableAlignedRect = tableAlignedRect.transposedRect(); | 
|  1507  |  1545  | 
|  1508   const Vector<int>& columnPos = table()->effectiveColumnPositions(); |  1546   const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 
|  1509   // FIXME: The table's direction should determine our row's direction, not the 
      section's (see bug 96691). |  1547   // FIXME: The table's direction should determine our row's direction, not the | 
 |  1548   // section's (see bug 96691). | 
|  1510   if (!style()->isLeftToRightDirection()) |  1549   if (!style()->isLeftToRightDirection()) | 
|  1511     tableAlignedRect.setX(columnPos[columnPos.size() - 1] - |  1550     tableAlignedRect.setX(columnPos[columnPos.size() - 1] - | 
|  1512                           tableAlignedRect.maxX()); |  1551                           tableAlignedRect.maxX()); | 
|  1513  |  1552  | 
|  1514   return tableAlignedRect; |  1553   return tableAlignedRect; | 
|  1515 } |  1554 } | 
|  1516  |  1555  | 
|  1517 CellSpan LayoutTableSection::dirtiedRows(const LayoutRect& damageRect) const { |  1556 CellSpan LayoutTableSection::dirtiedRows(const LayoutRect& damageRect) const { | 
|  1518   if (m_forceSlowPaintPathWithOverflowingCell) |  1557   if (m_forceSlowPaintPathWithOverflowingCell) | 
|  1519     return fullTableRowSpan(); |  1558     return fullTableRowSpan(); | 
|  1520  |  1559  | 
|  1521   if (!m_grid.size()) |  1560   if (!m_grid.size()) | 
|  1522     return CellSpan(0, 0); |  1561     return CellSpan(0, 0); | 
|  1523  |  1562  | 
|  1524   CellSpan coveredRows = spannedRows(damageRect); |  1563   CellSpan coveredRows = spannedRows(damageRect); | 
|  1525  |  1564  | 
|  1526   // To issue paint invalidations for the border we might need to paint invalida
      te the first |  1565   // To issue paint invalidations for the border we might need to paint | 
|  1527   // or last row even if they are not spanned themselves. |  1566   // invalidate the first or last row even if they are not spanned themselves. | 
|  1528   RELEASE_ASSERT(coveredRows.start() < m_rowPos.size()); |  1567   RELEASE_ASSERT(coveredRows.start() < m_rowPos.size()); | 
|  1529   if (coveredRows.start() == m_rowPos.size() - 1 && |  1568   if (coveredRows.start() == m_rowPos.size() - 1 && | 
|  1530       m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= |  1569       m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= | 
|  1531           damageRect.y()) |  1570           damageRect.y()) | 
|  1532     coveredRows.decreaseStart(); |  1571     coveredRows.decreaseStart(); | 
|  1533  |  1572  | 
|  1534   if (!coveredRows.end() && |  1573   if (!coveredRows.end() && | 
|  1535       m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY()) |  1574       m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY()) | 
|  1536     coveredRows.increaseEnd(); |  1575     coveredRows.increaseEnd(); | 
|  1537  |  1576  | 
|  1538   coveredRows.ensureConsistency(m_grid.size()); |  1577   coveredRows.ensureConsistency(m_grid.size()); | 
|  1539  |  1578  | 
|  1540   return coveredRows; |  1579   return coveredRows; | 
|  1541 } |  1580 } | 
|  1542  |  1581  | 
|  1543 CellSpan LayoutTableSection::dirtiedEffectiveColumns( |  1582 CellSpan LayoutTableSection::dirtiedEffectiveColumns( | 
|  1544     const LayoutRect& damageRect) const { |  1583     const LayoutRect& damageRect) const { | 
|  1545   if (m_forceSlowPaintPathWithOverflowingCell) |  1584   if (m_forceSlowPaintPathWithOverflowingCell) | 
|  1546     return fullTableEffectiveColumnSpan(); |  1585     return fullTableEffectiveColumnSpan(); | 
|  1547  |  1586  | 
|  1548   RELEASE_ASSERT(table()->numEffectiveColumns()); |  1587   RELEASE_ASSERT(table()->numEffectiveColumns()); | 
|  1549   CellSpan coveredColumns = spannedEffectiveColumns(damageRect); |  1588   CellSpan coveredColumns = spannedEffectiveColumns(damageRect); | 
|  1550  |  1589  | 
|  1551   const Vector<int>& columnPos = table()->effectiveColumnPositions(); |  1590   const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 
|  1552   // To issue paint invalidations for the border we might need to paint invalida
      te the first |  1591   // To issue paint invalidations for the border we might need to paint | 
|  1553   // or last column even if they are not spanned themselves. |  1592   // invalidate the first or last column even if they are not spanned | 
 |  1593   // themselves. | 
|  1554   RELEASE_ASSERT(coveredColumns.start() < columnPos.size()); |  1594   RELEASE_ASSERT(coveredColumns.start() < columnPos.size()); | 
|  1555   if (coveredColumns.start() == columnPos.size() - 1 && |  1595   if (coveredColumns.start() == columnPos.size() - 1 && | 
|  1556       columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= |  1596       columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= | 
|  1557           damageRect.x()) |  1597           damageRect.x()) | 
|  1558     coveredColumns.decreaseStart(); |  1598     coveredColumns.decreaseStart(); | 
|  1559  |  1599  | 
|  1560   if (!coveredColumns.end() && |  1600   if (!coveredColumns.end() && | 
|  1561       columnPos[0] - table()->outerBorderStart() <= damageRect.maxX()) |  1601       columnPos[0] - table()->outerBorderStart() <= damageRect.maxX()) | 
|  1562     coveredColumns.increaseEnd(); |  1602     coveredColumns.increaseEnd(); | 
|  1563  |  1603  | 
|  1564   coveredColumns.ensureConsistency(table()->numEffectiveColumns()); |  1604   coveredColumns.ensureConsistency(table()->numEffectiveColumns()); | 
|  1565  |  1605  | 
|  1566   return coveredColumns; |  1606   return coveredColumns; | 
|  1567 } |  1607 } | 
|  1568  |  1608  | 
|  1569 CellSpan LayoutTableSection::spannedRows(const LayoutRect& flippedRect) const { |  1609 CellSpan LayoutTableSection::spannedRows(const LayoutRect& flippedRect) const { | 
|  1570   // Find the first row that starts after rect top. |  1610   // Find the first row that starts after rect top. | 
|  1571   unsigned nextRow = |  1611   unsigned nextRow = | 
|  1572       std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - |  1612       std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - | 
|  1573       m_rowPos.begin(); |  1613       m_rowPos.begin(); | 
|  1574  |  1614  | 
 |  1615   // After all rows. | 
|  1575   if (nextRow == m_rowPos.size()) |  1616   if (nextRow == m_rowPos.size()) | 
|  1576     return CellSpan(m_rowPos.size() - 1, |  1617     return CellSpan(m_rowPos.size() - 1, m_rowPos.size() - 1); | 
|  1577                     m_rowPos.size() - 1);  // After all rows. |  | 
|  1578  |  1618  | 
|  1579   unsigned startRow = nextRow > 0 ? nextRow - 1 : 0; |  1619   unsigned startRow = nextRow > 0 ? nextRow - 1 : 0; | 
|  1580  |  1620  | 
|  1581   // Find the first row that starts after rect bottom. |  1621   // Find the first row that starts after rect bottom. | 
|  1582   unsigned endRow; |  1622   unsigned endRow; | 
|  1583   if (m_rowPos[nextRow] >= flippedRect.maxY()) { |  1623   if (m_rowPos[nextRow] >= flippedRect.maxY()) { | 
|  1584     endRow = nextRow; |  1624     endRow = nextRow; | 
|  1585   } else { |  1625   } else { | 
|  1586     endRow = std::upper_bound(m_rowPos.begin() + nextRow, m_rowPos.end(), |  1626     endRow = std::upper_bound(m_rowPos.begin() + nextRow, m_rowPos.end(), | 
|  1587                               flippedRect.maxY()) - |  1627                               flippedRect.maxY()) - | 
|  1588              m_rowPos.begin(); |  1628              m_rowPos.begin(); | 
|  1589     if (endRow == m_rowPos.size()) |  1629     if (endRow == m_rowPos.size()) | 
|  1590       endRow = m_rowPos.size() - 1; |  1630       endRow = m_rowPos.size() - 1; | 
|  1591   } |  1631   } | 
|  1592  |  1632  | 
|  1593   return CellSpan(startRow, endRow); |  1633   return CellSpan(startRow, endRow); | 
|  1594 } |  1634 } | 
|  1595  |  1635  | 
|  1596 CellSpan LayoutTableSection::spannedEffectiveColumns( |  1636 CellSpan LayoutTableSection::spannedEffectiveColumns( | 
|  1597     const LayoutRect& flippedRect) const { |  1637     const LayoutRect& flippedRect) const { | 
|  1598   const Vector<int>& columnPos = table()->effectiveColumnPositions(); |  1638   const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 
|  1599  |  1639  | 
|  1600   // Find the first column that starts after rect left. |  1640   // Find the first column that starts after rect left. | 
|  1601   // lower_bound doesn't handle the edge between two cells properly as it would 
      wrongly return the |  1641   // lower_bound doesn't handle the edge between two cells properly as it would | 
|  1602   // cell on the logical top/left. |  1642   // wrongly return the cell on the logical top/left. | 
|  1603   // upper_bound on the other hand properly returns the cell on the logical bott
      om/right, which also |  1643   // upper_bound on the other hand properly returns the cell on the logical | 
|  1604   // matches the behavior of other browsers. |  1644   // bottom/right, which also matches the behavior of other browsers. | 
|  1605   unsigned nextColumn = |  1645   unsigned nextColumn = | 
|  1606       std::upper_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - |  1646       std::upper_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - | 
|  1607       columnPos.begin(); |  1647       columnPos.begin(); | 
|  1608  |  1648  | 
|  1609   if (nextColumn == columnPos.size()) |  1649   if (nextColumn == columnPos.size()) | 
|  1610     return CellSpan(columnPos.size() - 1, |  1650     return CellSpan(columnPos.size() - 1, | 
|  1611                     columnPos.size() - 1);  // After all columns. |  1651                     columnPos.size() - 1);  // After all columns. | 
|  1612  |  1652  | 
|  1613   unsigned startColumn = nextColumn > 0 ? nextColumn - 1 : 0; |  1653   unsigned startColumn = nextColumn > 0 ? nextColumn - 1 : 0; | 
|  1614  |  1654  | 
|  1615   // Find the first column that starts after rect right. |  1655   // Find the first column that starts after rect right. | 
|  1616   unsigned endColumn; |  1656   unsigned endColumn; | 
|  1617   if (columnPos[nextColumn] >= flippedRect.maxX()) { |  1657   if (columnPos[nextColumn] >= flippedRect.maxX()) { | 
|  1618     endColumn = nextColumn; |  1658     endColumn = nextColumn; | 
|  1619   } else { |  1659   } else { | 
|  1620     endColumn = std::upper_bound(columnPos.begin() + nextColumn, |  1660     endColumn = std::upper_bound(columnPos.begin() + nextColumn, | 
|  1621                                  columnPos.end(), flippedRect.maxX()) - |  1661                                  columnPos.end(), flippedRect.maxX()) - | 
|  1622                 columnPos.begin(); |  1662                 columnPos.begin(); | 
|  1623     if (endColumn == columnPos.size()) |  1663     if (endColumn == columnPos.size()) | 
|  1624       endColumn = columnPos.size() - 1; |  1664       endColumn = columnPos.size() - 1; | 
|  1625   } |  1665   } | 
|  1626  |  1666  | 
|  1627   return CellSpan(startColumn, endColumn); |  1667   return CellSpan(startColumn, endColumn); | 
|  1628 } |  1668 } | 
|  1629  |  1669  | 
|  1630 void LayoutTableSection::recalcCells() { |  1670 void LayoutTableSection::recalcCells() { | 
|  1631   ASSERT(m_needsCellRecalc); |  1671   ASSERT(m_needsCellRecalc); | 
|  1632   // We reset the flag here to ensure that |addCell| works. This is safe to do a
      s |  1672   // We reset the flag here to ensure that |addCell| works. This is safe to do | 
|  1633   // fillRowsWithDefaultStartingAtPosition makes sure we match the table's colum
      ns |  1673   // as fillRowsWithDefaultStartingAtPosition makes sure we match the table's | 
|  1634   // representation. |  1674   // columns representation. | 
|  1635   m_needsCellRecalc = false; |  1675   m_needsCellRecalc = false; | 
|  1636  |  1676  | 
|  1637   m_cCol = 0; |  1677   m_cCol = 0; | 
|  1638   m_cRow = 0; |  1678   m_cRow = 0; | 
|  1639   m_grid.clear(); |  1679   m_grid.clear(); | 
|  1640  |  1680  | 
|  1641   for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { |  1681   for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { | 
|  1642     unsigned insertionRow = m_cRow; |  1682     unsigned insertionRow = m_cRow; | 
|  1643     ++m_cRow; |  1683     ++m_cRow; | 
|  1644     m_cCol = 0; |  1684     m_cCol = 0; | 
|  1645     ensureRows(m_cRow); |  1685     ensureRows(m_cRow); | 
|  1646  |  1686  | 
|  1647     m_grid[insertionRow].rowLayoutObject = row; |  1687     m_grid[insertionRow].rowLayoutObject = row; | 
|  1648     row->setRowIndex(insertionRow); |  1688     row->setRowIndex(insertionRow); | 
|  1649     setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); |  1689     setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); | 
|  1650  |  1690  | 
|  1651     for (LayoutTableCell* cell = row->firstCell(); cell; |  1691     for (LayoutTableCell* cell = row->firstCell(); cell; | 
|  1652          cell = cell->nextCell()) |  1692          cell = cell->nextCell()) | 
|  1653       addCell(cell, row); |  1693       addCell(cell, row); | 
|  1654   } |  1694   } | 
|  1655  |  1695  | 
|  1656   m_grid.shrinkToFit(); |  1696   m_grid.shrinkToFit(); | 
|  1657   setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Unknown); |  1697   setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Unknown); | 
|  1658 } |  1698 } | 
|  1659  |  1699  | 
|  1660 // FIXME: This function could be made O(1) in certain cases (like for the non-mo
      st-constrainive cells' case). |  1700 // FIXME: This function could be made O(1) in certain cases (like for the | 
 |  1701 // non-most-constrainive cells' case). | 
|  1661 void LayoutTableSection::rowLogicalHeightChanged(LayoutTableRow* row) { |  1702 void LayoutTableSection::rowLogicalHeightChanged(LayoutTableRow* row) { | 
|  1662   if (needsCellRecalc()) |  1703   if (needsCellRecalc()) | 
|  1663     return; |  1704     return; | 
|  1664  |  1705  | 
|  1665   unsigned rowIndex = row->rowIndex(); |  1706   unsigned rowIndex = row->rowIndex(); | 
|  1666   setRowLogicalHeightToRowStyleLogicalHeight(m_grid[rowIndex]); |  1707   setRowLogicalHeightToRowStyleLogicalHeight(m_grid[rowIndex]); | 
|  1667  |  1708  | 
|  1668   for (LayoutTableCell* cell = m_grid[rowIndex].rowLayoutObject->firstCell(); |  1709   for (LayoutTableCell* cell = m_grid[rowIndex].rowLayoutObject->firstCell(); | 
|  1669        cell; cell = cell->nextCell()) |  1710        cell; cell = cell->nextCell()) | 
|  1670     updateLogicalHeightForCell(m_grid[rowIndex], cell); |  1711     updateLogicalHeightForCell(m_grid[rowIndex], cell); | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1761   // Table sections cannot ever be hit tested.  Effectively they do not exist. |  1802   // Table sections cannot ever be hit tested.  Effectively they do not exist. | 
|  1762   // Just forward to our children always. |  1803   // Just forward to our children always. | 
|  1763   LayoutPoint adjustedLocation = accumulatedOffset + location(); |  1804   LayoutPoint adjustedLocation = accumulatedOffset + location(); | 
|  1764  |  1805  | 
|  1765   if (hasOverflowClip() && |  1806   if (hasOverflowClip() && | 
|  1766       !locationInContainer.intersects(overflowClipRect(adjustedLocation))) |  1807       !locationInContainer.intersects(overflowClipRect(adjustedLocation))) | 
|  1767     return false; |  1808     return false; | 
|  1768  |  1809  | 
|  1769   if (hasOverflowingCell()) { |  1810   if (hasOverflowingCell()) { | 
|  1770     for (LayoutTableRow* row = lastRow(); row; row = row->previousRow()) { |  1811     for (LayoutTableRow* row = lastRow(); row; row = row->previousRow()) { | 
|  1771       // FIXME: We have to skip over inline flows, since they can show up inside
       table rows |  1812       // FIXME: We have to skip over inline flows, since they can show up inside | 
|  1772       // at the moment (a demoted inline <form> for example). If we ever impleme
      nt a |  1813       // table rows at the moment (a demoted inline <form> for example). If we | 
|  1773       // table-specific hit-test method (which we should do for performance reas
      ons anyway), |  1814       // ever implement a table-specific hit-test method (which we should do for | 
|  1774       // then we can remove this check. |  1815       // performance reasons anyway), then we can remove this check. | 
|  1775       if (!row->hasSelfPaintingLayer()) { |  1816       if (!row->hasSelfPaintingLayer()) { | 
|  1776         LayoutPoint childPoint = |  1817         LayoutPoint childPoint = | 
|  1777             flipForWritingModeForChild(row, adjustedLocation); |  1818             flipForWritingModeForChild(row, adjustedLocation); | 
|  1778         if (row->nodeAtPoint(result, locationInContainer, childPoint, action)) { |  1819         if (row->nodeAtPoint(result, locationInContainer, childPoint, action)) { | 
|  1779           updateHitTestResult( |  1820           updateHitTestResult( | 
|  1780               result, toLayoutPoint(locationInContainer.point() - childPoint)); |  1821               result, toLayoutPoint(locationInContainer.point() - childPoint)); | 
|  1781           return true; |  1822           return true; | 
|  1782         } |  1823         } | 
|  1783       } |  1824       } | 
|  1784     } |  1825     } | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1837   newSection->setStyle(newStyle.release()); |  1878   newSection->setStyle(newStyle.release()); | 
|  1838   return newSection; |  1879   return newSection; | 
|  1839 } |  1880 } | 
|  1840  |  1881  | 
|  1841 void LayoutTableSection::setLogicalPositionForCell( |  1882 void LayoutTableSection::setLogicalPositionForCell( | 
|  1842     LayoutTableCell* cell, |  1883     LayoutTableCell* cell, | 
|  1843     unsigned effectiveColumn) const { |  1884     unsigned effectiveColumn) const { | 
|  1844   LayoutPoint cellLocation(0, m_rowPos[cell->rowIndex()]); |  1885   LayoutPoint cellLocation(0, m_rowPos[cell->rowIndex()]); | 
|  1845   int horizontalBorderSpacing = table()->hBorderSpacing(); |  1886   int horizontalBorderSpacing = table()->hBorderSpacing(); | 
|  1846  |  1887  | 
|  1847   // FIXME: The table's direction should determine our row's direction, not the 
      section's (see bug 96691). |  1888   // FIXME: The table's direction should determine our row's direction, not the | 
 |  1889   // section's (see bug 96691). | 
|  1848   if (!style()->isLeftToRightDirection()) |  1890   if (!style()->isLeftToRightDirection()) | 
|  1849     cellLocation.setX(LayoutUnit( |  1891     cellLocation.setX(LayoutUnit( | 
|  1850         table()->effectiveColumnPositions()[table()->numEffectiveColumns()] - |  1892         table()->effectiveColumnPositions()[table()->numEffectiveColumns()] - | 
|  1851         table()->effectiveColumnPositions() |  1893         table()->effectiveColumnPositions() | 
|  1852             [table()->absoluteColumnToEffectiveColumn( |  1894             [table()->absoluteColumnToEffectiveColumn( | 
|  1853                 cell->absoluteColumnIndex() + cell->colSpan())] + |  1895                 cell->absoluteColumnIndex() + cell->colSpan())] + | 
|  1854         horizontalBorderSpacing)); |  1896         horizontalBorderSpacing)); | 
|  1855   else |  1897   else | 
|  1856     cellLocation.setX( |  1898     cellLocation.setX( | 
|  1857         LayoutUnit(table()->effectiveColumnPositions()[effectiveColumn] + |  1899         LayoutUnit(table()->effectiveColumnPositions()[effectiveColumn] + | 
|  1858                    horizontalBorderSpacing)); |  1900                    horizontalBorderSpacing)); | 
|  1859  |  1901  | 
|  1860   cell->setLogicalLocation(cellLocation); |  1902   cell->setLogicalLocation(cellLocation); | 
|  1861 } |  1903 } | 
|  1862  |  1904  | 
|  1863 void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell, |  1905 void LayoutTableSection::relayoutCellIfFlexed(LayoutTableCell& cell, | 
|  1864                                               int rowIndex, |  1906                                               int rowIndex, | 
|  1865                                               int rowHeight) { |  1907                                               int rowHeight) { | 
|  1866   // Force percent height children to lay themselves out again. |  1908   // Force percent height children to lay themselves out again. | 
|  1867   // This will cause these children to grow to fill the cell. |  1909   // This will cause these children to grow to fill the cell. | 
|  1868   // FIXME: There is still more work to do here to fully match WinIE (should |  1910   // FIXME: There is still more work to do here to fully match WinIE (should | 
|  1869   // it become necessary to do so).  In quirks mode, WinIE behaves like we |  1911   // it become necessary to do so).  In quirks mode, WinIE behaves like we | 
|  1870   // do, but it will clip the cells that spill out of the table section.  In |  1912   // do, but it will clip the cells that spill out of the table section. | 
|  1871   // strict mode, Mozilla and WinIE both regrow the table to accommodate the |  1913   // strict mode, Mozilla and WinIE both regrow the table to accommodate the | 
|  1872   // new height of the cell (thus letting the percentages cause growth one |  1914   // new height of the cell (thus letting the percentages cause growth one | 
|  1873   // time only).  We may also not be handling row-spanning cells correctly. |  1915   // time only). We may also not be handling row-spanning cells correctly. | 
|  1874   // |  1916   // | 
|  1875   // Note also the oddity where replaced elements always flex, and yet |  1917   // Note also the oddity where replaced elements always flex, and yet blocks/ | 
|  1876   // blocks/tables do not necessarily flex. WinIE is crazy and inconsistent, |  1918   // tables do not necessarily flex. WinIE is crazy and inconsistent, and we | 
|  1877   // and we can't hope to match the behavior perfectly, but we'll continue to |  1919   // can't hope to match the behavior perfectly, but we'll continue to refine it | 
|  1878   // refine it as we discover new bugs. :) |  1920   // as we discover new bugs. :) | 
|  1879   bool cellChildrenFlex = false; |  1921   bool cellChildrenFlex = false; | 
|  1880   bool flexAllChildren = cell.style()->logicalHeight().isFixed() || |  1922   bool flexAllChildren = cell.style()->logicalHeight().isFixed() || | 
|  1881                          (!table()->style()->logicalHeight().isAuto() && |  1923                          (!table()->style()->logicalHeight().isAuto() && | 
|  1882                           rowHeight != cell.logicalHeight()); |  1924                           rowHeight != cell.logicalHeight()); | 
|  1883  |  1925  | 
|  1884   for (LayoutObject* child = cell.firstChild(); child; |  1926   for (LayoutObject* child = cell.firstChild(); child; | 
|  1885        child = child->nextSibling()) { |  1927        child = child->nextSibling()) { | 
|  1886     if (!child->isText() && child->style()->logicalHeight().isPercentOrCalc() && |  1928     if (!child->isText() && child->style()->logicalHeight().isPercentOrCalc() && | 
|  1887         (flexAllChildren || shouldFlexCellChild(child)) && |  1929         (flexAllChildren || shouldFlexCellChild(child)) && | 
|  1888         (!child->isTable() || toLayoutTable(child)->hasSections())) { |  1930         (!child->isTable() || toLayoutTable(child)->hasSections())) { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1926   // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? |  1968   // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? | 
|  1927   if (hasSelfPaintingLayer()) |  1969   if (hasSelfPaintingLayer()) | 
|  1928     return false; |  1970     return false; | 
|  1929   LayoutUnit pageHeight = table()->pageLogicalHeightForOffset(LayoutUnit()); |  1971   LayoutUnit pageHeight = table()->pageLogicalHeightForOffset(LayoutUnit()); | 
|  1930   if (!pageHeight) |  1972   if (!pageHeight) | 
|  1931     return false; |  1973     return false; | 
|  1932  |  1974  | 
|  1933   if (logicalHeight() > pageHeight) |  1975   if (logicalHeight() > pageHeight) | 
|  1934     return false; |  1976     return false; | 
|  1935  |  1977  | 
|  1936   // If the first row of the section after the header group doesn't fit on the p
      age, then |  1978   // If the first row of the section after the header group doesn't fit on the | 
|  1937   // don't repeat the header on each page. See https://drafts.csswg.org/css-tabl
      es-3/#repeated-headers |  1979   // page, then don't repeat the header on each page. | 
 |  1980   // See https://drafts.csswg.org/css-tables-3/#repeated-headers | 
|  1938   LayoutTableSection* sectionBelow = table()->sectionBelow(this); |  1981   LayoutTableSection* sectionBelow = table()->sectionBelow(this); | 
|  1939   if (sectionBelow && sectionBelow->firstRow() && |  1982   if (sectionBelow && sectionBelow->firstRow() && | 
|  1940       sectionBelow->firstRow()->paginationStrut()) |  1983       sectionBelow->firstRow()->paginationStrut()) | 
|  1941     return false; |  1984     return false; | 
|  1942  |  1985  | 
|  1943   return true; |  1986   return true; | 
|  1944 } |  1987 } | 
|  1945  |  1988  | 
|  1946 bool LayoutTableSection::mapToVisualRectInAncestorSpace( |  1989 bool LayoutTableSection::mapToVisualRectInAncestorSpace( | 
|  1947     const LayoutBoxModelObject* ancestor, |  1990     const LayoutBoxModelObject* ancestor, | 
|  1948     LayoutRect& rect, |  1991     LayoutRect& rect, | 
|  1949     VisualRectFlags flags) const { |  1992     VisualRectFlags flags) const { | 
|  1950   if (ancestor == this) |  1993   if (ancestor == this) | 
|  1951     return true; |  1994     return true; | 
|  1952   // Repeating table headers are painted once per fragmentation page/column. Thi
      s does not go through the regular fragmentation machinery, |  1995   // Repeating table headers are painted once per fragmentation page/column. | 
|  1953   // so we need special code to expand the invalidation rect to contain all posi
      tions of the header in all columns. |  1996   // This does not go through the regular fragmentation machinery, so we need | 
|  1954   // Note that this is in flow thread coordinates, not visual coordinates. The e
      nclosing LayoutFlowThread will convert to visual coordinates. |  1997   // special code to expand the invalidation rect to contain all positions of | 
 |  1998   // the header in all columns. | 
 |  1999   // Note that this is in flow thread coordinates, not visual coordinates. The | 
 |  2000   // enclosing LayoutFlowThread will convert to visual coordinates. | 
|  1955   if (table()->header() == this && isRepeatingHeaderGroup()) |  2001   if (table()->header() == this && isRepeatingHeaderGroup()) | 
|  1956     rect.setHeight(table()->logicalHeight()); |  2002     rect.setHeight(table()->logicalHeight()); | 
|  1957   return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, |  2003   return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, | 
|  1958                                                                  flags); |  2004                                                                  flags); | 
|  1959 } |  2005 } | 
|  1960  |  2006  | 
|  1961 }  // namespace blink |  2007 }  // namespace blink | 
| OLD | NEW |