Changeset 79694 in webkit
- Timestamp:
- Feb 25, 2011, 10:34:15 AM (16 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 12 edited
-
ChangeLog (modified) (1 diff)
-
platform/text/TextBreakIterator.h (modified) (3 diffs)
-
platform/text/TextBreakIteratorICU.cpp (modified) (2 diffs)
-
platform/text/brew/TextBreakIteratorBrew.cpp (modified) (2 diffs)
-
platform/text/gtk/TextBreakIteratorGtk.cpp (modified) (1 diff)
-
platform/text/qt/TextBreakIteratorQt.cpp (modified) (2 diffs)
-
platform/text/wince/TextBreakIteratorWinCE.cpp (modified) (2 diffs)
-
rendering/RenderBlock.h (modified) (2 diffs)
-
rendering/RenderBlockLineLayout.cpp (modified) (5 diffs)
-
rendering/RenderText.cpp (modified) (3 diffs)
-
rendering/break_lines.cpp (modified) (2 diffs)
-
rendering/break_lines.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r79691 r79694 1 2011-02-25 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/brew/TextBreakIteratorBrew.cpp: Ditto. 26 (WebCore::acquireLineBreakIterator): 27 (WebCore::releaseLineBreakIterator): 28 * platform/text/gtk/TextBreakIteratorGtk.cpp: Ditto. 29 (WebCore::acquireLineBreakIterator): 30 (WebCore::releaseLineBreakIterator): 31 * platform/text/qt/TextBreakIteratorQt.cpp: Ditto. 32 (WebCore::acquireLineBreakIterator): 33 (WebCore::releaseLineBreakIterator): 34 * platform/text/wince/TextBreakIteratorWinCE.cpp: Ditto. 35 (WebCore::acquireLineBreakIterator): 36 (WebCore::releaseLineBreakIterator): 37 * rendering/RenderBlock.h: 38 * rendering/RenderBlockLineLayout.cpp: 39 (WebCore::RenderBlock::layoutInlineChildren): Pass a mapping of RenderText to LazyLineBreakIterator from one call of findNextLineBreak() to the next. 40 (WebCore::RenderBlock::findNextLineBreak): Use said mapping, resetting LazyLineBreakIterator for any newly-encountered RenderText. 41 * rendering/RenderText.cpp: Use a local LazyLineBreakIterator. 42 (WebCore::RenderText::computePreferredLogicalWidths): 43 * rendering/break_lines.cpp: Accept LazyLineBreakIterator rather than UniChar buffer. 44 (WebCore::nextBreakablePosition): 45 * rendering/break_lines.h: Accept LazyLineBreakIterator rather than UniChar buffer. 46 (WebCore::isBreakable): 47 1 48 2011-02-25 David Hyatt <hyatt@apple.com> 2 49 -
trunk/Source/WebCore/platform/text/TextBreakIterator.h
r79518 r79694 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
r79518 r79694 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/brew/TextBreakIteratorBrew.cpp
r69722 r79694 27 27 #include <wtf/unicode/Unicode.h> 28 28 29 using namespace std; 29 30 using namespace WTF::Unicode; 30 31 … … 261 262 } 262 263 263 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 264 { 265 DEFINE_STATIC_LOCAL(LineBreakIterator , iterator, ()); 266 iterator.reset(string, length); 267 return &iterator; 264 static TextBreakIterator* staticLineBreakIterator; 265 266 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 267 { 268 TextBreakIterator* lineBreakIterator = 0; 269 if (staticLineBreakIterator) { 270 staticLineBreakIterator->reset(string, length); 271 swap(staticLineBreakIterator, lineBreakIterator); 272 } 273 274 if (!lineBreakIterator && string && length) 275 lineBreakIterator = new LineBreakIterator(string, length); 276 277 return lineBreakIterator; 278 } 279 280 void releaseLineBreakIterator(TextBreakIterator* iterator) 281 { 282 ASSERT(iterator); 283 284 if (!staticLineBreakIterator) 285 staticLineBreakIterator = iterator; 286 else 287 delete iterator; 268 288 } 269 289 -
trunk/Source/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
r71296 r79694 240 240 } 241 241 242 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 243 { 244 static bool createdLineBreakIterator = false; 245 static TextBreakIterator* staticLineBreakIterator; 246 return setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); 242 static bool createdLineBreakIterator = false; 243 static TextBreakIterator* staticLineBreakIterator; 244 245 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 246 { 247 TextBreakIterator* lineBreakIterator = 0; 248 if (!createdLineBreakIterator || staticLineBreakIterator) { 249 setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); 250 swap(staticLineBreakIterator, lineBreakIterator); 251 } 252 253 if (!lineBreakIterator) { 254 bool createdNewLineBreakIterator = false; 255 setUpIterator(createdNewLineBreakIterator, lineBreakIterator, UBRK_LINE, string, length); 256 } 257 258 return lineBreakIterator; 259 } 260 261 void releaseLineBreakIterator(TextBreakIterator* iterator) 262 { 263 ASSERT(createdLineBreakIterator); 264 ASSERT(iterator); 265 266 if (!staticLineBreakIterator) 267 staticLineBreakIterator = iterator; 268 else 269 delete iterator; 247 270 } 248 271 -
trunk/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
r79567 r79694 31 31 #define DEBUG if (1) {} else qDebug 32 32 #endif 33 34 using namespace std; 33 35 34 36 namespace WebCore { … … 81 83 } 82 84 83 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 85 static TextBreakIterator* staticLineBreakIterator; 86 87 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 84 88 { 85 static TextBreakIterator staticLineBreakIterator; 86 return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); 89 TextBreakIterator* lineBreakIterator = 0; 90 if (staticLineBreakIterator) { 91 setUpIterator(*staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); 92 swap(staticLineBreakIterator, lineBreakIterator); 93 } 94 95 if (!lineBreakIterator && string && length) 96 lineBreakIterator = new TextBreakIterator(QTextBoundaryFinder::Line, QString(reinterpret_cast<const QChar*>(string), length)); 97 98 return lineBreakIterator; 99 } 100 101 void releaseLineBreakIterator(TextBreakIterator* iterator) 102 { 103 ASSERT(iterator); 104 105 if (!staticLineBreakIterator) 106 staticLineBreakIterator = iterator; 107 else 108 delete iterator; 87 109 } 88 110 -
trunk/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp
r72483 r79694 27 27 #include <wtf/unicode/Unicode.h> 28 28 29 using namespace std; 29 30 using namespace WTF::Unicode; 30 31 … … 242 243 } 243 244 244 TextBreakIterator* lineBreakIterator(const UChar* string, int length) 245 { 246 DEFINE_STATIC_LOCAL(LineBreakIterator , iterator, ()); 247 iterator.reset(string, length); 248 return &iterator; 245 static TextBreakIterator* staticLineBreakIterator; 246 247 TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) 248 { 249 TextBreakIterator* lineBreakIterator = 0; 250 if (staticLineBreakIterator) { 251 staticLineBreakIterator->reset(string, length); 252 swap(staticLineBreakIterator, lineBreakIterator); 253 } 254 255 if (!lineBreakIterator && string && length) 256 lineBreakIterator = new LineBreakIterator(string, length); 257 258 return lineBreakIterator; 259 } 260 261 void releaseLineBreakIterator(TextBreakIterator* iterator) 262 { 263 ASSERT(iterator); 264 265 if (!staticLineBreakIterator) 266 staticLineBreakIterator = iterator; 267 else 268 delete iterator; 249 269 } 250 270 -
trunk/Source/WebCore/rendering/RenderBlock.h
r79629 r79694 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
r79656 r79694 35 35 #include "RenderView.h" 36 36 #include "Settings.h" 37 #include "TextBreakIterator.h" 37 38 #include "TextRun.h" 38 39 #include "TrailingFloatsRootInlineBox.h" … … 672 673 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated(); 673 674 675 LineBreakIteratorInfo lineBreakIteratorInfo; 674 676 VerticalPositionCache verticalPositionCache; 675 677 … … 688 690 InlineIterator oldEnd = end; 689 691 FloatingObject* lastFloatFromPreviousLine = m_floatingObjects ? m_floatingObjects->last() : 0; 690 end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine);692 end = findNextLineBreak(resolver, firstLine, isLineEmpty, lineBreakIteratorInfo, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine); 691 693 if (resolver.position().atEnd()) { 692 694 resolver.deleteRuns(); … … 1442 1444 } 1443 1445 1444 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly,1446 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, bool& isLineEmpty, LineBreakIteratorInfo& lineBreakIteratorInfo, bool& previousLineBrokeCleanly, 1445 1447 bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine) 1446 1448 { … … 1733 1735 } 1734 1736 1735 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(str, pos, strlen, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen))); 1737 if (lineBreakIteratorInfo.first != t) { 1738 lineBreakIteratorInfo.first = t; 1739 lineBreakIteratorInfo.second.reset(str, strlen); 1740 } 1741 1742 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(lineBreakIteratorInfo.second, pos, nextBreakable, breakNBSP) && (style->hyphens() != HyphensNone || (pos && str[pos - 1] != softHyphen))); 1736 1743 1737 1744 if (betweenWords || midWordBreak) { -
trunk/Source/WebCore/rendering/RenderText.cpp
r79518 r79694 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
r79518 r79694 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
r79518 r79694 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.