Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: Source/core/layout/LayoutBlockFlowLine.cpp

Issue 1156063002: Floats on an empty line should still get positioned. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « LayoutTests/fast/block/float/float-on-empty-line-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 BidiStatus cleanLineBidiStatus; 739 BidiStatus cleanLineBidiStatus;
740 if (!layoutState.isFullLayout() && startLine) 740 if (!layoutState.isFullLayout() && startLine)
741 determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBi diStatus); 741 determineEndPosition(layoutState, startLine, cleanLineStart, cleanLineBi diStatus);
742 742
743 if (startLine) { 743 if (startLine) {
744 if (!layoutState.usesPaintInvalidationBounds()) 744 if (!layoutState.usesPaintInvalidationBounds())
745 layoutState.setPaintInvalidationRange(logicalHeight()); 745 layoutState.setPaintInvalidationRange(logicalHeight());
746 deleteLineRange(layoutState, startLine); 746 deleteLineRange(layoutState, startLine);
747 } 747 }
748 748
749 if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithB reak()) {
750 // If the last line before the start line ends with a line break that cl ear floats,
751 // adjust the height accordingly.
752 // A line break can be either the first or the last object on a line, de pending on its direction.
753 if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
754 LayoutObject* lastObject = &lastLeafChild->layoutObject();
755 if (!lastObject->isBR())
756 lastObject = &lastRootBox()->firstLeafChild()->layoutObject();
757 if (lastObject->isBR()) {
758 EClear clear = lastObject->style()->clear();
759 if (clear != CNONE)
760 clearFloats(clear);
761 }
762 }
763 }
764
765 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB idiStatus); 749 layoutRunsAndFloatsInRange(layoutState, resolver, cleanLineStart, cleanLineB idiStatus);
766 linkToEndLineIfNeeded(layoutState); 750 linkToEndLineIfNeeded(layoutState);
767 markDirtyFloatsForPaintInvalidation(layoutState.floats()); 751 markDirtyFloatsForPaintInvalidation(layoutState.floats());
768 } 752 }
769 753
770 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver. 754 // Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
771 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange( LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn d) 755 inline const InlineIterator& LayoutBlockFlow::restartLayoutRunsAndFloatsInRange( LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastF loatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEn d)
772 { 756 {
773 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight); 757 removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
774 setLogicalHeight(newLogicalHeight); 758 setLogicalHeight(newLogicalHeight);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 } 865 }
882 } 866 }
883 } 867 }
884 } 868 }
885 } 869 }
886 870
887 if (!logicalWidthIsAvailable) { 871 if (!logicalWidthIsAvailable) {
888 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i) 872 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
889 setStaticPositions(this, lineBreaker.positionedObjects()[i]); 873 setStaticPositions(this, lineBreaker.positionedObjects()[i]);
890 874
891 if (!layoutState.lineInfo().isEmpty()) { 875 if (!layoutState.lineInfo().isEmpty())
892 layoutState.lineInfo().setFirstLine(false); 876 layoutState.lineInfo().setFirstLine(false);
893 clearFloats(lineBreaker.clear()); 877 clearFloats(lineBreaker.clear());
894 }
895 878
896 if (m_floatingObjects && lastRootBox()) { 879 if (m_floatingObjects && lastRootBox()) {
897 const FloatingObjectSet& floatingObjectSet = m_floatingObjects-> set(); 880 const FloatingObjectSet& floatingObjectSet = m_floatingObjects-> set();
898 FloatingObjectSetIterator it = floatingObjectSet.begin(); 881 FloatingObjectSetIterator it = floatingObjectSet.begin();
899 FloatingObjectSetIterator end = floatingObjectSet.end(); 882 FloatingObjectSetIterator end = floatingObjectSet.end();
900 if (layoutState.lastFloat()) { 883 if (layoutState.lastFloat()) {
901 FloatingObjectSetIterator lastFloatIterator = floatingObject Set.find(layoutState.lastFloat()); 884 FloatingObjectSetIterator lastFloatIterator = floatingObject Set.find(layoutState.lastFloat());
902 ASSERT(lastFloatIterator != end); 885 ASSERT(lastFloatIterator != end);
903 ++lastFloatIterator; 886 ++lastFloatIterator;
904 it = lastFloatIterator; 887 it = lastFloatIterator;
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 dirtiedByFloat = true; 1622 dirtiedByFloat = true;
1640 } 1623 }
1641 floatIndex++; 1624 floatIndex++;
1642 } 1625 }
1643 } 1626 }
1644 1627
1645 RootInlineBox* LayoutBlockFlow::determineStartPosition(LineLayoutState& layoutSt ate, InlineBidiResolver& resolver) 1628 RootInlineBox* LayoutBlockFlow::determineStartPosition(LineLayoutState& layoutSt ate, InlineBidiResolver& resolver)
1646 { 1629 {
1647 RootInlineBox* curr = nullptr; 1630 RootInlineBox* curr = nullptr;
1648 RootInlineBox* last = nullptr; 1631 RootInlineBox* last = nullptr;
1632 RootInlineBox* firstLineBoxWithBreakAndClearance = 0;
1649 1633
1650 // FIXME: This entire float-checking block needs to be broken into a new fun ction. 1634 // FIXME: This entire float-checking block needs to be broken into a new fun ction.
1651 bool dirtiedByFloat = false; 1635 bool dirtiedByFloat = false;
1652 if (!layoutState.isFullLayout()) { 1636 if (!layoutState.isFullLayout()) {
1653 // Paginate all of the clean lines. 1637 // Paginate all of the clean lines.
1654 bool paginated = view()->layoutState() && view()->layoutState()->isPagin ated(); 1638 bool paginated = view()->layoutState() && view()->layoutState()->isPagin ated();
1655 LayoutUnit paginationDelta = 0; 1639 LayoutUnit paginationDelta = 0;
1656 size_t floatIndex = 0; 1640 size_t floatIndex = 0;
1657 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR ootBox()) { 1641 for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextR ootBox()) {
1658 if (paginated) { 1642 if (paginated) {
1659 paginationDelta -= curr->paginationStrut(); 1643 paginationDelta -= curr->paginationStrut();
1660 adjustLinePositionForPagination(*curr, paginationDelta, layoutSt ate.flowThread()); 1644 adjustLinePositionForPagination(*curr, paginationDelta, layoutSt ate.flowThread());
1661 if (paginationDelta) { 1645 if (paginationDelta) {
1662 if (containsFloats() || !layoutState.floats().isEmpty()) { 1646 if (containsFloats() || !layoutState.floats().isEmpty()) {
1663 // FIXME: Do better eventually. For now if we ever shif t because of pagination and floats are present just go to a full layout. 1647 // FIXME: Do better eventually. For now if we ever shif t because of pagination and floats are present just go to a full layout.
1664 layoutState.markForFullLayout(); 1648 layoutState.markForFullLayout();
1665 break; 1649 break;
1666 } 1650 }
1667 1651
1668 layoutState.updatePaintInvalidationRangeFromBox(curr, pagina tionDelta); 1652 layoutState.updatePaintInvalidationRangeFromBox(curr, pagina tionDelta);
1669 curr->adjustBlockDirectionPosition(paginationDelta.toFloat() ); 1653 curr->adjustBlockDirectionPosition(paginationDelta.toFloat() );
1670 } 1654 }
1671 } 1655 }
1672 1656
1657 // 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.
1658 if (!firstLineBoxWithBreakAndClearance && curr->endsWithBreak()) {
1659 InlineBox* lastBox = style()->isLeftToRightDirection() ? curr->l astLeafChild() : curr->firstLeafChild();
1660 if (lastBox && lastBox->layoutObject().isBR() && lastBox->layout Object().style()->clear() != CNONE)
1661 firstLineBoxWithBreakAndClearance = curr;
1662 }
1663
1673 // If a new float has been inserted before this line or before its l ast known float, just do a full layout. 1664 // If a new float has been inserted before this line or before its l ast known float, just do a full layout.
1674 bool encounteredNewFloat = false; 1665 bool encounteredNewFloat = false;
1675 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou nteredNewFloat, dirtiedByFloat); 1666 checkFloatsInCleanLine(curr, layoutState.floats(), floatIndex, encou nteredNewFloat, dirtiedByFloat);
1676 if (encounteredNewFloat) 1667 if (encounteredNewFloat)
1677 layoutState.markForFullLayout(); 1668 layoutState.markForFullLayout();
1678 1669
1679 if (dirtiedByFloat || layoutState.isFullLayout()) 1670 if (dirtiedByFloat || layoutState.isFullLayout())
1680 break; 1671 break;
1681 } 1672 }
1682 // Check if a new float has been inserted after the last known float. 1673 // Check if a new float has been inserted after the last known float.
1683 if (!curr && floatIndex < layoutState.floats().size()) 1674 if (!curr && floatIndex < layoutState.floats().size())
1684 layoutState.markForFullLayout(); 1675 layoutState.markForFullLayout();
1685 } 1676 }
1686 1677
1687 if (layoutState.isFullLayout()) { 1678 if (layoutState.isFullLayout()) {
1688 // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations. 1679 // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
1689 if (layoutState.hasInlineChild() && !selfNeedsLayout()) { 1680 if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
1690 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Flo atDescendantChanged, MarkOnlyThis); 1681 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Flo atDescendantChanged, MarkOnlyThis);
1691 setShouldDoFullPaintInvalidation(); 1682 setShouldDoFullPaintInvalidation();
1692 } 1683 }
1693 1684
1694 deleteLineBoxTree(); 1685 deleteLineBoxTree();
1695 curr = nullptr; 1686 curr = nullptr;
1696 ASSERT(!firstLineBox() && !lastLineBox()); 1687 ASSERT(!firstLineBox() && !lastLineBox());
1697 } else { 1688 } else {
1689 if (firstLineBoxWithBreakAndClearance)
1690 curr = firstLineBoxWithBreakAndClearance;
1698 if (curr) { 1691 if (curr) {
1699 // We have a dirty line. 1692 // We have a dirty line.
1700 if (RootInlineBox* prevRootBox = curr->prevRootBox()) { 1693 if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
1701 // We have a previous line. 1694 // We have a previous line.
1702 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox-> lineBreakPos() >= toLayoutText(prevRootBox->lineBreakObj())->textLength()))) { 1695 if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRo otBox->lineBreakObj() || (prevRootBox->lineBreakObj()->isText() && prevRootBox-> lineBreakPos() >= toLayoutText(prevRootBox->lineBreakObj())->textLength()))) {
1703 // The previous line didn't break cleanly or broke at a newl ine 1696 // The previous line didn't break cleanly or broke at a newl ine
1704 // that has been deleted, so treat it as dirty too. 1697 // that has been deleted, so treat it as dirty too.
1705 curr = prevRootBox; 1698 curr = prevRootBox;
1706 } 1699 }
1707 } 1700 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false); 2060 LayoutUnit logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false);
2068 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight() , false) - logicalLeft; 2061 LayoutUnit availableLogicalWidth = logicalRightOffsetForLine(logicalHeight() , false) - logicalLeft;
2069 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0); 2062 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid th, availableLogicalWidth, 0);
2070 2063
2071 if (!style()->isLeftToRightDirection()) 2064 if (!style()->isLeftToRightDirection())
2072 return logicalWidth() - logicalLeft; 2065 return logicalWidth() - logicalLeft;
2073 return logicalLeft; 2066 return logicalLeft;
2074 } 2067 }
2075 2068
2076 } 2069 }
OLDNEW
« no previous file with comments | « LayoutTests/fast/block/float/float-on-empty-line-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698