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

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

Issue 1905923002: Don't lose the pagination strut when a line is re-created. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make a reftest instead. Created 4 years, 8 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
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/multicol/pushed-line-affected-by-float-expected.html ('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 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, 826 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart,
827 const BidiStatus& cleanLineBidiStatus) 827 const BidiStatus& cleanLineBidiStatus)
828 { 828 {
829 const ComputedStyle& styleToUse = styleRef(); 829 const ComputedStyle& styleToUse = styleRef();
830 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated (); 830 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated ();
831 LineMidpointState& lineMidpointState = resolver.midpointState(); 831 LineMidpointState& lineMidpointState = resolver.midpointState();
832 InlineIterator endOfLine = resolver.position(); 832 InlineIterator endOfLine = resolver.position();
833 LayoutTextInfo layoutTextInfo; 833 LayoutTextInfo layoutTextInfo;
834 VerticalPositionCache verticalPositionCache; 834 VerticalPositionCache verticalPositionCache;
835 835
836 // Pagination may require us to delete and re-create a line due to floats. W hen this happens,
837 // we need to store the pagination strut in the meantime.
838 LayoutUnit paginationStrutFromDeletedLine;
839
836 LineBreaker lineBreaker(LineLayoutBlockFlow(this)); 840 LineBreaker lineBreaker(LineLayoutBlockFlow(this));
837 841
838 while (!endOfLine.atEnd()) { 842 while (!endOfLine.atEnd()) {
839 bool logicalWidthIsAvailable = false;
840
841 // The runs from the previous line should have been cleaned up. 843 // The runs from the previous line should have been cleaned up.
842 ASSERT(!resolver.runs().runCount()); 844 ASSERT(!resolver.runs().runCount());
843 845
844 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end? 846 // FIXME: Is this check necessary before the first iteration or can it b e moved to the end?
845 if (layoutState.endLine()) { 847 if (layoutState.endLine()) {
846 layoutState.setEndLineMatched(layoutState.endLineMatched() || matche dEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); 848 layoutState.setEndLineMatched(layoutState.endLineMatched() || matche dEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus));
847 if (layoutState.endLineMatched()) { 849 if (layoutState.endLineMatched()) {
848 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); 850 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
849 break; 851 break;
850 } 852 }
(...skipping 17 matching lines...) Expand all
868 resolver.runs().deleteRuns(); 870 resolver.runs().deleteRuns();
869 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed). 871 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed).
870 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0); 872 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0 ), 0);
871 break; 873 break;
872 } 874 }
873 875
874 ASSERT(endOfLine != resolver.position()); 876 ASSERT(endOfLine != resolver.position());
875 877
876 // This is a short-cut for empty lines. 878 // This is a short-cut for empty lines.
877 if (layoutState.lineInfo().isEmpty()) { 879 if (layoutState.lineInfo().isEmpty()) {
880 ASSERT(!paginationStrutFromDeletedLine);
878 if (lastRootBox()) 881 if (lastRootBox())
879 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), e ndOfLine.offset(), resolver.status()); 882 lastRootBox()->setLineBreakInfo(endOfLine.getLineLayoutItem(), e ndOfLine.offset(), resolver.status());
880 resolver.runs().deleteRuns(); 883 resolver.runs().deleteRuns();
881 } else { 884 } else {
882 VisualDirectionOverride override = (styleToUse.rtlOrdering() == Visu alOrder ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride : VisualRig htToLeftOverride) : NoVisualOverride); 885 VisualDirectionOverride override = (styleToUse.rtlOrdering() == Visu alOrder ? (styleToUse.direction() == LTR ? VisualLeftToRightOverride : VisualRig htToLeftOverride) : NoVisualOverride);
883 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && !r esolver.context()->parent()) { 886 if (isNewUBAParagraph && styleToUse.unicodeBidi() == Plaintext && !r esolver.context()->parent()) {
884 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().getLineLayoutItem(), resolver.positio n().offset()); 887 TextDirection direction = determinePlaintextDirectionality(resol ver.position().root(), resolver.position().getLineLayoutItem(), resolver.positio n().offset());
885 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse.u nicodeBidi()))); 888 resolver.setStatus(BidiStatus(direction, isOverride(styleToUse.u nicodeBidi())));
886 } 889 }
887 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine. 890 // FIXME: This ownership is reversed. We should own the BidiRunList and pass it to createBidiRunsForLine.
888 BidiRunList<BidiRun>& bidiRuns = resolver.runs(); 891 BidiRunList<BidiRun>& bidiRuns = resolver.runs();
889 constructBidiRunsForLine(resolver, bidiRuns, endOfLine, override, la youtState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph); 892 constructBidiRunsForLine(resolver, bidiRuns, endOfLine, override, la youtState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
890 ASSERT(resolver.position() == endOfLine); 893 ASSERT(resolver.position() == endOfLine);
891 894
892 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun(); 895 BidiRun* trailingSpaceRun = resolver.trailingSpaceRun();
893 896
894 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) 897 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated())
895 bidiRuns.logicallyLastRun()->m_hasHyphen = true; 898 bidiRuns.logicallyLastRun()->m_hasHyphen = true;
896 899
897 // Now that the runs have been ordered, we create the line boxes. 900 // Now that the runs have been ordered, we create the line boxes.
898 // At the same time we figure out where border/padding/margin should be applied for 901 // At the same time we figure out where border/padding/margin should be applied for
899 // inline flow boxes. 902 // inline flow boxes.
900 903
901 LayoutUnit oldLogicalHeight = logicalHeight(); 904 LayoutUnit oldLogicalHeight = logicalHeight();
902 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status ().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi onCache, trailingSpaceRun, wordMeasurements); 905 RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status ().context->level(), bidiRuns, endOfLine, layoutState.lineInfo(), verticalPositi onCache, trailingSpaceRun, wordMeasurements);
903 906
904 bidiRuns.deleteRuns(); 907 bidiRuns.deleteRuns();
905 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed). 908 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla ced by an ASSERT (or just removed).
906 909
910 // If we decided to re-create the line due to pagination, we better have a new line now.
911 ASSERT(lineBox || !paginationStrutFromDeletedLine);
912
907 if (lineBox) { 913 if (lineBox) {
908 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi ne.offset(), resolver.status()); 914 lineBox->setLineBreakInfo(endOfLine.getLineLayoutItem(), endOfLi ne.offset(), resolver.status());
909 if (layoutState.usesPaintInvalidationBounds()) 915 if (layoutState.usesPaintInvalidationBounds())
910 layoutState.updatePaintInvalidationRangeFromBox(lineBox); 916 layoutState.updatePaintInvalidationRangeFromBox(lineBox);
911 917
912 if (paginated) { 918 if (paginated) {
913 LayoutUnit adjustment; 919 if (paginationStrutFromDeletedLine) {
914 adjustLinePositionForPagination(*lineBox, adjustment); 920 // This is a line that got re-created because it got pus hed to the next fragmentainer, and there
915 if (adjustment) { 921 // were floats in the vicinity that affected the availab le width. Restore the pagination info
916 LayoutUnit oldLineWidth = availableLogicalWidthForLine(o ldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIndent Text); 922 // for this line.
917 lineBox->moveInBlockDirection(adjustment); 923 lineBox->setIsFirstAfterPageBreak(true);
918 if (layoutState.usesPaintInvalidationBounds()) 924 lineBox->setPaginationStrut(paginationStrutFromDeletedLi ne);
919 layoutState.updatePaintInvalidationRangeFromBox(line Box); 925 paginationStrutFromDeletedLine = LayoutUnit();
926 } else {
927 LayoutUnit adjustment;
928 adjustLinePositionForPagination(*lineBox, adjustment);
929 if (adjustment) {
930 LayoutUnit oldLineWidth = availableLogicalWidthForLi ne(oldLogicalHeight, layoutState.lineInfo().isFirstLine() ? IndentText : DoNotIn dentText);
931 lineBox->moveInBlockDirection(adjustment);
932 if (layoutState.usesPaintInvalidationBounds())
933 layoutState.updatePaintInvalidationRangeFromBox( lineBox);
920 934
921 if (availableLogicalWidthForLine(oldLogicalHeight + adju stment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText) != o ldLineWidth) { 935 if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, layoutState.lineInfo().isFirstLine() ? IndentText: DoNotIndentText) != oldLineWidth) {
922 // We have to delete this line, remove all floats th at got added, and let line layout re-run. 936 // We have to delete this line, remove all float s that got added, and let line layout
923 lineBox->deleteLine(); 937 // re-run. We had just calculated the pagination strut for this line, and we need to
924 endOfLine = restartLayoutRunsAndFloatsInRange(oldLog icalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolver, previousEndofLine); 938 // stow it away, so that we can re-apply it when the new line has been created.
925 logicalWidthIsAvailable = true; 939 paginationStrutFromDeletedLine = lineBox->pagina tionStrut();
926 } else { 940 ASSERT(paginationStrutFromDeletedLine);
927 setLogicalHeight(lineBox->lineBottomWithLeading()); 941 // We're also going to assume that we're right a fter a page break when re-creating this
942 // line, so it better be so.
943 ASSERT(lineBox->isFirstAfterPageBreak());
944 lineBox->deleteLine();
945 endOfLine = restartLayoutRunsAndFloatsInRange(ol dLogicalHeight, oldLogicalHeight + adjustment, lastFloatFromPreviousLine, resolv er, previousEndofLine);
946 } else {
947 setLogicalHeight(lineBox->lineBottomWithLeading( ));
948 }
928 } 949 }
929 } 950 }
930 } 951 }
931 } 952 }
932 } 953 }
933 954
934 if (!logicalWidthIsAvailable) { 955 if (!paginationStrutFromDeletedLine) {
935 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i) 956 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i)
936 setStaticPositions(LineLayoutBlockFlow(this), LineLayoutBox(line Breaker.positionedObjects()[i]), DoNotIndentText); 957 setStaticPositions(LineLayoutBlockFlow(this), LineLayoutBox(line Breaker.positionedObjects()[i]), DoNotIndentText);
937 958
938 if (!layoutState.lineInfo().isEmpty()) 959 if (!layoutState.lineInfo().isEmpty())
939 layoutState.lineInfo().setFirstLine(false); 960 layoutState.lineInfo().setFirstLine(false);
940 clearFloats(lineBreaker.clear()); 961 clearFloats(lineBreaker.clear());
941 962
942 if (m_floatingObjects && lastRootBox()) { 963 if (m_floatingObjects && lastRootBox()) {
943 InlineBidiResolver endOfLineResolver; 964 InlineBidiResolver endOfLineResolver;
944 endOfLineResolver.setPosition(endOfLine, numberOfIsolateAncestor s(endOfLine)); 965 endOfLineResolver.setPosition(endOfLine, numberOfIsolateAncestor s(endOfLine));
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 if (!line || !line->isFirstLineStyle()) 2078 if (!line || !line->isFirstLineStyle())
2058 return reason; 2079 return reason;
2059 // It's the RootInlineBox that paints the ::first-line background. Note that since it may be 2080 // It's the RootInlineBox that paints the ::first-line background. Note that since it may be
2060 // expensive to figure out if the first line is affected by any ::first-line selectors at all, 2081 // expensive to figure out if the first line is affected by any ::first-line selectors at all,
2061 // we just invalidate it unconditionally, since that's typically cheaper. 2082 // we just invalidate it unconditionally, since that's typically cheaper.
2062 invalidateDisplayItemClient(*line); 2083 invalidateDisplayItemClient(*line);
2063 return reason; 2084 return reason;
2064 } 2085 }
2065 2086
2066 } // namespace blink 2087 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/multicol/pushed-line-affected-by-float-expected.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698