Changeset 179734 in webkit
- Timestamp:
- Feb 5, 2015, 5:40:21 PM (12 years ago)
- Location:
- branches/safari-600.1.4.15-branch
- Files:
-
- 12 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/mac/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/WebCore.exp.in (modified) (2 diffs)
-
Source/WebCore/platform/text/LineBreakIteratorPoolICU.h (modified) (5 diffs)
-
Source/WebCore/platform/text/TextBreakIterator.cpp (modified) (2 diffs)
-
Source/WebCore/platform/text/TextBreakIterator.h (modified) (13 diffs)
-
Source/WebCore/rendering/RenderText.cpp (modified) (5 diffs)
-
Source/WebCore/rendering/RenderText.h (modified) (2 diffs)
-
Source/WebCore/rendering/SimpleLineLayout.cpp (modified) (2 diffs)
-
Source/WebCore/rendering/break_lines.h (modified) (6 diffs)
-
Source/WebCore/rendering/line/BreakingContextInlineHeaders.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-600.1.4.15-branch/LayoutTests/ChangeLog
r179730 r179734 1 2015-02-05 David Kilzer <ddkilzer@apple.com> 2 3 Merge r176473. 4 5 2014-11-21 Glenn Adams <glenn@skynav.com> and Myles C. Maxfield <mmaxfield@apple.com> 6 7 CSS3: line-break property support 8 https://bugs.webkit.org/show_bug.cgi?id=89235 9 10 Reviewed by Eric Seidel and Dave Hyatt. 11 12 * platform/mac/TestExpectations: Mark css3/line-break tests as passing. 13 1 14 2015-02-05 Lucas Forschler <lforschler@apple.com> 2 15 -
branches/safari-600.1.4.15-branch/LayoutTests/platform/mac/TestExpectations
r172752 r179734 1391 1391 webkit.org/b/133686 media/track/w3c/interfaces/TextTrackCue/startTime.html [ Pass Failure ] 1392 1392 webkit.org/b/133686 media/track/w3c/interfaces/TextTrackCue/track.html [ Pass Failure ] 1393 1394 # Verified passing, so override generic skip 1395 webkit.org/b/89235 css3/line-break [ Pass ] 1396 webkit.org/b/138115 css3/line-break/line-break-auto-hyphens.html [ ImageOnlyFailure ] 1397 webkit.org/b/138115 css3/line-break/line-break-auto-sound-marks.html [ ImageOnlyFailure ] -
branches/safari-600.1.4.15-branch/Source/WebCore/ChangeLog
r179730 r179734 1 2015-02-05 David Kilzer <ddkilzer@apple.com> 2 3 Merge r176473. 4 5 * rendering/SimpleLineLayout.cpp: 6 (WebCore::SimpleLineLayout::canUseFor): Change from 7 r176473 not listed in that ChangeLog. 8 (WebCore::SimpleLineLayout::createLineRuns): Call 9 nextBreakablePositionNonLoosely() in place of 10 nextBreakablePosition(). 11 12 2014-11-21 Glenn Adams <glenn@skynav.com> and Myles C. Maxfield <mmaxfield@apple.com> 13 14 Add support to -webkit-line-break property for CSS3 Text line-break property values and semantics. 15 https://bugs.webkit.org/show_bug.cgi?id=89235 16 17 Reviewed by Eric Seidel and Dave Hyatt. 18 19 This patch adds semantic support for the CSS3 line-break property (qua -webkit-line-break), 20 and enables testing on (apple) mac ports. Follow on patches will enable these tests on 21 other ports as they are incrementally verified. 22 23 See also wiki documentation at: 24 [1] http://trac.webkit.org/wiki/LineBreaking 25 [2] http://trac.webkit.org/wiki/LineBreakingCSS3Mapping 26 27 Tests: css3/line-break/line-break-auto-centered.html 28 css3/line-break/line-break-auto-half-kana.html 29 css3/line-break/line-break-auto-hyphens.html 30 css3/line-break/line-break-auto-inseparables.html 31 css3/line-break/line-break-auto-iteration-marks.html 32 css3/line-break/line-break-auto-postfixes.html 33 css3/line-break/line-break-auto-prefixes.html 34 css3/line-break/line-break-auto-sound-marks.html 35 css3/line-break/line-break-loose-centered.html 36 css3/line-break/line-break-loose-half-kana.html 37 css3/line-break/line-break-loose-hyphens.html 38 css3/line-break/line-break-loose-inseparables.html 39 css3/line-break/line-break-loose-iteration-marks.html 40 css3/line-break/line-break-loose-postfixes.html 41 css3/line-break/line-break-loose-prefixes.html 42 css3/line-break/line-break-loose-sound-marks.html 43 css3/line-break/line-break-normal-centered.html 44 css3/line-break/line-break-normal-half-kana.html 45 css3/line-break/line-break-normal-hyphens.html 46 css3/line-break/line-break-normal-inseparables.html 47 css3/line-break/line-break-normal-iteration-marks.html 48 css3/line-break/line-break-normal-postfixes.html 49 css3/line-break/line-break-normal-prefixes.html 50 css3/line-break/line-break-normal-sound-marks.html 51 css3/line-break/line-break-strict-centered.html 52 css3/line-break/line-break-strict-half-kana.html 53 css3/line-break/line-break-strict-hyphens.html 54 css3/line-break/line-break-strict-inseparables.html 55 css3/line-break/line-break-strict-iteration-marks.html 56 css3/line-break/line-break-strict-postfixes.html 57 css3/line-break/line-break-strict-prefixes.html 58 css3/line-break/line-break-strict-sound-marks.html 59 60 These tests were previously added in http://trac.webkit.org/changeset/143378, but skipped 61 in generic TestExpectations. In this patch, they are marked as Pass for the (apple) mac ports. 62 63 * platform/text/LineBreakIteratorPoolICU.h: 64 (WebCore::LineBreakIteratorPool::makeLocaleWithBreakKeyword): 65 Add static function to construct ICU locale argument (also used as pool key) with additional 66 break keyword. 67 (LineBreakIteratorPool): 68 (WebCore::LineBreakIteratorPool::take): 69 (WebCore::LineBreakIteratorPool::put): 70 Remove direct dependency from ICU library (and types), moving that dependency into 71 new {open,close}LineBreakIterator() functions (defined in TextBreakIteratorICU.cpp). 72 Update to take line break mode into account. 73 Create (and cache) different break iterators depending on line break mode (in addition to locale), 74 which entails expanding pool entry key format to optionally append "@break=" + 75 "loose"|"normal"|"strict" keyword to locale string. 76 77 * platform/text/TextBreakIterator.h: 78 (WebCore::LazyLineBreakIterator::LazyLineBreakIterator): 79 (WebCore::LazyLineBreakIterator::isLooseCJKMode): 80 (WebCore::LazyLineBreakIterator::get): 81 (WebCore::LazyLineBreakIterator::reset): 82 (LazyLineBreakIterator): 83 Define LineBreakIteratorMode enumeration for use in TextBreakIterator et al. 84 Add state member to indicate line break mode. 85 86 * platform/text/TextBreakIteratorICU.cpp: 87 (WebCore::acquireLineBreakIterator): 88 Use new line break mode when making iterator from pool. 89 Handle change of return type of LineBreakIteratorPool::take() to non-ICU type, 90 i.e., TextBreakIterator* instead of ICU's UBreakIterator*. 91 (WebCore::releaseLineBreakIterator): 92 Handle change of parameter type of LineBreakIteratorPool::put() to non-ICU type, 93 i.e., TextBreakIterator* instead of ICU's UBreakIterator*. 94 (WebCore): 95 (WebCore::isCJKLocale): 96 New functions for determining if CJK rules apply. 97 (WebCore::openLineBreakIterator): 98 New function for abstracting opening of ICU style line break iterator. This is now 99 used in LineBreakIteratorPoolICU.h rather than having direct ICU API dependency there. 100 This function also takes into account the line break mode. 101 102 Note that this function only calls ubrk_openRules() when the author has opted-in via 103 using the -webkit-line-break CSS property. Eventually, we would like to be able to 104 customize the rules that ICU's line breaking algorithm uses (especially for CJK text); 105 however, ubrk_openRules() currently parses its input string to create a DFA and is 106 therefore very slow. In fact, it's so slow that increasing our cache size in 107 LineBreakIteratorPool doesn't actually help enough. Also note that the default value 108 for the line-break CSS property is 'auto'. 109 (WebCore::closeLineBreakIterator): 110 (WebCore::mapLineIteratorModeToRules): 111 New function for abstracting closing of ICU style line break iterator. This is now 112 used in LineBreakIteratorPoolICU.h rather than having direct ICU API dependency there. 113 114 * rendering/RenderBlockLineLayout.cpp: 115 (WebCore::RenderBlock::LineBreaker::nextSegmentBreak): 116 Pass line break iterator mode flag when reseting LazyLineBreakIterator. 117 Add looseMode local variable to prevent need for computing under isBreakable(). 118 119 * rendering/RenderText.cpp: 120 (WebCore::mapLineBreakToIteratorMode): 121 Add implementation for mapLineBreakToIteratorMode(), used by both RenderText::computePreferredLogicalWidths 122 and RenderBlock::LineBreaker::nextLineBreak. 123 (WebCore): 124 (WebCore::RenderText::computePreferredLogicalWidths): 125 Ensure (lazy line) breakIterator is initialized for line break mode. 126 Ensure isBreakable() is passed loose mode flag to match behavior in RenderBlock::LineBreaker::nextLineBreak. 127 128 * rendering/RenderText.h: 129 (WebCore): 130 Add declaration for mapLineBreakToIteratorMode(), used by both RenderText::computePreferredLogicalWidths 131 and RenderBlock::LineBreaker::nextLineBreak. 132 133 * rendering/break_lines.cpp: 134 (WebCore): 135 Introduce (local) enum NBSPBehavior for expanding template on nextBreakablePosition. 136 (WebCore::isBreakableSpace): 137 Add externally specified loose mode parameter to prevent need to invoke line break iterator 138 accessor method on each invocation. Use new loose mode flavors off NBP functions. 139 (WebCore::needsLineBreakIterator): 140 Use enum NBSP behavior template parameter rather than boolean. 141 (WebCore::nextBreakablePositionNonLoosely): 142 Extend name to distinguish from loose flavor of this function. 143 (WebCore::nextBreakablePositionLoosely): 144 Add loose flavor of NBP invoked only when loose mode applies, in which case ASCII shortcut 145 table cannot be used. 146 (WebCore::nextBreakablePosition): 147 (WebCore::nextBreakablePositionIgnoringNBSP): 148 Use (renamed) non-loose flavor of NBP. 149 (WebCore::nextBreakablePositionLoose): 150 (WebCore::nextBreakablePositionIgnoringNBSPLoose): 151 Introduce loose flavor of NBP template expansions. 152 153 * rendering/break_lines.h: 154 (WebCore): 155 (WebCore::isBreakable): 156 Add externally specified loose mode parameter to prevent need to invoke line break iterator 157 accessor method on each invocation. 158 1 159 2015-02-05 Lucas Forschler <lforschler@apple.com> 2 160 -
branches/safari-600.1.4.15-branch/Source/WebCore/WebCore.exp.in
r179678 r179734 2546 2546 __ZN7WebCore11MemoryCache18pruneDeadResourcesEv 2547 2547 __ZN7WebCore11MemoryCache18pruneLiveResourcesEb 2548 __ZN7WebCore11isCJKLocaleERKN3WTF12AtomicStringE 2548 2549 __ZN7WebCore11isEndOfLineERKNS_15VisiblePositionE 2549 2550 __ZN7WebCore11prefetchDNSERKN3WTF6StringE … … 2665 2666 __ZN7WebCore24FloatingPointEnvironment25saveMainThreadEnvironmentEv 2666 2667 __ZN7WebCore24FloatingPointEnvironment6sharedEv 2667 __ZN7WebCore24acquireLineBreakIteratorEN3WTF10StringViewERKNS0_12AtomicStringEPKtj 2668 __ZN7WebCore24acquireLineBreakIteratorEN3WTF10StringViewERKNS0_12AtomicStringEPKtjNS_21LineBreakIteratorModeEb 2668 2669 __ZN7WebCore24charactersAroundPositionERKNS_15VisiblePositionERiS3_S3_ 2669 2670 __ZN7WebCore24createTemporaryDirectoryEP8NSString -
branches/safari-600.1.4.15-branch/Source/WebCore/platform/text/LineBreakIteratorPoolICU.h
r161309 r179734 27 27 #define LineBreakIteratorPoolICU_h 28 28 29 #include "TextBreakIterator.h" 29 30 #include "TextBreakIteratorInternalICU.h" 30 31 #include <unicode/ubrk.h> … … 35 36 #include <wtf/text/AtomicString.h> 36 37 #include <wtf/text/CString.h> 38 #include <wtf/text/StringBuilder.h> 37 39 38 40 namespace WebCore { … … 49 51 static PassOwnPtr<LineBreakIteratorPool> create() { return adoptPtr(new LineBreakIteratorPool); } 50 52 51 UBreakIterator* take(const AtomicString& locale)53 static String makeLocaleWithBreakKeyword(const AtomicString& locale, LineBreakIteratorMode mode) 52 54 { 53 UBreakIterator* iterator = 0; 55 StringBuilder localeWithKeyword; 56 localeWithKeyword.append(locale); 57 localeWithKeyword.appendLiteral("@break="); 58 switch (mode) { 59 case LineBreakIteratorModeUAX14: 60 ASSERT_NOT_REACHED(); 61 break; 62 case LineBreakIteratorModeUAX14Loose: 63 localeWithKeyword.appendLiteral("loose"); 64 break; 65 case LineBreakIteratorModeUAX14Normal: 66 localeWithKeyword.appendLiteral("normal"); 67 break; 68 case LineBreakIteratorModeUAX14Strict: 69 localeWithKeyword.appendLiteral("strict"); 70 break; 71 } 72 return localeWithKeyword.toString(); 73 } 74 75 TextBreakIterator* take(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK) 76 { 77 AtomicString localeWithOptionalBreakKeyword; 78 if (mode == LineBreakIteratorModeUAX14) 79 localeWithOptionalBreakKeyword = locale; 80 else 81 localeWithOptionalBreakKeyword = makeLocaleWithBreakKeyword(locale, mode); 82 83 TextBreakIterator* iterator = 0; 54 84 for (size_t i = 0; i < m_pool.size(); ++i) { 55 if (m_pool[i].first == locale ) {85 if (m_pool[i].first == localeWithOptionalBreakKeyword) { 56 86 iterator = m_pool[i].second; 57 87 m_pool.remove(i); … … 61 91 62 92 if (!iterator) { 63 UErrorCode openStatus = U_ZERO_ERROR; 64 bool localeIsEmpty = locale.isEmpty(); 65 iterator = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &openStatus); 66 // locale comes from a web page and it can be invalid, leading ICU 67 // to fail, in which case we fall back to the default locale. 68 if (!localeIsEmpty && U_FAILURE(openStatus)) { 69 openStatus = U_ZERO_ERROR; 70 iterator = ubrk_open(UBRK_LINE, currentTextBreakLocaleID(), 0, 0, &openStatus); 71 } 72 73 if (U_FAILURE(openStatus)) { 74 LOG_ERROR("ubrk_open failed with status %d", openStatus); 93 iterator = openLineBreakIterator(localeWithOptionalBreakKeyword, mode, isCJK); 94 if (!iterator) 75 95 return 0; 76 }77 96 } 78 97 79 98 ASSERT(!m_vendedIterators.contains(iterator)); 80 m_vendedIterators.set(iterator, locale );99 m_vendedIterators.set(iterator, localeWithOptionalBreakKeyword); 81 100 return iterator; 82 101 } 83 102 84 void put( UBreakIterator* iterator)103 void put(TextBreakIterator* iterator) 85 104 { 86 105 ASSERT_ARG(iterator, m_vendedIterators.contains(iterator)); 87 106 88 107 if (m_pool.size() == capacity) { 89 ubrk_close(m_pool[0].second);108 closeLineBreakIterator(m_pool[0].second); 90 109 m_pool.remove(0); 91 110 } … … 99 118 static const size_t capacity = 4; 100 119 101 typedef std::pair<AtomicString, UBreakIterator*> Entry;120 typedef std::pair<AtomicString, TextBreakIterator*> Entry; 102 121 typedef Vector<Entry, capacity> Pool; 103 122 Pool m_pool; 104 HashMap< UBreakIterator*, AtomicString> m_vendedIterators;123 HashMap<TextBreakIterator*, AtomicString> m_vendedIterators; 105 124 106 125 friend WTF::ThreadSpecific<LineBreakIteratorPool>::operator LineBreakIteratorPool*(); -
branches/safari-600.1.4.15-branch/Source/WebCore/platform/text/TextBreakIterator.cpp
r179730 r179734 257 257 } 258 258 259 TextBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength )260 { 261 TextBreakIterator* iterator = reinterpret_cast<TextBreakIterator*>(LineBreakIteratorPool::sharedPool().take(locale));259 TextBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode mode, bool isCJK) 260 { 261 TextBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale, mode, isCJK); 262 262 if (!iterator) 263 263 return nullptr; … … 270 270 ASSERT_ARG(iterator, iterator); 271 271 272 LineBreakIteratorPool::sharedPool().put(reinterpret_cast<UBreakIterator*>(iterator)); 272 LineBreakIteratorPool::sharedPool().put(iterator); 273 } 274 275 static const char* uax14Prologue = 276 "!!chain;" 277 "!!LBCMNoChain;" 278 "!!lookAheadHardBreak;"; 279 280 static const char* uax14AssignmentsBefore = 281 // explicitly enumerate $CJ since ICU versions prior to 49 don't support :LineBreak=Conditional_Japanese_Starter: 282 "$CJ = [" 283 #if (U_ICU_VERSION_MAJOR_NUM >= 4) && (U_ICU_VERSION_MINOR_NUM >= 9) 284 ":LineBreak=Conditional_Japanese_Starter:" 285 #else 286 "\\u3041\\u3043\\u3045\\u3047\\u3049\\u3063\\u3083\\u3085\\u3087\\u308E\\u3095\\u3096\\u30A1\\u30A3\\u30A5\\u30A7" 287 "\\u30A9\\u30C3\\u30E3\\u30E5\\u30E7\\u30EE\\u30F5\\u30F6\\u30FC" 288 "\\u31F0\\u31F1\\u31F2\\u31F3\\u31F4\\u31F5\\u31F6\\u31F7\\u31F8\\u31F9\\u31FA\\u31FB\\u31FC\\u31FD\\u31FE\\u31FF" 289 "\\uFF67\\uFF68\\uFF69\\uFF6A\\uFF6B\\uFF6C\\uFF6D\\uFF6E\\uFF6F\\uFF70" 290 #endif 291 "];"; 292 293 static const char* uax14AssignmentsCustomLooseCJK = 294 "$BA_SUB = [\\u2010\\u2013];" 295 "$EX_SUB = [\\u0021\\u003F\\uFF01\\uFF1F];" 296 "$ID_SUB = '';" 297 "$IN_SUB = [\\u2025\\u2026];" 298 "$IS_SUB = [\\u003A\\u003B];" 299 "$NS_SUB = [\\u203C\\u2047\\u2048\\u2049\\u3005\\u301C\\u303B\\u309D\\u309E\\u30A0\\u30FB\\u30FD\\u30FE\\uFF1A\\uFF1B\\uFF65];" 300 "$PO_SUB = [\\u0025\\u00A2\\u00B0\\u2030\\u2032\\u2033\\u2103\\uFF05\\uFFE0];" 301 "$PR_SUB = [\\u0024\\u00A3\\u00A5\\u20AC\\u2116\\uFF04\\uFFE1\\uFFE5];" 302 "$ID_ADD = [$CJ $BA_SUB $EX_SUB $IN_SUB $IS_SUB $NS_SUB $PO_SUB $PR_SUB];" 303 "$NS_ADD = '';"; 304 305 static const char* uax14AssignmentsCustomLooseNonCJK = 306 "$BA_SUB = '';" 307 "$EX_SUB = '';" 308 "$ID_SUB = '';" 309 "$IN_SUB = [\\u2025\\u2026];" 310 "$IS_SUB = '';" 311 "$NS_SUB = [\\u3005\\u303B\\u309D\\u309E\\u30FD\\u30FE];" 312 "$PO_SUB = '';" 313 "$PR_SUB = '';" 314 "$ID_ADD = [$CJ $IN_SUB $NS_SUB];" 315 "$NS_ADD = '';"; 316 317 static const char* uax14AssignmentsCustomNormalCJK = 318 "$BA_SUB = [\\u2010\\u2013];" 319 "$EX_SUB = '';" 320 "$IN_SUB = '';" 321 "$ID_SUB = '';" 322 "$IS_SUB = '';" 323 "$NS_SUB = [\\u301C\\u30A0];" 324 "$PO_SUB = '';" 325 "$PR_SUB = '';" 326 "$ID_ADD = [$CJ $BA_SUB $NS_SUB];" 327 "$NS_ADD = '';"; 328 329 static const char* uax14AssignmentsCustomNormalNonCJK = 330 "$BA_SUB = '';" 331 "$EX_SUB = '';" 332 "$ID_SUB = '';" 333 "$IN_SUB = '';" 334 "$IS_SUB = '';" 335 "$NS_SUB = '';" 336 "$PO_SUB = '';" 337 "$PR_SUB = '';" 338 "$ID_ADD = [$CJ];" 339 "$NS_ADD = '';"; 340 341 static const char* uax14AssignmentsCustomStrictCJK = 342 "$BA_SUB = '';" 343 "$EX_SUB = '';" 344 "$ID_SUB = '';" 345 "$IN_SUB = '';" 346 "$IS_SUB = '';" 347 "$NS_SUB = '';" 348 "$PO_SUB = '';" 349 "$PR_SUB = '';" 350 "$ID_ADD = '';" 351 "$NS_ADD = [$CJ];"; 352 353 #define uax14AssignmentsCustomStrictNonCJK uax14AssignmentsCustomStrictCJK 354 #define uax14AssignmentsCustomDefaultCJK uax14AssignmentsCustomNormalCJK 355 #define uax14AssignmentsCustomDefaultNonCJK uax14AssignmentsCustomStrictNonCJK 356 357 static const char* uax14AssignmentsAfter = 358 "$AI = [:LineBreak = Ambiguous:];" 359 "$AL = [:LineBreak = Alphabetic:];" 360 "$BA = [[:LineBreak = Break_After:] - $BA_SUB];" 361 "$BB = [:LineBreak = Break_Before:];" 362 "$BK = [:LineBreak = Mandatory_Break:];" 363 "$B2 = [:LineBreak = Break_Both:];" 364 "$CB = [:LineBreak = Contingent_Break:];" 365 "$CL = [:LineBreak = Close_Punctuation:];" 366 "$CM = [:LineBreak = Combining_Mark:];" 367 "$CP = [:LineBreak = Close_Parenthesis:];" 368 "$CR = [:LineBreak = Carriage_Return:];" 369 "$EX = [[:LineBreak = Exclamation:] - $EX_SUB];" 370 "$GL = [:LineBreak = Glue:];" 371 #if (U_ICU_VERSION_MAJOR_NUM >= 4) && (U_ICU_VERSION_MINOR_NUM >= 9) 372 "$HL = [:LineBreak = Hebrew_Letter:];" 373 #else 374 "$HL = [[:Hebrew:] & [:Letter:]];" 375 #endif 376 "$HY = [:LineBreak = Hyphen:];" 377 "$H2 = [:LineBreak = H2:];" 378 "$H3 = [:LineBreak = H3:];" 379 "$ID = [[[[:LineBreak = Ideographic:] - $CJ] $ID_ADD] - $ID_SUB];" 380 "$IN = [[:LineBreak = Inseparable:] - $IN_SUB];" 381 "$IS = [[:LineBreak = Infix_Numeric:] - $IS_SUB];" 382 "$JL = [:LineBreak = JL:];" 383 "$JV = [:LineBreak = JV:];" 384 "$JT = [:LineBreak = JT:];" 385 "$LF = [:LineBreak = Line_Feed:];" 386 "$NL = [:LineBreak = Next_Line:];" 387 "$NS = [[[[:LineBreak = Nonstarter:] - $CJ] $NS_ADD] - $NS_SUB];" 388 "$NU = [:LineBreak = Numeric:];" 389 "$OP = [:LineBreak = Open_Punctuation:];" 390 "$PO = [[:LineBreak = Postfix_Numeric:] - $PO_SUB];" 391 "$PR = [[:LineBreak = Prefix_Numeric:] - $PR_SUB];" 392 "$QU = [:LineBreak = Quotation:];" 393 "$SA = [:LineBreak = Complex_Context:];" 394 "$SG = [:LineBreak = Surrogate:];" 395 "$SP = [:LineBreak = Space:];" 396 "$SY = [:LineBreak = Break_Symbols:];" 397 "$WJ = [:LineBreak = Word_Joiner:];" 398 "$XX = [:LineBreak = Unknown:];" 399 "$ZW = [:LineBreak = ZWSpace:];" 400 "$dictionary = [:LineBreak = Complex_Context:];" 401 "$ALPlus = [$AL $AI $SA $SG $XX];" 402 "$ALcm = $ALPlus $CM*;" 403 "$BAcm = $BA $CM*;" 404 "$BBcm = $BB $CM*;" 405 "$B2cm = $B2 $CM*;" 406 "$CLcm = $CL $CM*;" 407 "$CPcm = $CP $CM*;" 408 "$EXcm = $EX $CM*;" 409 "$GLcm = $GL $CM*;" 410 "$HLcm = $HL $CM*;" 411 "$HYcm = $HY $CM*;" 412 "$H2cm = $H2 $CM*;" 413 "$H3cm = $H3 $CM*;" 414 "$IDcm = $ID $CM*;" 415 "$INcm = $IN $CM*;" 416 "$IScm = $IS $CM*;" 417 "$JLcm = $JL $CM*;" 418 "$JVcm = $JV $CM*;" 419 "$JTcm = $JT $CM*;" 420 "$NScm = $NS $CM*;" 421 "$NUcm = $NU $CM*;" 422 "$OPcm = $OP $CM*;" 423 "$POcm = $PO $CM*;" 424 "$PRcm = $PR $CM*;" 425 "$QUcm = $QU $CM*;" 426 "$SYcm = $SY $CM*;" 427 "$WJcm = $WJ $CM*;"; 428 429 static const char* uax14Forward = 430 "!!forward;" 431 "$CAN_CM = [^$SP $BK $CR $LF $NL $ZW $CM];" 432 "$CANT_CM = [$SP $BK $CR $LF $NL $ZW $CM];" 433 "$AL_FOLLOW_NOCM = [$BK $CR $LF $NL $ZW $SP];" 434 "$AL_FOLLOW_CM = [$CL $CP $EX $HL $IS $SY $WJ $GL $OP $QU $BA $HY $NS $IN $NU $ALPlus];" 435 "$AL_FOLLOW = [$AL_FOLLOW_NOCM $AL_FOLLOW_CM];" 436 "$LB4Breaks = [$BK $CR $LF $NL];" 437 "$LB4NonBreaks = [^$BK $CR $LF $NL];" 438 "$LB8Breaks = [$LB4Breaks $ZW];" 439 "$LB8NonBreaks = [[$LB4NonBreaks] - [$ZW]];" 440 "$LB18NonBreaks = [$LB8NonBreaks - [$SP]];" 441 "$LB18Breaks = [$LB8Breaks $SP];" 442 "$LB20NonBreaks = [$LB18NonBreaks - $CB];" 443 "$ALPlus $CM+;" 444 "$BA $CM+;" 445 "$BB $CM+;" 446 "$B2 $CM+;" 447 "$CL $CM+;" 448 "$CP $CM+;" 449 "$EX $CM+;" 450 "$GL $CM+;" 451 "$HL $CM+;" 452 "$HY $CM+;" 453 "$H2 $CM+;" 454 "$H3 $CM+;" 455 "$ID $CM+;" 456 "$IN $CM+;" 457 "$IS $CM+;" 458 "$JL $CM+;" 459 "$JV $CM+;" 460 "$JT $CM+;" 461 "$NS $CM+;" 462 "$NU $CM+;" 463 "$OP $CM+;" 464 "$PO $CM+;" 465 "$PR $CM+;" 466 "$QU $CM+;" 467 "$SY $CM+;" 468 "$WJ $CM+;" 469 "$CR $LF {100};" 470 "$LB4NonBreaks? $LB4Breaks {100};" 471 "$CAN_CM $CM* $LB4Breaks {100};" 472 "$CM+ $LB4Breaks {100};" 473 "$LB4NonBreaks [$SP $ZW];" 474 "$CAN_CM $CM* [$SP $ZW];" 475 "$CM+ [$SP $ZW];" 476 "$CAN_CM $CM+;" 477 "$CM+;" 478 "$CAN_CM $CM* $WJcm;" 479 "$LB8NonBreaks $WJcm;" 480 "$CM+ $WJcm;" 481 "$WJcm $CANT_CM;" 482 "$WJcm $CAN_CM $CM*;" 483 "$GLcm $CAN_CM $CM*;" 484 "$GLcm $CANT_CM;" 485 "[[$LB8NonBreaks] - [$SP $BA $HY]] $CM* $GLcm;" 486 "$CM+ GLcm;" 487 "$LB8NonBreaks $CL;" 488 "$CAN_CM $CM* $CL;" 489 "$CM+ $CL;" 490 "$LB8NonBreaks $CP;" 491 "$CAN_CM $CM* $CP;" 492 "$CM+ $CP;" 493 "$LB8NonBreaks $EX;" 494 "$CAN_CM $CM* $EX;" 495 "$CM+ $EX;" 496 "$LB8NonBreaks $IS;" 497 "$CAN_CM $CM* $IS;" 498 "$CM+ $IS;" 499 "$LB8NonBreaks $SY;" 500 "$CAN_CM $CM* $SY;" 501 "$CM+ $SY;" 502 "$OPcm $SP* $CAN_CM $CM*;" 503 "$OPcm $SP* $CANT_CM;" 504 "$OPcm $SP+ $CM+ $AL_FOLLOW?;" 505 "$QUcm $SP* $OPcm;" 506 "($CLcm | $CPcm) $SP* $NScm;" 507 "$B2cm $SP* $B2cm;" 508 "$LB18NonBreaks $CM* $QUcm;" 509 "$CM+ $QUcm;" 510 "$QUcm .?;" 511 "$QUcm $LB18NonBreaks $CM*;" 512 "$LB20NonBreaks $CM* ($BAcm | $HYcm | $NScm); " 513 "$BBcm [^$CB];" 514 "$BBcm $LB20NonBreaks $CM*;" 515 "$HLcm ($HYcm | $BAcm) [^$CB]?;" 516 "($ALcm | $HLcm) $INcm;" 517 "$CM+ $INcm;" 518 "$IDcm $INcm;" 519 "$INcm $INcm;" 520 "$NUcm $INcm;" 521 "$IDcm $POcm;" 522 "$ALcm $NUcm;" 523 "$HLcm $NUcm;" 524 "$CM+ $NUcm;" 525 "$NUcm $ALcm;" 526 "$NUcm $HLcm;" 527 "$PRcm $IDcm;" 528 "$PRcm ($ALcm | $HLcm);" 529 "$POcm ($ALcm | $HLcm);" 530 "($PRcm | $POcm)? ($OPcm | $HYcm)? $NUcm ($NUcm | $SYcm | $IScm)* ($CLcm | $CPcm)? ($PRcm | $POcm)?;" 531 "$JLcm ($JLcm | $JVcm | $H2cm | $H3cm);" 532 "($JVcm | $H2cm) ($JVcm | $JTcm);" 533 "($JTcm | $H3cm) $JTcm;" 534 "($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $INcm;" 535 "($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $POcm;" 536 "$PRcm ($JLcm | $JVcm | $JTcm | $H2cm | $H3cm);" 537 "($ALcm | $HLcm) ($ALcm | $HLcm);" 538 "$CM+ ($ALcm | $HLcm);" 539 "$IScm ($ALcm | $HLcm);" 540 "($ALcm | $HLcm | $NUcm) $OPcm;" 541 "$CM+ $OPcm;" 542 "$CPcm ($ALcm | $HLcm | $NUcm);"; 543 544 static const char* uax14Reverse = 545 "!!reverse;" 546 "$CM+ $ALPlus;" 547 "$CM+ $BA;" 548 "$CM+ $BB;" 549 "$CM+ $B2;" 550 "$CM+ $CL;" 551 "$CM+ $CP;" 552 "$CM+ $EX;" 553 "$CM+ $GL;" 554 "$CM+ $HL;" 555 "$CM+ $HY;" 556 "$CM+ $H2;" 557 "$CM+ $H3;" 558 "$CM+ $ID;" 559 "$CM+ $IN;" 560 "$CM+ $IS;" 561 "$CM+ $JL;" 562 "$CM+ $JV;" 563 "$CM+ $JT;" 564 "$CM+ $NS;" 565 "$CM+ $NU;" 566 "$CM+ $OP;" 567 "$CM+ $PO;" 568 "$CM+ $PR;" 569 "$CM+ $QU;" 570 "$CM+ $SY;" 571 "$CM+ $WJ;" 572 "$CM+;" 573 "$AL_FOLLOW $CM+ / ([$BK $CR $LF $NL $ZW {eof}] | $SP+ $CM+ $SP | $SP+ $CM* ([^$OP $CM $SP] | [$AL {eof}]));" 574 "[$PR] / $CM+ [$BK $CR $LF $NL $ZW $SP {eof}];" 575 "$LB4Breaks [$LB4NonBreaks-$CM];" 576 "$LB4Breaks $CM+ $CAN_CM;" 577 "$LF $CR;" 578 "[$SP $ZW] [$LB4NonBreaks-$CM];" 579 "[$SP $ZW] $CM+ $CAN_CM;" 580 "$CM+ $CAN_CM;" 581 "$CM* $WJ $CM* $CAN_CM;" 582 "$CM* $WJ [$LB8NonBreaks-$CM];" 583 "$CANT_CM $CM* $WJ;" 584 "$CM* $CAN_CM $CM* $WJ;" 585 "$CM* $GL $CM* [$LB8NonBreaks-[$CM $SP $BA $HY]];" 586 "$CANT_CM $CM* $GL;" 587 "$CM* $CAN_CM $CM* $GL;" 588 "$CL $CM+ $CAN_CM;" 589 "$CP $CM+ $CAN_CM;" 590 "$EX $CM+ $CAN_CM;" 591 "$IS $CM+ $CAN_CM;" 592 "$SY $CM+ $CAN_CM;" 593 "$CL [$LB8NonBreaks-$CM];" 594 "$CP [$LB8NonBreaks-$CM];" 595 "$EX [$LB8NonBreaks-$CM];" 596 "$IS [$LB8NonBreaks-$CM];" 597 "$SY [$LB8NonBreaks-$CM];" 598 "[$CL $CP $EX $IS $SY] $CM+ $SP+ $CM* $OP; " 599 "$CM* $CAN_CM $SP* $CM* $OP;" 600 "$CANT_CM $SP* $CM* $OP;" 601 "$AL_FOLLOW? $CM+ $SP $SP* $CM* $OP;" 602 "$AL_FOLLOW_NOCM $CM+ $SP+ $CM* $OP;" 603 "$CM* $AL_FOLLOW_CM $CM+ $SP+ $CM* $OP;" 604 "$SY $CM $SP+ $OP;" 605 "$CM* $OP $SP* $CM* $QU;" 606 "$CM* $NS $SP* $CM* ($CL | $CP);" 607 "$CM* $B2 $SP* $CM* $B2;" 608 "$CM* $QU $CM* $CAN_CM;" 609 "$CM* $QU $LB18NonBreaks;" 610 "$CM* $CAN_CM $CM* $QU;" 611 "$CANT_CM $CM* $QU;" 612 "$CM* ($BA | $HY | $NS) $CM* [$LB20NonBreaks-$CM];" 613 "$CM* [$LB20NonBreaks-$CM] $CM* $BB;" 614 "[^$CB] $CM* $BB;" 615 "[^$CB] $CM* ($HY | $BA) $CM* $HL;" 616 "$CM* $IN $CM* ($ALPlus | $HL);" 617 "$CM* $IN $CM* $ID;" 618 "$CM* $IN $CM* $IN;" 619 "$CM* $IN $CM* $NU;" 620 "$CM* $PO $CM* $ID;" 621 "$CM* $NU $CM* ($ALPlus | $HL);" 622 "$CM* ($ALPlus | $HL) $CM* $NU;" 623 "$CM* $ID $CM* $PR;" 624 "$CM* ($ALPlus | $HL) $CM* $PR;" 625 "$CM* ($ALPlus | $HL) $CM* $PO;" 626 "($CM* ($PR | $PO))? ($CM* ($CL | $CP))? ($CM* ($NU | $IS | $SY))* $CM* $NU ($CM* ($OP | $HY))? ($CM* ($PR | $PO))?;" 627 "$CM* ($H3 | $H2 | $JV | $JL) $CM* $JL;" 628 "$CM* ($JT | $JV) $CM* ($H2 | $JV);" 629 "$CM* $JT $CM* ($H3 | $JT);" 630 "$CM* $IN $CM* ($H3 | $H2 | $JT | $JV | $JL);" 631 "$CM* $PO $CM* ($H3 | $H2 | $JT | $JV | $JL);" 632 "$CM* ($H3 | $H2 | $JT | $JV | $JL) $CM* $PR;" 633 "$CM* ($ALPlus | $HL) $CM* ($ALPlus | $HL);" 634 "$CM* ($ALPlus | $HL) $CM* $IS;" 635 "$CM* $OP $CM* ($ALPlus | $HL | $NU);" 636 "$CM* ($ALPlus | $HL | $NU) $CM* $CP;"; 637 638 static const char* uax14SafeForward = 639 "!!safe_forward;" 640 "[$CM $OP $QU $CL $CP $B2 $PR $HY $BA $SP $dictionary]+ [^$CM $OP $QU $CL $CP $B2 $PR $HY $BA $dictionary];" 641 "$dictionary $dictionary;"; 642 643 static const char* uax14SafeReverse = 644 "!!safe_reverse;" 645 "$CM+ [^$CM $BK $CR $LF $NL $ZW $SP];" 646 "$CM+ $SP / .;" 647 "$SP+ $CM* $OP;" 648 "$SP+ $CM* $QU;" 649 "$SP+ $CM* ($CL | $CP);" 650 "$SP+ $CM* $B2;" 651 "$CM* ($HY | $BA) $CM* $HL;" 652 "($CM* ($IS | $SY))+ $CM* $NU;" 653 "($CL | $CP) $CM* ($NU | $IS | $SY);" 654 "$dictionary $dictionary;"; 655 656 static String mapLineIteratorModeToRules(LineBreakIteratorMode mode, bool isCJK) 657 { 658 StringBuilder rulesBuilder; 659 rulesBuilder.append(uax14Prologue); 660 rulesBuilder.append(uax14AssignmentsBefore); 661 switch (mode) { 662 case LineBreakIteratorModeUAX14: 663 rulesBuilder.append(isCJK ? uax14AssignmentsCustomDefaultCJK : uax14AssignmentsCustomDefaultNonCJK); 664 break; 665 case LineBreakIteratorModeUAX14Loose: 666 rulesBuilder.append(isCJK ? uax14AssignmentsCustomLooseCJK : uax14AssignmentsCustomLooseNonCJK); 667 break; 668 case LineBreakIteratorModeUAX14Normal: 669 rulesBuilder.append(isCJK ? uax14AssignmentsCustomNormalCJK : uax14AssignmentsCustomNormalNonCJK); 670 break; 671 case LineBreakIteratorModeUAX14Strict: 672 rulesBuilder.append(isCJK ? uax14AssignmentsCustomStrictCJK : uax14AssignmentsCustomStrictNonCJK); 673 break; 674 } 675 rulesBuilder.append(uax14AssignmentsAfter); 676 rulesBuilder.append(uax14Forward); 677 rulesBuilder.append(uax14Reverse); 678 rulesBuilder.append(uax14SafeForward); 679 rulesBuilder.append(uax14SafeReverse); 680 return rulesBuilder.toString(); 681 } 682 683 // Recognize BCP47 compliant primary language values of 'zh', 'ja', 'ko' 684 // (in any combination of case), optionally followed by subtags. Don't 685 // recognize 3-letter variants 'chi'/'zho', 'jpn', or 'kor' since BCP47 686 // requires use of shortest language tag. 687 bool isCJKLocale(const AtomicString& locale) 688 { 689 size_t length = locale.length(); 690 if (length < 2) 691 return false; 692 auto c1 = locale[0]; 693 auto c2 = locale[1]; 694 auto c3 = length == 2 ? 0 : locale[2]; 695 if (!c3 || c3 == '-' || c3 == '_' || c3 == '@') { 696 if (c1 == 'z' || c1 == 'Z') 697 return c2 == 'h' || c2 == 'H'; 698 if (c1 == 'j' || c1 == 'J') 699 return c2 == 'a' || c2 == 'A'; 700 if (c1 == 'k' || c1 == 'K') 701 return c2 == 'o' || c2 == 'O'; 702 } 703 return false; 704 } 705 706 TextBreakIterator* openLineBreakIterator(const AtomicString& locale, LineBreakIteratorMode mode, bool isCJK) 707 { 708 UBreakIterator* ubrkIter; 709 UErrorCode openStatus = U_ZERO_ERROR; 710 bool localeIsEmpty = locale.isEmpty(); 711 if (mode == LineBreakIteratorModeUAX14) 712 ubrkIter = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &openStatus); 713 else { 714 UParseError parseStatus; 715 auto rules = mapLineIteratorModeToRules(mode, isCJK); 716 ubrkIter = ubrk_openRules(StringView(rules).upconvertedCharacters(), rules.length(), 0, 0, &parseStatus, &openStatus); 717 } 718 // locale comes from a web page and it can be invalid, leading ICU 719 // to fail, in which case we fall back to the default locale. 720 if (!localeIsEmpty && U_FAILURE(openStatus)) { 721 openStatus = U_ZERO_ERROR; 722 ubrkIter = ubrk_open(UBRK_LINE, currentTextBreakLocaleID(), 0, 0, &openStatus); 723 } 724 725 if (U_FAILURE(openStatus)) { 726 LOG_ERROR("ubrk_open failed with status %d", openStatus); 727 return nullptr; 728 } 729 730 return reinterpret_cast<TextBreakIterator*>(ubrkIter); 731 } 732 733 void closeLineBreakIterator(TextBreakIterator*& iterator) 734 { 735 UBreakIterator* ubrkIter = reinterpret_cast<UBreakIterator*>(iterator); 736 ASSERT(ubrkIter); 737 ubrk_close(ubrkIter); 738 iterator = nullptr; 273 739 } 274 740 -
branches/safari-600.1.4.15-branch/Source/WebCore/platform/text/TextBreakIterator.h
r163310 r179734 31 31 32 32 // Note: The returned iterator is good only until you get another iterator, with the exception of acquireLineBreakIterator. 33 34 enum LineBreakIteratorMode { 35 LineBreakIteratorModeUAX14, 36 LineBreakIteratorModeUAX14Loose, 37 LineBreakIteratorModeUAX14Normal, 38 LineBreakIteratorModeUAX14Strict, 39 }; 33 40 34 41 // This is similar to character break iterator in most cases, but is subject to … … 41 48 TextBreakIterator* sentenceBreakIterator(StringView); 42 49 43 TextBreakIterator* acquireLineBreakIterator(StringView, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength );50 TextBreakIterator* acquireLineBreakIterator(StringView, const AtomicString& locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode, bool isCJK); 44 51 void releaseLineBreakIterator(TextBreakIterator*); 52 TextBreakIterator* openLineBreakIterator(const AtomicString& locale, LineBreakIteratorMode, bool isCJK); 53 void closeLineBreakIterator(TextBreakIterator*&); 45 54 46 55 int textBreakFirst(TextBreakIterator*); … … 56 65 const int TextBreakDone = -1; 57 66 67 bool isCJKLocale(const AtomicString&); 68 58 69 class LazyLineBreakIterator { 59 70 public: 60 71 LazyLineBreakIterator() 61 : m_iterator(0) 62 , m_cachedPriorContext(0) 72 : m_iterator(nullptr) 73 , m_cachedPriorContext(nullptr) 74 , m_mode(LineBreakIteratorModeUAX14) 63 75 , m_cachedPriorContextLength(0) 76 , m_isCJK(false) 64 77 { 65 78 resetPriorContext(); 66 79 } 67 80 68 LazyLineBreakIterator(String string, const AtomicString& locale = AtomicString() )81 LazyLineBreakIterator(String string, const AtomicString& locale = AtomicString(), LineBreakIteratorMode mode = LineBreakIteratorModeUAX14) 69 82 : m_string(string) 70 83 , m_locale(locale) 71 , m_iterator(0) 72 , m_cachedPriorContext(0) 84 , m_iterator(nullptr) 85 , m_cachedPriorContext(nullptr) 86 , m_mode(mode) 73 87 , m_cachedPriorContextLength(0) 74 88 { 75 89 resetPriorContext(); 90 m_isCJK = isCJKLocale(locale); 76 91 } 77 92 … … 83 98 84 99 String string() const { return m_string; } 100 bool isLooseCJKMode() const { return m_isCJK && m_mode == LineBreakIteratorModeUAX14Loose; } 85 101 86 102 UChar lastCharacter() const … … 89 105 return m_priorContext[1]; 90 106 } 107 91 108 UChar secondToLastCharacter() const 92 109 { … … 94 111 return m_priorContext[0]; 95 112 } 113 96 114 void setPriorContext(UChar last, UChar secondToLast) 97 115 { … … 100 118 m_priorContext[1] = last; 101 119 } 120 102 121 void updatePriorContext(UChar last) 103 122 { … … 106 125 m_priorContext[1] = last; 107 126 } 127 108 128 void resetPriorContext() 109 129 { … … 112 132 m_priorContext[1] = 0; 113 133 } 134 114 135 unsigned priorContextLength() const 115 136 { … … 123 144 return priorContextLength; 124 145 } 146 125 147 // Obtain text break iterator, possibly previously cached, where this iterator is (or has been) 126 148 // initialized to use the previously stored string as the primary breaking context and using … … 131 153 const UChar* priorContext = priorContextLength ? &m_priorContext[priorContextCapacity - priorContextLength] : 0; 132 154 if (!m_iterator) { 133 m_iterator = acquireLineBreakIterator(m_string, m_locale, priorContext, priorContextLength );155 m_iterator = acquireLineBreakIterator(m_string, m_locale, priorContext, priorContextLength, m_mode, m_isCJK); 134 156 m_cachedPriorContext = priorContext; 135 157 m_cachedPriorContextLength = priorContextLength; 136 158 } else if (priorContext != m_cachedPriorContext || priorContextLength != m_cachedPriorContextLength) { 137 this->resetStringAndReleaseIterator(m_string, m_locale);159 resetStringAndReleaseIterator(m_string, m_locale, m_mode); 138 160 return this->get(priorContextLength); 139 161 } 140 162 return m_iterator; 141 163 } 142 void resetStringAndReleaseIterator(String string, const AtomicString& locale) 164 165 void resetStringAndReleaseIterator(String string, const AtomicString& locale, LineBreakIteratorMode mode) 143 166 { 144 167 if (m_iterator) … … 146 169 m_string = string; 147 170 m_locale = locale; 148 m_iterator = 0; 149 m_cachedPriorContext = 0; 171 m_iterator = nullptr; 172 m_cachedPriorContext = nullptr; 173 m_mode = mode; 174 m_isCJK = isCJKLocale(locale); 150 175 m_cachedPriorContextLength = 0; 151 176 } … … 156 181 AtomicString m_locale; 157 182 TextBreakIterator* m_iterator; 183 const UChar* m_cachedPriorContext; 184 LineBreakIteratorMode m_mode; 185 unsigned m_cachedPriorContextLength; 158 186 UChar m_priorContext[priorContextCapacity]; 159 const UChar* m_cachedPriorContext; 160 unsigned m_cachedPriorContextLength; 187 bool m_isCJK; 161 188 }; 162 189 -
branches/safari-600.1.4.15-branch/Source/WebCore/rendering/RenderText.cpp
r179730 r179734 598 598 } 599 599 600 LineBreakIteratorMode mapLineBreakToIteratorMode(LineBreak lineBreak) 601 { 602 switch (lineBreak) { 603 case LineBreakAuto: 604 case LineBreakAfterWhiteSpace: 605 return LineBreakIteratorModeUAX14; 606 case LineBreakLoose: 607 return LineBreakIteratorModeUAX14Loose; 608 case LineBreakNormal: 609 return LineBreakIteratorModeUAX14Normal; 610 case LineBreakStrict: 611 return LineBreakIteratorModeUAX14Strict; 612 } 613 return LineBreakIteratorModeUAX14; 614 } 615 600 616 void RenderText::computePreferredLogicalWidths(float leadWidth) 601 617 { … … 674 690 float wordSpacing = font.wordSpacing(); 675 691 int len = textLength(); 676 LazyLineBreakIterator breakIterator(m_text, style.locale() );692 LazyLineBreakIterator breakIterator(m_text, style.locale(), mapLineBreakToIteratorMode(style.lineBreak())); 677 693 bool needsWordSpacing = false; 678 694 bool ignoringSpaces = false; … … 709 725 bool breakNBSP = style.autoWrap() && style.nbspMode() == SPACE; 710 726 bool breakAll = (style.wordBreak() == BreakAllWordBreak || style.wordBreak() == BreakWordBreak) && style.autoWrap(); 727 bool isLooseCJKMode = breakIterator.isLooseCJKMode(); 711 728 712 729 for (int i = 0; i < len; i++) { … … 756 773 } 757 774 758 bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP );775 bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP, isLooseCJKMode); 759 776 bool betweenWords = true; 760 777 int j = i; … … 764 781 break; 765 782 c = uncheckedCharacterAt(j); 766 if (isBreakable(breakIterator, j, nextBreakable, breakNBSP ) && characterAt(j - 1) != softHyphen)783 if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, isLooseCJKMode) && characterAt(j - 1) != softHyphen) 767 784 break; 768 785 if (breakAll) { -
branches/safari-600.1.4.15-branch/Source/WebCore/rendering/RenderText.h
r179133 r179734 28 28 #include "SimpleLineLayout.h" 29 29 #include "Text.h" 30 #include "TextBreakIterator.h" 30 31 #include <wtf/Forward.h> 31 32 … … 258 259 void applyTextTransform(const RenderStyle&, String&, UChar); 259 260 void makeCapitalized(String*, UChar previous); 261 LineBreakIteratorMode mapLineBreakToIteratorMode(LineBreak); 260 262 261 263 inline RenderText* Text::renderer() const -
branches/safari-600.1.4.15-branch/Source/WebCore/rendering/SimpleLineLayout.cpp
r170871 r179734 163 163 if (style.borderFit() == BorderFitLines) 164 164 return false; 165 if (style.lineBreak() != LineBreakAuto) 166 return false; 165 167 const RenderText& textRenderer = toRenderText(*flow.firstChild()); 166 168 if (flow.containsFloats()) { … … 284 286 wordEnd = wordStart + 1; 285 287 else 286 wordEnd = nextBreakablePosition <CharacterType, false>(lineBreakIterator, text, textLength, wordStart + 1);288 wordEnd = nextBreakablePositionNonLoosely<CharacterType, NBSPBehavior::IgnoreNBSP>(lineBreakIterator, text, textLength, wordStart + 1); 287 289 288 290 bool wordIsPrecededByWhitespace = style.collapseWhitespace && wordStart > lineStart && isWhitespace(text[wordStart - 1], style.preserveNewline); -
branches/safari-600.1.4.15-branch/Source/WebCore/rendering/break_lines.h
r163310 r179734 36 36 extern const unsigned char asciiLineBreakTable[][asciiLineBreakTableColumnCount]; 37 37 38 int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&, int pos); 39 int nextBreakablePosition(LazyLineBreakIterator&, int pos); 40 41 template<bool treatNoBreakSpaceAsBreak> 38 enum class NBSPBehavior { 39 IgnoreNBSP, 40 TreatNBSPAsBreak, 41 }; 42 43 template<NBSPBehavior nbspBehavior> 42 44 static inline bool isBreakableSpace(UChar ch) 43 45 { … … 48 50 return true; 49 51 case noBreakSpace: 50 return treatNoBreakSpaceAsBreak;52 return nbspBehavior == NBSPBehavior::TreatNBSPAsBreak; 51 53 default: 52 54 return false; … … 72 74 } 73 75 74 template< bool treatNoBreakSpaceAsBreak>76 template<NBSPBehavior nbspBehavior> 75 77 inline bool needsLineBreakIterator(UChar ch) 76 78 { 77 if ( treatNoBreakSpaceAsBreak)79 if (nbspBehavior == NBSPBehavior::TreatNBSPAsBreak) 78 80 return ch > asciiLineBreakTableLastChar; 79 81 return ch > asciiLineBreakTableLastChar && ch != noBreakSpace; 80 82 } 81 83 82 template<typename CharacterType, bool treatNoBreakSpaceAsBreak> 83 inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) 84 // When in non-loose mode, we can use the ASCII shortcut table. 85 template<typename CharacterType, NBSPBehavior nbspBehavior> 86 inline int nextBreakablePositionNonLoosely(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) 84 87 { 85 88 int len = static_cast<int>(length); … … 92 95 CharacterType ch = str[i]; 93 96 94 if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) 97 // Non-loose mode, so use ASCII shortcut (shouldBreakAfter) if not breakable space. 98 if (isBreakableSpace<nbspBehavior>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) 95 99 return i; 96 100 97 if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) { 101 // Non-loose mode, so conditionally use break iterator. 102 if (needsLineBreakIterator<nbspBehavior>(ch) || needsLineBreakIterator<nbspBehavior>(lastCh)) { 98 103 if (nextBreak < i) { 99 104 // Don't break if positioned at start of primary context and there is no prior context. … … 107 112 } 108 113 } 109 if (i == nextBreak && !isBreakableSpace< treatNoBreakSpaceAsBreak>(lastCh))114 if (i == nextBreak && !isBreakableSpace<nbspBehavior>(lastCh)) 110 115 return i; 111 116 } … … 118 123 } 119 124 125 // When in loose mode, we can't use the ASCII shortcut table since loose mode allows "$100" to break after '$' in content marked as CJK. 126 // N.B. It should be possible to combine the following with the non-loose version above by adding a LooseBehavior template parameter; 127 // however, when doing this, a 10% performance regression appeared on chromium-win (https://bugs.webkit.org/show_bug.cgi?id=89235#c112). 128 template<typename CharacterType, NBSPBehavior nbspBehavior> 129 static inline int nextBreakablePositionLoosely(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) 130 { 131 int len = static_cast<int>(length); 132 int nextBreak = -1; 133 134 CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter()); 135 unsigned priorContextLength = lazyBreakIterator.priorContextLength(); 136 for (int i = pos; i < len; i++) { 137 CharacterType ch = str[i]; 138 139 // Always loose mode, so don't use ASCII shortcut (shouldBreakAfter). 140 if (isBreakableSpace<nbspBehavior>(ch)) 141 return i; 142 143 // Always use line break iterator in loose mode. 144 if (nextBreak < i) { 145 // Don't break if positioned at start of primary context and there is no prior context. 146 if (i || priorContextLength) { 147 TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength); 148 if (breakIterator) { 149 nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength); 150 if (nextBreak >= 0) 151 nextBreak -= priorContextLength; 152 } 153 } 154 } 155 if (i == nextBreak && !isBreakableSpace<nbspBehavior>(lastCh)) 156 return i; 157 158 lastCh = ch; 159 } 160 161 return len; 162 } 163 164 inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos) 165 { 166 String string = lazyBreakIterator.string(); 167 if (string.is8Bit()) 168 return nextBreakablePositionNonLoosely<LChar, NBSPBehavior::TreatNBSPAsBreak>(lazyBreakIterator, string.characters8(), string.length(), pos); 169 return nextBreakablePositionNonLoosely<UChar, NBSPBehavior::TreatNBSPAsBreak>(lazyBreakIterator, string.characters16(), string.length(), pos); 170 } 171 120 172 inline int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos) 121 173 { 122 174 String string = lazyBreakIterator.string(); 123 175 if (string.is8Bit()) 124 return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos); 125 return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos); 126 } 127 128 inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos) 129 { 130 String string = lazyBreakIterator.string(); 131 if (string.is8Bit()) 132 return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos); 133 return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos); 134 } 135 136 inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP) 137 { 138 if (pos > nextBreakable) { 176 return nextBreakablePositionNonLoosely<LChar, NBSPBehavior::IgnoreNBSP>(lazyBreakIterator, string.characters8(), string.length(), pos); 177 return nextBreakablePositionNonLoosely<UChar, NBSPBehavior::IgnoreNBSP>(lazyBreakIterator, string.characters16(), string.length(), pos); 178 } 179 180 inline int nextBreakablePositionLoose(LazyLineBreakIterator& lazyBreakIterator, int pos) 181 { 182 String string = lazyBreakIterator.string(); 183 if (string.is8Bit()) 184 return nextBreakablePositionLoosely<LChar, NBSPBehavior::TreatNBSPAsBreak>(lazyBreakIterator, string.characters8(), string.length(), pos); 185 return nextBreakablePositionLoosely<UChar, NBSPBehavior::TreatNBSPAsBreak>(lazyBreakIterator, string.characters16(), string.length(), pos); 186 } 187 188 inline int nextBreakablePositionIgnoringNBSPLoose(LazyLineBreakIterator& lazyBreakIterator, int pos) 189 { 190 String string = lazyBreakIterator.string(); 191 if (string.is8Bit()) 192 return nextBreakablePositionLoosely<LChar, NBSPBehavior::IgnoreNBSP>(lazyBreakIterator, string.characters8(), string.length(), pos); 193 return nextBreakablePositionLoosely<UChar, NBSPBehavior::IgnoreNBSP>(lazyBreakIterator, string.characters16(), string.length(), pos); 194 } 195 196 inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP, bool isLooseMode) 197 { 198 if (pos <= nextBreakable) 199 return pos == nextBreakable; 200 201 if (isLooseMode) { 202 if (breakNBSP) 203 nextBreakable = nextBreakablePositionLoose(lazyBreakIterator, pos); 204 else 205 nextBreakable = nextBreakablePositionIgnoringNBSPLoose(lazyBreakIterator, pos); 206 } else { 139 207 if (breakNBSP) 140 208 nextBreakable = nextBreakablePosition(lazyBreakIterator, pos); -
branches/safari-600.1.4.15-branch/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h
r179722 r179734 629 629 bool breakAll = m_currentStyle->wordBreak() == BreakAllWordBreak && m_autoWrap; 630 630 float hyphenWidth = 0; 631 bool isLooseCJKMode = false; 631 632 632 633 if (isSVGText) { … … 640 641 m_renderTextInfo.m_font = &font; 641 642 m_renderTextInfo.m_layout = font.createLayout(renderText, m_width.currentWidth(), m_collapseWhiteSpace); 642 m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(renderText->text(), style.locale()); 643 m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(renderText->text(), style.locale(), mapLineBreakToIteratorMode(m_blockStyle.lineBreak())); 644 isLooseCJKMode = m_renderTextInfo.m_lineBreakIterator.isLooseCJKMode(); 643 645 } else if (m_renderTextInfo.m_layout && m_renderTextInfo.m_font != &font) { 644 646 m_renderTextInfo.m_font = &font; … … 681 683 682 684 int nextBreakablePosition = m_current.nextBreakablePosition(); 683 bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP )685 bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, isLooseCJKMode) 684 686 && (style.hyphens() != HyphensNone || (m_current.previousInSameNode() != softHyphen))); 685 687 m_current.setNextBreakablePosition(nextBreakablePosition);
Note:
See TracChangeset
for help on using the changeset viewer.