OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google 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, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 | 1548 |
1549 if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()
) { | 1549 if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()
) { |
1550 LayoutBox* box = toLayoutBox(o); | 1550 LayoutBox* box = toLayoutBox(o); |
1551 | 1551 |
1552 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box); | 1552 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box); |
1553 | 1553 |
1554 if (o->isOutOfFlowPositioned()) { | 1554 if (o->isOutOfFlowPositioned()) { |
1555 o->containingBlock()->insertPositionedObject(box); | 1555 o->containingBlock()->insertPositionedObject(box); |
1556 } else if (o->isFloating()) { | 1556 } else if (o->isFloating()) { |
1557 layoutState.floats().append(FloatWithRect(box)); | 1557 layoutState.floats().append(FloatWithRect(box)); |
| 1558 if (box->needsLayout()) { |
| 1559 box->layout(); |
| 1560 dirtyLinesFromChangedChild(o); |
| 1561 } |
1558 } else if (isFullLayout || o->needsLayout()) { | 1562 } else if (isFullLayout || o->needsLayout()) { |
1559 // Replaced element. | 1563 // Replaced element. |
1560 box->dirtyLineBoxes(isFullLayout); | 1564 box->dirtyLineBoxes(isFullLayout); |
1561 if (isFullLayout) | 1565 if (isFullLayout) |
1562 replacedChildren.append(box); | 1566 replacedChildren.append(box); |
1563 else | 1567 else |
1564 o->layoutIfNeeded(); | 1568 o->layoutIfNeeded(); |
1565 } | 1569 } |
1566 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { | 1570 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { |
1567 if (!o->isText()) | 1571 if (!o->isText()) |
(...skipping 29 matching lines...) Expand all Loading... |
1597 // See if we have any lines that spill out of our block. If we do, then we
will possibly need to | 1601 // See if we have any lines that spill out of our block. If we do, then we
will possibly need to |
1598 // truncate text. | 1602 // truncate text. |
1599 if (hasTextOverflow) | 1603 if (hasTextOverflow) |
1600 checkLinesForTextOverflow(); | 1604 checkLinesForTextOverflow(); |
1601 | 1605 |
1602 // Ensure the new line boxes will be painted. | 1606 // Ensure the new line boxes will be painted. |
1603 if (isFullLayout && firstLineBox()) | 1607 if (isFullLayout && firstLineBox()) |
1604 setShouldDoFullPaintInvalidation(); | 1608 setShouldDoFullPaintInvalidation(); |
1605 } | 1609 } |
1606 | 1610 |
1607 void LayoutBlockFlow::checkFloatsInCleanLine(RootInlineBox* line, Vector<FloatWi
thRect>& floats, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByF
loat) | |
1608 { | |
1609 Vector<LayoutBox*>* cleanLineFloats = line->floatsPtr(); | |
1610 if (!cleanLineFloats) | |
1611 return; | |
1612 | |
1613 for (auto* floatingBox : *cleanLineFloats) { | |
1614 floatingBox->layoutIfNeeded(); | |
1615 LayoutSize newSize = floatingBox->size() + | |
1616 LayoutSize(floatingBox->marginWidth(), floatingBox->marginHeight()); | |
1617 if (floats[floatIndex].object != floatingBox) { | |
1618 encounteredNewFloat = true; | |
1619 return; | |
1620 } | |
1621 | |
1622 if (floats[floatIndex].rect.size() != newSize) { | |
1623 LayoutUnit floatTop = isHorizontalWritingMode() ? floats[floatIndex]
.rect.y() : floats[floatIndex].rect.x(); | |
1624 LayoutUnit floatHeight = isHorizontalWritingMode() ? std::max(floats
[floatIndex].rect.height(), newSize.height()) | |
1625 : std::max(floats[floatIndex].rect.width(), newSize.width()); | |
1626 floatHeight = std::min(floatHeight, LayoutUnit::max() - floatTop); | |
1627 line->markDirty(); | |
1628 markLinesDirtyInBlockRange(line->lineBottomWithLeading(), floatTop +
floatHeight, line); | |
1629 floats[floatIndex].rect.setSize(newSize); | |
1630 dirtiedByFloat = true; | |
1631 } | |
1632 floatIndex++; | |
1633 } | |
1634 } | |
1635 | |
1636 RootInlineBox* LayoutBlockFlow::determineStartPosition(LineLayoutState& layoutSt
ate, InlineBidiResolver& resolver) | 1611 RootInlineBox* LayoutBlockFlow::determineStartPosition(LineLayoutState& layoutSt
ate, InlineBidiResolver& resolver) |
1637 { | 1612 { |
1638 RootInlineBox* curr = nullptr; | 1613 RootInlineBox* curr = nullptr; |
1639 RootInlineBox* last = nullptr; | 1614 RootInlineBox* last = nullptr; |
1640 RootInlineBox* firstLineBoxWithBreakAndClearance = 0; | 1615 RootInlineBox* firstLineBoxWithBreakAndClearance = 0; |
1641 | 1616 |
1642 // FIXME: This entire float-checking block needs to be broken into a new fun
ction. | 1617 // FIXME: This entire float-checking block needs to be broken into a new fun
ction. |
1643 bool dirtiedByFloat = false; | 1618 bool dirtiedByFloat = false; |
1644 if (!layoutState.isFullLayout()) { | 1619 if (!layoutState.isFullLayout()) { |
1645 // Paginate all of the clean lines. | 1620 // Paginate all of the clean lines. |
1646 bool paginated = view()->layoutState() && view()->layoutState()->isPagin
ated(); | 1621 bool paginated = view()->layoutState() && view()->layoutState()->isPagin
ated(); |
1647 LayoutUnit paginationDelta = 0; | 1622 LayoutUnit paginationDelta = 0; |
1648 size_t floatIndex = 0; | |
1649 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR
ootBox()) { | 1623 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR
ootBox()) { |
1650 if (paginated) { | 1624 if (paginated) { |
1651 paginationDelta -= curr->paginationStrut(); | 1625 paginationDelta -= curr->paginationStrut(); |
1652 adjustLinePositionForPagination(*curr, paginationDelta); | 1626 adjustLinePositionForPagination(*curr, paginationDelta); |
1653 if (paginationDelta) { | 1627 if (paginationDelta) { |
1654 if (containsFloats() || !layoutState.floats().isEmpty()) { | 1628 if (containsFloats() || !layoutState.floats().isEmpty()) { |
1655 // FIXME: Do better eventually. For now if we ever shif
t because of pagination and floats are present just go to a full layout. | 1629 // FIXME: Do better eventually. For now if we ever shif
t because of pagination and floats are present just go to a full layout. |
1656 layoutState.markForFullLayout(); | 1630 layoutState.markForFullLayout(); |
1657 break; | 1631 break; |
1658 } | 1632 } |
1659 | 1633 |
1660 layoutState.updatePaintInvalidationRangeFromBox(curr, pagina
tionDelta); | 1634 layoutState.updatePaintInvalidationRangeFromBox(curr, pagina
tionDelta); |
1661 curr->moveInBlockDirection(paginationDelta); | 1635 curr->moveInBlockDirection(paginationDelta); |
1662 } | 1636 } |
1663 } | 1637 } |
1664 | 1638 |
1665 // If the linebox breaks cleanly and with clearance then dirty from
at least this point onwards so that we can clear the correct floats without diff
iculty. | 1639 // If the linebox breaks cleanly and with clearance then dirty from
at least this point onwards so that we can clear the correct floats without diff
iculty. |
1666 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(
curr)) | 1640 if (!firstLineBoxWithBreakAndClearance && lineBoxHasBRWithClearance(
curr)) |
1667 firstLineBoxWithBreakAndClearance = curr; | 1641 firstLineBoxWithBreakAndClearance = curr; |
1668 | 1642 |
1669 // If a new float has been inserted before this line or before its l
ast known float, just do a full layout. | |
1670 bool encounteredNewFloat = false; | |
1671 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou
nteredNewFloat, dirtiedByFloat); | |
1672 if (encounteredNewFloat) | |
1673 layoutState.markForFullLayout(); | |
1674 | |
1675 if (dirtiedByFloat || layoutState.isFullLayout()) | 1643 if (dirtiedByFloat || layoutState.isFullLayout()) |
1676 break; | 1644 break; |
1677 } | 1645 } |
1678 // Check if a new float has been inserted after the last known float. | |
1679 if (!curr && floatIndex < layoutState.floats().size()) | |
1680 layoutState.markForFullLayout(); | |
1681 } | 1646 } |
1682 | 1647 |
1683 if (layoutState.isFullLayout()) { | 1648 if (layoutState.isFullLayout()) { |
1684 // If we encountered a new float and have inline children, mark ourself
to force us to issue paint invalidations. | 1649 // If we encountered a new float and have inline children, mark ourself
to force us to issue paint invalidations. |
1685 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { | 1650 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { |
1686 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Flo
atDescendantChanged, MarkOnlyThis); | 1651 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Flo
atDescendantChanged, MarkOnlyThis); |
1687 setShouldDoFullPaintInvalidation(); | 1652 setShouldDoFullPaintInvalidation(); |
1688 } | 1653 } |
1689 | 1654 |
1690 deleteLineBoxTree(); | 1655 deleteLineBoxTree(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 // If the linebox breaks cleanly and with clearance then dirty from at least
this point onwards so that we can clear the correct floats without difficulty. | 1727 // If the linebox breaks cleanly and with clearance then dirty from at least
this point onwards so that we can clear the correct floats without difficulty. |
1763 if (!curr->endsWithBreak()) | 1728 if (!curr->endsWithBreak()) |
1764 return false; | 1729 return false; |
1765 InlineBox* lastBox = style()->isLeftToRightDirection() ? curr->lastLeafChild
() : curr->firstLeafChild(); | 1730 InlineBox* lastBox = style()->isLeftToRightDirection() ? curr->lastLeafChild
() : curr->firstLeafChild(); |
1766 return lastBox && lastBox->layoutObject().isBR() && lastBox->layoutObject().
style()->clear() != CNONE; | 1731 return lastBox && lastBox->layoutObject().isBR() && lastBox->layoutObject().
style()->clear() != CNONE; |
1767 } | 1732 } |
1768 | 1733 |
1769 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInl
ineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStat
us) | 1734 void LayoutBlockFlow::determineEndPosition(LineLayoutState& layoutState, RootInl
ineBox* startLine, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStat
us) |
1770 { | 1735 { |
1771 ASSERT(!layoutState.endLine()); | 1736 ASSERT(!layoutState.endLine()); |
1772 size_t floatIndex = layoutState.floatIndex(); | |
1773 RootInlineBox* last = nullptr; | 1737 RootInlineBox* last = nullptr; |
1774 for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->next
RootBox()) { | 1738 for (RootInlineBox* curr = startLine->nextRootBox(); curr; curr = curr->next
RootBox()) { |
1775 if (!curr->isDirty()) { | 1739 if (!curr->isDirty() && lineBoxHasBRWithClearance(curr)) |
1776 bool encounteredNewFloat = false; | 1740 return; |
1777 bool dirtiedByFloat = false; | 1741 |
1778 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou
nteredNewFloat, dirtiedByFloat); | |
1779 if (encounteredNewFloat) | |
1780 return; | |
1781 if (lineBoxHasBRWithClearance(curr)) | |
1782 return; | |
1783 } | |
1784 if (curr->isDirty()) | 1742 if (curr->isDirty()) |
1785 last = nullptr; | 1743 last = nullptr; |
1786 else if (!last) | 1744 else if (!last) |
1787 last = curr; | 1745 last = curr; |
1788 } | 1746 } |
1789 | 1747 |
1790 if (!last) | 1748 if (!last) |
1791 return; | 1749 return; |
1792 | 1750 |
1793 // At this point, |last| is the first line in a run of clean lines that ends
with the last line | 1751 // At this point, |last| is the first line in a run of clean lines that ends
with the last line |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false); | 2027 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false); |
2070 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, false) - logicalLeft; | 2028 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight()
, false) - logicalLeft; |
2071 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2029 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
2072 | 2030 |
2073 if (!style()->isLeftToRightDirection()) | 2031 if (!style()->isLeftToRightDirection()) |
2074 return logicalWidth() - logicalLeft; | 2032 return logicalWidth() - logicalLeft; |
2075 return logicalLeft; | 2033 return logicalLeft; |
2076 } | 2034 } |
2077 | 2035 |
2078 } | 2036 } |
OLD | NEW |