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. All r ights reserved. |
8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 if (!spanningRowsHeight.rowHeight[row]) | 286 if (!spanningRowsHeight.rowHeight[row]) |
287 spanningRowsHeight.isAnyRowWithOnlySpanningCells |= rowHasOnlySpanni ngCells(actualRow); | 287 spanningRowsHeight.isAnyRowWithOnlySpanningCells |= rowHasOnlySpanni ngCells(actualRow); |
288 | 288 |
289 spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row]; | 289 spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row]; |
290 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpac ingForRow(actualRow); | 290 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpac ingForRow(actualRow); |
291 } | 291 } |
292 // We don't span the following row so its border-spacing (if any) should be included. | 292 // We don't span the following row so its border-spacing (if any) should be included. |
293 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += borderSpacingF orRow(rowIndex + rowSpan - 1); | 293 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += borderSpacingF orRow(rowIndex + rowSpan - 1); |
294 } | 294 } |
295 | 295 |
296 void LayoutTableSection::distributeExtraRowSpanHeightToPercentRows(LayoutTableCe ll* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsHeight ) | 296 void LayoutTableSection::distributeExtraRowSpanHeightToPercentRows(LayoutTableCe ll* cell, LayoutUnit totalPercent, int& extraRowSpanningHeight, Vector<int>& row sHeight) |
297 { | 297 { |
298 if (!extraRowSpanningHeight || !totalPercent) | 298 if (!extraRowSpanningHeight || !totalPercent) |
299 return; | 299 return; |
300 | 300 |
301 const unsigned rowSpan = cell->rowSpan(); | 301 const unsigned rowSpan = cell->rowSpan(); |
302 const unsigned rowIndex = cell->rowIndex(); | 302 const unsigned rowIndex = cell->rowIndex(); |
303 int percent = std::min(totalPercent, 100); | 303 LayoutUnit percent = 100; |
304 percent = std::min(totalPercent, percent); | |
304 const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight; | 305 const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight; |
305 | 306 |
306 // Our algorithm matches Firefox. Extra spanning height would be distributed Only in first percent height rows | 307 // Our algorithm matches Firefox. Extra spanning height would be distributed Only in first percent height rows |
307 // those total percent is 100. Other percent rows would be uneffected even e xtra spanning height is remain. | 308 // those total percent is 100. Other percent rows would be uneffected even e xtra spanning height is remain. |
308 int accumulatedPositionIncrease = 0; | 309 int accumulatedPositionIncrease = 0; |
309 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { | 310 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { |
310 if (percent > 0 && extraRowSpanningHeight > 0) { | 311 if (percent > 0 && extraRowSpanningHeight > 0) { |
311 if (m_grid[row].logicalHeight.isPercent()) { | 312 if (m_grid[row].logicalHeight.isPercent()) { |
312 int toAdd = (tableHeight * m_grid[row].logicalHeight.percent() / 100) - rowsHeight[row - rowIndex]; | 313 int toAdd = (tableHeight * m_grid[row].logicalHeight.percent() / 100) - rowsHeight[row - rowIndex]; |
313 // FIXME: Note that this is wrong if we have a percentage above 100% and may make us grow | 314 // FIXME: Note that this is wrong if we have a percentage above 100% and may make us grow |
314 // above the available space. | 315 // above the available space. |
315 | 316 |
316 toAdd = std::min(toAdd, extraRowSpanningHeight); | 317 toAdd = std::min(toAdd, extraRowSpanningHeight); |
317 accumulatedPositionIncrease += toAdd; | 318 accumulatedPositionIncrease += toAdd; |
318 extraRowSpanningHeight -= toAdd; | 319 extraRowSpanningHeight -= toAdd; |
319 percent -= m_grid[row].logicalHeight.percent(); | 320 percent -= m_grid[row].logicalHeight.percent(); |
320 } | 321 } |
321 } | 322 } |
322 m_rowPos[row + 1] += accumulatedPositionIncrease; | 323 m_rowPos[row + 1] += accumulatedPositionIncrease; |
323 } | 324 } |
324 } | 325 } |
325 | 326 |
326 // Sometimes the multiplication of the 2 values below will overflow an integer. | 327 static void updatePositionIncreasedWithRowHeight(int extraHeight, LayoutUnit row Height, LayoutUnit totalHeight, int& accumulatedPositionIncrease, int& remainder ) |
327 // So we convert the parameters to 'long long' instead of 'int' to avoid the | |
328 // problem in this function. | |
329 static void updatePositionIncreasedWithRowHeight(long long extraHeight, long lon g rowHeight, long long totalHeight, int& accumulatedPositionIncrease, int& remai nder) | |
330 { | 328 { |
331 static_assert(sizeof(long long int) > sizeof(int), "int should be smaller th an long long"); | 329 static_assert(sizeof(long long int) > sizeof(int), "int should be smaller th an long long"); |
332 | 330 |
333 accumulatedPositionIncrease += (extraHeight * rowHeight) / totalHeight; | 331 // Multiplication of the 2 values below will overflow in LayoutUnit. |
334 remainder += (extraHeight * rowHeight) % totalHeight; | 332 // So we converted to 'long long' instead of 'int' to avoid the problem in t his function. |
333 // Upto 2 digits of rational part is considered for calculation. | |
Julien - ping for review
2015/03/26 17:05:15
That's a lot of computation, most of which makes l
| |
334 long long rHeight = static_cast<int>(rowHeight * 100); | |
335 long long tHeight = static_cast<int>(totalHeight * 100); | |
336 | |
337 accumulatedPositionIncrease += (extraHeight * rHeight) / tHeight; | |
338 remainder += ((extraHeight * rHeight) % tHeight) / 100; | |
335 } | 339 } |
336 | 340 |
337 // This is mainly used to distribute whole extra rowspanning height in percent r ows when all spanning rows are | 341 // This is mainly used to distribute whole extra rowspanning height in percent r ows when all spanning rows are |
338 // percent rows. | 342 // percent rows. |
339 // Distributing whole extra rowspanning height in percent rows based on the rati os of percent because this method works | 343 // Distributing whole extra rowspanning height in percent rows based on the rati os of percent because this method works |
340 // same as percent distribution when only percent rows are present and percent i s 100. Also works perfectly fine when | 344 // same as percent distribution when only percent rows are present and percent i s 100. Also works perfectly fine when |
341 // percent is not equal to 100. | 345 // percent is not equal to 100. |
342 void LayoutTableSection::distributeWholeExtraRowSpanHeightToPercentRows(LayoutTa bleCell* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsH eight) | 346 void LayoutTableSection::distributeWholeExtraRowSpanHeightToPercentRows(LayoutTa bleCell* cell, LayoutUnit totalPercent, int& extraRowSpanningHeight, Vector<int> & rowsHeight) |
343 { | 347 { |
344 if (!extraRowSpanningHeight || !totalPercent) | 348 if (!extraRowSpanningHeight || !totalPercent) |
345 return; | 349 return; |
346 | 350 |
347 const unsigned rowSpan = cell->rowSpan(); | 351 const unsigned rowSpan = cell->rowSpan(); |
348 const unsigned rowIndex = cell->rowIndex(); | 352 const unsigned rowIndex = cell->rowIndex(); |
349 int remainder = 0; | 353 int remainder = 0; |
350 | 354 |
351 int accumulatedPositionIncrease = 0; | 355 int accumulatedPositionIncrease = 0; |
352 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { | 356 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { |
353 if (m_grid[row].logicalHeight.isPercent()) { | 357 if (m_grid[row].logicalHeight.isPercent()) { |
354 updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, m_grid[ row].logicalHeight.percent(), totalPercent, accumulatedPositionIncrease, remaind er); | 358 updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, m_grid[ row].logicalHeight.percent(), totalPercent, accumulatedPositionIncrease, remaind er); |
355 | 359 |
356 // While whole extra spanning height is distributing in percent span ning rows, rational parts remains | 360 // While whole extra spanning height is distributing in percent span ning rows, rational parts remains |
357 // in every integer division. So accumulating all remainder part in integer division and when total remainder | 361 // in every integer division. So accumulating all remainder part in integer division and when total remainder |
358 // is equvalent to divisor then 1 unit increased in row position. | 362 // is equvalent to divisor then 1 unit increased in row position. |
359 // Note that this algorithm is biased towards adding more space towa rds the lower rows. | 363 // Note that this algorithm is biased towards adding more space towa rds the lower rows. |
360 if (remainder >= totalPercent) { | 364 if (remainder >= totalPercent) { |
361 remainder -= totalPercent; | 365 remainder = remainder - totalPercent; |
362 accumulatedPositionIncrease++; | 366 accumulatedPositionIncrease++; |
363 } | 367 } |
364 } | 368 } |
365 m_rowPos[row + 1] += accumulatedPositionIncrease; | 369 m_rowPos[row + 1] += accumulatedPositionIncrease; |
366 } | 370 } |
367 | 371 |
368 ASSERT(!remainder); | 372 ASSERT(!remainder); |
369 | 373 |
370 extraRowSpanningHeight -= accumulatedPositionIncrease; | 374 extraRowSpanningHeight -= accumulatedPositionIncrease; |
371 } | 375 } |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBe forePosition; | 616 extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBe forePosition; |
613 continue; | 617 continue; |
614 } | 618 } |
615 | 619 |
616 if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanni ngRowsHeight.totalRowsHeight) { | 620 if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanni ngRowsHeight.totalRowsHeight) { |
617 extraHeightToPropagate = m_rowPos[rowIndex + rowSpan] - originalBefo rePosition; | 621 extraHeightToPropagate = m_rowPos[rowIndex + rowSpan] - originalBefo rePosition; |
618 continue; | 622 continue; |
619 } | 623 } |
620 | 624 |
621 // Below we are handling only row(s) who have at least one visible cell without rowspan value. | 625 // Below we are handling only row(s) who have at least one visible cell without rowspan value. |
622 int totalPercent = 0; | 626 LayoutUnit totalPercent = 0; |
623 int totalAutoRowsHeight = 0; | 627 int totalAutoRowsHeight = 0; |
624 int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight; | 628 int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight; |
625 | 629 |
626 // FIXME: Inner spanning cell height should not change if it have fixed height when it's parent spanning cell | 630 // FIXME: Inner spanning cell height should not change if it have fixed height when it's parent spanning cell |
627 // is distributing it's extra height in rows. | 631 // is distributing it's extra height in rows. |
628 | 632 |
629 // Calculate total percentage, total auto rows height and total rows hei ght except percent rows. | 633 // Calculate total percentage, total auto rows height and total rows hei ght except percent rows. |
630 for (unsigned row = rowIndex; row < spanningCellEndIndex; row++) { | 634 for (unsigned row = rowIndex; row < spanningCellEndIndex; row++) { |
631 if (m_grid[row].logicalHeight.isPercent()) { | 635 if (m_grid[row].logicalHeight.isPercent()) { |
632 totalPercent += m_grid[row].logicalHeight.percent(); | 636 totalPercent += m_grid[row].logicalHeight.percent(); |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1604 // FIXME: The table's direction should determine our row's direction, not th e section's (see bug 96691). | 1608 // FIXME: The table's direction should determine our row's direction, not th e section's (see bug 96691). |
1605 if (!style()->isLeftToRightDirection()) | 1609 if (!style()->isLeftToRightDirection()) |
1606 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing); | 1610 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing); |
1607 else | 1611 else |
1608 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing); | 1612 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing); |
1609 | 1613 |
1610 cell->setLogicalLocation(cellLocation); | 1614 cell->setLogicalLocation(cellLocation); |
1611 } | 1615 } |
1612 | 1616 |
1613 } // namespace blink | 1617 } // namespace blink |
OLD | NEW |