Changeset 79510 in webkit
- Timestamp:
- Feb 23, 2011, 5:45:06 PM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r79508 r79510 1 2011-02-23 Ned Holbrook <nholbrook@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 Minimize calls to ubrk_setText() 6 https://bugs.webkit.org/show_bug.cgi?id=54912 7 <rdar://problem/9032774> 8 9 Avoid calling ubrk_setText() once per call to isBreakable() by using a LazyLineBreakIterator, which defers 10 break iterator creation until needed. This requires replacing the global line break iterator primitive with a 11 version that can be nested, since in some cases two iterators may need to be outstanding. In particular, 12 layoutInlineChildren() may indirectly call computePreferredLogicalWidths() and each may need an iterator. 13 In a test with a paragraph of Japanese text, this reduced the number of ubrk_setText() calls from 164 to 1. 14 15 * platform/text/TextBreakIterator.h: Add LazyLineBreakIterator. 16 (WebCore::LazyLineBreakIterator::LazyLineBreakIterator): 17 (WebCore::LazyLineBreakIterator::~LazyLineBreakIterator): 18 (WebCore::LazyLineBreakIterator::string): 19 (WebCore::LazyLineBreakIterator::length): 20 (WebCore::LazyLineBreakIterator::get): 21 (WebCore::LazyLineBreakIterator::reset): 22 * platform/text/TextBreakIteratorICU.cpp: Replace lineBreakIterator() primitive with acquireLineBreakIterator()/releaseLineBreakIterator(). 23 (WebCore::acquireLineBreakIterator): 24 (WebCore::releaseLineBreakIterator): 25 * platform/text/qt/TextBreakIteratorQt.cpp: Ditto TextBreakIteratorICU.cpp. 26 (WebCore::acquireLineBreakIterator): 27 (WebCore::releaseLineBreakIterator): 28 * rendering/RenderBlock.h: 29 * rendering/RenderBlockLineLayout.cpp: 30 (WebCore::RenderBlock::layoutInlineChildren): Pass a mapping of RenderText to LazyLineBreakIterator from one call of findNextLineBreak() to the next. 31 (WebCore::RenderBlock::findNextLineBreak): Use said mapping, resetting LazyLineBreakIterator for any newly-encountered RenderText. 32 * rendering/RenderText.cpp: Use a local LazyLineBreakIterator. 33 (WebCore::RenderText::computePreferredLogicalWidths): 34 * rendering/break_lines.cpp: Accept LazyLineBreakIterator rather than TextBreakIterator. 35 (WebCore::nextBreakablePosition): 36 * rendering/break_lines.h: Accept LazyLineBreakIterator rather than TextBreakIterator. 37 (WebCore::isBreakable): 38 1 39 2011-02-23 Anders Carlsson <andersca@apple.com> 2 40 -
trunk/Source/WebCore/platform/text/TextBreakIterator.h
r50977 r79510 29 29 class TextBreakIterator; 30 30 31 // Note: The returned iterator is good only until you get another iterator .31 // Note: The returned iterator is good only until you get another iterator, with the exception of acquireLineBreakIterator. 32 32 33 33 // Iterates over "extended grapheme clusters", as defined in UAX #29. … … 44 44 45 45 TextBreakIterator* wordBreakIterator(const UChar*, int length); 46 TextBreakIterator* lineBreakIterator(const UChar*, int length); 46 TextBreakIterator* acquireLineBreakIterator(const UChar*, int length); 47 void releaseLineBreakIterator(TextBreakIterator*); 47 48 TextBreakIterator* sentenceBreakIterator(const UChar*, int length); 48 49 … … 58 59 const int TextBreakDone = -1; 59 60 61 class LazyLineBreakIterator { 62 public: 63 LazyLineBreakIterator(const UChar* string = 0, int length = 0) 64 : m_string(string) 65 , m_length(length) 66 , m_iterator(0) 67 { 68 } 69 70 ~LazyLineBreakIterator() 71 { 72 if (m_iterator) 73 releaseLineBreakIterator(m_iterator); 74 } 75 76 const UChar* string() const { return m_string; } 77 int length() const { return m_length; } 78 79 TextBreakIterator* get() 80 { 81 if (!m_iterator) 82 m_iterator = acquireLineBreakIterator(m_string, m_length); 83 return m_iterator; 84 } 85 86 void reset(const UChar* string, int length) 87 { 88 if (m_iterator) 89 releaseLineBreakIterator(m_iterator); 90 91 m_string = string; 92 m_length = length; 93 m_iterator = 0; 94 } 95 96 private: 97 const UChar* m_string; 98 int m_length; 99 TextBreakIterator* m_iterator; 100 }; 101 60 102 } 61 103 -
trunk/Source/WebCore/platform/text/TextBreakIteratorICU.cpp
r56345 r79510 27 27 #include <unicode/ubrk.h> 28 28 #include <wtf/Assertions.h> 29 30 using namespace std; 29 31 30 32 namespace WebCore { … … 69 71 } 70 72 71 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 72 { 73 static bool createdLineBreakIterator = false; 74 static TextBreakIterator* staticLineBreakIterator; 75 return setUpIterator(createdLineBreakIterator, 76 staticLineBreakIterator, UBRK_LINE, string, length); 73 static bool createdLineBreakIterator = false; 74 static TextBreakIterator* staticLineBreakIterator; 75 76 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 77 { 78 TextBreakIterator* lineBreakIterator = 0; 79 if (!createdLineBreakIterator || staticLineBreakIterator) { 80 setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); 81 swap(staticLineBreakIterator, lineBreakIterator); 82 } 83 84 if (!lineBreakIterator) { 85 bool createdNewLineBreakIterator = false; 86 setUpIterator(createdNewLineBreakIterator, lineBreakIterator, UBRK_LINE, string, length); 87 } 88 89 return lineBreakIterator; 90 } 91 92 void releaseLineBreakIterator(TextBreakIterator* iterator) 93 { 94 ASSERT(createdLineBreakIterator); 95 ASSERT(iterator); 96 97 if (!staticLineBreakIterator) 98 staticLineBreakIterator = iterator; 99 else 100 ubrk_close(reinterpret_cast<UBreakIterator*>(iterator)); 77 101 } 78 102 -
trunk/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
r69773 r79510 31 31 #define DEBUG if (1) {} else qDebug 32 32 #endif 33 34 using namespace std; 33 35 34 36 namespace WebCore { … … 90 92 } 91 93 92 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 94 static TextBreakIterator* staticLineBreakIterator; 95 96 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 93 97 { 94 static TextBreakIterator staticLineBreakIterator; 95 return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); 98 TextBreakIterator* lineBreakIterator = 0; 99 if (staticLineBreakIterator) { 100 setUpIterator(*staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); 101 swap(staticLineBreakIterator, lineBreakIterator); 102 } 103 104 if (!lineBreakIterator && string && length) 105 lineBreakIterator = new TextBreakIterator(QTextBoundaryFinder::Line, string, length); 106 107 return lineBreakIterator; 108 } 109 110 void releaseLineBreakIterator(TextBreakIterator* iterator) 111 { 112 ASSERT(iterator); 113 114 if (!staticLineBreakIterator) 115 staticLineBreakIterator = iterator; 116 else 117 delete iterator; 96 118 } 97 119 -
trunk/Source/WebCore/rendering/RenderBlock.h
r78846 r79510 36 36 class InlineIterator; 37 37 class LayoutStateMaintainer; 38 class LazyLineBreakIterator; 38 39 class RenderInline; 39 40 … … 487 488 int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly, FloatingObject* lastFloatFromPreviousLine); 488 489 void fitBelowFloats(float widthToFit, bool firstLine, float& availableWidth); 489 InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine); 490 typedef std::pair<RenderText*, LazyLineBreakIterator> LineBreakIteratorInfo; 491 InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo&, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine); 490 492 RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject); 491 493 InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine); -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r79286 r79510 35 35 #include "RenderView.h" 36 36 #include "Settings.h" 37 #include "TextBreakIterator.h" 37 38 #include "TextRun.h" 38 39 #include "TrailingFloatsRootInlineBox.h" … … 663 664 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated(); 664 665 666 LineBreakIteratorInfo lineBreakIteratorInfo; 665 667 VerticalPositionCache verticalPositionCache; 666 668 … … 679 681 InlineIterator oldEnd = end; 680 682 FloatingObject* lastFloatFromPreviousLine = m_floatingObjects ? m_floatingObjects->last() : 0; 681 end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine);683 end = findNextLineBreak(resolver, firstLine, isLineEmpty, lineBreakIteratorInfo, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine); 682 684 if (resolver.position().atEnd()) { 683 685 resolver.deleteRuns(); … … 1433 1435 } 1434 1436 1435 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly,1437 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo& lineBreakIteratorInfo, bool& previousLineBrokeCleanly, 1436 1438 bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine) 1437 1439 { … … 1724 1726 } 1725 1727 1726 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(str, pos, strlen, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen))); 1728 if (lineBreakIteratorInfo.first != t) { 1729 lineBreakIteratorInfo.first = t; 1730 lineBreakIteratorInfo.second.reset(str, strlen); 1731 } 1732 1733 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(lineBreakIteratorInfo.second, pos, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen))); 1727 1734 1728 1735 if (betweenWords || midWordBreak) { -
trunk/Source/WebCore/rendering/RenderText.cpp
r78846 r79510 749 749 int len = textLength(); 750 750 const UChar* txt = characters(); 751 LazyLineBreakIterator breakIterator(txt, len); 751 752 bool needsWordSpacing = false; 752 753 bool ignoringSpaces = false; … … 808 809 } 809 810 810 bool hasBreak = breakAll || isBreakable( txt, i, len, nextBreakable, breakNBSP);811 bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP); 811 812 bool betweenWords = true; 812 813 int j = i; … … 816 817 break; 817 818 c = txt[j]; 818 if (isBreakable( txt, j, len, nextBreakable, breakNBSP))819 if (isBreakable(breakIterator, j, nextBreakable, breakNBSP)) 819 820 break; 820 821 if (breakAll) { -
trunk/Source/WebCore/rendering/break_lines.cpp
r77062 r79510 155 155 #endif 156 156 157 int nextBreakablePosition( const UChar* str, int pos, int len, bool treatNoBreakSpaceAsBreak)157 int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool treatNoBreakSpaceAsBreak) 158 158 { 159 #if !PLATFORM(MAC) || !defined(BUILDING_ON_TIGER) 160 TextBreakIterator* breakIterator = 0; 161 #endif 159 const UChar* str = lazyBreakIterator.string(); 160 int len = lazyBreakIterator.length(); 162 161 int nextBreak = -1; 163 162 … … 172 171 if (nextBreak < i && i) { 173 172 #if !PLATFORM(MAC) || !defined(BUILDING_ON_TIGER) 174 if (!breakIterator) 175 breakIterator = lineBreakIterator(str, len); 173 TextBreakIterator* breakIterator = lazyBreakIterator.get(); 176 174 if (breakIterator) 177 175 nextBreak = textBreakFollowing(breakIterator, i - 1); -
trunk/Source/WebCore/rendering/break_lines.h
r50583 r79510 26 26 namespace WebCore { 27 27 28 int nextBreakablePosition(const UChar*, int pos, int len, bool breakNBSP = false);28 class LazyLineBreakIterator; 29 29 30 inline bool isBreakable(const UChar* str, int pos, int len, int& nextBreakable, bool breakNBSP = false) 31 { 32 if (pos > nextBreakable) 33 nextBreakable = nextBreakablePosition(str, pos, len, breakNBSP); 34 return pos == nextBreakable; 35 } 30 int nextBreakablePosition(LazyLineBreakIterator&, int pos, bool breakNBSP = false); 31 32 inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP = false) 33 { 34 if (pos > nextBreakable) 35 nextBreakable = nextBreakablePosition(lazyBreakIterator, pos, breakNBSP); 36 return pos == nextBreakable; 37 } 36 38 37 39 } // namespace WebCore
Note:
See TracChangeset
for help on using the changeset viewer.