<!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>[205396] 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/205396">205396</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-09-02 22:52:44 -0700 (Fri, 02 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Cocoa] Distinguish between paint advances and base advances
https://bugs.webkit.org/show_bug.cgi?id=160892

Reviewed by Simon Fraser.

Source/WebCore:

This patch introduces the concept of a layout (or &quot;base&quot;) advance which is distinct
from a painting advance. In extremely complicated scripts such as Urdu, it is common
for a glyph advance to be negative in the horizontal direction, and have large advances
in the vertical direction. In particular, in cursive scripts, the glyph placement is
only indirectly related to where the actual characters lie. Conceptually, these glyph
locations are correct for painting, but are not correct when performing width
measurements.

In many text engines, glyph shaping actually can be split into two phases: adjusting
advances, and then placing glyphs relative to those advances. The secondary glyph
placement step is much more context-sensitive than the first step. In addition, when
multiple glyphs combine to form a character, it is common for one glyph to own the
full base advance for the character, and for the other glyphs in the character to
have zero base advances. (Then, in the glyph placement phase, the other glyphs get
placed all around.)

Because of the context-insensitivity of the base advances, it is valuable to use
these for text measurement. Then, when we want to paint, we should add in the extra
origins. This dramatically improves the layout of complex fonts like Noto Nastaliq.

This patch migrates WebKit to use this two-phase shaping.

No new tests just yet, because I have to create a font which exercises the
advanced glyph placement support.

* platform/graphics/GlyphBuffer.h:
(WebCore::GlyphBufferAdvance::setHeight):
(WebCore::GlyphBufferAdvance::setWidth): Deleted.
* platform/graphics/TextRun.h:
(WebCore::TextRun::TextRun):
(WebCore::TextRun::shouldDisableLayoutSpecificAdvances):
(WebCore::TextRun::setShouldDisableLayoutSpecificAdvances):
(WebCore::TextRun::spacingDisabled): Deleted.
(WebCore::TextRun::setCharacterScanForCodePath): Deleted.
* platform/graphics/cocoa/FontCascadeCocoa.mm:
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
* platform/graphics/mac/ComplexTextController.cpp:
(WebCore::ComplexTextController::ComplexTextController):
(WebCore::ComplexTextController::offsetForPosition):
(WebCore::ComplexTextController::collectComplexTextRuns):
(WebCore::ComplexTextController::ComplexTextRun::setIsNonMonotonic):
(WebCore::ComplexTextController::runWidthSoFarFraction):
(WebCore::ComplexTextController::advance):
(WebCore::ComplexTextController::adjustGlyphsAndAdvances):
* platform/graphics/mac/ComplexTextController.h:
(WebCore::ComplexTextController::ComplexTextRun::create):
(WebCore::ComplexTextController::ComplexTextRun::baseAdvances):
(WebCore::ComplexTextController::ComplexTextRun::glyphOrigins):
(WebCore::ComplexTextController::useLayoutSpecificAdvances):
(WebCore::ComplexTextController::finalRoundingWidth): Deleted.
(WebCore::ComplexTextController::ComplexTextRun::advances): Deleted.
* platform/graphics/mac/ComplexTextControllerCoreText.mm:
(SOFT_LINK):
(WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* platform/spi/cocoa/CoreTextSPI.h:

LayoutTests:

Update tests. There are some expected (small) changes in metrics due to this patch.

* platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.png: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png.
* platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt.
* platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.png: Copied from LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png.
* platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt: Added.
* platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.png: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png.
* platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt.
* platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png:
* platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt:
* platform/mac/css2.1/t1508-c527-font-00-b-expected.png:
* platform/mac/css2.1/t1508-c527-font-00-b-expected.txt: Added.
* platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png:
* platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedpng">trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedtxt">trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmaccss21t1508c527font00bexpectedpng">trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedpng">trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedtxt">trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGlyphBufferh">trunk/Source/WebCore/platform/graphics/GlyphBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaFontCascadeCocoamm">trunk/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacComplexTextControllercpp">trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacComplexTextControllerh">trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacComplexTextControllerCoreTextmm">trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformspicocoaCoreTextSPIh">trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsplatformmaccss21t1508c527font00bexpectedtxt">trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.txt</a></li>
<li>trunk/LayoutTests/platform/mac-elcapitan/css2.1/</li>
<li><a href="#trunkLayoutTestsplatformmacelcapitancss21t051202c26psudonest00cexpectedpng">trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmacelcapitancss21t051202c26psudonest00cexpectedtxt">trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacelcapitancss21t1508c527font00bexpectedpng">trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmacelcapitancss21t1508c527font00bexpectedtxt">trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt</a></li>
<li>trunk/LayoutTests/platform/mac-elcapitan/fast/inline/</li>
<li><a href="#trunkLayoutTestsplatformmacelcapitanfastinlineabsolutepositionedinlineincentredblockexpectedpng">trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.png</a></li>
<li><a href="#trunkLayoutTestsplatformmacelcapitanfastinlineabsolutepositionedinlineincentredblockexpectedtxt">trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/LayoutTests/ChangeLog        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2016-09-02  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] Distinguish between paint advances and base advances
+        https://bugs.webkit.org/show_bug.cgi?id=160892
+
+        Reviewed by Simon Fraser.
+
+        Update tests. There are some expected (small) changes in metrics due to this patch.
+
+        * platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.png: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png.
+        * platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt.
+        * platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.png: Copied from LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png.
+        * platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt: Added.
+        * platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.png: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png.
+        * platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt.
+        * platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png:
+        * platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt:
+        * platform/mac/css2.1/t1508-c527-font-00-b-expected.png:
+        * platform/mac/css2.1/t1508-c527-font-00-b-expected.txt: Added.
+        * platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png:
+        * platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt:
+
</ins><span class="cx"> 2016-09-02  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Should never be reached failure in WebCore::floatValueForLength
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedpng"></a>
<div class="binary"><h4>Modified: trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -56,13 +56,13 @@
</span><span class="cx">         RenderInline {STRONG} at (0,0) size 111x18
</span><span class="cx">           RenderText {#text} at (130,15) size 111x18
</span><span class="cx">             text run at (130,15) width 111: &quot;two characters&quot;
</span><del>-        RenderText {#text} at (240,15) size 452x18
-          text run at (240,15) width 121: &quot; in this paragraph &quot;
-          text run at (360,15) width 332: &quot;(a double-quote mark and a capital 'T') should be &quot;
-        RenderInline {STRONG} at (0,0) size 89x18
-          RenderText {#text} at (691,15) size 89x18
-            text run at (691,15) width 45: &quot;200% &quot;
-            text run at (735,15) width 45: &quot;bigger&quot;
</del><ins>+        RenderText {#text} at (240,15) size 451x18
+          text run at (240,15) width 120: &quot; in this paragraph &quot;
+          text run at (359,15) width 332: &quot;(a double-quote mark and a capital 'T') should be &quot;
+        RenderInline {STRONG} at (0,0) size 90x18
+          RenderText {#text} at (690,15) size 90x18
+            text run at (690,15) width 45: &quot;200% &quot;
+            text run at (734,15) width 46: &quot;bigger&quot;
</ins><span class="cx">         RenderText {#text} at (0,37) size 223x18
</span><span class="cx">           text run at (0,37) width 223: &quot;than the rest of the paragraph, and &quot;
</span><span class="cx">         RenderInline {STRONG} at (0,0) size 34x18
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmaccss21t1508c527font00bexpectedpng"></a>
<div class="binary"><h4>Modified: trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmaccss21t1508c527font00bexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.txt (0 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x101
+  RenderBlock {HTML} at (0,0) size 800x101
+    RenderBody {BODY} at (8,13) size 784x75 [color=#000080]
+      RenderBlock {P} at (0,0) size 784x75
+        RenderText {#text} at (0,0) size 616x15
+          text run at (0,0) width 616: &quot;This text should be 13px Helvetica in small-caps and italicized. There should be a small gap between each line. &quot;
+        RenderInline {SPAN} at (0,0) size 781x75 [color=#C0C0C0]
+          RenderText {#text} at (615,0) size 781x75
+            text run at (615,0) width 166: &quot;dummy text dummy text dummy&quot;
+            text run at (0,15) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,15) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,15) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,30) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,30) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,30) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,45) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,45) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,45) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,60) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,60) width 349: &quot;text dummy text dummy text dummy text dummy text dummy text&quot;
+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">Property changes on: trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Author Date Id Rev URL
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedpng"></a>
<div class="binary"><h4>Modified: trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -6,5 +6,5 @@
</span><span class="cx">       RenderBlock {DIV} at (0,0) size 784x0
</span><span class="cx"> layer at (250,562) size 303x28
</span><span class="cx">   RenderBlock (positioned) {FONT} at (250,562) size 303x28
</span><del>-    RenderText {#text} at (0,0) size 303x28
-      text run at (0,0) width 303: &quot;Hello World, And Stuff!&quot;
</del><ins>+    RenderText {#text} at (0,0) size 302x28
+      text run at (0,0) width 302: &quot;Hello World, And Stuff!&quot;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacelcapitancss21t051202c26psudonest00cexpectedpngfromrev205393trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedpng"></a>
<div class="binary"><h4>Copied: trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.png (from rev 205393, trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png)</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacelcapitancss21t051202c26psudonest00cexpectedtxtfromrev205393trunkLayoutTestsplatformmaccss21t051202c26psudonest00cexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt (from rev 205393, trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt) (0 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -0,0 +1,137 @@
</span><ins>+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x455
+  RenderBlock {HTML} at (0,0) size 800x455
+    RenderBody {BODY} at (8,16) size 784x431 [color=#0000FF]
+      RenderBlock {P} at (0,0) size 784x238
+        RenderInline (generated) at (0,0) size 88x166 [color=#00FFFF]
+          RenderText {#text} at (0,0) size 88x166
+            text run at (0,0) width 88: &quot;T&quot;
+        RenderText {#text} at (87,87) size 59x55
+          text run at (87,87) width 59: &quot;he &quot;
+        RenderInline {STRONG} at (0,0) size 205x55
+          RenderText {#text} at (145,87) size 205x55
+            text run at (145,87) width 205: &quot;first letter&quot;
+        RenderText {#text} at (349,87) size 780x97
+          text run at (349,87) width 431: &quot; of this paragraph, and&quot;
+          text run at (0,166) width 61: &quot;only that &quot;
+          text run at (60,166) width 98: &quot;one, should be &quot;
+        RenderInline {STRONG} at (0,0) size 88x18
+          RenderText {#text} at (157,166) size 88x18
+            text run at (157,166) width 88: &quot;600% bigger&quot;
+        RenderText {#text} at (244,166) size 527x18
+          text run at (244,166) width 138: &quot; than the normal text &quot;
+          text run at (381,166) width 390: &quot;(300% bigger than the rest of first line of this paragraph) and&quot;
+        RenderInline {STRONG} at (0,0) size 34x18
+          RenderText {#text} at (0,184) size 34x18
+            text run at (0,184) width 34: &quot;aqua&quot;
+        RenderText {#text} at (33,184) size 113x18
+          text run at (33,184) width 113: &quot;, while the entire &quot;
+        RenderInline {STRONG} at (0,0) size 57x18
+          RenderText {#text} at (145,184) size 57x18
+            text run at (145,184) width 57: &quot;first line&quot;
+        RenderText {#text} at (201,184) size 71x18
+          text run at (201,184) width 5: &quot; &quot;
+          text run at (205,184) width 67: &quot;should be &quot;
+        RenderInline {STRONG} at (0,0) size 89x18
+          RenderText {#text} at (271,184) size 89x18
+            text run at (271,184) width 89: &quot;300% bigger&quot;
+        RenderText {#text} at (359,184) size 113x18
+          text run at (359,184) width 113: &quot; than normal and &quot;
+        RenderInline {STRONG} at (0,0) size 25x18
+          RenderText {#text} at (471,184) size 25x18
+            text run at (471,184) width 25: &quot;teal&quot;
+        RenderText {#text} at (495,184) size 778x54
+          text run at (495,184) width 281: &quot;. If this precise combination does not occur,&quot;
+          text run at (0,202) width 421: &quot;then the user agent has failed this test. Remember that in order to &quot;
+          text run at (420,202) width 358: &quot;ensure a complete test, the paragraph must be displayed&quot;
+          text run at (0,220) width 57: &quot;on more &quot;
+          text run at (56,220) width 149: &quot;than one line. (TEST1)&quot;
+      RenderBlock {P} at (0,254) size 784x73
+        RenderInline (generated) at (0,0) size 33x37 [color=#00FFFF]
+          RenderText {#text} at (0,0) size 33x37
+            text run at (0,0) width 33: &quot;\&quot;T&quot;
+        RenderText {#text} at (32,15) size 99x18
+          text run at (32,15) width 99: &quot;est\&quot;: The first &quot;
+        RenderInline {STRONG} at (0,0) size 111x18
+          RenderText {#text} at (130,15) size 111x18
+            text run at (130,15) width 111: &quot;two characters&quot;
+        RenderText {#text} at (240,15) size 452x18
+          text run at (240,15) width 121: &quot; in this paragraph &quot;
+          text run at (360,15) width 332: &quot;(a double-quote mark and a capital 'T') should be &quot;
+        RenderInline {STRONG} at (0,0) size 89x18
+          RenderText {#text} at (691,15) size 89x18
+            text run at (691,15) width 45: &quot;200% &quot;
+            text run at (735,15) width 45: &quot;bigger&quot;
+        RenderText {#text} at (0,37) size 223x18
+          text run at (0,37) width 223: &quot;than the rest of the paragraph, and &quot;
+        RenderInline {STRONG} at (0,0) size 34x18
+          RenderText {#text} at (222,37) size 34x18
+            text run at (222,37) width 34: &quot;aqua&quot;
+        RenderText {#text} at (255,37) size 151x18
+          text run at (255,37) width 151: &quot;. In addition, the entire &quot;
+        RenderInline {STRONG} at (0,0) size 58x18
+          RenderText {#text} at (405,37) size 58x18
+            text run at (405,37) width 33: &quot;first &quot;
+            text run at (437,37) width 26: &quot;line&quot;
+        RenderText {#text} at (462,37) size 98x18
+          text run at (462,37) width 98: &quot; should be in a &quot;
+        RenderInline {STRONG} at (0,0) size 163x18
+          RenderText {#text} at (559,37) size 163x18
+            text run at (559,37) width 138: &quot;small-caps font and &quot;
+            text run at (696,37) width 26: &quot;teal&quot;
+        RenderText {#text} at (721,37) size 738x36
+          text run at (721,37) width 5: &quot;.&quot;
+          text run at (0,55) width 323: &quot;Remember that in order to ensure a complete test, &quot;
+          text run at (322,55) width 416: &quot;the paragraph must be displayed on more than one line. (TEST2)&quot;
+      RenderBlock {P} at (0,343) size 784x54
+        RenderInline (generated) at (0,0) size 10x18 [color=#00FFFF]
+          RenderText {#text} at (0,0) size 10x18
+            text run at (0,0) width 10: &quot;T&quot;
+        RenderText {#text} at (9,0) size 20x18
+          text run at (9,0) width 20: &quot;he &quot;
+        RenderInline {STRONG} at (0,0) size 69x18
+          RenderText {#text} at (28,0) size 69x18
+            text run at (28,0) width 69: &quot;first letter&quot;
+        RenderText {#text} at (96,0) size 306x18
+          text run at (96,0) width 209: &quot; of this paragraph, and only that &quot;
+          text run at (304,0) width 98: &quot;one, should be &quot;
+        RenderInline {STRONG} at (0,0) size 35x18
+          RenderText {#text} at (401,0) size 35x18
+            text run at (401,0) width 35: &quot;aqua&quot;
+        RenderText {#text} at (435,0) size 112x18
+          text run at (435,0) width 112: &quot;, while the entire &quot;
+        RenderInline {STRONG} at (0,0) size 58x18
+          RenderText {#text} at (546,0) size 58x18
+            text run at (546,0) width 58: &quot;first line&quot;
+        RenderText {#text} at (603,0) size 71x18
+          text run at (603,0) width 71: &quot; should be &quot;
+        RenderInline {STRONG} at (0,0) size 26x18
+          RenderText {#text} at (673,0) size 26x18
+            text run at (673,0) width 26: &quot;teal&quot;
+        RenderText {#text} at (698,0) size 770x54
+          text run at (698,0) width 23: &quot;. If &quot;
+          text run at (720,0) width 24: &quot;this&quot;
+          text run at (0,18) width 384: &quot;precise combination does not occur, then the user agent has &quot;
+          text run at (383,18) width 387: &quot;failed this test. Remember that in order to ensure a complete&quot;
+          text run at (0,36) width 31: &quot;test, &quot;
+          text run at (30,36) width 416: &quot;the paragraph must be displayed on more than one line. (TEST3)&quot;
+      RenderBlock {DIV} at (0,413) size 784x18
+        RenderText {#text} at (0,0) size 168x18
+          text run at (0,0) width 168: &quot;You should see the words &quot;
+        RenderInline {STRONG} at (0,0) size 68x18
+          RenderText {#text} at (167,0) size 68x18
+            text run at (167,0) width 68: &quot;\&quot;TEST1\&quot;&quot;
+        RenderText {#text} at (234,0) size 9x18
+          text run at (234,0) width 9: &quot;, &quot;
+        RenderInline {STRONG} at (0,0) size 68x18
+          RenderText {#text} at (242,0) size 68x18
+            text run at (242,0) width 68: &quot;\&quot;TEST2\&quot;&quot;
+        RenderText {#text} at (309,0) size 36x18
+          text run at (309,0) width 36: &quot;, and &quot;
+        RenderInline {STRONG} at (0,0) size 67x18
+          RenderText {#text} at (344,0) size 67x18
+            text run at (344,0) width 67: &quot;\&quot;TEST3\&quot;&quot;
+        RenderText {#text} at (410,0) size 241x18
+          text run at (410,0) width 89: &quot; at the end of &quot;
+          text run at (498,0) width 153: &quot;three paragraphs above.&quot;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacelcapitancss21t1508c527font00bexpectedpngfromrev205393trunkLayoutTestsplatformmaccss21t1508c527font00bexpectedpng"></a>
<div class="binary"><h4>Copied: trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.png (from rev 205393, trunk/LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png)</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacelcapitancss21t1508c527font00bexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt (0 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x101
+  RenderBlock {HTML} at (0,0) size 800x101
+    RenderBody {BODY} at (8,13) size 784x75 [color=#000080]
+      RenderBlock {P} at (0,0) size 784x75
+        RenderText {#text} at (0,0) size 617x15
+          text run at (0,0) width 617: &quot;This text should be 13px Helvetica in small-caps and italicized. There should be a small gap between each line. &quot;
+        RenderInline {SPAN} at (0,0) size 781x75 [color=#C0C0C0]
+          RenderText {#text} at (616,0) size 781x75
+            text run at (616,0) width 165: &quot;dummy text dummy text dummy&quot;
+            text run at (0,15) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,15) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,15) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,30) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,30) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,30) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,45) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,45) width 390: &quot;text dummy text dummy text dummy text dummy text dummy text dummy &quot;
+            text run at (583,45) width 192: &quot;text dummy text dummy text dummy&quot;
+            text run at (0,60) width 195: &quot;text dummy text dummy text dummy &quot;
+            text run at (194,60) width 349: &quot;text dummy text dummy text dummy text dummy text dummy text&quot;
+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">Property changes on: trunk/LayoutTests/platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Author Date Id Rev URL
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestsplatformmacelcapitanfastinlineabsolutepositionedinlineincentredblockexpectedpngfromrev205393trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedpng"></a>
<div class="binary"><h4>Copied: trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.png (from rev 205393, trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png)</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacelcapitanfastinlineabsolutepositionedinlineincentredblockexpectedtxtfromrev205393trunkLayoutTestsplatformmacfastinlineabsolutepositionedinlineincentredblockexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt (from rev 205393, trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt) (0 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 784x0
+layer at (250,562) size 303x28
+  RenderBlock (positioned) {FONT} at (250,562) size 303x28
+    RenderText {#text} at (0,0) size 303x28
+      text run at (0,0) width 303: &quot;Hello World, And Stuff!&quot;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/ChangeLog        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2016-09-02  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] Distinguish between paint advances and base advances
+        https://bugs.webkit.org/show_bug.cgi?id=160892
+
+        Reviewed by Simon Fraser.
+
+        This patch introduces the concept of a layout (or &quot;base&quot;) advance which is distinct
+        from a painting advance. In extremely complicated scripts such as Urdu, it is common
+        for a glyph advance to be negative in the horizontal direction, and have large advances
+        in the vertical direction. In particular, in cursive scripts, the glyph placement is
+        only indirectly related to where the actual characters lie. Conceptually, these glyph
+        locations are correct for painting, but are not correct when performing width
+        measurements.
+
+        In many text engines, glyph shaping actually can be split into two phases: adjusting
+        advances, and then placing glyphs relative to those advances. The secondary glyph
+        placement step is much more context-sensitive than the first step. In addition, when
+        multiple glyphs combine to form a character, it is common for one glyph to own the
+        full base advance for the character, and for the other glyphs in the character to
+        have zero base advances. (Then, in the glyph placement phase, the other glyphs get
+        placed all around.)
+
+        Because of the context-insensitivity of the base advances, it is valuable to use
+        these for text measurement. Then, when we want to paint, we should add in the extra
+        origins. This dramatically improves the layout of complex fonts like Noto Nastaliq.
+
+        This patch migrates WebKit to use this two-phase shaping.
+
+        No new tests just yet, because I have to create a font which exercises the
+        advanced glyph placement support.
+
+        * platform/graphics/GlyphBuffer.h:
+        (WebCore::GlyphBufferAdvance::setHeight):
+        (WebCore::GlyphBufferAdvance::setWidth): Deleted.
+        * platform/graphics/TextRun.h:
+        (WebCore::TextRun::TextRun):
+        (WebCore::TextRun::shouldDisableLayoutSpecificAdvances):
+        (WebCore::TextRun::setShouldDisableLayoutSpecificAdvances):
+        (WebCore::TextRun::spacingDisabled): Deleted.
+        (WebCore::TextRun::setCharacterScanForCodePath): Deleted.
+        * platform/graphics/cocoa/FontCascadeCocoa.mm:
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
+        * platform/graphics/mac/ComplexTextController.cpp:
+        (WebCore::ComplexTextController::ComplexTextController):
+        (WebCore::ComplexTextController::offsetForPosition):
+        (WebCore::ComplexTextController::collectComplexTextRuns):
+        (WebCore::ComplexTextController::ComplexTextRun::setIsNonMonotonic):
+        (WebCore::ComplexTextController::runWidthSoFarFraction):
+        (WebCore::ComplexTextController::advance):
+        (WebCore::ComplexTextController::adjustGlyphsAndAdvances):
+        * platform/graphics/mac/ComplexTextController.h:
+        (WebCore::ComplexTextController::ComplexTextRun::create):
+        (WebCore::ComplexTextController::ComplexTextRun::baseAdvances):
+        (WebCore::ComplexTextController::ComplexTextRun::glyphOrigins):
+        (WebCore::ComplexTextController::useLayoutSpecificAdvances):
+        (WebCore::ComplexTextController::finalRoundingWidth): Deleted.
+        (WebCore::ComplexTextController::ComplexTextRun::advances): Deleted.
+        * platform/graphics/mac/ComplexTextControllerCoreText.mm:
+        (SOFT_LINK):
+        (WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+        * platform/spi/cocoa/CoreTextSPI.h:
+
</ins><span class="cx"> 2016-09-02  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Should never be reached failure in WebCore::floatValueForLength
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGlyphBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GlyphBuffer.h (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GlyphBuffer.h        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/graphics/GlyphBuffer.h        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void setWidth(CGFloat width) { this-&gt;CGSize::width = width; }
</span><ins>+    void setHeight(CGFloat height) { this-&gt;CGSize::height = height; }
</ins><span class="cx">     CGFloat width() const { return this-&gt;CGSize::width; }
</span><span class="cx">     CGFloat height() const { return this-&gt;CGSize::height; }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaFontCascadeCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -514,7 +514,7 @@
</span><span class="cx">     float afterWidth = controller.runWidthSoFar();
</span><span class="cx"> 
</span><span class="cx">     if (run.rtl()) {
</span><del>-        initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth + controller.leadingExpansion();
</del><ins>+        initialAdvance = controller.totalWidth() - afterWidth + controller.leadingExpansion();
</ins><span class="cx">         glyphBuffer.reverse(0, glyphBuffer.size());
</span><span class="cx">     } else
</span><span class="cx">         initialAdvance = beforeWidth;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacComplexTextControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -107,28 +107,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ComplexTextController::ComplexTextController(const FontCascade&amp; font, const TextRun&amp; run, bool mayUseNaturalWritingDirection, HashSet&lt;const Font*&gt;* fallbackFonts, bool forTextEmphasis)
</span><del>-    : m_font(font)
</del><ins>+    : m_fallbackFonts(fallbackFonts)
+    , m_font(font)
</ins><span class="cx">     , m_run(run)
</span><del>-    , m_isLTROnly(true)
</del><ins>+    , m_end(run.length())
+    , m_expansion(run.expansion())
</ins><span class="cx">     , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
</span><span class="cx">     , m_forTextEmphasis(forTextEmphasis)
</span><del>-    , m_currentCharacter(0)
-    , m_end(run.length())
-    , m_totalWidth(0)
-    , m_runWidthSoFar(0)
-    , m_numGlyphsSoFar(0)
-    , m_currentRun(0)
-    , m_glyphInCurrentRun(0)
-    , m_characterInCurrentGlyph(0)
-    , m_finalRoundingWidth(0)
-    , m_expansion(run.expansion())
-    , m_leadingExpansion(0)
-    , m_fallbackFonts(fallbackFonts)
-    , m_minGlyphBoundingBoxX(std::numeric_limits&lt;float&gt;::max())
-    , m_maxGlyphBoundingBoxX(std::numeric_limits&lt;float&gt;::min())
-    , m_minGlyphBoundingBoxY(std::numeric_limits&lt;float&gt;::max())
-    , m_maxGlyphBoundingBoxY(std::numeric_limits&lt;float&gt;::min())
-    , m_lastRoundingGlyph(0)
</del><span class="cx"> {
</span><span class="cx">     if (!m_expansion)
</span><span class="cx">         m_expansionPerOpportunity = 0;
</span><span class="lines">@@ -158,7 +143,7 @@
</span><span class="cx">     m_runWidthSoFar = m_leadingExpansion;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)
</del><ins>+unsigned ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)
</ins><span class="cx"> {
</span><span class="cx">     if (h &gt;= m_totalWidth)
</span><span class="cx">         return m_run.ltr() ? m_end : 0;
</span><span class="lines">@@ -176,7 +161,7 @@
</span><span class="cx">         const ComplexTextRun&amp; complexTextRun = *m_complexTextRuns[r];
</span><span class="cx">         for (unsigned j = 0; j &lt; complexTextRun.glyphCount(); ++j) {
</span><span class="cx">             size_t index = offsetIntoAdjustedGlyphs + j;
</span><del>-            CGFloat adjustedAdvance = m_adjustedAdvances[index].width;
</del><ins>+            CGFloat adjustedAdvance = m_adjustedBaseAdvances[index].width;
</ins><span class="cx">             if (!index)
</span><span class="cx">                 adjustedAdvance += complexTextRun.initialAdvance().width;
</span><span class="cx">             if (x &lt; adjustedAdvance) {
</span><span class="lines">@@ -188,8 +173,7 @@
</span><span class="cx">                     hitGlyphEnd = std::max&lt;CFIndex&gt;(hitGlyphStart, j &gt; 0 ? complexTextRun.indexAt(j - 1) : static_cast&lt;CFIndex&gt;(complexTextRun.indexEnd()));
</span><span class="cx"> 
</span><span class="cx">                 // FIXME: Instead of dividing the glyph's advance equally between the characters, this
</span><del>-                // could use the glyph's &quot;ligature carets&quot;. However, there is no Core Text API to get the
-                // ligature carets.
</del><ins>+                // could use the glyph's &quot;ligature carets&quot;. This is available in CoreText via CTFontGetLigatureCaretPositions().
</ins><span class="cx">                 CFIndex hitIndex = hitGlyphStart + (hitGlyphEnd - hitGlyphStart) * (m_run.ltr() ? x / adjustedAdvance : 1 - x / adjustedAdvance);
</span><span class="cx">                 int stringLength = complexTextRun.stringLength();
</span><span class="cx">                 TextBreakIterator* cursorPositionIterator = cursorMovementIterator(StringView(complexTextRun.characters(), stringLength));
</span><span class="lines">@@ -217,7 +201,7 @@
</span><span class="cx">                     clusterWidth = adjustedAdvance;
</span><span class="cx">                     int firstGlyphBeforeCluster = j - 1;
</span><span class="cx">                     while (firstGlyphBeforeCluster &gt;= 0 &amp;&amp; complexTextRun.indexAt(firstGlyphBeforeCluster) &gt;= clusterStart &amp;&amp; complexTextRun.indexAt(firstGlyphBeforeCluster) &lt; clusterEnd) {
</span><del>-                        CGFloat width = m_adjustedAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width;
</del><ins>+                        CGFloat width = m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width;
</ins><span class="cx">                         clusterWidth += width;
</span><span class="cx">                         x += width;
</span><span class="cx">                         firstGlyphBeforeCluster--;
</span><span class="lines">@@ -224,7 +208,7 @@
</span><span class="cx">                     }
</span><span class="cx">                     unsigned firstGlyphAfterCluster = j + 1;
</span><span class="cx">                     while (firstGlyphAfterCluster &lt; complexTextRun.glyphCount() &amp;&amp; complexTextRun.indexAt(firstGlyphAfterCluster) &gt;= clusterStart &amp;&amp; complexTextRun.indexAt(firstGlyphAfterCluster) &lt; clusterEnd) {
</span><del>-                        clusterWidth += m_adjustedAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width;
</del><ins>+                        clusterWidth += m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width;
</ins><span class="cx">                         firstGlyphAfterCluster++;
</span><span class="cx">                     }
</span><span class="cx">                 } else {
</span><span class="lines">@@ -325,8 +309,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_run.is8Bit()) {
</span><span class="cx">         String stringFor8BitRun = String::make16BitFrom8BitSource(m_run.characters8(), m_run.length());
</span><del>-        cp = stringFor8BitRun.characters16();
-        m_stringsFor8BitRuns.append(stringFor8BitRun);
</del><ins>+        m_stringsFor8BitRuns.append(WTFMove(stringFor8BitRun));
+        cp = m_stringsFor8BitRuns.last().characters16();
</ins><span class="cx">     } else
</span><span class="cx">         cp = m_run.characters16();
</span><span class="cx"> 
</span><span class="lines">@@ -428,6 +412,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ASSERT(m_end &gt;= indexOfFontTransition);
</ins><span class="cx">     unsigned itemLength = m_end - indexOfFontTransition;
</span><span class="cx">     if (itemLength) {
</span><span class="cx">         unsigned itemStart = indexOfFontTransition;
</span><span class="lines">@@ -463,7 +448,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_glyphEndOffsets.grow(m_glyphCount);
</span><del>-    for (size_t i = 0; i &lt; m_glyphCount; ++i) {
</del><ins>+    for (unsigned i = 0; i &lt; m_glyphCount; ++i) {
</ins><span class="cx">         CFIndex nextMappedIndex = m_indexEnd;
</span><span class="cx">         for (size_t j = indexAt(i) + 1; j &lt; m_stringLength; ++j) {
</span><span class="cx">             if (mappedIndices[j]) {
</span><span class="lines">@@ -530,9 +515,28 @@
</span><span class="cx">     return indexOfCurrentRun(leftmostGlyph);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+float ComplexTextController::runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle iterationStyle) const
+{
+    // FIXME: Instead of dividing the glyph's advance equally between the characters, this
+    // could use the glyph's &quot;ligature carets&quot;. This is available in CoreText via CTFontGetLigatureCaretPositions().
+    if (glyphStartOffset == glyphEndOffset) {
+        // When there are multiple glyphs per character we need to advance by the full width of the glyph.
+        ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph);
+        return 1;
+    }
+
+    if (iterationStyle == ByWholeGlyphs) {
+        if (!oldCharacterInCurrentGlyph)
+            return 1;
+        return 0;
+    }
+
+    return static_cast&lt;float&gt;(m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset);
+}
+
</ins><span class="cx"> void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle, HashSet&lt;const Font*&gt;* fallbackFonts)
</span><span class="cx"> {
</span><del>-    if (static_cast&lt;int&gt;(offset) &gt; m_end)
</del><ins>+    if (offset &gt; m_end)
</ins><span class="cx">         offset = m_end;
</span><span class="cx"> 
</span><span class="cx">     if (offset &lt;= m_currentCharacter) {
</span><span class="lines">@@ -562,7 +566,14 @@
</span><span class="cx">         // When leftmostGlyph is 0, it represents the first glyph to draw, taking into
</span><span class="cx">         // account the text direction.
</span><span class="cx">         if (glyphBuffer &amp;&amp; !leftmostGlyph) {
</span><del>-            glyphBuffer-&gt;setInitialAdvance(complexTextRun.initialAdvance());
</del><ins>+            CGSize initialAdvance = complexTextRun.initialAdvance();
+#if USE_LAYOUT_SPECIFIC_ADVANCES
+            unsigned index = ltr ? 0 : m_glyphOrigins.size() - 1;
+            initialAdvance.width += m_glyphOrigins[index].x;
+            initialAdvance.height += m_glyphOrigins[index].y;
+#endif
+            glyphBuffer-&gt;setInitialAdvance(initialAdvance);
+
</ins><span class="cx">             glyphBuffer-&gt;setLeadingExpansion(m_leadingExpansion);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -577,28 +588,25 @@
</span><span class="cx">             } else
</span><span class="cx">                 glyphEndOffset = complexTextRun.endOffsetAt(g);
</span><span class="cx"> 
</span><del>-            CGSize adjustedAdvance = m_adjustedAdvances[k];
</del><ins>+            CGSize adjustedBaseAdvance = m_adjustedBaseAdvances[k];
</ins><span class="cx"> 
</span><span class="cx">             if (glyphStartOffset + complexTextRun.stringLocation() &gt;= m_currentCharacter)
</span><span class="cx">                 return;
</span><span class="cx"> 
</span><del>-            if (glyphBuffer &amp;&amp; !m_characterInCurrentGlyph)
-                glyphBuffer-&gt;add(m_adjustedGlyphs[k], &amp;complexTextRun.font(), adjustedAdvance, complexTextRun.indexAt(m_glyphInCurrentRun));
</del><ins>+            if (glyphBuffer &amp;&amp; !m_characterInCurrentGlyph) {
+                GlyphBufferAdvance paintAdvance = adjustedBaseAdvance;
+#if USE_LAYOUT_SPECIFIC_ADVANCES
+                if (k + 1 &lt; m_adjustedBaseAdvances.size()) {
+                    paintAdvance.setWidth(paintAdvance.width() + m_glyphOrigins[k + 1].x - m_glyphOrigins[k].x);
+                    paintAdvance.setHeight(paintAdvance.height() - m_glyphOrigins[k + 1].y + m_glyphOrigins[k].y);
+                }
+#endif
+                glyphBuffer-&gt;add(m_adjustedGlyphs[k], &amp;complexTextRun.font(), paintAdvance, complexTextRun.indexAt(m_glyphInCurrentRun));
+            }
</ins><span class="cx"> 
</span><span class="cx">             unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph;
</span><span class="cx">             m_characterInCurrentGlyph = std::min(m_currentCharacter - complexTextRun.stringLocation(), glyphEndOffset) - glyphStartOffset;
</span><del>-            // FIXME: Instead of dividing the glyph's advance equally between the characters, this
-            // could use the glyph's &quot;ligature carets&quot;. However, there is no Core Text API to get the
-            // ligature carets.
-            if (glyphStartOffset == glyphEndOffset) {
-                // When there are multiple glyphs per character we need to advance by the full width of the glyph.
-                ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph);
-                m_runWidthSoFar += adjustedAdvance.width;
-            } else if (iterationStyle == ByWholeGlyphs) {
-                if (!oldCharacterInCurrentGlyph)
-                    m_runWidthSoFar += adjustedAdvance.width;
-            } else
-                m_runWidthSoFar += adjustedAdvance.width * (m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset);
</del><ins>+            m_runWidthSoFar += adjustedBaseAdvance.width * runWidthSoFarFraction(glyphStartOffset, glyphEndOffset, oldCharacterInCurrentGlyph, iterationStyle);
</ins><span class="cx"> 
</span><span class="cx">             if (glyphEndOffset + complexTextRun.stringLocation() &gt; m_currentCharacter)
</span><span class="cx">                 return;
</span><span class="lines">@@ -617,8 +625,6 @@
</span><span class="cx">         currentRunIndex = incrementCurrentRun(leftmostGlyph);
</span><span class="cx">         m_glyphInCurrentRun = 0;
</span><span class="cx">     }
</span><del>-    if (!m_run.ltr() &amp;&amp; m_numGlyphsSoFar == m_adjustedAdvances.size())
-        m_runWidthSoFar += m_finalRoundingWidth;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline std::pair&lt;bool, bool&gt; expansionLocation(bool ideograph, bool treatAsSpace, bool ltr, bool isAfterExpansion, bool forbidLeadingExpansion, bool forbidTrailingExpansion, bool forceLeadingExpansion, bool forceTrailingExpansion)
</span><span class="lines">@@ -656,6 +662,7 @@
</span><span class="cx">     bool runForcesTrailingExpansion = (m_run.expansionBehavior() &amp; TrailingExpansionMask) == ForceTrailingExpansion;
</span><span class="cx">     bool runForbidsLeadingExpansion = (m_run.expansionBehavior() &amp; LeadingExpansionMask) == ForbidLeadingExpansion;
</span><span class="cx">     bool runForbidsTrailingExpansion = (m_run.expansionBehavior() &amp; TrailingExpansionMask) == ForbidTrailingExpansion;
</span><ins>+
</ins><span class="cx">     // We are iterating in glyph order, not string order. Compare this to WidthIterator::advanceInternal()
</span><span class="cx">     for (size_t r = 0; r &lt; runCount; ++r) {
</span><span class="cx">         ComplexTextRun&amp; complexTextRun = *m_complexTextRuns[r];
</span><span class="lines">@@ -664,11 +671,11 @@
</span><span class="cx"> 
</span><span class="cx">         // Represent the initial advance for a text run by adjusting the advance
</span><span class="cx">         // of the last glyph of the previous text run in the glyph buffer.
</span><del>-        if (r &amp;&amp; m_adjustedAdvances.size()) {
-            CGSize previousAdvance = m_adjustedAdvances.last();
</del><ins>+        if (r &amp;&amp; m_adjustedBaseAdvances.size()) {
+            CGSize previousAdvance = m_adjustedBaseAdvances.last();
</ins><span class="cx">             previousAdvance.width += complexTextRun.initialAdvance().width;
</span><span class="cx">             previousAdvance.height -= complexTextRun.initialAdvance().height;
</span><del>-            m_adjustedAdvances[m_adjustedAdvances.size() - 1] = previousAdvance;
</del><ins>+            m_adjustedBaseAdvances[m_adjustedBaseAdvances.size() - 1] = previousAdvance;
</ins><span class="cx">         }
</span><span class="cx">         widthSinceLastCommit += complexTextRun.initialAdvance().width;
</span><span class="cx"> 
</span><span class="lines">@@ -676,7 +683,7 @@
</span><span class="cx">             m_isLTROnly = false;
</span><span class="cx"> 
</span><span class="cx">         const CGGlyph* glyphs = complexTextRun.glyphs();
</span><del>-        const CGSize* advances = complexTextRun.advances();
</del><ins>+        const CGSize* advances = complexTextRun.baseAdvances();
</ins><span class="cx"> 
</span><span class="cx">         bool lastRun = r + 1 == runCount;
</span><span class="cx">         float spaceWidth = font.spaceWidth() - font.syntheticBoldOffset();
</span><span class="lines">@@ -750,10 +757,10 @@
</span><span class="cx">                             // Increase previous width
</span><span class="cx">                             m_expansion -= m_expansionPerOpportunity;
</span><span class="cx">                             m_totalWidth += m_expansionPerOpportunity;
</span><del>-                            if (m_adjustedAdvances.isEmpty())
</del><ins>+                            if (m_adjustedBaseAdvances.isEmpty())
</ins><span class="cx">                                 m_leadingExpansion = m_expansionPerOpportunity;
</span><span class="cx">                             else
</span><del>-                                m_adjustedAdvances.last().width += m_expansionPerOpportunity;
</del><ins>+                                m_adjustedBaseAdvances.last().width += m_expansionPerOpportunity;
</ins><span class="cx">                         }
</span><span class="cx">                         if (expandRight) {
</span><span class="cx">                             m_expansion -= m_expansionPerOpportunity;
</span><span class="lines">@@ -777,7 +784,10 @@
</span><span class="cx">                 glyph = 0;
</span><span class="cx"> 
</span><span class="cx">             advance.height *= -1;
</span><del>-            m_adjustedAdvances.append(advance);
</del><ins>+            m_adjustedBaseAdvances.append(advance);
+#if USE_LAYOUT_SPECIFIC_ADVANCES
+            m_glyphOrigins.append(complexTextRun.glyphOrigins()[i]);
+#endif
</ins><span class="cx">             m_adjustedGlyphs.append(glyph);
</span><span class="cx">             
</span><span class="cx">             FloatRect glyphBounds = font.boundsForGlyph(glyph);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacComplexTextControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><ins>+#define USE_LAYOUT_SPECIFIC_ADVANCES ((PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101100) || (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 90000))
+
</ins><span class="cx"> typedef unsigned short CGGlyph;
</span><span class="cx"> 
</span><span class="cx"> typedef const struct __CTRun * CTRunRef;
</span><span class="lines">@@ -56,7 +58,7 @@
</span><span class="cx">     void advance(unsigned to, GlyphBuffer* = nullptr, GlyphIterationStyle = IncludePartialGlyphs, HashSet&lt;const Font*&gt;* fallbackFonts = nullptr);
</span><span class="cx"> 
</span><span class="cx">     // Compute the character offset for a given x coordinate.
</span><del>-    int offsetForPosition(float x, bool includePartialGlyphs);
</del><ins>+    unsigned offsetForPosition(float x, bool includePartialGlyphs);
</ins><span class="cx"> 
</span><span class="cx">     // Returns the width of everything we've consumed so far.
</span><span class="cx">     float runWidthSoFar() const { return m_runWidthSoFar; }
</span><span class="lines">@@ -63,8 +65,6 @@
</span><span class="cx"> 
</span><span class="cx">     float totalWidth() const { return m_totalWidth; }
</span><span class="cx"> 
</span><del>-    float finalRoundingWidth() const { return m_finalRoundingWidth; }
-
</del><span class="cx">     float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; }
</span><span class="cx">     float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; }
</span><span class="cx">     float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; }
</span><span class="lines">@@ -95,8 +95,20 @@
</span><span class="cx">         CFIndex indexEnd() const { return m_indexEnd; }
</span><span class="cx">         CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
</span><span class="cx">         const CGGlyph* glyphs() const { return m_glyphs; }
</span><ins>+
+        /*
+         *                                              X (Paint glyph position)   X (Paint glyph position)   X (Paint glyph position)
+         *                                             7                          7                          7
+         *                                            /                          /                          /
+         *                                           / (Glyph origin)           / (Glyph origin)           / (Glyph origin)
+         *                                          /                          /                          /
+         *                                         /                          /                          /
+         *                X-----------------------X--------------------------X--------------------------X----&gt;...
+         * (text position ^)  (initial advance)          (base advance)             (base advance)
+         */
</ins><span class="cx">         CGSize initialAdvance() const { return m_initialAdvance; }
</span><del>-        const CGSize* advances() const { return m_advances; }
</del><ins>+        const CGSize* baseAdvances() const { return m_baseAdvances; }
+        const CGPoint* glyphOrigins() const { return m_glyphOrigins.data(); }
</ins><span class="cx">         bool isLTR() const { return m_isLTR; }
</span><span class="cx">         bool isMonotonic() const { return m_isMonotonic; }
</span><span class="cx">         void setIsNonMonotonic();
</span><span class="lines">@@ -105,21 +117,22 @@
</span><span class="cx">         ComplexTextRun(CTRunRef, const Font&amp;, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange);
</span><span class="cx">         ComplexTextRun(const Font&amp;, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr);
</span><span class="cx"> 
</span><del>-        unsigned m_glyphCount;
</del><ins>+        Vector&lt;CGSize, 64&gt; m_baseAdvancesVector;
+        Vector&lt;CGPoint, 64&gt; m_glyphOrigins;
+        Vector&lt;CGGlyph, 64&gt; m_glyphsVector;
+        Vector&lt;CFIndex, 64&gt; m_glyphEndOffsets;
+        Vector&lt;CFIndex, 64&gt; m_coreTextIndicesVector;
+        CGSize m_initialAdvance;
</ins><span class="cx">         const Font&amp; m_font;
</span><span class="cx">         const UChar* m_characters;
</span><del>-        unsigned m_stringLocation;
</del><span class="cx">         size_t m_stringLength;
</span><del>-        Vector&lt;CFIndex, 64&gt; m_coreTextIndicesVector;
</del><span class="cx">         const CFIndex* m_coreTextIndices;
</span><ins>+        const CGGlyph* m_glyphs;
+        const CGSize* m_baseAdvances;
</ins><span class="cx">         CFIndex m_indexBegin;
</span><span class="cx">         CFIndex m_indexEnd;
</span><del>-        Vector&lt;CFIndex, 64&gt; m_glyphEndOffsets;
-        Vector&lt;CGGlyph, 64&gt; m_glyphsVector;
-        const CGGlyph* m_glyphs;
-        CGSize m_initialAdvance;
-        Vector&lt;CGSize, 64&gt; m_advancesVector;
-        const CGSize* m_advances;
</del><ins>+        unsigned m_glyphCount;
+        unsigned m_stringLocation;
</ins><span class="cx">         bool m_isLTR;
</span><span class="cx">         bool m_isMonotonic;
</span><span class="cx">     };
</span><span class="lines">@@ -135,18 +148,12 @@
</span><span class="cx">     unsigned indexOfCurrentRun(unsigned&amp; leftmostGlyph);
</span><span class="cx">     unsigned incrementCurrentRun(unsigned&amp; leftmostGlyph);
</span><span class="cx"> 
</span><del>-    // The initial capacity of these vectors was selected as being the smallest power of two greater than
-    // the average (3.5) plus one standard deviation (7.5) of nonzero sizes used on Arabic Wikipedia.
-    Vector&lt;unsigned, 16&gt; m_runIndices;
-    Vector&lt;unsigned, 16&gt; m_glyphCountFromStartToIndex;
</del><ins>+    float runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle) const;
</ins><span class="cx"> 
</span><del>-    const FontCascade&amp; m_font;
-    const TextRun&amp; m_run;
-    bool m_isLTROnly;
-    bool m_mayUseNaturalWritingDirection;
-    bool m_forTextEmphasis;
</del><ins>+    Vector&lt;CGSize, 256&gt; m_adjustedBaseAdvances;
+    Vector&lt;CGPoint, 256&gt; m_glyphOrigins;
+    Vector&lt;CGGlyph, 256&gt; m_adjustedGlyphs;
</ins><span class="cx"> 
</span><del>-    Vector&lt;String&gt; m_stringsFor8BitRuns;
</del><span class="cx">     Vector&lt;UChar, 256&gt; m_smallCapsBuffer;
</span><span class="cx"> 
</span><span class="cx">     // There is a 3-level hierarchy here. At the top, we are interested in m_run.string(). We partition that string
</span><span class="lines">@@ -156,34 +163,43 @@
</span><span class="cx">     // relative to m_run.string(). ComplexTextRun::indexAt() returns to the offset of a codepoint relative to
</span><span class="cx">     // its Line. ComplexTextRun::glyphs() and ComplexTextRun::advances() refer to glyphs relative to the ComplexTextRun.
</span><span class="cx">     // The length of the entire TextRun is m_run.length()
</span><del>-    Vector&lt;RetainPtr&lt;CTLineRef&gt;&gt; m_coreTextLines;
</del><span class="cx">     Vector&lt;RefPtr&lt;ComplexTextRun&gt;, 16&gt; m_complexTextRuns;
</span><del>-    Vector&lt;CGSize, 256&gt; m_adjustedAdvances;
-    Vector&lt;CGGlyph, 256&gt; m_adjustedGlyphs;

-    unsigned m_currentCharacter;
-    int m_end;
</del><span class="cx"> 
</span><del>-    CGFloat m_totalWidth;
</del><ins>+    // The initial capacity of these vectors was selected as being the smallest power of two greater than
+    // the average (3.5) plus one standard deviation (7.5) of nonzero sizes used on Arabic Wikipedia.
+    Vector&lt;unsigned, 16&gt; m_runIndices;
+    Vector&lt;unsigned, 16&gt; m_glyphCountFromStartToIndex;
</ins><span class="cx"> 
</span><del>-    float m_runWidthSoFar;
-    unsigned m_numGlyphsSoFar;
-    size_t m_currentRun;
-    unsigned m_glyphInCurrentRun;
-    unsigned m_characterInCurrentGlyph;
-    float m_finalRoundingWidth;
-    float m_expansion;
-    float m_expansionPerOpportunity;
-    float m_leadingExpansion;
</del><ins>+    Vector&lt;RetainPtr&lt;CTLineRef&gt;&gt; m_coreTextLines;
</ins><span class="cx"> 
</span><del>-    HashSet&lt;const Font*&gt;* m_fallbackFonts;
</del><ins>+    Vector&lt;String&gt; m_stringsFor8BitRuns;
</ins><span class="cx"> 
</span><del>-    float m_minGlyphBoundingBoxX;
-    float m_maxGlyphBoundingBoxX;
-    float m_minGlyphBoundingBoxY;
-    float m_maxGlyphBoundingBoxY;
</del><ins>+    HashSet&lt;const Font*&gt;* m_fallbackFonts { nullptr };
</ins><span class="cx"> 
</span><del>-    unsigned m_lastRoundingGlyph;
</del><ins>+    const FontCascade&amp; m_font;
+    const TextRun&amp; m_run;

+    unsigned m_currentCharacter { 0 };
+    unsigned m_end { 0 };
+
+    float m_totalWidth { 0 };
+    float m_runWidthSoFar { 0 };
+    unsigned m_numGlyphsSoFar { 0 };
+    unsigned m_currentRun { 0 };
+    unsigned m_glyphInCurrentRun { 0 };
+    unsigned m_characterInCurrentGlyph { 0 };
+    float m_expansion { 0 };
+    float m_expansionPerOpportunity { 0 };
+    float m_leadingExpansion { 0 };
+
+    float m_minGlyphBoundingBoxX { std::numeric_limits&lt;float&gt;::max() };
+    float m_maxGlyphBoundingBoxX { std::numeric_limits&lt;float&gt;::min() };
+    float m_minGlyphBoundingBoxY { std::numeric_limits&lt;float&gt;::max() };
+    float m_maxGlyphBoundingBoxY { std::numeric_limits&lt;float&gt;::min() };
+
+    bool m_isLTROnly { true };
+    bool m_mayUseNaturalWritingDirection { false };
+    bool m_forTextEmphasis { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacComplexTextControllerCoreTextmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #include &quot;CoreTextSPI.h&quot;
</span><span class="cx"> #include &quot;FontCache.h&quot;
</span><span class="cx"> #include &quot;FontCascade.h&quot;
</span><ins>+#include &quot;SoftLinking.h&quot;
</ins><span class="cx"> #include &quot;TextRun.h&quot;
</span><span class="cx"> #include &quot;WebCoreSystemInterface.h&quot;
</span><span class="cx"> #include &lt;wtf/WeakPtr.h&gt;
</span><span class="lines">@@ -39,6 +40,12 @@
</span><span class="cx"> #include &lt;ApplicationServices/ApplicationServices.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &lt; 101100) || (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &lt; 90000)
+SOFT_LINK_FRAMEWORK(CoreText);
+SOFT_LINK(CoreText, CTRunGetBaseAdvancesAndOrigins, void, (CTRunRef run, CFRange range, CGSize baseAdvances[], CGPoint origins[]), (run, range, baseAdvances, origins))
+#endif
+
+
</ins><span class="cx"> // Note: CTFontDescriptorRefs can live forever in caches inside CoreText, so this object can too.
</span><span class="cx"> @interface WebCascadeList : NSArray {
</span><span class="cx">     @private
</span><span class="lines">@@ -100,13 +107,13 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Font&amp; font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
</span><del>-    : m_font(font)
</del><ins>+    : m_initialAdvance(CTRunGetInitialAdvance(ctRun))
+    , m_font(font)
</ins><span class="cx">     , m_characters(characters)
</span><del>-    , m_stringLocation(stringLocation)
</del><span class="cx">     , m_stringLength(stringLength)
</span><span class="cx">     , m_indexBegin(runRange.location)
</span><span class="cx">     , m_indexEnd(runRange.location + runRange.length)
</span><del>-    , m_initialAdvance(CTRunGetInitialAdvance(ctRun))
</del><ins>+    , m_stringLocation(stringLocation)
</ins><span class="cx">     , m_isLTR(!(CTRunGetStatus(ctRun) &amp; kCTRunStatusRightToLeft))
</span><span class="cx">     , m_isMonotonic(true)
</span><span class="cx"> {
</span><span class="lines">@@ -125,24 +132,31 @@
</span><span class="cx">         m_glyphs = m_glyphsVector.data();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_advances = CTRunGetAdvancesPtr(ctRun);
-    if (!m_advances) {
-        m_advancesVector.grow(m_glyphCount);
-        CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_advancesVector.data());
-        m_advances = m_advancesVector.data();
</del><ins>+#if USE_LAYOUT_SPECIFIC_ADVANCES
+    m_baseAdvancesVector.grow(m_glyphCount);
+    m_glyphOrigins.grow(m_glyphCount);
+    CTRunGetBaseAdvancesAndOrigins(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data(), m_glyphOrigins.data());
+    m_baseAdvances = m_baseAdvancesVector.data();
+#else
+    m_baseAdvances = CTRunGetAdvancesPtr(ctRun);
+    if (!m_baseAdvances) {
+        m_baseAdvancesVector.grow(m_glyphCount);
+        CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data());
+        m_baseAdvances = m_baseAdvancesVector.data();
</ins><span class="cx">     }
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on
</span><span class="cx"> // glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path.
</span><span class="cx"> ComplexTextController::ComplexTextRun::ComplexTextRun(const Font&amp; font, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
</span><del>-    : m_font(font)
</del><ins>+    : m_initialAdvance(CGSizeZero)
+    , m_font(font)
</ins><span class="cx">     , m_characters(characters)
</span><del>-    , m_stringLocation(stringLocation)
</del><span class="cx">     , m_stringLength(stringLength)
</span><span class="cx">     , m_indexBegin(0)
</span><span class="cx">     , m_indexEnd(stringLength)
</span><del>-    , m_initialAdvance(CGSizeZero)
</del><ins>+    , m_stringLocation(stringLocation)
</ins><span class="cx">     , m_isLTR(ltr)
</span><span class="cx">     , m_isMonotonic(true)
</span><span class="cx"> {
</span><span class="lines">@@ -150,10 +164,8 @@
</span><span class="cx">     unsigned r = 0;
</span><span class="cx">     while (r &lt; m_stringLength) {
</span><span class="cx">         m_coreTextIndicesVector.uncheckedAppend(r);
</span><del>-        if (U_IS_LEAD(m_characters[r]) &amp;&amp; r + 1 &lt; m_stringLength &amp;&amp; U_IS_TRAIL(m_characters[r + 1]))
-            r += 2;
-        else
-            r++;
</del><ins>+        UChar32 character;
+        U16_NEXT(m_characters, r, m_stringLength, character);
</ins><span class="cx">     }
</span><span class="cx">     m_glyphCount = m_coreTextIndicesVector.size();
</span><span class="cx">     if (!ltr) {
</span><span class="lines">@@ -165,8 +177,8 @@
</span><span class="cx">     // Synthesize a run of missing glyphs.
</span><span class="cx">     m_glyphsVector.fill(0, m_glyphCount);
</span><span class="cx">     m_glyphs = m_glyphsVector.data();
</span><del>-    m_advancesVector.fill(CGSizeMake(m_font.widthForGlyph(0), 0), m_glyphCount);
-    m_advances = m_advancesVector.data();
</del><ins>+    m_baseAdvancesVector.fill(CGSizeMake(m_font.widthForGlyph(0), 0), m_glyphCount);
+    m_baseAdvances = m_baseAdvancesVector.data();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct ProviderInfo {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformspicocoaCoreTextSPIh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h (205395 => 205396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h        2016-09-03 05:45:10 UTC (rev 205395)
+++ trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h        2016-09-03 05:52:44 UTC (rev 205396)
</span><span class="lines">@@ -68,6 +68,7 @@
</span><span class="cx"> 
</span><span class="cx"> CGSize CTRunGetInitialAdvance(CTRunRef run);
</span><span class="cx"> CTLineRef CTLineCreateWithUniCharProvider(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon);
</span><ins>+void CTRunGetBaseAdvancesAndOrigins(CTRunRef, CFRange, CGSize baseAdvances[], CGPoint origins[]);
</ins><span class="cx"> CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options);
</span><span class="cx"> bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>