Changeset 85810 in webkit
- Timestamp:
- May 4, 2011 5:01:11 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r85800 r85810 1 2011-05-04 Levi Weintraub <leviw@chromium.org> 2 3 Reviewed by Eric Seidel. 4 5 Split findNextLineBreak into a LineBreaker class 6 https://bugs.webkit.org/show_bug.cgi?id=60209 7 8 Breaking findNextLineBreak into a new class inside RenderBlock. Currently it's tracking 9 nearly no state, but subsequent patches will move some of the local variables used throughout 10 the nextLineBreak function into member variables to simplify breaking off helper functions from 11 the bloated function. 12 13 No new tests since this is just moving code around. 14 15 * WebCore.xcodeproj/project.pbxproj: 16 * rendering/RenderBlock.h: 17 (WebCore::RenderBlock::LineBreaker::LineBreaker): 18 (WebCore::RenderBlock::LineBreaker::lineWasHyphenated): Accessor. 19 (WebCore::RenderBlock::LineBreaker::positionedObjects): Ditto. 20 (WebCore::RenderBlock::LineBreaker::clear): Ditto. 21 * rendering/RenderBlockLineLayout.cpp: 22 (WebCore::RenderBlock::layoutRunsAndFloats): 23 (WebCore::RenderBlock::LineBreaker::skipTrailingWhitespace): 24 (WebCore::RenderBlock::LineBreaker::skipLeadingWhitespace): 25 (WebCore::RenderBlock::LineBreaker::reset): 26 (WebCore::RenderBlock::LineBreaker::nextLineBreak): 27 1 28 2011-05-04 Fridrich Strba <fridrich.strba@bluewin.ch> 2 29 -
trunk/Source/WebCore/rendering/RenderBlock.h
r85732 r85810 495 495 496 496 // The following functions' implementations are in RenderBlockLineLayout.cpp. 497 typedef std::pair<RenderText*, LazyLineBreakIterator> LineBreakIteratorInfo; 498 class LineBreaker { 499 public: 500 LineBreaker(RenderBlock* block) 501 : m_block(block) 502 { 503 reset(); 504 } 505 506 InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, LineBreakIteratorInfo&, FloatingObject* lastFloatFromPreviousLine); 507 508 bool lineWasHyphenated() { return m_hyphenated; } 509 const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; } 510 EClear clear() { return m_clear; } 511 private: 512 void reset(); 513 514 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); 515 void skipLeadingWhitespace(InlineBidiResolver&, const LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&); 516 517 RenderBlock* m_block; 518 bool m_hyphenated; 519 EClear m_clear; 520 Vector<RenderBox*> m_positionedObjects; 521 }; 522 497 523 void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat); 498 524 RootInlineBox* determineStartPosition(LineInfo&, bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats, … … 503 529 RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop); 504 530 505 void skipTrailingWhitespace(InlineIterator&, const LineInfo&);506 void skipLeadingWhitespace(InlineBidiResolver&, const LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);507 typedef std::pair<RenderText*, LazyLineBreakIterator> LineBreakIteratorInfo;508 InlineIterator findNextLineBreak(InlineBidiResolver&, LineInfo&, LineBreakIteratorInfo&, bool& hyphenated,509 EClear*, FloatingObject* lastFloatFromPreviousLine, Vector<RenderBox*>& positionedObjects);510 531 RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&); 511 532 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox); -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r85737 r85810 899 899 VerticalPositionCache verticalPositionCache; 900 900 901 LineBreaker lineBreaker(this); 902 901 903 while (!end.atEnd()) { 902 904 // FIXME: Is this check necessary before the first iteration or can it be moved to the end? … … 908 910 lineInfo.setEmpty(true); 909 911 910 EClear clear = CNONE;911 bool hyphenated;912 Vector<RenderBox*> positionedObjects;913 914 912 InlineIterator oldEnd = end; 915 913 FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0; 916 end = findNextLineBreak(resolver, lineInfo, lineBreakIteratorInfo, hyphenated, &clear, lastFloatFromPreviousLine, positionedObjects);914 end = lineBreaker.nextLineBreak(resolver, lineInfo, lineBreakIteratorInfo, lastFloatFromPreviousLine); 917 915 if (resolver.position().atEnd()) { 918 916 // FIXME: We shouldn't be creating any runs in findNextLineBreak to begin with! … … 938 936 BidiRun* trailingSpaceRun = !lineInfo.previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0; 939 937 940 if (bidiRuns.runCount() && hyphenated)938 if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) 941 939 bidiRuns.logicallyLastRun()->m_hasHyphen = true; 942 940 … … 982 980 } 983 981 984 for (size_t i = 0; i < positionedObjects.size(); ++i)985 setStaticPositions(this, positionedObjects[i]);982 for (size_t i = 0; i < lineBreaker.positionedObjects().size(); ++i) 983 setStaticPositions(this, lineBreaker.positionedObjects()[i]); 986 984 987 985 lineInfo.setFirstLine(false); 988 newLine( clear);986 newLine(lineBreaker.clear()); 989 987 } 990 988 … … 1507 1505 1508 1506 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, since we really need to be building 1509 // line boxes even for containers that may ultimately collapse away. 1510 // elements quite right. 1507 // line boxes even for containers that may ultimately collapse away. Otherwise we'll never get positioned 1508 // elements quite right. In other words, we need to build this function's work into the normal line 1511 1509 // object iteration process. 1512 1510 // NB. this function will insert any floating elements that would otherwise 1513 1511 // be skipped but it will not position them. 1514 void RenderBlock:: skipTrailingWhitespace(InlineIterator& iterator, const LineInfo& lineInfo)1512 void RenderBlock::LineBreaker::skipTrailingWhitespace(InlineIterator& iterator, const LineInfo& lineInfo) 1515 1513 { 1516 1514 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo)) { 1517 1515 RenderObject* object = iterator.m_obj; 1518 1516 if (object->isFloating()) { 1519 insertFloatingObject(toRenderBox(object));1517 m_block->insertFloatingObject(toRenderBox(object)); 1520 1518 } else if (object->isPositioned()) 1521 setStaticPositions( this, toRenderBox(object));1519 setStaticPositions(m_block, toRenderBox(object)); 1522 1520 iterator.increment(); 1523 1521 } 1524 1522 } 1525 1523 1526 void RenderBlock:: skipLeadingWhitespace(InlineBidiResolver& resolver, const LineInfo& lineInfo,1527 FloatingObject* lastFloatFromPreviousLine, LineWidth& width)1524 void RenderBlock::LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, const LineInfo& lineInfo, 1525 FloatingObject* lastFloatFromPreviousLine, LineWidth& width) 1528 1526 { 1529 1527 while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo)) { 1530 1528 RenderObject* object = resolver.position().m_obj; 1531 1529 if (object->isFloating()) 1532 positionNewFloatOnLine(insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, width);1530 m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, width); 1533 1531 else if (object->isPositioned()) 1534 setStaticPositions( this, toRenderBox(object));1532 setStaticPositions(m_block, toRenderBox(object)); 1535 1533 resolver.increment(); 1536 1534 } … … 1801 1799 } 1802 1800 1803 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, LineBreakIteratorInfo& lineBreakIteratorInfo, 1804 bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine, Vector<RenderBox*>& positionedBoxes) 1805 { 1806 ASSERT(resolver.position().root() == this); 1801 void RenderBlock::LineBreaker::reset() 1802 { 1803 m_positionedObjects.clear(); 1804 m_hyphenated = false; 1805 m_clear = CNONE; 1806 } 1807 1808 InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, 1809 LineBreakIteratorInfo& lineBreakIteratorInfo, FloatingObject* lastFloatFromPreviousLine) 1810 { 1811 reset(); 1812 1813 ASSERT(resolver.position().root() == m_block); 1807 1814 1808 1815 bool appliedStartWidth = resolver.position().m_pos > 0; 1809 1816 LineMidpointState& lineMidpointState = resolver.midpointState(); 1810 1817 1811 LineWidth width( this, lineInfo.isFirstLine());1818 LineWidth width(m_block, lineInfo.isFirstLine()); 1812 1819 1813 1820 skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width); … … 1839 1846 lineInfo.setPreviousLineBrokeCleanly(false); 1840 1847 1841 hyphenated = false;1842 1843 1848 bool autoWrapWasEverTrueOnLine = false; 1844 1849 bool floatsFitOnLine = true; … … 1847 1852 // very specific circumstances (in order to match common WinIE renderings). 1848 1853 // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.) 1849 bool allowImagesToBreak = ! document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();1850 1851 EWhiteSpace currWS = style()->whiteSpace();1854 bool allowImagesToBreak = !m_block->document()->inQuirksMode() || !m_block->isTableCell() || !m_block->style()->logicalWidth().isIntrinsicOrAuto(); 1855 1856 EWhiteSpace currWS = m_block->style()->whiteSpace(); 1852 1857 EWhiteSpace lastWS = currWS; 1853 1858 while (current.m_obj) { 1854 RenderObject* next = bidiNext( this, current.m_obj);1859 RenderObject* next = bidiNext(m_block, current.m_obj); 1855 1860 1856 1861 currWS = current.m_obj->isReplaced() ? current.m_obj->parent()->style()->whiteSpace() : current.m_obj->style()->whiteSpace(); … … 1883 1888 lineInfo.setPreviousLineBrokeCleanly(true); 1884 1889 1885 if (!lineInfo.isEmpty() && clear)1886 *clear = current.m_obj->style()->clear();1890 if (!lineInfo.isEmpty()) 1891 m_clear = current.m_obj->style()->clear(); 1887 1892 } 1888 1893 goto end; … … 1891 1896 if (current.m_obj->isFloating()) { 1892 1897 RenderBox* floatBox = toRenderBox(current.m_obj); 1893 FloatingObject* f = insertFloatingObject(floatBox);1898 FloatingObject* f = m_block->insertFloatingObject(floatBox); 1894 1899 // check if it fits in the current line. 1895 1900 // If it does, position it now, otherwise, position 1896 1901 // it after moving to next line (in newLine() func) 1897 if (floatsFitOnLine && width.fitsOnLine( logicalWidthForFloat(f))) {1898 positionNewFloatOnLine(f, lastFloatFromPreviousLine, width);1902 if (floatsFitOnLine && width.fitsOnLine(m_block->logicalWidthForFloat(f))) { 1903 m_block->positionNewFloatOnLine(f, lastFloatFromPreviousLine, width); 1899 1904 if (lBreak.m_obj == current.m_obj) { 1900 1905 ASSERT(!lBreak.m_pos); … … 1909 1914 bool isInlineType = box->style()->isOriginalDisplayInlineType(); 1910 1915 if (!isInlineType) 1911 box->layer()->setStaticInlinePosition( borderAndPaddingStart());1916 box->layer()->setStaticInlinePosition(m_block->borderAndPaddingStart()); 1912 1917 else { 1913 1918 // If our original display was an INLINE type, then we can go ahead 1914 1919 // and determine our static y position now. 1915 box->layer()->setStaticBlockPosition( logicalHeight());1920 box->layer()->setStaticBlockPosition(m_block->logicalHeight()); 1916 1921 } 1917 1922 … … 1927 1932 trailingObjects.appendBoxIfNeeded(box); 1928 1933 } else 1929 positionedBoxes.append(box);1934 m_positionedObjects.append(box); 1930 1935 } else if (current.m_obj->isRenderInline()) { 1931 1936 // Right now, we should only encounter empty inlines here. … … 1944 1949 addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, 0)); // Stop ignoring spaces. 1945 1950 addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, 0)); // Start ignoring again. 1946 } else if ( style()->collapseWhiteSpace() && resolver.position().m_obj == current.m_obj1947 && shouldSkipWhitespaceAfterStartObject( this, current.m_obj, lineMidpointState)) {1951 } else if (m_block->style()->collapseWhiteSpace() && resolver.position().m_obj == current.m_obj 1952 && shouldSkipWhitespaceAfterStartObject(m_block, current.m_obj, lineMidpointState)) { 1948 1953 // Like with list markers, we start ignoring spaces to make sure that any 1949 1954 // additional spaces we see will be discarded. … … 1975 1980 // Optimize for a common case. If we can't find whitespace after the list 1976 1981 // item, then this is all moot. 1977 int replacedLogicalWidth = logicalWidthForChild(replacedBox) + marginStartForChild(replacedBox) +marginEndForChild(replacedBox) + inlineLogicalWidth(current.m_obj);1982 int replacedLogicalWidth = m_block->logicalWidthForChild(replacedBox) + m_block->marginStartForChild(replacedBox) + m_block->marginEndForChild(replacedBox) + inlineLogicalWidth(current.m_obj); 1978 1983 if (current.m_obj->isListMarker()) { 1979 if ( style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, current.m_obj, lineMidpointState)) {1984 if (m_block->style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(m_block, current.m_obj, lineMidpointState)) { 1980 1985 // Like with inline flows, we start ignoring spaces to make sure that any 1981 1986 // additional spaces we see will be discarded. … … 2117 2122 if (lineWasTooWide || !width.fitsOnLine()) { 2118 2123 if (canHyphenate && !width.fitsOnLine()) { 2119 tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, hyphenated);2120 if ( hyphenated)2124 tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated); 2125 if (m_hyphenated) 2121 2126 goto end; 2122 2127 } … … 2131 2136 } 2132 2137 if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characters()[lBreak.m_pos - 1] == softHyphen && style->hyphens() != HyphensNone) 2133 hyphenated = true;2138 m_hyphenated = true; 2134 2139 goto end; // Didn't fit. Jump to the end. 2135 2140 } else { … … 2233 2238 if (!width.fitsOnLine()) { 2234 2239 if (canHyphenate) 2235 tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, hyphenated);2236 2237 if (! hyphenated && lBreak.previousInSameNode() == softHyphen && style->hyphens() != HyphensNone)2238 hyphenated = true;2239 2240 if ( hyphenated)2240 tryHyphenating(t, f, style->locale(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTmpW, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated); 2241 2242 if (!m_hyphenated && lBreak.previousInSameNode() == softHyphen && style->hyphens() != HyphensNone) 2243 m_hyphenated = true; 2244 2245 if (m_hyphenated) 2241 2246 goto end; 2242 2247 } … … 2312 2317 if (lBreak == resolver.position() && (!lBreak.m_obj || !lBreak.m_obj->isBR())) { 2313 2318 // we just add as much as possible 2314 if ( style()->whiteSpace() == PRE) {2319 if (m_block->style()->whiteSpace() == PRE) { 2315 2320 // FIXME: Don't really understand this case. 2316 2321 if (current.m_pos) {
Note: See TracChangeset
for help on using the changeset viewer.