<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212235] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212235">212235</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2017-02-13 11:07:43 -0800 (Mon, 13 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update custom line breaking iterators to the latest version of Unicode
https://bugs.webkit.org/show_bug.cgi?id=168182

Reviewed by Zalan Bujtas.

Source/WebCore:

Clean up our breaking code to be more descriptive about the difference between
line-break: auto vs line-break: loose | normal | strict. The only difference is
that we have some hardcoded tables to speed up character iteration for
line-break: auto.

Tests: TestWebKitAPI WebKit2.LineBreaking

* rendering/BreakLines.h:
(WebCore::nextBreakablePosition):
(WebCore::nextBreakablePositionIgnoringNBSP):
(WebCore::nextBreakablePositionWithoutShortcut):
(WebCore::nextBreakablePositionIgnoringNBSPWithoutShortcut):
(WebCore::isBreakable):
(WebCore::nextBreakablePositionNonLoosely): Deleted.
(WebCore::nextBreakablePositionLoosely): Deleted.
(WebCore::nextBreakablePositionLoose): Deleted.
(WebCore::nextBreakablePositionIgnoringNBSPLoose): Deleted.
* rendering/RenderText.cpp:
(WebCore::RenderText::computePreferredLogicalWidths):
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::nextBreakablePositionInSegment):
* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::handleText):
(WebCore::BreakingContext::optimalLineBreakLocationForTrailingWord):

Source/WTF:

ICU 55.1 supports loose / normal / strict line breaking rules. The oldest platform we ship
on has a version of ICU &gt;= that one. Therefore, we don't need to compile our own rules;
we can just use ICU's rules.

* wtf/text/LineBreakIteratorPoolICU.h:
(WTF::LineBreakIteratorPool::makeLocaleWithBreakKeyword):
(WTF::LineBreakIteratorPool::take):
* wtf/text/TextBreakIterator.cpp:
(WTF::acquireLineBreakIterator):
(WTF::openLineBreakIterator):
(WTF::mapLineIteratorModeToRules): Deleted.
(WTF::isCJKLocale): Deleted.
* wtf/text/TextBreakIterator.h:
(WTF::LazyLineBreakIterator::LazyLineBreakIterator):
(WTF::LazyLineBreakIterator::mode):
(WTF::LazyLineBreakIterator::get):
(WTF::LazyLineBreakIterator::resetStringAndReleaseIterator):
(WTF::LazyLineBreakIterator::isLooseCJKMode): Deleted.

Tools:

Treat the system's ICU as the source of truth to compare breaking positions against.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/LineBreaking.mm: Added.
(generateJavaScriptForTest):
(breakingLocationsFromICU):
(testAFewStrings):
(TEST):
* TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg: Renamed from LayoutTests/css3/line-break/resources/AllAhem.svg.
* TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html: Added.

LayoutTests:

Migrated to TestWebKitAPI.

* css3/line-break/line-break-auto-centered-2-expected.html: Removed.
* css3/line-break/line-break-auto-centered-2.html: Removed.
* css3/line-break/line-break-auto-centered-expected.html: Removed.
* css3/line-break/line-break-auto-centered.html: Removed.
* css3/line-break/line-break-auto-half-kana-2-expected.html: Removed.
* css3/line-break/line-break-auto-half-kana-2.html: Removed.
* css3/line-break/line-break-auto-half-kana-3-expected.html: Removed.
* css3/line-break/line-break-auto-half-kana-3.html: Removed.
* css3/line-break/line-break-auto-half-kana-4-expected.html: Removed.
* css3/line-break/line-break-auto-half-kana-4.html: Removed.
* css3/line-break/line-break-auto-half-kana-5-expected.html: Removed.
* css3/line-break/line-break-auto-half-kana-5.html: Removed.
* css3/line-break/line-break-auto-half-kana-expected.html: Removed.
* css3/line-break/line-break-auto-half-kana.html: Removed.
* css3/line-break/line-break-auto-hyphens-expected.html: Removed.
* css3/line-break/line-break-auto-hyphens.html: Removed.
* css3/line-break/line-break-auto-inseparables-expected.html: Removed.
* css3/line-break/line-break-auto-inseparables.html: Removed.
* css3/line-break/line-break-auto-iteration-marks-expected.html: Removed.
* css3/line-break/line-break-auto-iteration-marks.html: Removed.
* css3/line-break/line-break-auto-postfixes-expected.html: Removed.
* css3/line-break/line-break-auto-postfixes.html: Removed.
* css3/line-break/line-break-auto-prefixes-expected.html: Removed.
* css3/line-break/line-break-auto-prefixes.html: Removed.
* css3/line-break/line-break-auto-sound-marks-expected.html: Removed.
* css3/line-break/line-break-auto-sound-marks.html: Removed.
* css3/line-break/line-break-loose-centered-2-expected.html: Removed.
* css3/line-break/line-break-loose-centered-2.html: Removed.
* css3/line-break/line-break-loose-centered-expected.html: Removed.
* css3/line-break/line-break-loose-centered.html: Removed.
* css3/line-break/line-break-loose-half-kana-2-expected.html: Removed.
* css3/line-break/line-break-loose-half-kana-2.html: Removed.
* css3/line-break/line-break-loose-half-kana-3-expected.html: Removed.
* css3/line-break/line-break-loose-half-kana-3.html: Removed.
* css3/line-break/line-break-loose-half-kana-4-expected.html: Removed.
* css3/line-break/line-break-loose-half-kana-4.html: Removed.
* css3/line-break/line-break-loose-half-kana-5-expected.html: Removed.
* css3/line-break/line-break-loose-half-kana-5.html: Removed.
* css3/line-break/line-break-loose-half-kana-expected.html: Removed.
* css3/line-break/line-break-loose-half-kana.html: Removed.
* css3/line-break/line-break-loose-hyphens-expected.html: Removed.
* css3/line-break/line-break-loose-hyphens.html: Removed.
* css3/line-break/line-break-loose-inseparables-expected.html: Removed.
* css3/line-break/line-break-loose-inseparables.html: Removed.
* css3/line-break/line-break-loose-iteration-marks-expected.html: Removed.
* css3/line-break/line-break-loose-iteration-marks.html: Removed.
* css3/line-break/line-break-loose-postfixes-expected.html: Removed.
* css3/line-break/line-break-loose-postfixes.html: Removed.
* css3/line-break/line-break-loose-prefixes-expected.html: Removed.
* css3/line-break/line-break-loose-prefixes.html: Removed.
* css3/line-break/line-break-loose-sound-marks-expected.html: Removed.
* css3/line-break/line-break-loose-sound-marks.html: Removed.
* css3/line-break/line-break-normal-centered-2-expected.html: Removed.
* css3/line-break/line-break-normal-centered-2.html: Removed.
* css3/line-break/line-break-normal-centered-expected.html: Removed.
* css3/line-break/line-break-normal-centered.html: Removed.
* css3/line-break/line-break-normal-half-kana-2-expected.html: Removed.
* css3/line-break/line-break-normal-half-kana-2.html: Removed.
* css3/line-break/line-break-normal-half-kana-3-expected.html: Removed.
* css3/line-break/line-break-normal-half-kana-3.html: Removed.
* css3/line-break/line-break-normal-half-kana-4-expected.html: Removed.
* css3/line-break/line-break-normal-half-kana-4.html: Removed.
* css3/line-break/line-break-normal-half-kana-5-expected.html: Removed.
* css3/line-break/line-break-normal-half-kana-5.html: Removed.
* css3/line-break/line-break-normal-half-kana-expected.html: Removed.
* css3/line-break/line-break-normal-half-kana.html: Removed.
* css3/line-break/line-break-normal-hyphens-expected.html: Removed.
* css3/line-break/line-break-normal-hyphens.html: Removed.
* css3/line-break/line-break-normal-inseparables-expected.html: Removed.
* css3/line-break/line-break-normal-inseparables.html: Removed.
* css3/line-break/line-break-normal-iteration-marks-expected.html: Removed.
* css3/line-break/line-break-normal-iteration-marks.html: Removed.
* css3/line-break/line-break-normal-postfixes-expected.html: Removed.
* css3/line-break/line-break-normal-postfixes.html: Removed.
* css3/line-break/line-break-normal-prefixes-expected.html: Removed.
* css3/line-break/line-break-normal-prefixes.html: Removed.
* css3/line-break/line-break-normal-sound-marks-expected.html: Removed.
* css3/line-break/line-break-normal-sound-marks.html: Removed.
* css3/line-break/line-break-strict-centered-2-expected.html: Removed.
* css3/line-break/line-break-strict-centered-2.html: Removed.
* css3/line-break/line-break-strict-centered-expected.html: Removed.
* css3/line-break/line-break-strict-centered.html: Removed.
* css3/line-break/line-break-strict-half-kana-2-expected.html: Removed.
* css3/line-break/line-break-strict-half-kana-2.html: Removed.
* css3/line-break/line-break-strict-half-kana-3-expected.html: Removed.
* css3/line-break/line-break-strict-half-kana-3.html: Removed.
* css3/line-break/line-break-strict-half-kana-4-expected.html: Removed.
* css3/line-break/line-break-strict-half-kana-4.html: Removed.
* css3/line-break/line-break-strict-half-kana-5-expected.html: Removed.
* css3/line-break/line-break-strict-half-kana-5.html: Removed.
* css3/line-break/line-break-strict-half-kana-expected.html: Removed.
* css3/line-break/line-break-strict-half-kana.html: Removed.
* css3/line-break/line-break-strict-hyphens-expected.html: Removed.
* css3/line-break/line-break-strict-hyphens.html: Removed.
* css3/line-break/line-break-strict-inseparables-expected.html: Removed.
* css3/line-break/line-break-strict-inseparables.html: Removed.
* css3/line-break/line-break-strict-iteration-marks-expected.html: Removed.
* css3/line-break/line-break-strict-iteration-marks.html: Removed.
* css3/line-break/line-break-strict-postfixes-expected.html: Removed.
* css3/line-break/line-break-strict-postfixes.html: Removed.
* css3/line-break/line-break-strict-prefixes-expected.html: Removed.
* css3/line-break/line-break-strict-prefixes.html: Removed.
* css3/line-break/line-break-strict-sound-marks-expected.html: Removed.
* css3/line-break/line-break-strict-sound-marks.html: Removed.
* platform/ios-simulator-wk1/TestExpectations:
* platform/ios-simulator/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorTestExpectations">trunk/LayoutTests/platform/ios-simulator/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk1TestExpectations">trunk/LayoutTests/platform/ios-simulator-wk1/TestExpectations</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextLineBreakIteratorPoolICUh">trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h</a></li>
<li><a href="#trunkSourceWTFwtftextTextBreakIteratorcpp">trunk/Source/WTF/wtf/text/TextBreakIterator.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextTextBreakIteratorh">trunk/Source/WTF/wtf/text/TextBreakIterator.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingBreakLinesh">trunk/Source/WebCore/rendering/BreakLines.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextcpp">trunk/Source/WebCore/rendering/RenderText.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp">trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderinglineBreakingContexth">trunk/Source/WebCore/rendering/line/BreakingContext.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreLineBreakingmm">trunk/Tools/TestWebKitAPI/Tests/WebCore/LineBreaking.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaAllAhemsvg">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaLineBreakinghtml">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li>trunk/LayoutTests/css3/line-break/</li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/LayoutTests/ChangeLog        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -1,3 +1,119 @@
</span><ins>+2017-02-13  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Update custom line breaking iterators to the latest version of Unicode
+        https://bugs.webkit.org/show_bug.cgi?id=168182
+
+        Reviewed by Zalan Bujtas.
+
+        Migrated to TestWebKitAPI.
+
+        * css3/line-break/line-break-auto-centered-2-expected.html: Removed.
+        * css3/line-break/line-break-auto-centered-2.html: Removed.
+        * css3/line-break/line-break-auto-centered-expected.html: Removed.
+        * css3/line-break/line-break-auto-centered.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-2-expected.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-2.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-3-expected.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-3.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-4-expected.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-4.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-5-expected.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-5.html: Removed.
+        * css3/line-break/line-break-auto-half-kana-expected.html: Removed.
+        * css3/line-break/line-break-auto-half-kana.html: Removed.
+        * css3/line-break/line-break-auto-hyphens-expected.html: Removed.
+        * css3/line-break/line-break-auto-hyphens.html: Removed.
+        * css3/line-break/line-break-auto-inseparables-expected.html: Removed.
+        * css3/line-break/line-break-auto-inseparables.html: Removed.
+        * css3/line-break/line-break-auto-iteration-marks-expected.html: Removed.
+        * css3/line-break/line-break-auto-iteration-marks.html: Removed.
+        * css3/line-break/line-break-auto-postfixes-expected.html: Removed.
+        * css3/line-break/line-break-auto-postfixes.html: Removed.
+        * css3/line-break/line-break-auto-prefixes-expected.html: Removed.
+        * css3/line-break/line-break-auto-prefixes.html: Removed.
+        * css3/line-break/line-break-auto-sound-marks-expected.html: Removed.
+        * css3/line-break/line-break-auto-sound-marks.html: Removed.
+        * css3/line-break/line-break-loose-centered-2-expected.html: Removed.
+        * css3/line-break/line-break-loose-centered-2.html: Removed.
+        * css3/line-break/line-break-loose-centered-expected.html: Removed.
+        * css3/line-break/line-break-loose-centered.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-2-expected.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-2.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-3-expected.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-3.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-4-expected.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-4.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-5-expected.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-5.html: Removed.
+        * css3/line-break/line-break-loose-half-kana-expected.html: Removed.
+        * css3/line-break/line-break-loose-half-kana.html: Removed.
+        * css3/line-break/line-break-loose-hyphens-expected.html: Removed.
+        * css3/line-break/line-break-loose-hyphens.html: Removed.
+        * css3/line-break/line-break-loose-inseparables-expected.html: Removed.
+        * css3/line-break/line-break-loose-inseparables.html: Removed.
+        * css3/line-break/line-break-loose-iteration-marks-expected.html: Removed.
+        * css3/line-break/line-break-loose-iteration-marks.html: Removed.
+        * css3/line-break/line-break-loose-postfixes-expected.html: Removed.
+        * css3/line-break/line-break-loose-postfixes.html: Removed.
+        * css3/line-break/line-break-loose-prefixes-expected.html: Removed.
+        * css3/line-break/line-break-loose-prefixes.html: Removed.
+        * css3/line-break/line-break-loose-sound-marks-expected.html: Removed.
+        * css3/line-break/line-break-loose-sound-marks.html: Removed.
+        * css3/line-break/line-break-normal-centered-2-expected.html: Removed.
+        * css3/line-break/line-break-normal-centered-2.html: Removed.
+        * css3/line-break/line-break-normal-centered-expected.html: Removed.
+        * css3/line-break/line-break-normal-centered.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-2-expected.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-2.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-3-expected.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-3.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-4-expected.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-4.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-5-expected.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-5.html: Removed.
+        * css3/line-break/line-break-normal-half-kana-expected.html: Removed.
+        * css3/line-break/line-break-normal-half-kana.html: Removed.
+        * css3/line-break/line-break-normal-hyphens-expected.html: Removed.
+        * css3/line-break/line-break-normal-hyphens.html: Removed.
+        * css3/line-break/line-break-normal-inseparables-expected.html: Removed.
+        * css3/line-break/line-break-normal-inseparables.html: Removed.
+        * css3/line-break/line-break-normal-iteration-marks-expected.html: Removed.
+        * css3/line-break/line-break-normal-iteration-marks.html: Removed.
+        * css3/line-break/line-break-normal-postfixes-expected.html: Removed.
+        * css3/line-break/line-break-normal-postfixes.html: Removed.
+        * css3/line-break/line-break-normal-prefixes-expected.html: Removed.
+        * css3/line-break/line-break-normal-prefixes.html: Removed.
+        * css3/line-break/line-break-normal-sound-marks-expected.html: Removed.
+        * css3/line-break/line-break-normal-sound-marks.html: Removed.
+        * css3/line-break/line-break-strict-centered-2-expected.html: Removed.
+        * css3/line-break/line-break-strict-centered-2.html: Removed.
+        * css3/line-break/line-break-strict-centered-expected.html: Removed.
+        * css3/line-break/line-break-strict-centered.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-2-expected.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-2.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-3-expected.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-3.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-4-expected.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-4.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-5-expected.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-5.html: Removed.
+        * css3/line-break/line-break-strict-half-kana-expected.html: Removed.
+        * css3/line-break/line-break-strict-half-kana.html: Removed.
+        * css3/line-break/line-break-strict-hyphens-expected.html: Removed.
+        * css3/line-break/line-break-strict-hyphens.html: Removed.
+        * css3/line-break/line-break-strict-inseparables-expected.html: Removed.
+        * css3/line-break/line-break-strict-inseparables.html: Removed.
+        * css3/line-break/line-break-strict-iteration-marks-expected.html: Removed.
+        * css3/line-break/line-break-strict-iteration-marks.html: Removed.
+        * css3/line-break/line-break-strict-postfixes-expected.html: Removed.
+        * css3/line-break/line-break-strict-postfixes.html: Removed.
+        * css3/line-break/line-break-strict-prefixes-expected.html: Removed.
+        * css3/line-break/line-break-strict-prefixes.html: Removed.
+        * css3/line-break/line-break-strict-sound-marks-expected.html: Removed.
+        * css3/line-break/line-break-strict-sound-marks.html: Removed.
+        * platform/ios-simulator-wk1/TestExpectations:
+        * platform/ios-simulator/TestExpectations:
+
</ins><span class="cx"> 2017-02-13  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         TestExpectations gardening for imported/w3c/web-platform-tests/html/semantics/text-level-semantics/the-a-element/a-download-click.html.
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -2335,13 +2335,6 @@
</span><span class="cx"> webkit.org/b/148806 imported/w3c/css/css-multicol-1/multicol-span-all-block-sibling-003.xht [ ImageOnlyFailure ]
</span><span class="cx"> webkit.org/b/148806 imported/w3c/css/css-multicol-1/multicol-span-all-margin-nested-firstchild-001.xht [ ImageOnlyFailure ]
</span><span class="cx"> 
</span><del>-# Flaky tests ( these tests were affected by https://bugs.webkit.org/show_bug.cgi?id=149320 )
-
-css3/line-break/line-break-loose-centered.html [ ImageOnlyFailure Pass ]
-css3/line-break/line-break-loose-postfixes.html [ ImageOnlyFailure Pass ]
-css3/line-break/line-break-loose-sound-marks.html [ ImageOnlyFailure Pass ]
-css3/line-break/line-break-normal-sound-marks.html [ ImageOnlyFailure Pass ]
-
</del><span class="cx"> # Enable &quot;aria-current&quot; test for iOS
</span><span class="cx"> webkit.org/b/149297 accessibility/aria-current.html [ Pass ]
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk1TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk1/TestExpectations (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk1/TestExpectations        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/LayoutTests/platform/ios-simulator-wk1/TestExpectations        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -673,7 +673,6 @@
</span><span class="cx"> css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html [ ImageOnlyFailure ]
</span><span class="cx"> css3/filters/backdrop/backdrop-filter-with-clip-path.html [ ImageOnlyFailure ]
</span><span class="cx"> css3/flexbox/content-height-with-scrollbars.html [ ImageOnlyFailure ]
</span><del>-css3/line-break/line-break-auto-centered-2.html [ ImageOnlyFailure ]
</del><span class="cx"> css3/masking/mask-repeat-space-border.html [ ImageOnlyFailure ]
</span><span class="cx"> 
</span><span class="cx"> # CSS tests that pass:
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WTF/ChangeLog        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-02-13  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Update custom line breaking iterators to the latest version of Unicode
+        https://bugs.webkit.org/show_bug.cgi?id=168182
+
+        Reviewed by Zalan Bujtas.
+
+        ICU 55.1 supports loose / normal / strict line breaking rules. The oldest platform we ship
+        on has a version of ICU &gt;= that one. Therefore, we don't need to compile our own rules;
+        we can just use ICU's rules.
+
+        * wtf/text/LineBreakIteratorPoolICU.h:
+        (WTF::LineBreakIteratorPool::makeLocaleWithBreakKeyword):
+        (WTF::LineBreakIteratorPool::take):
+        * wtf/text/TextBreakIterator.cpp:
+        (WTF::acquireLineBreakIterator):
+        (WTF::openLineBreakIterator):
+        (WTF::mapLineIteratorModeToRules): Deleted.
+        (WTF::isCJKLocale): Deleted.
+        * wtf/text/TextBreakIterator.h:
+        (WTF::LazyLineBreakIterator::LazyLineBreakIterator):
+        (WTF::LazyLineBreakIterator::mode):
+        (WTF::LazyLineBreakIterator::get):
+        (WTF::LazyLineBreakIterator::resetStringAndReleaseIterator):
+        (WTF::LazyLineBreakIterator::isLooseCJKMode): Deleted.
+
</ins><span class="cx"> 2017-02-10  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Xcode] WTF installs extra copies of two headers outside /usr/local/include/wtf
</span></span></pre></div>
<a id="trunkSourceWTFwtftextLineBreakIteratorPoolICUh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;TextBreakIterator.h&quot;
</span><ins>+#include &lt;unicode/uloc.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSpecific.h&gt;
</span><span class="lines">@@ -46,21 +47,46 @@
</span><span class="cx"> 
</span><span class="cx">     static AtomicString makeLocaleWithBreakKeyword(const AtomicString&amp; locale, LineBreakIteratorMode mode)
</span><span class="cx">     {
</span><ins>+        // The uloc functions model locales as char*, so we have to downconvert our AtomicString.
+        auto utf8Locale = locale.string().utf8();
+        if (!utf8Locale.length())
+            return locale;
+        Vector&lt;char&gt; scratchBuffer(utf8Locale.length() + 11, 0);
+        memcpy(scratchBuffer.data(), utf8Locale.data(), utf8Locale.length());
+
+        const char* keywordValue = nullptr;
</ins><span class="cx">         switch (mode) {
</span><span class="cx">         case LineBreakIteratorMode::Default:
</span><del>-            return locale;
</del><ins>+            // nullptr will cause any existing values to be removed.
+            break;
</ins><span class="cx">         case LineBreakIteratorMode::Loose:
</span><del>-            return makeString(locale, &quot;@break=loose&quot;);
</del><ins>+            keywordValue = &quot;loose&quot;;
+            break;
</ins><span class="cx">         case LineBreakIteratorMode::Normal:
</span><del>-            return makeString(locale, &quot;@break=normal&quot;);
</del><ins>+            keywordValue = &quot;normal&quot;;
+            break;
</ins><span class="cx">         case LineBreakIteratorMode::Strict:
</span><del>-            return makeString(locale, &quot;@break=strict&quot;);
</del><ins>+            keywordValue = &quot;strict&quot;;
+            break;
</ins><span class="cx">         }
</span><del>-        ASSERT_NOT_REACHED();
</del><ins>+
+        UErrorCode status = U_ZERO_ERROR;
+        int32_t lengthNeeded = uloc_setKeywordValue(&quot;lb&quot;, keywordValue, scratchBuffer.data(), scratchBuffer.size(), &amp;status);
+        if (U_SUCCESS(status))
+            return AtomicString::fromUTF8(scratchBuffer.data(), lengthNeeded);
+        if (status == U_BUFFER_OVERFLOW_ERROR) {
+            scratchBuffer.grow(lengthNeeded + 1);
+            memset(scratchBuffer.data() + utf8Locale.length(), 0, scratchBuffer.size() - utf8Locale.length());
+            status = U_ZERO_ERROR;
+            int32_t lengthNeeded2 = uloc_setKeywordValue(&quot;lb&quot;, keywordValue, scratchBuffer.data(), scratchBuffer.size(), &amp;status);
+            if (!U_SUCCESS(status) || lengthNeeded != lengthNeeded2)
+                return locale;
+            return AtomicString::fromUTF8(scratchBuffer.data(), lengthNeeded);
+        }
</ins><span class="cx">         return locale;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    UBreakIterator* take(const AtomicString&amp; locale, LineBreakIteratorMode mode, bool isCJK)
</del><ins>+    UBreakIterator* take(const AtomicString&amp; locale, LineBreakIteratorMode mode)
</ins><span class="cx">     {
</span><span class="cx">         auto localeWithOptionalBreakKeyword = makeLocaleWithBreakKeyword(locale, mode);
</span><span class="cx"> 
</span><span class="lines">@@ -74,7 +100,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!iterator) {
</span><del>-            iterator = openLineBreakIterator(localeWithOptionalBreakKeyword, mode, isCJK);
</del><ins>+            iterator = openLineBreakIterator(localeWithOptionalBreakKeyword);
</ins><span class="cx">             if (!iterator)
</span><span class="cx">                 return nullptr;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWTFwtftextTextBreakIteratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/TextBreakIterator.cpp (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/TextBreakIterator.cpp        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WTF/wtf/text/TextBreakIterator.cpp        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -303,9 +303,9 @@
</span><span class="cx">     return setTextForIterator(*staticCursorMovementIterator, string);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-UBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString&amp; locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode mode, bool isCJK)
</del><ins>+UBreakIterator* acquireLineBreakIterator(StringView string, const AtomicString&amp; locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode mode)
</ins><span class="cx"> {
</span><del>-    UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale, mode, isCJK);
</del><ins>+    UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale, mode);
</ins><span class="cx">     if (!iterator)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -319,479 +319,11 @@
</span><span class="cx">     LineBreakIteratorPool::sharedPool().put(iterator);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const char* uax14Prologue =
-    &quot;!!chain;&quot;
-    &quot;!!LBCMNoChain;&quot;
-    &quot;!!lookAheadHardBreak;&quot;;
-
-static const char* uax14AssignmentsBefore =
-    // explicitly enumerate $CJ since ICU versions prior to 49 don't support :LineBreak=Conditional_Japanese_Starter:
-    &quot;$CJ = [&quot;
-#if (U_ICU_VERSION_MAJOR_NUM &gt;= 4) &amp;&amp; (U_ICU_VERSION_MINOR_NUM &gt;= 9)
-    &quot;:LineBreak=Conditional_Japanese_Starter:&quot;
-#else
-    &quot;\\u3041\\u3043\\u3045\\u3047\\u3049\\u3063\\u3083\\u3085\\u3087\\u308E\\u3095\\u3096\\u30A1\\u30A3\\u30A5\\u30A7&quot;
-    &quot;\\u30A9\\u30C3\\u30E3\\u30E5\\u30E7\\u30EE\\u30F5\\u30F6\\u30FC&quot;
-    &quot;\\u31F0\\u31F1\\u31F2\\u31F3\\u31F4\\u31F5\\u31F6\\u31F7\\u31F8\\u31F9\\u31FA\\u31FB\\u31FC\\u31FD\\u31FE\\u31FF&quot;
-    &quot;\\uFF67\\uFF68\\uFF69\\uFF6A\\uFF6B\\uFF6C\\uFF6D\\uFF6E\\uFF6F\\uFF70&quot;
-#endif
-    &quot;];&quot;;
-
-static const char* uax14AssignmentsCustomLooseCJK =
-    &quot;$BA_SUB = [\\u2010\\u2013];&quot;
-    &quot;$EX_SUB = [\\u0021\\u003F\\uFF01\\uFF1F];&quot;
-    &quot;$ID_SUB = '';&quot;
-    &quot;$IN_SUB = [\\u2025\\u2026];&quot;
-    &quot;$IS_SUB = [\\u003A\\u003B];&quot;
-    &quot;$NS_SUB = [\\u203C\\u2047\\u2048\\u2049\\u3005\\u301C\\u303B\\u309D\\u309E\\u30A0\\u30FB\\u30FD\\u30FE\\uFF1A\\uFF1B\\uFF65];&quot;
-    &quot;$PO_SUB = [\\u0025\\u00A2\\u00B0\\u2030\\u2032\\u2033\\u2103\\uFF05\\uFFE0];&quot;
-    &quot;$PR_SUB = [\\u0024\\u00A3\\u00A5\\u20AC\\u2116\\uFF04\\uFFE1\\uFFE5];&quot;
-    &quot;$ID_ADD = [$CJ $BA_SUB $EX_SUB $IN_SUB $IS_SUB $NS_SUB $PO_SUB $PR_SUB];&quot;
-    &quot;$NS_ADD = '';&quot;;
-
-static const char* uax14AssignmentsCustomLooseNonCJK =
-    &quot;$BA_SUB = '';&quot;
-    &quot;$EX_SUB = '';&quot;
-    &quot;$ID_SUB = '';&quot;
-    &quot;$IN_SUB = [\\u2025\\u2026];&quot;
-    &quot;$IS_SUB = '';&quot;
-    &quot;$NS_SUB = [\\u3005\\u303B\\u309D\\u309E\\u30FD\\u30FE];&quot;
-    &quot;$PO_SUB = '';&quot;
-    &quot;$PR_SUB = '';&quot;
-    &quot;$ID_ADD = [$CJ $IN_SUB $NS_SUB];&quot;
-    &quot;$NS_ADD = '';&quot;;
-
-static const char* uax14AssignmentsCustomNormalCJK =
-    &quot;$BA_SUB = [\\u2010\\u2013];&quot;
-    &quot;$EX_SUB = '';&quot;
-    &quot;$IN_SUB = '';&quot;
-    &quot;$ID_SUB = '';&quot;
-    &quot;$IS_SUB = '';&quot;
-    &quot;$NS_SUB = [\\u301C\\u30A0];&quot;
-    &quot;$PO_SUB = '';&quot;
-    &quot;$PR_SUB = '';&quot;
-    &quot;$ID_ADD = [$CJ $BA_SUB $NS_SUB];&quot;
-    &quot;$NS_ADD = '';&quot;;
-
-static const char* uax14AssignmentsCustomNormalNonCJK =
-    &quot;$BA_SUB = '';&quot;
-    &quot;$EX_SUB = '';&quot;
-    &quot;$ID_SUB = '';&quot;
-    &quot;$IN_SUB = '';&quot;
-    &quot;$IS_SUB = '';&quot;
-    &quot;$NS_SUB = '';&quot;
-    &quot;$PO_SUB = '';&quot;
-    &quot;$PR_SUB = '';&quot;
-    &quot;$ID_ADD = [$CJ];&quot;
-    &quot;$NS_ADD = '';&quot;;
-
-static const char* uax14AssignmentsCustomStrictCJK =
-    &quot;$BA_SUB = '';&quot;
-    &quot;$EX_SUB = '';&quot;
-    &quot;$ID_SUB = '';&quot;
-    &quot;$IN_SUB = '';&quot;
-    &quot;$IS_SUB = '';&quot;
-    &quot;$NS_SUB = '';&quot;
-    &quot;$PO_SUB = '';&quot;
-    &quot;$PR_SUB = '';&quot;
-    &quot;$ID_ADD = '';&quot;
-    &quot;$NS_ADD = [$CJ];&quot;;
-
-#define uax14AssignmentsCustomStrictNonCJK      uax14AssignmentsCustomStrictCJK
-#define uax14AssignmentsCustomDefaultCJK        uax14AssignmentsCustomNormalCJK
-#define uax14AssignmentsCustomDefaultNonCJK     uax14AssignmentsCustomStrictNonCJK
-
-static const char* uax14AssignmentsAfter =
-    &quot;$AI = [:LineBreak = Ambiguous:];&quot;
-    &quot;$AL = [:LineBreak = Alphabetic:];&quot;
-    &quot;$BA = [[:LineBreak = Break_After:] - $BA_SUB];&quot;
-    &quot;$BB = [:LineBreak = Break_Before:];&quot;
-    &quot;$BK = [:LineBreak = Mandatory_Break:];&quot;
-    &quot;$B2 = [:LineBreak = Break_Both:];&quot;
-    &quot;$CB = [:LineBreak = Contingent_Break:];&quot;
-    &quot;$CL = [:LineBreak = Close_Punctuation:];&quot;
-    &quot;$CM = [:LineBreak = Combining_Mark:];&quot;
-    &quot;$CP = [:LineBreak = Close_Parenthesis:];&quot;
-    &quot;$CR = [:LineBreak = Carriage_Return:];&quot;
-    &quot;$EX = [[:LineBreak = Exclamation:] - $EX_SUB];&quot;
-    &quot;$GL = [:LineBreak = Glue:];&quot;
-#if (U_ICU_VERSION_MAJOR_NUM &gt;= 4) &amp;&amp; (U_ICU_VERSION_MINOR_NUM &gt;= 9)
-    &quot;$HL = [:LineBreak = Hebrew_Letter:];&quot;
-#else
-    &quot;$HL = [[:Hebrew:] &amp; [:Letter:]];&quot;
-#endif
-    &quot;$HY = [:LineBreak = Hyphen:];&quot;
-    &quot;$H2 = [:LineBreak = H2:];&quot;
-    &quot;$H3 = [:LineBreak = H3:];&quot;
-    &quot;$ID = [[[[:LineBreak = Ideographic:] - $CJ] $ID_ADD] - $ID_SUB];&quot;
-    &quot;$IN = [[:LineBreak = Inseparable:] - $IN_SUB];&quot;
-    &quot;$IS = [[:LineBreak = Infix_Numeric:] - $IS_SUB];&quot;
-    &quot;$JL = [:LineBreak = JL:];&quot;
-    &quot;$JV = [:LineBreak = JV:];&quot;
-    &quot;$JT = [:LineBreak = JT:];&quot;
-    &quot;$LF = [:LineBreak = Line_Feed:];&quot;
-    &quot;$NL = [:LineBreak = Next_Line:];&quot;
-    &quot;$NS = [[[[:LineBreak = Nonstarter:] - $CJ] $NS_ADD] - $NS_SUB];&quot;
-    &quot;$NU = [:LineBreak = Numeric:];&quot;
-    &quot;$OP = [:LineBreak = Open_Punctuation:];&quot;
-    &quot;$PO = [[:LineBreak = Postfix_Numeric:] - $PO_SUB];&quot;
-    &quot;$PR = [[:LineBreak = Prefix_Numeric:] - $PR_SUB];&quot;
-    &quot;$QU = [:LineBreak = Quotation:];&quot;
-    &quot;$RI = [\\U0001F1E6-\\U0001F1FF];&quot;
-    &quot;$SA = [:LineBreak = Complex_Context:];&quot;
-    &quot;$SG = [:LineBreak = Surrogate:];&quot;
-    &quot;$SP = [:LineBreak = Space:];&quot;
-    &quot;$SY = [:LineBreak = Break_Symbols:];&quot;
-    &quot;$WJ = [:LineBreak = Word_Joiner:];&quot;
-    &quot;$XX = [:LineBreak = Unknown:];&quot;
-    &quot;$ZW = [:LineBreak = ZWSpace:];&quot;
-    &quot;$ZWJ = \\u200D;&quot;
-    &quot;$EmojiVar = \\uFE0F;&quot;
-#if ADDITIONAL_EMOJI_SUPPORT
-    &quot;$EmojiForSeqs = [\\u2640 \\u2642 \\u26F9 \\u2764 \\U0001F308 \\U0001F3C3-\\U0001F3C4 \\U0001F3CA-\\U0001F3CC \\U0001F3F3 \\U0001F441 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F46F \\U0001F471 \\U0001F473 \\U0001F477 \\U0001F481-\\U0001F482 \\U0001F486-\\U0001F487 \\U0001F48B \\U0001F575 \\U0001F5E8 \\U0001F645-\\U0001F647 \\U0001F64B \\U0001F64D-\\U0001F64E \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\u2695-\\u2696 \\u2708 \\U0001F33E \\U0001F373 \\U0001F393 \\U0001F3A4 \\U0001F3A8 \\U0001F3EB \\U0001F3ED \\U0001F4BB-\\U0001F4BC \\U0001F527 \\U0001F52C \\U0001F680 \\U0001F692 \\U0001F926 \\U0001F937-\\U0001F939 \\U0001F93C-\\U0001F93E];&quot; // Emoji that participate in ZWJ sequences
-    &quot;$EmojiForMods = [\\u261D \\u26F9 \\u270A-\\u270D \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3CA \\U0001F3CB \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F575 \\U0001F590 \\U0001F595 \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0 \\U0001F918 \\U0001F3C2 \\U0001F3C7 \\U0001F3CC \\U0001F574 \\U0001F57A \\U0001F6CC \\U0001F919-\\U0001F91E \\U0001F926 \\U0001F930 \\U0001F933-\\U0001F939 \\U0001F93C-\\U0001F93E] ;&quot; // Emoji that take Fitzpatrick modifiers
-#else
-    &quot;$EmojiForSeqs = [\\u2764 \\U0001F466-\\U0001F469 \\U0001F48B];&quot;
-    &quot;$EmojiForMods = [\\u261D \\u270A-\\u270C \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0] ;&quot; // Emoji that take Fitzpatrick modifiers
-#endif
-    &quot;$EmojiMods = [\\U0001F3FB-\\U0001F3FF];&quot;
-    &quot;$dictionary = [:LineBreak = Complex_Context:];&quot;
-    &quot;$ALPlus = [$AL $AI $SA $SG $XX];&quot;
-    &quot;$ALcm = $ALPlus $CM*;&quot;
-    &quot;$BAcm = $BA $CM*;&quot;
-    &quot;$BBcm = $BB $CM*;&quot;
-    &quot;$B2cm = $B2 $CM*;&quot;
-    &quot;$CLcm = $CL $CM*;&quot;
-    &quot;$CPcm = $CP $CM*;&quot;
-    &quot;$EXcm = $EX $CM*;&quot;
-    &quot;$GLcm = $GL $CM*;&quot;
-    &quot;$HLcm = $HL $CM*;&quot;
-    &quot;$HYcm = $HY $CM*;&quot;
-    &quot;$H2cm = $H2 $CM*;&quot;
-    &quot;$H3cm = $H3 $CM*;&quot;
-    &quot;$IDcm = $ID $CM*;&quot;
-    &quot;$INcm = $IN $CM*;&quot;
-    &quot;$IScm = $IS $CM*;&quot;
-    &quot;$JLcm = $JL $CM*;&quot;
-    &quot;$JVcm = $JV $CM*;&quot;
-    &quot;$JTcm = $JT $CM*;&quot;
-    &quot;$NScm = $NS $CM*;&quot;
-    &quot;$NUcm = $NU $CM*;&quot;
-    &quot;$OPcm = $OP $CM*;&quot;
-    &quot;$POcm = $PO $CM*;&quot;
-    &quot;$PRcm = $PR $CM*;&quot;
-    &quot;$QUcm = $QU $CM*;&quot;
-    &quot;$RIcm = $RI $CM*;&quot;
-    &quot;$SYcm = $SY $CM*;&quot;
-    &quot;$WJcm = $WJ $CM*;&quot;;
-
-static const char* uax14Forward =
-    &quot;!!forward;&quot;
-    &quot;$CAN_CM = [^$SP $BK $CR $LF $NL $ZW $CM];&quot;
-    &quot;$CANT_CM = [$SP $BK $CR $LF $NL $ZW $CM];&quot;
-    &quot;$AL_FOLLOW_NOCM = [$BK $CR $LF $NL $ZW $SP];&quot;
-    &quot;$AL_FOLLOW_CM = [$CL $CP $EX $HL $IS $SY $WJ $GL $OP $QU $BA $HY $NS $IN $NU $ALPlus];&quot;
-    &quot;$AL_FOLLOW = [$AL_FOLLOW_NOCM $AL_FOLLOW_CM];&quot;
-    &quot;$LB4Breaks = [$BK $CR $LF $NL];&quot;
-    &quot;$LB4NonBreaks = [^$BK $CR $LF $NL];&quot;
-    &quot;$LB8Breaks = [$LB4Breaks $ZW];&quot;
-    &quot;$LB8NonBreaks = [[$LB4NonBreaks] - [$ZW]];&quot;
-    &quot;$LB18NonBreaks = [$LB8NonBreaks - [$SP]];&quot;
-    &quot;$LB18Breaks = [$LB8Breaks $SP];&quot;
-    &quot;$LB20NonBreaks = [$LB18NonBreaks - $CB];&quot;
-    &quot;$ALPlus $CM+;&quot;
-    &quot;$BA $CM+;&quot;
-    &quot;$BB $CM+;&quot;
-    &quot;$B2 $CM+;&quot;
-    &quot;$CL $CM+;&quot;
-    &quot;$CP $CM+;&quot;
-    &quot;$EX $CM+;&quot;
-    &quot;$GL $CM+;&quot;
-    &quot;$HL $CM+;&quot;
-    &quot;$HY $CM+;&quot;
-    &quot;$H2 $CM+;&quot;
-    &quot;$H3 $CM+;&quot;
-    &quot;$ID $CM+;&quot;
-    &quot;$IN $CM+;&quot;
-    &quot;$IS $CM+;&quot;
-    &quot;$JL $CM+;&quot;
-    &quot;$JV $CM+;&quot;
-    &quot;$JT $CM+;&quot;
-    &quot;$NS $CM+;&quot;
-    &quot;$NU $CM+;&quot;
-    &quot;$OP $CM+;&quot;
-    &quot;$PO $CM+;&quot;
-    &quot;$PR $CM+;&quot;
-    &quot;$QU $CM+;&quot;
-    &quot;$RI $CM+;&quot;
-    &quot;$SY $CM+;&quot;
-    &quot;$WJ $CM+;&quot;
-    &quot;$CR $LF {100};&quot;
-    &quot;$LB4NonBreaks? $LB4Breaks {100};&quot;
-    &quot;$CAN_CM $CM* $LB4Breaks {100};&quot;
-    &quot;$CM+ $LB4Breaks {100};&quot;
-    &quot;$LB4NonBreaks [$SP $ZW];&quot;
-    &quot;$CAN_CM $CM* [$SP $ZW];&quot;
-    &quot;$CM+ [$SP $ZW];&quot;
-    &quot;$EmojiForSeqs $EmojiVar? $EmojiMods? $ZWJ $EmojiForSeqs;&quot;
-    &quot;$CAN_CM $CM+;&quot;
-    &quot;$CM+;&quot;
-    &quot;$CAN_CM $CM* $WJcm;&quot;
-    &quot;$LB8NonBreaks $WJcm;&quot;
-    &quot;$CM+ $WJcm;&quot;
-    &quot;$WJcm $CANT_CM;&quot;
-    &quot;$WJcm $CAN_CM $CM*;&quot;
-    &quot;$GLcm $CAN_CM $CM*;&quot;
-    &quot;$GLcm $CANT_CM;&quot;
-    &quot;[[$LB8NonBreaks] - [$SP $BA $HY]] $CM* $GLcm;&quot;
-    &quot;$CM+ GLcm;&quot;
-    &quot;$LB8NonBreaks $CL;&quot;
-    &quot;$CAN_CM $CM* $CL;&quot;
-    &quot;$CM+ $CL;&quot;
-    &quot;$LB8NonBreaks $CP;&quot;
-    &quot;$CAN_CM $CM* $CP;&quot;
-    &quot;$CM+ $CP;&quot;
-    &quot;$LB8NonBreaks $EX;&quot;
-    &quot;$CAN_CM $CM* $EX;&quot;
-    &quot;$CM+ $EX;&quot;
-    &quot;$LB8NonBreaks $IS;&quot;
-    &quot;$CAN_CM $CM* $IS;&quot;
-    &quot;$CM+ $IS;&quot;
-    &quot;$LB8NonBreaks $SY;&quot;
-    &quot;$CAN_CM $CM* $SY;&quot;
-    &quot;$CM+ $SY;&quot;
-    &quot;$OPcm $SP* $CAN_CM $CM*;&quot;
-    &quot;$OPcm $SP* $CANT_CM;&quot;
-    &quot;$OPcm $SP+ $CM+ $AL_FOLLOW?;&quot;
-    &quot;$QUcm $SP* $OPcm;&quot;
-    &quot;($CLcm | $CPcm) $SP* $NScm;&quot;
-    &quot;$B2cm $SP* $B2cm;&quot;
-    &quot;$LB18NonBreaks $CM* $QUcm;&quot;
-    &quot;$CM+ $QUcm;&quot;
-    &quot;$QUcm .?;&quot;
-    &quot;$QUcm $LB18NonBreaks $CM*;&quot;
-    &quot;$LB20NonBreaks $CM* ($BAcm | $HYcm | $NScm); &quot;
-    &quot;$BBcm [^$CB];&quot;
-    &quot;$BBcm $LB20NonBreaks $CM*;&quot;
-    &quot;$HLcm ($HYcm | $BAcm) [^$CB]?;&quot;
-    &quot;$SYcm $HLcm;&quot;
-    &quot;($ALcm | $HLcm) $INcm;&quot;
-    &quot;$CM+ $INcm;&quot;
-    &quot;$EXcm $INcm;&quot;
-    &quot;$IDcm $INcm;&quot;
-    &quot;$INcm $INcm;&quot;
-    &quot;$NUcm $INcm;&quot;
-    &quot;$IDcm $POcm;&quot;
-    &quot;$ALcm $NUcm;&quot;
-    &quot;$HLcm $NUcm;&quot;
-    &quot;$CM+ $NUcm;&quot;
-    &quot;$NUcm $ALcm;&quot;
-    &quot;$NUcm $HLcm;&quot;
-    &quot;$PRcm $IDcm;&quot;
-    &quot;$PRcm ($ALcm | $HLcm);&quot;
-    &quot;$POcm ($ALcm | $HLcm);&quot;
-    &quot;($PRcm | $POcm)? ($OPcm | $HYcm)? $NUcm ($NUcm | $SYcm | $IScm)* ($CLcm | $CPcm)? ($PRcm | $POcm)?;&quot;
-    &quot;$JLcm ($JLcm | $JVcm | $H2cm | $H3cm);&quot;
-    &quot;($JVcm | $H2cm) ($JVcm | $JTcm);&quot;
-    &quot;($JTcm | $H3cm) $JTcm;&quot;
-    &quot;($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $INcm;&quot;
-    &quot;($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $POcm;&quot;
-    &quot;$PRcm ($JLcm | $JVcm | $JTcm | $H2cm | $H3cm);&quot;
-    &quot;($ALcm | $HLcm) ($ALcm | $HLcm);&quot;
-    &quot;$CM+ ($ALcm | $HLcm);&quot;
-    &quot;$IScm ($ALcm | $HLcm);&quot;
-    &quot;($ALcm | $HLcm | $NUcm) $OPcm;&quot;
-    &quot;$CM+ $OPcm;&quot;
-    &quot;$CPcm ($ALcm | $HLcm | $NUcm);&quot;
-#if ADDITIONAL_EMOJI_SUPPORT
-    &quot;$RIcm $RIcm;&quot;
-#endif
-    &quot;$EmojiForMods $EmojiVar? $EmojiMods;&quot;;
-
-static const char* uax14Reverse =
-    &quot;!!reverse;&quot;
-    &quot;$CM+ $ALPlus;&quot;
-    &quot;$CM+ $BA;&quot;
-    &quot;$CM+ $BB;&quot;
-    &quot;$CM+ $B2;&quot;
-    &quot;$CM+ $CL;&quot;
-    &quot;$CM+ $CP;&quot;
-    &quot;$CM+ $EX;&quot;
-    &quot;$CM+ $GL;&quot;
-    &quot;$CM+ $HL;&quot;
-    &quot;$CM+ $HY;&quot;
-    &quot;$CM+ $H2;&quot;
-    &quot;$CM+ $H3;&quot;
-    &quot;$CM+ $ID;&quot;
-    &quot;$CM+ $IN;&quot;
-    &quot;$CM+ $IS;&quot;
-    &quot;$CM+ $JL;&quot;
-    &quot;$CM+ $JV;&quot;
-    &quot;$CM+ $JT;&quot;
-    &quot;$CM+ $NS;&quot;
-    &quot;$CM+ $NU;&quot;
-    &quot;$CM+ $OP;&quot;
-    &quot;$CM+ $PO;&quot;
-    &quot;$CM+ $PR;&quot;
-    &quot;$CM+ $QU;&quot;
-#if ADDITIONAL_EMOJI_SUPPORT
-    &quot;$CM+ $RI;&quot;
-#endif
-    &quot;$CM+ $SY;&quot;
-    &quot;$CM+ $WJ;&quot;
-    &quot;$CM+;&quot;
-    &quot;$AL_FOLLOW $CM+ / ([$BK $CR $LF $NL $ZW {eof}] | $SP+ $CM+ $SP | $SP+ $CM* ([^$OP $CM $SP] | [$AL {eof}]));&quot;
-    &quot;[$PR] / $CM+ [$BK $CR $LF $NL $ZW $SP {eof}];&quot;
-    &quot;$LB4Breaks [$LB4NonBreaks-$CM];&quot;
-    &quot;$LB4Breaks $CM+ $CAN_CM;&quot;
-    &quot;$LF $CR;&quot;
-    &quot;[$SP $ZW] [$LB4NonBreaks-$CM];&quot;
-    &quot;[$SP $ZW] $CM+ $CAN_CM;&quot;
-    &quot;$EmojiForSeqs $ZWJ $EmojiMods? $EmojiVar? $EmojiForSeqs;&quot;
-    &quot;$CM+ $CAN_CM;&quot;
-    &quot;$CM* $WJ $CM* $CAN_CM;&quot;
-    &quot;$CM* $WJ [$LB8NonBreaks-$CM];&quot;
-    &quot;$CANT_CM $CM* $WJ;&quot;
-    &quot;$CM* $CAN_CM $CM* $WJ;&quot;
-    &quot;$CM* $GL $CM* [$LB8NonBreaks-[$CM $SP $BA $HY]];&quot;
-    &quot;$CANT_CM $CM* $GL;&quot;
-    &quot;$CM* $CAN_CM $CM* $GL;&quot;
-    &quot;$CL $CM+ $CAN_CM;&quot;
-    &quot;$CP $CM+ $CAN_CM;&quot;
-    &quot;$EX $CM+ $CAN_CM;&quot;
-    &quot;$IS $CM+ $CAN_CM;&quot;
-    &quot;$SY $CM+ $CAN_CM;&quot;
-    &quot;$CL [$LB8NonBreaks-$CM];&quot;
-    &quot;$CP [$LB8NonBreaks-$CM];&quot;
-    &quot;$EX [$LB8NonBreaks-$CM];&quot;
-    &quot;$IS [$LB8NonBreaks-$CM];&quot;
-    &quot;$SY [$LB8NonBreaks-$CM];&quot;
-    &quot;[$CL $CP $EX $IS $SY] $CM+ $SP+ $CM* $OP; &quot;
-    &quot;$CM* $CAN_CM $SP* $CM* $OP;&quot;
-    &quot;$CANT_CM $SP* $CM* $OP;&quot;
-    &quot;$AL_FOLLOW? $CM+ $SP $SP* $CM* $OP;&quot;
-    &quot;$AL_FOLLOW_NOCM $CM+ $SP+ $CM* $OP;&quot;
-    &quot;$CM* $AL_FOLLOW_CM $CM+ $SP+ $CM* $OP;&quot;
-    &quot;$SY $CM $SP+ $OP;&quot;
-    &quot;$CM* $OP $SP* $CM* $QU;&quot;
-    &quot;$CM* $NS $SP* $CM* ($CL | $CP);&quot;
-    &quot;$CM* $B2 $SP* $CM* $B2;&quot;
-    &quot;$CM* $QU $CM* $CAN_CM;&quot;
-    &quot;$CM* $QU $LB18NonBreaks;&quot;
-    &quot;$CM* $CAN_CM $CM* $QU;&quot;
-    &quot;$CANT_CM $CM* $QU;&quot;
-    &quot;$CM* ($BA | $HY | $NS) $CM* [$LB20NonBreaks-$CM];&quot;
-    &quot;$CM* [$LB20NonBreaks-$CM] $CM* $BB;&quot;
-    &quot;[^$CB] $CM* $BB;&quot;
-    &quot;[^$CB] $CM* ($HY | $BA) $CM* $HL;&quot;
-    &quot;$CM* $HL $CM* $SY;&quot;
-    &quot;$CM* $IN $CM* ($ALPlus | $HL);&quot;
-    &quot;$CM* $IN $CM* $EX;&quot;
-    &quot;$CM* $IN $CM* $ID;&quot;
-    &quot;$CM* $IN $CM* $IN;&quot;
-    &quot;$CM* $IN $CM* $NU;&quot;
-    &quot;$CM* $PO $CM* $ID;&quot;
-    &quot;$CM* $NU $CM* ($ALPlus | $HL);&quot;
-    &quot;$CM* ($ALPlus | $HL) $CM* $NU;&quot;
-    &quot;$CM* $ID $CM* $PR;&quot;
-    &quot;$CM* ($ALPlus | $HL) $CM* $PR;&quot;
-    &quot;$CM* ($ALPlus | $HL) $CM* $PO;&quot;
-    &quot;($CM* ($PR | $PO))? ($CM* ($CL | $CP))? ($CM* ($NU | $IS | $SY))* $CM* $NU ($CM* ($OP | $HY))? ($CM* ($PR | $PO))?;&quot;
-    &quot;$CM* ($H3 | $H2 | $JV | $JL) $CM* $JL;&quot;
-    &quot;$CM* ($JT | $JV) $CM* ($H2 | $JV);&quot;
-    &quot;$CM* $JT $CM* ($H3 | $JT);&quot;
-    &quot;$CM* $IN $CM* ($H3 | $H2 | $JT | $JV | $JL);&quot;
-    &quot;$CM* $PO $CM* ($H3 | $H2 | $JT | $JV | $JL);&quot;
-    &quot;$CM* ($H3 | $H2 | $JT | $JV | $JL) $CM* $PR;&quot;
-    &quot;$CM* ($ALPlus | $HL) $CM* ($ALPlus | $HL);&quot;
-    &quot;$CM* ($ALPlus | $HL) $CM* $IS;&quot;
-    &quot;$CM* $OP $CM* ($ALPlus | $HL | $NU);&quot;
-    &quot;$CM* ($ALPlus | $HL | $NU) $CM* $CP;&quot;
-#if ADDITIONAL_EMOJI_SUPPORT
-    &quot;$CM* $RI $CM* $RI;&quot;
-#endif
-    &quot;$EmojiMods $EmojiVar? $EmojiForMods;&quot;;
-
-static const char* uax14SafeForward =
-    &quot;!!safe_forward;&quot;
-    &quot;[$CM $OP $QU $CL $CP $B2 $PR $HY $BA $SP $dictionary]+ [^$CM $OP $QU $CL $CP $B2 $PR $HY $BA $dictionary];&quot;
-    &quot;$dictionary $dictionary;&quot;;
-
-static const char* uax14SafeReverse =
-    &quot;!!safe_reverse;&quot;
-    &quot;$CM+ [^$CM $BK $CR $LF $NL $ZW $SP];&quot;
-    &quot;$CM+ $SP / .;&quot;
-    &quot;$SP+ $CM* $OP;&quot;
-    &quot;$SP+ $CM* $QU;&quot;
-    &quot;$SP+ $CM* ($CL | $CP);&quot;
-    &quot;$SP+ $CM* $B2;&quot;
-    &quot;$CM* ($HY | $BA) $CM* $HL;&quot;
-    &quot;($CM* ($IS | $SY))+ $CM* $NU;&quot;
-    &quot;($CL | $CP) $CM* ($NU | $IS | $SY);&quot;
-    &quot;$dictionary $dictionary;&quot;;
-
-static String mapLineIteratorModeToRules(LineBreakIteratorMode mode, bool isCJK)
</del><ins>+UBreakIterator* openLineBreakIterator(const AtomicString&amp; locale)
</ins><span class="cx"> {
</span><del>-    StringBuilder rulesBuilder;
-    rulesBuilder.append(uax14Prologue);
-    rulesBuilder.append(uax14AssignmentsBefore);
-    switch (mode) {
-    case LineBreakIteratorMode::Default:
-        rulesBuilder.append(isCJK ? uax14AssignmentsCustomDefaultCJK : uax14AssignmentsCustomDefaultNonCJK);
-        break;
-    case LineBreakIteratorMode::Loose:
-        rulesBuilder.append(isCJK ? uax14AssignmentsCustomLooseCJK : uax14AssignmentsCustomLooseNonCJK);
-        break;
-    case LineBreakIteratorMode::Normal:
-        rulesBuilder.append(isCJK ? uax14AssignmentsCustomNormalCJK : uax14AssignmentsCustomNormalNonCJK);
-        break;
-    case LineBreakIteratorMode::Strict:
-        rulesBuilder.append(isCJK ? uax14AssignmentsCustomStrictCJK : uax14AssignmentsCustomStrictNonCJK);
-        break;
-    }
-    rulesBuilder.append(uax14AssignmentsAfter);
-    rulesBuilder.append(uax14Forward);
-    rulesBuilder.append(uax14Reverse);
-    rulesBuilder.append(uax14SafeForward);
-    rulesBuilder.append(uax14SafeReverse);
-    return rulesBuilder.toString();
-}
-
-// Recognize BCP47 compliant primary language values of 'zh', 'ja', 'ko'
-// (in any combination of case), optionally followed by subtags. Don't
-// recognize 3-letter variants 'chi'/'zho', 'jpn', or 'kor' since BCP47
-// requires use of shortest language tag.
-bool isCJKLocale(const AtomicString&amp; locale)
-{
-    size_t length = locale.length();
-    if (length &lt; 2)
-        return false;
-    auto c1 = locale[0];
-    auto c2 = locale[1];
-    auto c3 = length == 2 ? 0 : locale[2];
-    if (!c3 || c3 == '-' || c3 == '_' || c3 == '@') {
-        if (c1 == 'z' || c1 == 'Z')
-            return c2 == 'h' || c2 == 'H';
-        if (c1 == 'j' || c1 == 'J')
-            return c2 == 'a' || c2 == 'A';
-        if (c1 == 'k' || c1 == 'K')
-            return c2 == 'o' || c2 == 'O';
-    }
-    return false;
-}
-
-UBreakIterator* openLineBreakIterator(const AtomicString&amp; locale, LineBreakIteratorMode mode, bool isCJK)
-{
-    UBreakIterator* ubrkIter;
</del><ins>+    bool localeIsEmpty = locale.isEmpty();
</ins><span class="cx">     UErrorCode openStatus = U_ZERO_ERROR;
</span><del>-    bool localeIsEmpty = locale.isEmpty();
-    if (mode == LineBreakIteratorMode::Default)
-        ubrkIter = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &amp;openStatus);
-    else {
-        UParseError parseStatus;
-        auto rules = mapLineIteratorModeToRules(mode, isCJK);
-        ubrkIter = ubrk_openRules(StringView(rules).upconvertedCharacters(), rules.length(), 0, 0, &amp;parseStatus, &amp;openStatus);
-    }
</del><ins>+    UBreakIterator* ubrkIter = ubrk_open(UBRK_LINE, localeIsEmpty ? currentTextBreakLocaleID() : locale.string().utf8().data(), 0, 0, &amp;openStatus);
</ins><span class="cx">     // locale comes from a web page and it can be invalid, leading ICU
</span><span class="cx">     // to fail, in which case we fall back to the default locale.
</span><span class="cx">     if (!localeIsEmpty &amp;&amp; U_FAILURE(openStatus)) {
</span></span></pre></div>
<a id="trunkSourceWTFwtftextTextBreakIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/TextBreakIterator.h (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/TextBreakIterator.h        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WTF/wtf/text/TextBreakIterator.h        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -38,15 +38,13 @@
</span><span class="cx"> WTF_EXPORT_PRIVATE UBreakIterator* wordBreakIterator(StringView);
</span><span class="cx"> WTF_EXPORT_PRIVATE UBreakIterator* sentenceBreakIterator(StringView);
</span><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE UBreakIterator* acquireLineBreakIterator(StringView, const AtomicString&amp; locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode, bool isCJK);
</del><ins>+WTF_EXPORT_PRIVATE UBreakIterator* acquireLineBreakIterator(StringView, const AtomicString&amp; locale, const UChar* priorContext, unsigned priorContextLength, LineBreakIteratorMode);
</ins><span class="cx"> WTF_EXPORT_PRIVATE void releaseLineBreakIterator(UBreakIterator*);
</span><del>-UBreakIterator* openLineBreakIterator(const AtomicString&amp; locale, LineBreakIteratorMode, bool isCJK);
</del><ins>+UBreakIterator* openLineBreakIterator(const AtomicString&amp; locale);
</ins><span class="cx"> void closeLineBreakIterator(UBreakIterator*&amp;);
</span><span class="cx"> 
</span><span class="cx"> WTF_EXPORT_PRIVATE bool isWordTextBreak(UBreakIterator*);
</span><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE bool isCJKLocale(const AtomicString&amp;);
-
</del><span class="cx"> class LazyLineBreakIterator {
</span><span class="cx"> public:
</span><span class="cx">     LazyLineBreakIterator()
</span><span class="lines">@@ -58,7 +56,6 @@
</span><span class="cx">         : m_stringView(stringView)
</span><span class="cx">         , m_locale(locale)
</span><span class="cx">         , m_mode(mode)
</span><del>-        , m_isCJK(isCJKLocale(locale))
</del><span class="cx">     {
</span><span class="cx">         resetPriorContext();
</span><span class="cx">     }
</span><span class="lines">@@ -70,7 +67,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     StringView stringView() const { return m_stringView; }
</span><del>-    bool isLooseCJKMode() const { return m_isCJK &amp;&amp; m_mode == LineBreakIteratorMode::Loose; }
</del><ins>+    LineBreakIteratorMode mode() const { return m_mode; }
</ins><span class="cx"> 
</span><span class="cx">     UChar lastCharacter() const
</span><span class="cx">     {
</span><span class="lines">@@ -125,7 +122,7 @@
</span><span class="cx">         ASSERT(priorContextLength &lt;= priorContextCapacity);
</span><span class="cx">         const UChar* priorContext = priorContextLength ? &amp;m_priorContext[priorContextCapacity - priorContextLength] : 0;
</span><span class="cx">         if (!m_iterator) {
</span><del>-            m_iterator = acquireLineBreakIterator(m_stringView, m_locale, priorContext, priorContextLength, m_mode, m_isCJK);
</del><ins>+            m_iterator = acquireLineBreakIterator(m_stringView, m_locale, priorContext, priorContextLength, m_mode);
</ins><span class="cx">             m_cachedPriorContext = priorContext;
</span><span class="cx">             m_cachedPriorContextLength = priorContextLength;
</span><span class="cx">         } else if (priorContext != m_cachedPriorContext || priorContextLength != m_cachedPriorContextLength) {
</span><span class="lines">@@ -144,7 +141,6 @@
</span><span class="cx">         m_iterator = nullptr;
</span><span class="cx">         m_cachedPriorContext = nullptr;
</span><span class="cx">         m_mode = mode;
</span><del>-        m_isCJK = isCJKLocale(locale);
</del><span class="cx">         m_cachedPriorContextLength = 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -157,7 +153,6 @@
</span><span class="cx">     LineBreakIteratorMode m_mode { LineBreakIteratorMode::Default };
</span><span class="cx">     unsigned m_cachedPriorContextLength { 0 };
</span><span class="cx">     UChar m_priorContext[priorContextCapacity];
</span><del>-    bool m_isCJK { false };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // Iterates over &quot;extended grapheme clusters&quot;, as defined in UAX #29.
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WebCore/ChangeLog        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2017-02-13  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Update custom line breaking iterators to the latest version of Unicode
+        https://bugs.webkit.org/show_bug.cgi?id=168182
+
+        Reviewed by Zalan Bujtas.
+
+        Clean up our breaking code to be more descriptive about the difference between
+        line-break: auto vs line-break: loose | normal | strict. The only difference is
+        that we have some hardcoded tables to speed up character iteration for
+        line-break: auto.
+
+        Tests: TestWebKitAPI WebKit2.LineBreaking
+
+        * rendering/BreakLines.h:
+        (WebCore::nextBreakablePosition):
+        (WebCore::nextBreakablePositionIgnoringNBSP):
+        (WebCore::nextBreakablePositionWithoutShortcut):
+        (WebCore::nextBreakablePositionIgnoringNBSPWithoutShortcut):
+        (WebCore::isBreakable):
+        (WebCore::nextBreakablePositionNonLoosely): Deleted.
+        (WebCore::nextBreakablePositionLoosely): Deleted.
+        (WebCore::nextBreakablePositionLoose): Deleted.
+        (WebCore::nextBreakablePositionIgnoringNBSPLoose): Deleted.
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::computePreferredLogicalWidths):
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::nextBreakablePositionInSegment):
+        * rendering/line/BreakingContext.h:
+        (WebCore::BreakingContext::handleText):
+        (WebCore::BreakingContext::optimalLineBreakLocationForTrailingWord):
+
</ins><span class="cx"> 2017-02-13  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove @getUserMedia identifier
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingBreakLinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/BreakLines.h (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/BreakLines.h        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WebCore/rendering/BreakLines.h        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -40,6 +40,11 @@
</span><span class="cx">     TreatNonBreakingSpaceAsBreak,
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+enum class CanUseShortcut {
+    Yes,
+    No
+};
+
</ins><span class="cx"> template&lt;NonBreakingSpaceBehavior nonBreakingSpaceBehavior&gt;
</span><span class="cx"> static inline bool isBreakableSpace(UChar character)
</span><span class="cx"> {
</span><span class="lines">@@ -82,8 +87,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // When in non-loose mode, we can use the ASCII shortcut table.
</span><del>-template&lt;typename CharacterType, NonBreakingSpaceBehavior nonBreakingSpaceBehavior&gt;
-inline unsigned nextBreakablePositionNonLoosely(LazyLineBreakIterator&amp; lazyBreakIterator, const CharacterType* string, unsigned length, unsigned startPosition)
</del><ins>+template&lt;typename CharacterType, NonBreakingSpaceBehavior nonBreakingSpaceBehavior, CanUseShortcut canUseShortcut&gt;
+inline unsigned nextBreakablePosition(LazyLineBreakIterator&amp; lazyBreakIterator, const CharacterType* string, unsigned length, unsigned startPosition)
</ins><span class="cx"> {
</span><span class="cx">     std::optional&lt;unsigned&gt; nextBreak;
</span><span class="cx"> 
</span><span class="lines">@@ -93,12 +98,10 @@
</span><span class="cx">     for (unsigned i = startPosition; i &lt; length; i++) {
</span><span class="cx">         CharacterType character = string[i];
</span><span class="cx"> 
</span><del>-        // Non-loose mode, so use ASCII shortcut (shouldBreakAfter) if not breakable space.
-        if (isBreakableSpace&lt;nonBreakingSpaceBehavior&gt;(character) || shouldBreakAfter(lastLastCharacter, lastCharacter, character))
</del><ins>+        if (isBreakableSpace&lt;nonBreakingSpaceBehavior&gt;(character) || (canUseShortcut == CanUseShortcut::Yes &amp;&amp; shouldBreakAfter(lastLastCharacter, lastCharacter, character)))
</ins><span class="cx">             return i;
</span><span class="cx"> 
</span><del>-        // Non-loose mode, so conditionally use break iterator.
-        if (needsLineBreakIterator&lt;nonBreakingSpaceBehavior&gt;(character) || needsLineBreakIterator&lt;nonBreakingSpaceBehavior&gt;(lastCharacter)) {
</del><ins>+        if (canUseShortcut == CanUseShortcut::No || needsLineBreakIterator&lt;nonBreakingSpaceBehavior&gt;(character) || needsLineBreakIterator&lt;nonBreakingSpaceBehavior&gt;(lastCharacter)) {
</ins><span class="cx">             if (!nextBreak || nextBreak.value() &lt; i) {
</span><span class="cx">                 // Don't break if positioned at start of primary context and there is no prior context.
</span><span class="cx">                 if (i || priorContextLength) {
</span><span class="lines">@@ -126,51 +129,7 @@
</span><span class="cx">     return length;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// When in loose mode, we can't use the ASCII shortcut table since loose mode allows &quot;$100&quot; to break after '$' in content marked as CJK.
-// N.B. It should be possible to combine the following with the non-loose version above by adding a LooseBehavior template parameter;
-// however, when doing this, a 10% performance regression appeared on chromium-win (https://bugs.webkit.org/show_bug.cgi?id=89235#c112).
</del><span class="cx"> template&lt;typename CharacterType, NonBreakingSpaceBehavior nonBreakingSpaceBehavior&gt;
</span><del>-static inline unsigned nextBreakablePositionLoosely(LazyLineBreakIterator&amp; lazyBreakIterator, const CharacterType* string, unsigned length, unsigned startPosition)
-{
-    std::optional&lt;unsigned&gt; nextBreak;
-
-    CharacterType lastCharacter = startPosition &gt; 0 ? string[startPosition - 1] : static_cast&lt;CharacterType&gt;(lazyBreakIterator.lastCharacter());
-    unsigned priorContextLength = lazyBreakIterator.priorContextLength();
-    for (unsigned i = startPosition; i &lt; length; i++) {
-        CharacterType character = string[i];
-
-        // Always loose mode, so don't use ASCII shortcut (shouldBreakAfter).
-        if (isBreakableSpace&lt;nonBreakingSpaceBehavior&gt;(character))
-            return i;
-
-        // Always use line break iterator in loose mode.
-        if (!nextBreak || nextBreak.value() &lt; i) {
-            // Don't break if positioned at start of primary context and there is no prior context.
-            if (i || priorContextLength) {
-                UBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
-                if (breakIterator) {
-                    ASSERT(i + priorContextLength &gt;= 1);
-                    int candidate = ubrk_following(breakIterator, i + priorContextLength - 1);
-                    if (candidate == UBRK_DONE)
-                        nextBreak = std::nullopt;
-                    else {
-                        unsigned result = candidate;
-                        ASSERT(result &gt; priorContextLength);
-                        nextBreak = result - priorContextLength;
-                    }
-                }
-            }
-        }
-        if (i == nextBreak &amp;&amp; !isBreakableSpace&lt;nonBreakingSpaceBehavior&gt;(lastCharacter))
-            return i;
-
-        lastCharacter = character;
-    }
-
-    return length;
-}
-
-template&lt;typename CharacterType, NonBreakingSpaceBehavior nonBreakingSpaceBehavior&gt;
</del><span class="cx"> inline unsigned nextBreakablePositionKeepingAllWords(const CharacterType* string, unsigned length, unsigned startPosition)
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = startPosition; i &lt; length; i++) {
</span><span class="lines">@@ -200,8 +159,8 @@
</span><span class="cx"> {
</span><span class="cx">     auto stringView = iterator.stringView();
</span><span class="cx">     if (stringView.is8Bit())
</span><del>-        return nextBreakablePositionNonLoosely&lt;LChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak&gt;(iterator, stringView.characters8(), stringView.length(), startPosition);
-    return nextBreakablePositionNonLoosely&lt;UChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak&gt;(iterator, stringView.characters16(), stringView.length(), startPosition);
</del><ins>+        return nextBreakablePosition&lt;LChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak, CanUseShortcut::Yes&gt;(iterator, stringView.characters8(), stringView.length(), startPosition);
+    return nextBreakablePosition&lt;UChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak, CanUseShortcut::Yes&gt;(iterator, stringView.characters16(), stringView.length(), startPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline unsigned nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition)
</span><span class="lines">@@ -208,27 +167,27 @@
</span><span class="cx"> {
</span><span class="cx">     auto stringView = lazyBreakIterator.stringView();
</span><span class="cx">     if (stringView.is8Bit())
</span><del>-        return nextBreakablePositionNonLoosely&lt;LChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
-    return nextBreakablePositionNonLoosely&lt;UChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</del><ins>+        return nextBreakablePosition&lt;LChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace, CanUseShortcut::Yes&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
+    return nextBreakablePosition&lt;UChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace, CanUseShortcut::Yes&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline unsigned nextBreakablePositionLoose(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition)
</del><ins>+inline unsigned nextBreakablePositionWithoutShortcut(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition)
</ins><span class="cx"> {
</span><span class="cx">     auto stringView = lazyBreakIterator.stringView();
</span><span class="cx">     if (stringView.is8Bit())
</span><del>-        return nextBreakablePositionLoosely&lt;LChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
-    return nextBreakablePositionLoosely&lt;UChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</del><ins>+        return nextBreakablePosition&lt;LChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak, CanUseShortcut::No&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
+    return nextBreakablePosition&lt;UChar, NonBreakingSpaceBehavior::TreatNonBreakingSpaceAsBreak, CanUseShortcut::No&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline unsigned nextBreakablePositionIgnoringNBSPLoose(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition)
</del><ins>+inline unsigned nextBreakablePositionIgnoringNBSPWithoutShortcut(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition)
</ins><span class="cx"> {
</span><span class="cx">     auto stringView = lazyBreakIterator.stringView();
</span><span class="cx">     if (stringView.is8Bit())
</span><del>-        return nextBreakablePositionLoosely&lt;LChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
-    return nextBreakablePositionLoosely&lt;UChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</del><ins>+        return nextBreakablePosition&lt;LChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace, CanUseShortcut::No&gt;(lazyBreakIterator, stringView.characters8(), stringView.length(), startPosition);
+    return nextBreakablePosition&lt;UChar, NonBreakingSpaceBehavior::IgnoreNonBreakingSpace, CanUseShortcut::No&gt;(lazyBreakIterator, stringView.characters16(), stringView.length(), startPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool isBreakable(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition, std::optional&lt;unsigned&gt;&amp; nextBreakable, bool breakNBSP, bool isLooseMode, bool keepAllWords)
</del><ins>+inline bool isBreakable(LazyLineBreakIterator&amp; lazyBreakIterator, unsigned startPosition, std::optional&lt;unsigned&gt;&amp; nextBreakable, bool breakNBSP, bool canUseShortcut, bool keepAllWords)
</ins><span class="cx"> {
</span><span class="cx">     if (nextBreakable &amp;&amp; nextBreakable.value() &gt;= startPosition)
</span><span class="cx">         return startPosition == nextBreakable;
</span><span class="lines">@@ -238,11 +197,11 @@
</span><span class="cx">             nextBreakable = nextBreakablePositionKeepingAllWords(lazyBreakIterator, startPosition);
</span><span class="cx">         else
</span><span class="cx">             nextBreakable = nextBreakablePositionKeepingAllWordsIgnoringNBSP(lazyBreakIterator, startPosition);
</span><del>-    } else if (isLooseMode) {
</del><ins>+    } else if (!canUseShortcut) {
</ins><span class="cx">         if (breakNBSP)
</span><del>-            nextBreakable = nextBreakablePositionLoose(lazyBreakIterator, startPosition);
</del><ins>+            nextBreakable = nextBreakablePositionWithoutShortcut(lazyBreakIterator, startPosition);
</ins><span class="cx">         else
</span><del>-            nextBreakable = nextBreakablePositionIgnoringNBSPLoose(lazyBreakIterator, startPosition);
</del><ins>+            nextBreakable = nextBreakablePositionIgnoringNBSPWithoutShortcut(lazyBreakIterator, startPosition);
</ins><span class="cx">     } else {
</span><span class="cx">         if (breakNBSP)
</span><span class="cx">             nextBreakable = nextBreakablePosition(lazyBreakIterator, startPosition);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.cpp (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.cpp        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WebCore/rendering/RenderText.cpp        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -797,7 +797,8 @@
</span><span class="cx">     const FontCascade&amp; font = style.fontCascade(); // FIXME: This ignores first-line.
</span><span class="cx">     float wordSpacing = font.wordSpacing();
</span><span class="cx">     unsigned len = textLength();
</span><del>-    LazyLineBreakIterator breakIterator(m_text, style.locale(), mapLineBreakToIteratorMode(style.lineBreak()));
</del><ins>+    auto iteratorMode = mapLineBreakToIteratorMode(style.lineBreak());
+    LazyLineBreakIterator breakIterator(m_text, style.locale(), iteratorMode);
</ins><span class="cx">     bool needsWordSpacing = false;
</span><span class="cx">     bool ignoringSpaces = false;
</span><span class="cx">     bool isSpace = false;
</span><span class="lines">@@ -834,7 +835,7 @@
</span><span class="cx">     // word-break, but we support it as though it means break-all.
</span><span class="cx">     bool breakAll = (style.wordBreak() == BreakAllWordBreak || style.wordBreak() == BreakWordBreak) &amp;&amp; style.autoWrap();
</span><span class="cx">     bool keepAllWords = style.wordBreak() == KeepAllWordBreak;
</span><del>-    bool isLooseCJKMode = breakIterator.isLooseCJKMode();
</del><ins>+    bool canUseLineBreakShortcut = iteratorMode == LineBreakIteratorMode::Default;
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i &lt; len; i++) {
</span><span class="cx">         UChar c = uncheckedCharacterAt(i);
</span><span class="lines">@@ -880,7 +881,7 @@
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP, isLooseCJKMode, keepAllWords);
</del><ins>+        bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable, breakNBSP, canUseLineBreakShortcut, keepAllWords);
</ins><span class="cx">         bool betweenWords = true;
</span><span class="cx">         unsigned j = i;
</span><span class="cx">         while (c != '\n' &amp;&amp; !isSpaceAccordingToStyle(c, style) &amp;&amp; c != '\t' &amp;&amp; (c != softHyphen || style.hyphens() == HyphensNone)) {
</span><span class="lines">@@ -888,7 +889,7 @@
</span><span class="cx">             if (j == len)
</span><span class="cx">                 break;
</span><span class="cx">             c = uncheckedCharacterAt(j);
</span><del>-            if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, isLooseCJKMode, keepAllWords) &amp;&amp; characterAt(j - 1) != softHyphen)
</del><ins>+            if (isBreakable(breakIterator, j, nextBreakable, breakNBSP, canUseLineBreakShortcut, keepAllWords) &amp;&amp; characterAt(j - 1) != softHyphen)
</ins><span class="cx">                 break;
</span><span class="cx">             if (breakAll) {
</span><span class="cx">                 betweenWords = false;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -127,15 +127,15 @@
</span><span class="cx">         return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (lineBreakIterator.isLooseCJKMode()) {
</del><ins>+    if (lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
</ins><span class="cx">         if (breakNBSP)
</span><del>-            return nextBreakablePositionLoose(lineBreakIterator, startPosition);
-        return nextBreakablePositionIgnoringNBSPLoose(lineBreakIterator, startPosition);
</del><ins>+            return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
+        return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
</ins><span class="cx">     }
</span><del>-        
</del><ins>+
</ins><span class="cx">     if (breakNBSP)
</span><del>-        return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
-    return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
</del><ins>+        return nextBreakablePositionWithoutShortcut(lineBreakIterator, startPosition);
+    return nextBreakablePositionIgnoringNBSPWithoutShortcut(lineBreakIterator, startPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned TextFragmentIterator::nextBreakablePosition(const FlowContents::Segment&amp; segment, unsigned startPosition)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderinglineBreakingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/BreakingContext.h        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -804,7 +804,8 @@
</span><span class="cx">     bool breakAll = m_currentStyle-&gt;wordBreak() == BreakAllWordBreak &amp;&amp; m_autoWrap;
</span><span class="cx">     bool keepAllWords = m_currentStyle-&gt;wordBreak() == KeepAllWordBreak;
</span><span class="cx">     float hyphenWidth = 0;
</span><del>-    bool isLooseCJKMode = false;
</del><ins>+    auto iteratorMode = mapLineBreakToIteratorMode(m_blockStyle.lineBreak());
+    bool canUseLineBreakShortcut = iteratorMode == LineBreakIteratorMode::Default;
</ins><span class="cx">     bool isLineEmpty = m_lineInfo.isEmpty();
</span><span class="cx"> 
</span><span class="cx">     if (isSVGText) {
</span><span class="lines">@@ -817,8 +818,7 @@
</span><span class="cx">         m_renderTextInfo.text = &amp;renderText;
</span><span class="cx">         m_renderTextInfo.font = &amp;font;
</span><span class="cx">         m_renderTextInfo.layout = font.createLayout(renderText, m_width.currentWidth(), m_collapseWhiteSpace);
</span><del>-        m_renderTextInfo.lineBreakIterator.resetStringAndReleaseIterator(renderText.text(), style.locale(), mapLineBreakToIteratorMode(m_blockStyle.lineBreak()));
-        isLooseCJKMode = m_renderTextInfo.lineBreakIterator.isLooseCJKMode();
</del><ins>+        m_renderTextInfo.lineBreakIterator.resetStringAndReleaseIterator(renderText.text(), style.locale(), iteratorMode);
</ins><span class="cx">     } else if (m_renderTextInfo.layout &amp;&amp; m_renderTextInfo.font != &amp;font) {
</span><span class="cx">         m_renderTextInfo.font = &amp;font;
</span><span class="cx">         m_renderTextInfo.layout = font.createLayout(renderText, m_width.currentWidth(), m_collapseWhiteSpace);
</span><span class="lines">@@ -869,7 +869,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         std::optional&lt;unsigned&gt; nextBreakablePosition = m_current.nextBreakablePosition();
</span><del>-        bool betweenWords = c == '\n' || (m_currWS != PRE &amp;&amp; !m_atStart &amp;&amp; isBreakable(m_renderTextInfo.lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, isLooseCJKMode, keepAllWords)
</del><ins>+        bool betweenWords = c == '\n' || (m_currWS != PRE &amp;&amp; !m_atStart &amp;&amp; isBreakable(m_renderTextInfo.lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, canUseLineBreakShortcut, keepAllWords)
</ins><span class="cx">             &amp;&amp; (style.hyphens() != HyphensNone || (m_current.previousInSameNode() != softHyphen)));
</span><span class="cx">         m_current.setNextBreakablePosition(nextBreakablePosition);
</span><span class="cx">         
</span><span class="lines">@@ -1332,10 +1332,10 @@
</span><span class="cx">     // Don't even bother measuring if our remaining line has many characters
</span><span class="cx">     if (renderText.textLength() == lineBreak.offset() || renderText.textLength() - lineBreak.offset() &gt; longTrailingWordLength)
</span><span class="cx">         return lineBreak;
</span><del>-    bool isLooseCJKMode = m_renderTextInfo.text != &amp;renderText &amp;&amp; m_renderTextInfo.lineBreakIterator.isLooseCJKMode();
</del><ins>+    bool canUseLineBreakShortcut = m_renderTextInfo.lineBreakIterator.mode() == LineBreakIteratorMode::Default;
</ins><span class="cx">     bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
</span><span class="cx">     std::optional&lt;unsigned&gt; nextBreakablePosition = lineBreak.nextBreakablePosition();
</span><del>-    isBreakable(m_renderTextInfo.lineBreakIterator, lineBreak.offset() + 1, nextBreakablePosition, breakNBSP, isLooseCJKMode, m_currentStyle-&gt;wordBreak() == KeepAllWordBreak);
</del><ins>+    isBreakable(m_renderTextInfo.lineBreakIterator, lineBreak.offset() + 1, nextBreakablePosition, breakNBSP, canUseLineBreakShortcut, m_currentStyle-&gt;wordBreak() == KeepAllWordBreak);
</ins><span class="cx">     if (!nextBreakablePosition || nextBreakablePosition.value() != renderText.textLength())
</span><span class="cx">         return lineBreak;
</span><span class="cx">     const RenderStyle&amp; style = lineStyle(renderText, m_lineInfo);
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Tools/ChangeLog        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2017-02-13  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Update custom line breaking iterators to the latest version of Unicode
+        https://bugs.webkit.org/show_bug.cgi?id=168182
+
+        Reviewed by Zalan Bujtas.
+
+        Treat the system's ICU as the source of truth to compare breaking positions against.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/LineBreaking.mm: Added.
+        (generateJavaScriptForTest):
+        (breakingLocationsFromICU):
+        (testAFewStrings):
+        (TEST):
+        * TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg: Renamed from LayoutTests/css3/line-break/resources/AllAhem.svg.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html: Added.
+
</ins><span class="cx"> 2017-02-12  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Several failing WebViewEditor API tests
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (212234 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-02-13 18:58:32 UTC (rev 212234)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -506,6 +506,9 @@
</span><span class="cx">                 C0ADBE9612FCA79B00D2C129 /* simple-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C0ADBE8412FCA6B600D2C129 /* simple-form.html */; };
</span><span class="cx">                 C0BD669F131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0BD669E131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp */; };
</span><span class="cx">                 C0C5D3C61459912900A802A6 /* GetBackingScaleFactor_Bundle.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0C5D3BD14598B6F00A802A6 /* GetBackingScaleFactor_Bundle.mm */; };
</span><ins>+                C25CCA061E51380B0026CB8A /* LineBreaking.mm in Sources */ = {isa = PBXBuildFile; fileRef = C25CCA051E51380B0026CB8A /* LineBreaking.mm */; };
+                C25CCA0B1E5140C10026CB8A /* LineBreaking.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C25CCA0A1E513F490026CB8A /* LineBreaking.html */; };
+                C25CCA0D1E5141840026CB8A /* AllAhem.svg in Copy Resources */ = {isa = PBXBuildFile; fileRef = C25CCA0C1E5140E50026CB8A /* AllAhem.svg */; };
</ins><span class="cx">                 C2CF975A16CEC7140054E99D /* JSContextBackForwardCache2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C2CF975916CEC69E0054E99D /* JSContextBackForwardCache2.html */; };
</span><span class="cx">                 C2CF975B16CEC71B0054E99D /* JSContextBackForwardCache1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C2CF975816CEC69E0054E99D /* JSContextBackForwardCache1.html */; };
</span><span class="cx">                 C5101C4F176B8D9200EE9B15 /* findRanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C5101C4E176B8BB900EE9B15 /* findRanges.html */; };
</span><span class="lines">@@ -625,6 +628,8 @@
</span><span class="cx">                         dstPath = TestWebKitAPI.resources;
</span><span class="cx">                         dstSubfolderSpec = 7;
</span><span class="cx">                         files = (
</span><ins>+                                C25CCA0D1E5141840026CB8A /* AllAhem.svg in Copy Resources */,
+                                C25CCA0B1E5140C10026CB8A /* LineBreaking.html in Copy Resources */,
</ins><span class="cx">                                 F47728991E4AE3C1007ABF6A /* full-page-contenteditable.html in Copy Resources */,
</span><span class="cx">                                 C99B675F1E39736F00FC6C80 /* no-autoplay-with-controls.html in Copy Resources */,
</span><span class="cx">                                 C99B675D1E39722000FC6C80 /* js-play-with-controls.html in Copy Resources */,
</span><span class="lines">@@ -1099,7 +1104,7 @@
</span><span class="cx">                 7C83E0261D0A5B8D00FEBCF3 /* TestWTF.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TestWTF.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C83E0271D0A5B8D00FEBCF3 /* TestWTFLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TestWTFLibrary.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C83E0291D0A5CDF00FEBCF3 /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libWTF.a; path = ../../../../../Builds/Debug/libWTF.a; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = &quot;compiled.mach-o.dylib&quot;; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
</del><ins>+                7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = &quot;compiled.mach-o.dylib&quot;; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = SDKROOT; };
</ins><span class="cx">                 7C83E0361D0A5F7000FEBCF3 /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C83E0391D0A602700FEBCF3 /* UtilitiesCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UtilitiesCocoa.mm; path = cocoa/UtilitiesCocoa.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C882E031C80C624006BF731 /* UserContentWorld.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserContentWorld.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1293,6 +1298,9 @@
</span><span class="cx">                 C0BD669E131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResponsivenessTimerDoesntFireEarly_Bundle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C0C5D3BC14598B6F00A802A6 /* GetBackingScaleFactor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetBackingScaleFactor.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C0C5D3BD14598B6F00A802A6 /* GetBackingScaleFactor_Bundle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetBackingScaleFactor_Bundle.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                C25CCA051E51380B0026CB8A /* LineBreaking.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = LineBreaking.mm; path = ../WebCore/LineBreaking.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C25CCA0A1E513F490026CB8A /* LineBreaking.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LineBreaking.html; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C25CCA0C1E5140E50026CB8A /* AllAhem.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AllAhem.svg; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 C2CF975816CEC69E0054E99D /* JSContextBackForwardCache1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JSContextBackForwardCache1.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C2CF975916CEC69E0054E99D /* JSContextBackForwardCache2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JSContextBackForwardCache2.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 C2EB2DD116CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewDidCreateJavaScriptContext.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1414,6 +1422,7 @@
</span><span class="cx">                         isa = PBXFrameworksBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><ins>+                                7C83E03F1D0A61A000FEBCF3 /* libicucore.dylib in Frameworks */,
</ins><span class="cx">                                 7A010BCD1D877C0D00EDE72A /* QuartzCore.framework in Frameworks */,
</span><span class="cx">                                 7A010BCB1D877C0500EDE72A /* CoreGraphics.framework in Frameworks */,
</span><span class="cx">                         );
</span><span class="lines">@@ -1523,6 +1532,7 @@
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="cx">                                 A16F66B81C40E9E100BD4D24 /* Resources */,
</span><ins>+                                C25CCA051E51380B0026CB8A /* LineBreaking.mm */,
</ins><span class="cx">                                 7CEFA9641AC0B9E200B910FD /* _WKUserContentExtensionStore.mm */,
</span><span class="cx">                                 A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */,
</span><span class="cx">                                 2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */,
</span><span class="lines">@@ -1762,6 +1772,8 @@
</span><span class="cx">                                 515BE16E1D4288FF00DD7C68 /* StoreBlobToBeDeleted.html */,
</span><span class="cx">                                 51714EB21CF8C761004723C4 /* WebProcessKillIDBCleanup-1.html */,
</span><span class="cx">                                 51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */,
</span><ins>+                                C25CCA0A1E513F490026CB8A /* LineBreaking.html */,
+                                C25CCA0C1E5140E50026CB8A /* AllAhem.svg */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = Resources;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -2752,6 +2764,7 @@
</span><span class="cx">                                 7CCE7EDE1A411A9200447C4C /* URL.cpp in Sources */,
</span><span class="cx">                                 7CCE7EB01A411A4400447C4C /* URLExtras.mm in Sources */,
</span><span class="cx">                                 07492B3B1DF8B14C00633DE1 /* EnumerateMediaDevices.cpp in Sources */,
</span><ins>+                                C25CCA061E51380B0026CB8A /* LineBreaking.mm in Sources */,
</ins><span class="cx">                                 7A6A2C701DCCFA8C00C0D085 /* LocalStorageQuirkTest.mm in Sources */,
</span><span class="cx">                                 2DFF7B6D1DA487AF00814614 /* SnapshotStore.mm in Sources */,
</span><span class="cx">                                 5C6E65441D5CEFD400F7862E /* URLParser.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreLineBreakingmm"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/LineBreaking.mm (0 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/LineBreaking.mm                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/LineBreaking.mm        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -0,0 +1,338 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#if WK_API_ENABLED
+
+#import &quot;PlatformUtilities.h&quot;
+#import &quot;TestNavigationDelegate.h&quot;
+#import &lt;unicode/ubrk.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+#import &lt;wtf/Vector.h&gt;
+#import &lt;wtf/text/WTFString.h&gt;
+
+NSString *generateJavaScriptForTest(NSString *testContent, NSString *localeString, NSString *lineBreakValue)
+{
+    return [NSString stringWithFormat:@&quot;runTest('%@', '%@', '%@')&quot;, testContent, localeString, lineBreakValue];
+}
+
+Vector&lt;unsigned&gt; breakingLocationsFromICU(const Vector&lt;UInt16&gt;&amp; testString, const String&amp; locale, const String lineBreakValue)
+{
+    constexpr int bufferSize = 100;
+    char buffer[bufferSize];
+    memset(buffer, 0, bufferSize);
+    auto utf8Locale = locale.utf8();
+    ASSERT(utf8Locale.length() &lt; bufferSize);
+    memcpy(buffer, utf8Locale.data(), utf8Locale.length());
+    CString icuValue;
+    if (lineBreakValue != &quot;auto&quot;)
+        icuValue = lineBreakValue.utf8();
+    UErrorCode status = U_ZERO_ERROR;
+    uloc_setKeywordValue(&quot;lb&quot;, icuValue.data(), buffer, bufferSize, &amp;status);
+    ASSERT(U_SUCCESS(status));
+
+    UBreakIterator* iterator = ubrk_open(UBRK_LINE, buffer, testString.data(), testString.size(), &amp;status);
+    ASSERT(U_SUCCESS(status));
+    ASSERT(iterator);
+
+    Vector&lt;unsigned&gt; result;
+    int32_t position = 0;
+    for (; position != UBRK_DONE; position = ubrk_next(iterator)) {
+        if (position)
+            result.append(position);
+    }
+    ubrk_close(iterator);
+    return result;
+}
+
+static void testAFewStrings(Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings)
+{
+    Vector&lt;String&gt; locales = { &quot;en&quot;, &quot;ja&quot;, &quot;ko&quot;, &quot;zh&quot; };
+
+    Vector&lt;String&gt; lineBreakValues = { &quot;auto&quot;, &quot;loose&quot;, &quot;normal&quot;, &quot;strict&quot; };
+
+    RetainPtr&lt;WKWebViewConfiguration&gt; configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    RetainPtr&lt;WKWebView&gt; webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@&quot;LineBreaking&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;]]];
+    [webView _test_waitForDidFinishNavigation];
+
+    for (auto&amp; testCodePoints : testStrings) {
+        NSString *testString = [NSString stringWithCharacters:testCodePoints.data() length:testCodePoints.size()];
+        for (auto&amp; locale : locales) {
+            for (auto&amp; lineBreakValue : lineBreakValues) {
+                __block bool didEvaluateJavaScript = false;
+                __block Vector&lt;unsigned&gt; webkitLocations;
+                [webView evaluateJavaScript:generateJavaScriptForTest(testString, locale, lineBreakValue) completionHandler:^(id value, NSError *error) {
+                    for (NSNumber *v in (NSArray *)value)
+                        webkitLocations.append(floor([v floatValue] + 0.5));
+                    didEvaluateJavaScript = true;
+                }];
+                TestWebKitAPI::Util::run(&amp;didEvaluateJavaScript);
+
+                const auto&amp; icuLocations = breakingLocationsFromICU(testCodePoints, locale, lineBreakValue);
+                EXPECT_EQ(icuLocations.size(), webkitLocations.size());
+                if (icuLocations.size() != webkitLocations.size())
+                    break;
+                for (size_t i = 0; i &lt; icuLocations.size(); ++i)
+                    EXPECT_EQ(icuLocations[i], webkitLocations[i]);
+            }
+        }
+    }
+}
+
+// Split up the tests because they take too long otherwise and people start thinking their computer is hung.
+TEST(WebKit2, LineBreaking1)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x0024, 0x31, 0x32, 0x33},
+        {0x00a3, 0x31, 0x32, 0x33},
+        {0x00a5, 0x31, 0x32, 0x33},
+        {0x20ac, 0x31, 0x32, 0x33},
+        {0x2116, 0x31, 0x32, 0x33},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking2)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x2025, 0x2025},
+        {0x4e00, 0x2025, 0x2026},
+        {0x4e00, 0x2026, 0x2025},
+        {0x4e00, 0x2026, 0x2026},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x0021},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking3)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x0025},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x003a},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x003b},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x003f},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x00a2},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking4)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x00b0},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2010},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2013},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2030},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2032},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking5)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2033},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x203c},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2047},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2048},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2049},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking6)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x2103},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3005},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x301c},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x303b},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3041},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking7)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3043},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3045},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3047},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3049},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3063},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking8)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3083},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3085},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3087},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x308e},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3095},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking9)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x3096},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x309d},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x309e},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a0},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a1},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking10)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a3},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a5},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a7},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30a9},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30c3},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking11)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30e3},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30e5},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30e7},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30ee},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30f5},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking12)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30f6},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30fb},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30fc},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30fd},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x30fe},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking13)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f0},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f1},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f2},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f3},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f4},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking14)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f5},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f6},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f7},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f8},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31f9},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking15)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31fa},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31fb},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31fc},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31fd},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31fe},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking16)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x31ff},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff01},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff05},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff1a},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff1b},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking17)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff1f},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff65},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff67},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff68},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff69},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking18)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6a},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6b},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6c},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6d},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6e},
+    };
+    testAFewStrings(testStrings);
+}
+
+TEST(WebKit2, LineBreaking19)
+{
+    Vector&lt;Vector&lt;UInt16&gt;&gt; testStrings = {
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff6f},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xff70},
+        {0x4e00, 0x4e8c, 0x4e09, 0x56db, 0xffe0},
+        {0xff04, 0x31, 0x32, 0x33},
+        {0xffe1, 0x31, 0x32, 0x33},
+        {0xffe5, 0x31, 0x32, 0x33}
+    };
+    testAFewStrings(testStrings);
+}
+
+
+#endif
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaAllAhemsvgfromrev212234trunkLayoutTestscss3linebreakresourcesAllAhemsvg"></a>
<div class="copfile"><h4>Copied: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg (from rev 212234, trunk/LayoutTests/css3/line-break/resources/AllAhem.svg) (0 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/AllAhem.svg        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; standalone=&quot;no&quot;?&gt;
+&lt;!DOCTYPE svg PUBLIC &quot;-//W3C//DTD SVG 1.1//EN&quot; &quot;http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&quot; &gt;
+&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
+&lt;metadata&gt;&lt;/metadata&gt;
+&lt;defs&gt;
+&lt;font id=&quot;Litherum&quot; horiz-adv-x=&quot;1024&quot;&gt;
+&lt;font-face units-per-em=&quot;1024&quot; ascent=&quot;1024&quot; descent=&quot;-1&quot;/&gt;
+&lt;glyph unicode=&quot;1&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;2&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;3&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x0021;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x0024;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x0025;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x003a;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x003b;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x003f;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x00a2;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x00a3;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x00a5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x00b0;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2010;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2013;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2025;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2026;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2030;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2032;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2033;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x203c;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2047;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2048;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2049;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x20ac;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2103;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x2116;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3005;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x301c;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x303b;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3041;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3043;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3045;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3047;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3049;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3063;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3083;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3085;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3087;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x308e;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3095;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x3096;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x309d;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x309e;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a0;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a1;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a3;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a7;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30a9;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30c3;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30e3;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30e5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30e7;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30ee;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30f5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30f6;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30fb;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30fc;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30fd;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x30fe;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f0;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f1;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f2;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f3;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f4;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f6;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f7;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f8;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31f9;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31fa;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31fb;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31fc;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31fd;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31fe;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x31ff;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x4e00;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x4e09;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x4e8c;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#x56db;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff01;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff04;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff05;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff1a;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff1b;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff1f;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff65;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff67;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff68;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff69;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6a;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6b;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6c;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6d;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6e;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff6f;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xff70;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xffe0;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xffe1;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;glyph unicode=&quot;&amp;#xffe5;&quot; horiz-adv-x=&quot;1024&quot; d=&quot;M0 0V1024H1024V0z&quot;/&gt;
+&lt;/font&gt;
+&lt;/defs&gt;
+&lt;/svg&gt;
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaLineBreakinghtml"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html (0 => 212235)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LineBreaking.html        2017-02-13 19:07:43 UTC (rev 212235)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;meta charset=&quot;utf-8&quot;&gt;
+&lt;style&gt;
+@font-face {
+    font-family: &quot;AllAhem&quot;;
+    src: url(&quot;AllAhem.svg&quot;) format(&quot;svg&quot;);
+}
+
+#test {
+    font: 20px &quot;AllAhem&quot;;
+}
+&lt;/style&gt;
+&lt;script&gt;
+function runTest(testContent, localeString, lineBreakValue) {
+    var container = document.getElementById(&quot;container&quot;);
+    var test = document.getElementById(&quot;test&quot;);
+
+    test.textContent = testContent;
+    container.lang = localeString;
+    container.style.webkitLineBreak = lineBreakValue;
+
+    var current = 0;
+    var breakpoints = [];
+    var clientRectsLength = 2;
+    for (var i = 1; clientRectsLength &gt; 1; i += 5) {
+        container.style.width = &quot;&quot; + i + &quot;px&quot;;
+        var width = test.getClientRects()[0].width;
+        if (current != width) {
+            current = width;
+            breakpoints.push(width / 20);
+        }
+        clientRectsLength = test.getClientRects().length;
+    }
+    return breakpoints;
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div id=&quot;container&quot; style=&quot;width: 99999999px;&quot;&gt;
+    &lt;span id=&quot;test&quot;&gt;Hello World&lt;/span&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre>
</div>
</div>

</body>
</html>