Changeset 86698 in webkit
- Timestamp:
- May 17, 2011 12:45:24 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r86695 r86698 1 2011-05-17 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Ryosuke Niwa. 4 5 Add a LineLayoutState object to hold global state during line layout 6 https://bugs.webkit.org/show_bug.cgi?id=60113 7 8 Like LayoutState for layout(), LineLayoutState keeps track of global information 9 during an entire linebox tree layout pass (aka layoutInlineChildren). 10 11 For now it just holds isFullLayout and the logicalRepaintTop/Bottom. 12 It's possible we should hold the useRepaintBounds bool as well as 13 the startLine and endLine RootInlineBox pointers. 14 15 No change in behavior, thus no tests. 16 17 * rendering/RenderBlock.cpp: 18 (WebCore::RenderBlock::layoutBlock): 19 * rendering/RenderBlock.h: 20 * rendering/RenderBlockLineLayout.cpp: 21 (WebCore::LineLayoutState::LineLayoutState): 22 (WebCore::LineLayoutState::markForFullLayout): 23 (WebCore::LineLayoutState::isFullLayout): 24 (WebCore::LineLayoutState::setRepaintRange): 25 (WebCore::LineLayoutState::updateRepaintRangeFromBox): 26 (WebCore::LineLayoutState::startLine): 27 (WebCore::LineLayoutState::endLine): 28 (WebCore::deleteLineRange): 29 (WebCore::RenderBlock::layoutRunsAndFloats): 30 (WebCore::RenderBlock::layoutInlineChildren): 31 (WebCore::RenderBlock::checkFloatsInCleanLine): 32 (WebCore::RenderBlock::determineStartPosition): 33 (WebCore::RenderBlock::determineEndPosition): 34 (WebCore::RenderBlock::matchedEndLine): 35 1 36 2011-05-17 Andreas Kling <kling@webkit.org> 2 37 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r86451 r86698 1283 1283 updateScrollInfoAfterLayout(); 1284 1284 1285 // FIXME: This repaint logic should be moved into a separate helper function! 1285 1286 // Repaint with our new bounds if they are different from our old bounds. 1286 1287 bool didFullRepaint = repainter.repaintAfterLayout(); -
trunk/Source/WebCore/rendering/RenderBlock.h
r86377 r86698 38 38 class LayoutStateMaintainer; 39 39 class LazyLineBreakIterator; 40 class LineLayoutState; 40 41 class LineWidth; 41 42 class RenderInline; … … 521 522 Vector<RenderBox*> m_positionedObjects; 522 523 }; 523 524 524 525 void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat); 525 RootInlineBox* determineStartPosition(LineInfo&, bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats, 526 bool& useRepaintBounds, int& repaintTop, int& repaintBottom); 527 RootInlineBox* determineEndPosition(RootInlineBox* startBox, Vector<FloatWithRect>& floats, size_t floatIndex, InlineIterator& cleanLineStart, 528 BidiStatus& cleanLineBidiStatus, int& yPos); 529 bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, 530 RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop); 526 RootInlineBox* determineStartPosition(LineLayoutState&, LineInfo&, InlineBidiResolver&, Vector<FloatWithRect>&, unsigned& numCleanFloats, bool& useRepaintBounds); 527 RootInlineBox* determineEndPosition(RootInlineBox* startBox, Vector<FloatWithRect>&, size_t floatIndex, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus, int& yPos); 528 bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, int& endYPos); 531 529 532 530 RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&); … … 732 730 // Helper function for layoutInlineChildren() 733 731 RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun); 734 void layoutRunsAndFloats( bool fullLayout, bool hasInlineChild, Vector<FloatWithRect>&, int& repaintLogicalTop, int& repaintLogicalBottom);732 void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild, Vector<FloatWithRect>&); 735 733 736 734 // Pagination routines. -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r86628 r86698 817 817 } 818 818 819 static void deleteLineRange(RenderArena* arena, RootInlineBox* startLine, int& repaintLogicalTop, int& repaintLogicalBottom, RootInlineBox* stopLine = 0) 819 // Like LayoutState for layout(), LineLayoutState keeps track of global information 820 // during an entire linebox tree layout pass (aka layoutInlineChildren). 821 class LineLayoutState { 822 public: 823 LineLayoutState(bool fullLayout, int& repaintLogicalTop, int& repaintLogicalBottom) 824 : m_isFullLayout(fullLayout) 825 , m_repaintLogicalTop(repaintLogicalTop) 826 , m_repaintLogicalBottom(repaintLogicalBottom) 827 { } 828 829 void markForFullLayout() { m_isFullLayout = true; } 830 bool isFullLayout() const { return m_isFullLayout; } 831 832 void setRepaintRange(int logicalHeight) { m_repaintLogicalTop = m_repaintLogicalBottom = logicalHeight; } 833 void updateRepaintRangeFromBox(RootInlineBox* box, int paginationDelta = 0) 834 { 835 m_repaintLogicalTop = min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + min(paginationDelta, 0)); 836 m_repaintLogicalBottom = max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + max(paginationDelta, 0)); 837 } 838 839 private: 840 bool m_isFullLayout; 841 842 // FIXME: Should this be a range object instead of two ints? 843 int& m_repaintLogicalTop; 844 int& m_repaintLogicalBottom; 845 }; 846 847 static void deleteLineRange(LineLayoutState& layoutState, RenderArena* arena, RootInlineBox* startLine, RootInlineBox* stopLine = 0) 820 848 { 821 849 RootInlineBox* boxToDelete = startLine; 822 850 while (boxToDelete && boxToDelete != stopLine) { 823 repaintLogicalTop = min(repaintLogicalTop, boxToDelete->logicalTopVisualOverflow()); 824 repaintLogicalBottom = max(repaintLogicalBottom, boxToDelete->logicalBottomVisualOverflow()); 851 layoutState.updateRepaintRangeFromBox(boxToDelete); 825 852 // Note: deleteLineRange(renderArena(), firstRootBox()) is not identical to deleteLineBoxTree(). 826 853 // deleteLineBoxTree uses nextLineBox() instead of nextRootBox() when traversing. … … 831 858 } 832 859 833 void RenderBlock::layoutRunsAndFloats( bool fullLayout, bool hasInlineChild, Vector<FloatWithRect>& floats, int& repaintLogicalTop, int& repaintLogicalBottom)860 void RenderBlock::layoutRunsAndFloats(LineLayoutState& layoutState, bool hasInlineChild, Vector<FloatWithRect>& floats) 834 861 { 835 862 // We want to skip ahead to the first dirty line … … 837 864 unsigned floatIndex; 838 865 LineInfo lineInfo; 866 // FIXME: Should useRepaintBounds be on the LineLayoutState? 867 // It appears to be used to track the case where we're only repainting a subset of our lines. 839 868 bool useRepaintBounds = false; 840 869 841 RootInlineBox* startLine = determineStartPosition(lineInfo, fullLayout, resolver, floats, floatIndex, 842 useRepaintBounds, repaintLogicalTop, repaintLogicalBottom); 870 RootInlineBox* startLine = determineStartPosition(layoutState, lineInfo, resolver, floats, floatIndex, useRepaintBounds); 843 871 844 872 // FIXME: This would make more sense outside of this function, but since 845 873 // determineStartPosition can change the fullLayout flag we have to do this here. Failure to call 846 874 // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html. 847 if ( fullLayout&& hasInlineChild && !selfNeedsLayout()) {875 if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) { 848 876 setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like 849 877 // we're supposed to. … … 867 895 BidiStatus cleanLineBidiStatus; 868 896 int endLineLogicalTop = 0; 869 RootInlineBox* endLine = ( fullLayout|| !startLine) ?897 RootInlineBox* endLine = (layoutState.isFullLayout() || !startLine) ? 870 898 0 : determineEndPosition(startLine, floats, floatIndex, cleanLineStart, cleanLineBidiStatus, endLineLogicalTop); 871 899 … … 873 901 if (!useRepaintBounds) { 874 902 useRepaintBounds = true; 875 repaintLogicalTop = logicalHeight(); 876 repaintLogicalBottom = logicalHeight(); 877 } 878 deleteLineRange(renderArena(), startLine, repaintLogicalTop, repaintLogicalBottom); 903 layoutState.setRepaintRange(logicalHeight()); 904 } 905 deleteLineRange(layoutState, renderArena(), startLine); 879 906 } 880 907 881 908 InlineIterator end = resolver.position(); 882 909 883 if (! fullLayout&& lastRootBox() && lastRootBox()->endsWithBreak()) {910 if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithBreak()) { 884 911 // If the last line before the start line ends with a line break that clear floats, 885 912 // adjust the height accordingly. … … 910 937 while (!end.atEnd()) { 911 938 // FIXME: Is this check necessary before the first iteration or can it be moved to the end? 912 if (checkForEndLineMatch && (endLineMatched = matchedEndLine( resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop, repaintLogicalBottom, repaintLogicalTop)))939 if (checkForEndLineMatch && (endLineMatched = matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus, endLine, endLineLogicalTop))) 913 940 break; 914 941 … … 958 985 if (lineBox) { 959 986 lineBox->setLineBreakInfo(end.m_obj, end.m_pos, resolver.status()); 960 if (useRepaintBounds) { 961 repaintLogicalTop = min(repaintLogicalTop, lineBox->logicalTopVisualOverflow()); 962 repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow()); 963 } 987 if (useRepaintBounds) 988 layoutState.updateRepaintRangeFromBox(lineBox); 964 989 965 990 if (paginated) { … … 969 994 int oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, lineInfo.isFirstLine()); 970 995 lineBox->adjustBlockDirectionPosition(adjustment); 971 if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.972 repaintLogicalBottom = max(repaintLogicalBottom, lineBox->logicalBottomVisualOverflow());996 if (useRepaintBounds) 997 layoutState.updateRepaintRangeFromBox(lineBox); 973 998 974 999 if (availableLogicalWidthForLine(oldLogicalHeight + adjustment, lineInfo.isFirstLine()) != oldLineWidth) { … … 1031 1056 } 1032 1057 if (delta) { 1033 repaintLogicalTop = min(repaintLogicalTop, line->logicalTopVisualOverflow() + min(delta, 0)); 1034 repaintLogicalBottom = max(repaintLogicalBottom, line->logicalBottomVisualOverflow() + max(delta, 0)); 1058 layoutState.updateRepaintRangeFromBox(line, delta); 1035 1059 line->adjustBlockDirectionPosition(delta); 1036 1060 } … … 1049 1073 } else { 1050 1074 // Delete all the remaining lines. 1051 deleteLineRange( renderArena(), endLine, repaintLogicalTop, repaintLogicalBottom);1075 deleteLineRange(layoutState, renderArena(), endLine); 1052 1076 } 1053 1077 } … … 1106 1130 // Figure out if we should clear out our line boxes. 1107 1131 // FIXME: Handle resize eventually! 1108 bool fullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren; 1109 if (fullLayout) 1132 bool isFullLayout = !firstLineBox() || selfNeedsLayout() || relayoutChildren; 1133 LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom); 1134 1135 if (isFullLayout) 1110 1136 lineBoxes()->deleteLineBoxes(renderArena()); 1111 1137 … … 1145 1171 else if (o->isFloating()) 1146 1172 floats.append(FloatWithRect(box)); 1147 else if ( fullLayout|| o->needsLayout()) {1173 else if (layoutState.isFullLayout() || o->needsLayout()) { 1148 1174 // Replaced elements 1149 toRenderBox(o)->dirtyLineBoxes( fullLayout);1175 toRenderBox(o)->dirtyLineBoxes(layoutState.isFullLayout()); 1150 1176 o->layoutIfNeeded(); 1151 1177 } … … 1153 1179 if (!o->isText()) 1154 1180 toRenderInline(o)->updateAlwaysCreateLineBoxes(); 1155 if ( fullLayout|| o->selfNeedsLayout())1156 dirtyLineBoxesForRenderer(o, fullLayout);1181 if (layoutState.isFullLayout() || o->selfNeedsLayout()) 1182 dirtyLineBoxesForRenderer(o, layoutState.isFullLayout()); 1157 1183 o->setNeedsLayout(false); 1158 1184 } … … 1160 1186 } 1161 1187 1162 layoutRunsAndFloats( fullLayout, hasInlineChild, floats, repaintLogicalTop, repaintLogicalBottom);1188 layoutRunsAndFloats(layoutState, hasInlineChild, floats); 1163 1189 } 1164 1190 … … 1201 1227 return; 1202 1228 } 1229 1203 1230 if (floats[floatIndex].rect.size() != newSize) { 1204 1231 int floatTop = isHorizontalWritingMode() ? floats[floatIndex].rect.y() : floats[floatIndex].rect.x(); … … 1215 1242 } 1216 1243 1217 RootInlineBox* RenderBlock::determineStartPosition(Line Info& lineInfo, bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats,1218 unsigned& numCleanFloats, bool& useRepaintBounds , int& repaintLogicalTop, int& repaintLogicalBottom)1244 RootInlineBox* RenderBlock::determineStartPosition(LineLayoutState& layoutState, LineInfo& lineInfo, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, 1245 unsigned& numCleanFloats, bool& useRepaintBounds) 1219 1246 { 1220 1247 RootInlineBox* curr = 0; 1221 1248 RootInlineBox* last = 0; 1222 1249 1250 // FIXME: This entire float-checking block needs to be broken into a new function. 1223 1251 bool dirtiedByFloat = false; 1224 if (! fullLayout) {1252 if (!layoutState.isFullLayout()) { 1225 1253 // Paginate all of the clean lines. 1226 1254 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated(); … … 1234 1262 if (containsFloats() || !floats.isEmpty()) { 1235 1263 // FIXME: Do better eventually. For now if we ever shift because of pagination and floats are present just go to a full layout. 1236 fullLayout = true;1264 layoutState.markForFullLayout(); 1237 1265 break; 1238 1266 } … … 1241 1269 useRepaintBounds = true; 1242 1270 1243 repaintLogicalTop = min(repaintLogicalTop, curr->logicalTopVisualOverflow() + min(paginationDelta, 0)); 1244 repaintLogicalBottom = max(repaintLogicalBottom, curr->logicalBottomVisualOverflow() + max(paginationDelta, 0)); 1271 layoutState.updateRepaintRangeFromBox(curr, paginationDelta); 1245 1272 curr->adjustBlockDirectionPosition(paginationDelta); 1246 1273 } 1247 1274 } 1248 1275 1249 // If a new float has been inserted before this line or before its last known float,just do a full layout. 1250 checkFloatsInCleanLine(curr, floats, floatIndex, fullLayout, dirtiedByFloat); 1251 if (dirtiedByFloat || fullLayout) 1276 // If a new float has been inserted before this line or before its last known float, just do a full layout. 1277 bool encounteredNewFloat = false; 1278 checkFloatsInCleanLine(curr, floats, floatIndex, encounteredNewFloat, dirtiedByFloat); 1279 if (encounteredNewFloat) 1280 layoutState.markForFullLayout(); 1281 1282 if (dirtiedByFloat || layoutState.isFullLayout()) 1252 1283 break; 1253 1284 } 1254 1285 // Check if a new float has been inserted after the last known float. 1255 1286 if (!curr && floatIndex < floats.size()) 1256 fullLayout = true;1257 } 1258 1259 if ( fullLayout) {1287 layoutState.markForFullLayout(); 1288 } 1289 1290 if (layoutState.isFullLayout()) { 1260 1291 // FIXME: This should just call deleteLineBoxTree, but that causes 1261 1292 // crashes for fast/repaint tests. … … 1362 1393 } 1363 1394 1364 bool RenderBlock::matchedEndLine(const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, 1365 int& endLogicalTop, int& repaintLogicalBottom, int& repaintLogicalTop) 1395 bool RenderBlock::matchedEndLine(LineLayoutState& layoutState, const InlineBidiResolver& resolver, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, RootInlineBox*& endLine, int& endLogicalTop) 1366 1396 { 1367 1397 if (resolver.position() == endLineStart) { … … 1429 1459 1430 1460 // Now delete the lines that we failed to sync. 1431 deleteLineRange( renderArena(), endLine, repaintLogicalTop, repaintLogicalBottom, result);1461 deleteLineRange(layoutState, renderArena(), endLine, result); 1432 1462 endLine = result; 1433 1463 return result;
Note: See TracChangeset
for help on using the changeset viewer.