| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2002 Dirk Mueller (mueller@kde.org) | 3 * (C) 2002 Dirk Mueller (mueller@kde.org) |
| 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. | 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License. | 9 * version 2 of the License. |
| 10 * | 10 * |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 if (available > 0) { | 583 if (available > 0) { |
| 584 for (size_t i = 0; i < nEffCols; ++i) { | 584 for (size_t i = 0; i < nEffCols; ++i) { |
| 585 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 585 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 586 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { | 586 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { |
| 587 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); | 587 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); |
| 588 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); | 588 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 | 592 |
| 593 // now satisfy variable | 593 // Give each auto width column its share of the available width. |
| 594 if (available > 0 && numAuto) { | 594 if (available > 0 && numAuto) { |
| 595 available += allocAuto; // this gets redistributed | 595 available += allocAuto; |
| 596 for (size_t i = 0; i < nEffCols; ++i) { | 596 distributeWidthToColumns(Auto, available, totalAuto, NonEmptyCells, Init
ialWidth); |
| 597 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | |
| 598 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCe
llsOnly) { | |
| 599 int cellLogicalWidth = std::max<int>(m_layoutStruct[i].computedL
ogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].e
ffectiveMaxLogicalWidth) / totalAuto)); | |
| 600 available -= cellLogicalWidth; | |
| 601 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; | |
| 602 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; | |
| 603 } | |
| 604 } | |
| 605 } | 597 } |
| 606 | 598 |
| 607 // spread over fixed columns | 599 // Any remaining available width expands fixed width, percent width and non-
empty auto width columns, in that order. |
| 608 if (available > 0 && numFixed) { | 600 if (available > 0 && numFixed) |
| 609 for (size_t i = 0; i < nEffCols; ++i) { | 601 distributeWidthToColumns(Fixed, available, totalFixed); |
| 610 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | |
| 611 if (logicalWidth.isFixed()) { | |
| 612 int cellLogicalWidth = static_cast<int>(available * static_cast<
float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed); | |
| 613 available -= cellLogicalWidth; | |
| 614 totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth; | |
| 615 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; | |
| 616 } | |
| 617 } | |
| 618 } | |
| 619 | 602 |
| 620 // spread over percent colums | 603 if (available > 0 && m_hasPercent && totalPercent < 100) |
| 621 if (available > 0 && m_hasPercent && totalPercent < 100) { | 604 distributeWidthToColumns(Percent, available, totalPercent); |
| 622 for (size_t i = 0; i < nEffCols; ++i) { | |
| 623 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | |
| 624 if (logicalWidth.isPercent()) { | |
| 625 int cellLogicalWidth = available * logicalWidth.percent() / tota
lPercent; | |
| 626 available -= cellLogicalWidth; | |
| 627 totalPercent -= logicalWidth.percent(); | |
| 628 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; | |
| 629 if (!available || !totalPercent) | |
| 630 break; | |
| 631 } | |
| 632 } | |
| 633 } | |
| 634 | 605 |
| 635 // spread over the rest | |
| 636 if (available > 0 && nEffCols > numAutoEmptyCellsOnly) { | 606 if (available > 0 && nEffCols > numAutoEmptyCellsOnly) { |
| 637 unsigned total = nEffCols - numAutoEmptyCellsOnly; | 607 unsigned total = nEffCols - numAutoEmptyCellsOnly; |
| 638 // still have some width to spread | 608 // Starting from the last cell is for compatibility with FF/IE - it isn'
t specified anywhere. |
| 639 for (unsigned i = nEffCols; i; ) { | 609 distributeWidthToColumns(Auto, available, total, NonEmptyCells, Leftover
Width, EndToStart); |
| 640 --i; | |
| 641 // variable columns with empty cells only don't get any width | |
| 642 if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStru
ct[i].emptyCellsOnly) | |
| 643 continue; | |
| 644 int cellLogicalWidth = available / total; | |
| 645 available -= cellLogicalWidth; | |
| 646 total--; | |
| 647 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; | |
| 648 } | |
| 649 } | 610 } |
| 650 | 611 |
| 651 // If we have overallocated, reduce every cell according to the difference b
etween desired width and minwidth | 612 // If we have overallocated, reduce every cell according to the difference b
etween desired width and minwidth |
| 652 // this seems to produce to the pixel exact results with IE. Wonder is some
of this also holds for width distributing. | 613 // this seems to produce to the pixel exact results with IE. Wonder is some
of this also holds for width distributing. |
| 653 // Need to reduce cells with the following prioritization: | |
| 654 // This is basically the reverse of how we grew the cells. | 614 // This is basically the reverse of how we grew the cells. |
| 655 if (available < 0) | 615 if (available < 0) |
| 656 shrinkCellWidth(Auto, available); | 616 shrinkColumnWidth(Auto, available); |
| 657 if (available < 0) | 617 if (available < 0) |
| 658 shrinkCellWidth(Fixed, available); | 618 shrinkColumnWidth(Fixed, available); |
| 659 if (available < 0) | 619 if (available < 0) |
| 660 shrinkCellWidth(Percent, available); | 620 shrinkColumnWidth(Percent, available); |
| 661 | 621 |
| 662 int pos = 0; | 622 int pos = 0; |
| 663 for (size_t i = 0; i < nEffCols; ++i) { | 623 for (size_t i = 0; i < nEffCols; ++i) { |
| 664 m_table->setColumnPosition(i, pos); | 624 m_table->setColumnPosition(i, pos); |
| 665 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); | 625 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); |
| 666 } | 626 } |
| 667 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); | 627 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); |
| 668 } | 628 } |
| 669 | 629 |
| 670 void TableLayoutAlgorithmAuto::shrinkCellWidth(const LengthType& lengthType, int
& available) | 630 void TableLayoutAlgorithmAuto::distributeWidthToColumns(const LengthType& length
Type, int& available, float total, CellsToProcess limitToCells, DistributionMode
distributionMode, DistributionDirection distributionDirection) |
| 631 { |
| 632 int nEffCols = static_cast<int>(m_table->numEffCols()); |
| 633 bool startToEnd = distributionDirection == StartToEnd; |
| 634 for (int i = startToEnd ? 0 : nEffCols - 1; startToEnd ? i < nEffCols : i >
-1; startToEnd ? ++i : --i) { |
| 635 const Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 636 if (limitToCells == NonEmptyCells && logicalWidth.isAuto() && m_layoutSt
ruct[i].emptyCellsOnly) |
| 637 continue; |
| 638 if (distributionMode != LeftoverWidth && logicalWidth.type() != lengthTy
pe) |
| 639 continue; |
| 640 |
| 641 float factor = 1; |
| 642 if (distributionMode != LeftoverWidth) { |
| 643 if (lengthType == Percent) |
| 644 factor = logicalWidth.percent(); |
| 645 else if (lengthType == Auto || lengthType == Fixed) |
| 646 factor = m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 647 } |
| 648 |
| 649 int newWidth = available * factor / total; |
| 650 int cellLogicalWidth = (distributionMode == InitialWidth) ? max<int>(m_l
ayoutStruct[i].computedLogicalWidth, newWidth) : newWidth; |
| 651 available -= cellLogicalWidth; |
| 652 total -= factor; |
| 653 m_layoutStruct[i].computedLogicalWidth = (distributionMode == InitialWid
th) ? cellLogicalWidth : m_layoutStruct[i].computedLogicalWidth + cellLogicalWid
th; |
| 654 |
| 655 // If we have run out of width to allocate we're done. |
| 656 // Also, any overallocation will be unwound later so no point in buildin
g up cells to unwind, just bail now. |
| 657 if (available <= 0 || total <= 0) |
| 658 return; |
| 659 } |
| 660 } |
| 661 |
| 662 void TableLayoutAlgorithmAuto::shrinkColumnWidth(const LengthType& lengthType, i
nt& available) |
| 671 { | 663 { |
| 672 size_t nEffCols = m_table->numEffCols(); | 664 size_t nEffCols = m_table->numEffCols(); |
| 673 int logicalWidthBeyondMin = 0; | 665 int logicalWidthBeyondMin = 0; |
| 674 for (unsigned i = nEffCols; i; ) { | 666 for (unsigned i = nEffCols; i; ) { |
| 675 --i; | 667 --i; |
| 676 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 668 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 677 if (logicalWidth.type() == lengthType) | 669 if (logicalWidth.type() == lengthType) |
| 678 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_
layoutStruct[i].effectiveMinLogicalWidth; | 670 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_
layoutStruct[i].effectiveMinLogicalWidth; |
| 679 } | 671 } |
| 680 | 672 |
| 681 for (unsigned i = nEffCols; i && logicalWidthBeyondMin > 0; ) { | 673 for (unsigned i = nEffCols; i && logicalWidthBeyondMin > 0; ) { |
| 682 --i; | 674 --i; |
| 683 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 675 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 684 if (logicalWidth.type() == lengthType) { | 676 if (logicalWidth.type() == lengthType) { |
| 685 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutSt
ruct[i].effectiveMinLogicalWidth; | 677 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutSt
ruct[i].effectiveMinLogicalWidth; |
| 686 int reduce = available * minMaxDiff / logicalWidthBeyondMin; | 678 int reduce = available * minMaxDiff / logicalWidthBeyondMin; |
| 687 m_layoutStruct[i].computedLogicalWidth += reduce; | 679 m_layoutStruct[i].computedLogicalWidth += reduce; |
| 688 available -= reduce; | 680 available -= reduce; |
| 689 logicalWidthBeyondMin -= minMaxDiff; | 681 logicalWidthBeyondMin -= minMaxDiff; |
| 690 if (available >= 0) | 682 if (available >= 0) |
| 691 break; | 683 break; |
| 692 } | 684 } |
| 693 } | 685 } |
| 694 } | 686 } |
| 695 } | 687 } |
| OLD | NEW |