Title: [237834] trunk
Revision
237834
Author
[email protected]
Date
2018-11-05 16:09:08 -0800 (Mon, 05 Nov 2018)

Log Message

Spelling dots are drawn in the wrong place
https://bugs.webkit.org/show_bug.cgi?id=190764

Reviewed by Dean Jackson.

Source/WebCore:

- Dots should not be clipped.
- Dots should be horizontally centered.
- Dots should be drawn behind the text.
- Distance from the baseline to the top of the dot should be 11.035% of font size.
- Dot diameter should be 13.247% of the font size.
- Distance between the dots (right side of the left dot to left side of the right dot) should be 9.457% of the font size.
- The "font size" used in these calculations should be clamped so it's 10px <= font size <= 40px.

Tests: editing/spelling/spelling-dots-position-2.html
       editing/spelling/spelling-dots-position-3.html
       editing/spelling/spelling-dots-position.html
       editing/spelling/spelling-dots-repaint.html

* platform/graphics/cocoa/GraphicsContextCocoa.mm:
(WebCore::colorForMarkerLineStyle): Align iOS and macOS implementations.
(WebCore::GraphicsContext::drawDotsForDocumentMarker): Place the dots correctly.
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::addToLine): The KnownToHaveNoOverflow flag should be cleared if the element has spelling dots,
    because there is no guarantee the spelling dots will lie inside the layout rect of the element.
(WebCore::InlineFlowBox::addTextBoxVisualOverflow): Update the repaint rects to include splling dot positions.
* rendering/InlineFlowBox.h: Comments should explain why, not say what.
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint): Draw the dots behind the text.
(WebCore::InlineTextBox::hasMarkers const): Convenience.
(WebCore::InlineTextBox::paintPlatformDocumentMarkers): Refactor bounds information into a helper function.
(WebCore::InlineTextBox::calculateUnionOfAllDocumentMarkerBounds const): Use for repaint rect calculation.
(WebCore::InlineTextBox::calculateDocumentMarkerBounds const): Place the dots correctly.
(WebCore::InlineTextBox::paintPlatformDocumentMarker): Call the helper method.
(WebCore::InlineTextBox::collectMarkedTextsForDocumentMarkers const):
(WebCore::InlineTextBox::collectMarkedTextsForDocumentMarkers): Deleted.
* rendering/InlineTextBox.h: Declare the helper methods.
* rendering/SimpleLineLayout.cpp: Simple line layout doesn't know how to paint spelling dots, so make the presence of
    spelling dots opt us out of SLL.
(WebCore::SimpleLineLayout::canUseForWithReason):
* rendering/SimpleLineLayoutCoverage.cpp:
(WebCore::SimpleLineLayout::printReason):
* rendering/SimpleLineLayoutCoverage.h: Add a new opt-out reason.

Tools:

Previously, it was impossible for WebKitTestRunner to draw spelling dots. This patch adds support for a header
at the top of test files, of the form <!-- webkit-test-runner [ spellCheckingDots=true ] --> which will cause
dots to be drawn.

* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetStateToConsistentValues):
(WTR::updateTestOptionsFromTestHeader):
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::hasSameInitializationOptions const):
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::TestController::cocoaResetStateToConsistentValues):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/mac/TestControllerMac.mm:
(WTR::TestController::platformResetStateToConsistentValues):

LayoutTests:

* editing/spelling/resources/VerySmallDescentAhem.ttf: Added. In order to test repaint rects,
      this is a version of Ahem with a very small descent, so that the dots don't intersect
      with the text itself.
* editing/spelling/spelling-dots-position-2-expected-mismatch.html: Added.
* editing/spelling/spelling-dots-position-2.html: Added. Make sure dots are painted in the
      correct vertical place.
* editing/spelling/spelling-dots-position-3-expected-mismatch.html: Added.
* editing/spelling/spelling-dots-position-3.html: Added. Make sure dots are painted in the
      correct vertical place.
* editing/spelling/spelling-dots-position-expected.html: Added.
* editing/spelling/spelling-dots-position.html: Added. Make sure dots are not painted in
      the wrong place.
* editing/spelling/spelling-dots-repaint-expected.html: Added.
* editing/spelling/spelling-dots-repaint.html: Added. Test repaint by drawing an element
      with spelling dots, and then deleting the element from the document. The spelling
      dots should be removed too.
* fast/writing-mode/english-bt-text-with-spelling-marker-expected.html:
* fast/writing-mode/english-bt-text-with-spelling-marker.html: Update the test to compensate
      for new spelling dot positions.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237833 => 237834)


--- trunk/LayoutTests/ChangeLog	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/LayoutTests/ChangeLog	2018-11-06 00:09:08 UTC (rev 237834)
@@ -1,3 +1,30 @@
+2018-11-05  Myles C. Maxfield  <[email protected]>
+
+        Spelling dots are drawn in the wrong place
+        https://bugs.webkit.org/show_bug.cgi?id=190764
+
+        Reviewed by Dean Jackson.
+
+        * editing/spelling/resources/VerySmallDescentAhem.ttf: Added. In order to test repaint rects,
+              this is a version of Ahem with a very small descent, so that the dots don't intersect
+              with the text itself.
+        * editing/spelling/spelling-dots-position-2-expected-mismatch.html: Added.
+        * editing/spelling/spelling-dots-position-2.html: Added. Make sure dots are painted in the
+              correct vertical place.
+        * editing/spelling/spelling-dots-position-3-expected-mismatch.html: Added.
+        * editing/spelling/spelling-dots-position-3.html: Added. Make sure dots are painted in the
+              correct vertical place.
+        * editing/spelling/spelling-dots-position-expected.html: Added.
+        * editing/spelling/spelling-dots-position.html: Added. Make sure dots are not painted in
+              the wrong place.
+        * editing/spelling/spelling-dots-repaint-expected.html: Added.
+        * editing/spelling/spelling-dots-repaint.html: Added. Test repaint by drawing an element
+              with spelling dots, and then deleting the element from the document. The spelling
+              dots should be removed too.
+        * fast/writing-mode/english-bt-text-with-spelling-marker-expected.html:
+        * fast/writing-mode/english-bt-text-with-spelling-marker.html: Update the test to compensate
+              for new spelling dot positions.
+
 2018-11-05  Ryan Haddad  <[email protected]>
 
         Layout Test imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html is flaky

Added: trunk/LayoutTests/editing/spelling/resources/VerySmallDescentAhem.ttf (0 => 237834)


--- trunk/LayoutTests/editing/spelling/resources/VerySmallDescentAhem.ttf	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/resources/VerySmallDescentAhem.ttf	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,44 @@
+����������\x80����0OS/2r\xA0\xF9E������\xBC������`cmap9\x96U\xEE��������gasp����	����(������glyf\xF4r\xEB\x8D����8����\xAAhead\xDBP͵���� \xE4������6hhea
+\xFD����!������$hmtx+����!@����Xloca\xBF6\xB8\x99����%\x98����.maxp��	����'\xC8������ name\xB8)\xC6����'\xE8����)\xA2postc\xA1[#����Q\x8C������\xD6\x90������\xBC\x8A������\x8F\xBC\x8A����\xC5��2��������������������\x80����\xAF�� H����������������W3C ��@�� \xFE\xFF \xFF\xFE���� ��\xFF\xFC����\xFF\xFF  ������ ����������������������������������\xF8����:������:��&��~��\xA0��\xA1��\xA3��\xA4��\xA5��\xA6��\xA7��\xA8��\xA9��\xAA��\xAB��\xAC��\xAD��\xAE��\xAF��\xB0��\xB1��\xB3��\xB4��\xB5��\xB6��\xB7��\xB8��\xB9��\xBA��\xBB��\xBC��\xBD��\xBE��\xBF��\xC0��\xC1��\xC2��\xC3��\xC5��\xC6��\xC7��\xC8��\xC9��\xCA��\xCB��\xCC��\xCF��\xD0��\xD1��\xD2��\xD4��\xD5��\xD6��\xD7��\xD8��\xD9��\xDB��\xDC��\xDD��\xDE��\xDF��\xE0��\xE1��\xE2��\xE3��\xE4��\xE5��\xE6��\xE7��\xE8��\xE9��\xEB��\xEC��\xED��\xEF��\xF0��\xF1��\xF2��\xF3��\xF4��\xF5��\xF6��\xF7��\xF8��\xF9��\xFA��\xFC��\xFD��\xFE��\xFF1Sx\x92\xC6\xC7\xC9\xDA\xDB\xDC\xDD\x94\xA5\xA7\xA9\
 xBC\xC0   +      " & 0 : D!"!&"""""""""+"H"`"e"\xF2%\xCA0��0N��NN	N]N\x8CN\x9
 4QkQmSAV\xD7V\xDBWg(j*l4pk~\xB5\x91\xD1\xF0\xFE\xFF\xFF\xFF������ ��(��\xA0��\xA1��\xA2��\xA4��\xA5��\xA6��\xA7��\xA8��\xA9��\xAA��\xAB��\xAC��\xAD��\xAE��\xAF��\xB0��\xB1��\xB2��\xB4��\xB5��\xB6��\xB7��\xB8��\xB9��\xBA��\xBB��\xBC��\xBD��\xBE��\xBF��\xC0��\xC1��\xC2��\xC3��\xC4��\xC6��\xC7��\xC8��\xC9��\xCA��\xCB��\xCC��\xCD��\xD0��\xD1��\xD2��\xD3��\xD5��\xD6��\xD7��\xD8��\xD9��\xDA��\xDC��\xDD��\xDE��\xDF��\xE0��\xE1��\xE2��\xE3��\xE4��\xE5��\xE6��\xE7��\xE8��\xE9��\xEA��\xEC��\xED��\xEE��\xF0��\xF1��\xF2��\xF3��\xF4��\xF5��\xF6��\xF7��\xF8��\xF9��\xFA��\xFB��\xFD��\xFE��\xFF1Rx\x92\xC6\xC7\xC9\xD8\xDB\xDC\xDD\x94\xA5\xA7\xA9\xBC\xC0  	         & 0 9 D!"!&"""""""""+"H"`"d"\xF2%\xCA0��0N��NN	N]N\x8CN\x94QkQmSAV\xD7V\xDBWg(j*l4pk~\xB5\x91\xD1\xF0��\xFE\xFF\xFF\xFF\xFF\xE3\xFF\xE2\xFF\xF9\xFF\xF4\xFF\xE0\xFF\xFD\xFF\xE9��\xFF\xDD\xFF\xE2\xFF\xDF\xFF\xE6\xFF\xEC\xFF\xEA
 ��\xFF\xD9��\xFF\xD1\xFF\xDC��\xFF\xD5\xFF\xDA\xFF\xCF\xFF\xEB����+\xFF\xD7\xFF\xDD������+\xFF
 \xD5\xFF\xDA\xFF\xE4\xFF\xE1\xFF\xD8\xFF\x9D\xFF\xC5\xFF\x9C\xFF\xDF\xFF\x9B\xFF\xDA\xFF\xDB\xFF\xDF\xFF\xDB\xFF\xEE\xFF\x94\xFF\xDC\xFF\xD9\xFF\xC7\xFF\x90\xFF\xEE\xFF\xB4\xFF\xD8\xFF\xD5\xFF\x8B\xFF\xE3\xFF\xE4\xFF\xA7\xFF\x89\xFF\x87\xFF\x88\xFF\x89\xFF\x87\xFF\x88\xFF\xAC\xFF\x87\xFF\x88\xFF\x86\xFF\x87\xFF\x88\xFF\x86\xFF\x87\xFF\xCF\xFF\x86\xFF\x87\xFF\x85\xFF\x86\xFF\x87\xFF\x85\xFF\xA8\xFF\x9B\xFF\x85\xFF\x83\xFF\x84\xFF\xC4\xFF\xC5\xFF\xA1\xFF\x81\xFF|\xFFX\xFF?\xFD\xED\xFD\xF5\xFD\xEC\xFD\xDE\xFD\xE0\xFD\xD8\xFD\xDD\xFD>\xFDo\xFDk\xFD*\xFC\xD3\xFD\xE0\xF4\xE0\xF2\xE0\xF3\xDF\xFF\xE0\xC2\xE0\x85\xE0\xBD\xE0\xBC\xE0\xBB\xE0\xB8\xE0\xAF\xE0\xA7\xE0\x9E\xDF\xC1߭\xDE\xE2\xDE\xCC\xDE\xD6\xDE\xD5޲މ\xDE\xCD\xDE\xCA޾ޥފއ\xDD\xFB\xDB$\xD0\xFE\xD1\xB3\xB3\xB2\xFA\xB2\xAC\xB2v\xB2q\xAF\x9D\xAF\x99\xADɪ5\xAA)\xA9\xF2\x99\xE7\x96\xE9\x94ڐ\xA2\x82`o?\xEF\xF6������������������������������������������������������������������������������������������������������������������
 ������������������������������������������������������������������������������������������������������������������
 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������\xFF\xFF������}����k ��������3!%!!}\xEE\xFD\x8F\xF4\xFE \xFC\xE0}&����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0��
 ��������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8
  ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8
 \xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE
 8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0�
 ���������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\
 xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\x
 E8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE
 8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\x
 E8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\
 xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE
 0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xF
 C\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������
 \xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\
 xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!
 \xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!
 \xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\
 xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \
 xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0���������
 �\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������
 \xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!!\xE8\xFC \xFC\xE0����������\xE8 ������!
 !\xE8\xFC \xFC\xE0������\x90\xE8X������!!\xE8\xFCX\xC8��������\x90\xE8X������!!\xE8\xFCX\xC8������\xC8\xFF8\x90 ������3#\xC8\xC8\xC8 \xFC������\xC8\xFF8
 \x90 ������3#\xC8\xC8\xC8 \xFC��������������\x80��M\xBA\xDAL_<\xF5��	\xE8��������\xB3o_Y��������\xC4ݫ$����\xFF8\xE8 ���������������������������� \xFF\xFE����\xE8��������\xE8������������������������������\xE8��}��������\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8��
 ��\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE
 8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\
 xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8������������\xF4����\xE8����M������\xFA������\xA7������\xC8������d������������\xE8��������������������\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE
 8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8����\xE8��\xC8\xE8��\xC8��������������!��.��;��H��U��b��o��|��\x89��\x96��\xA3��\xB0��\xBD��\xCA��\xD7��\xE4��\xF1��\xFE%2?LYfs\x80\x8D\x9A\xA7\xB4\xC1\xCE\xDB\xE8\xF5)6CP]jw\x84\x91\x9E\xAB\xB8\xC5\xD2\xDF\xEC\xF9 -:GTan{\x88\x95\xA2\xAF\xBC\xC9\xD6\xE3\xF0\xFD
+$1>KXer\x8C\x99\xA6\xB3\xC0\xCD\xDA\xE7\xF4(5BO\iv\x83\x90\x9D\xAA\xB7\xC4\xD1\xDE\xEB\xF8,9FS`mz\x87\x94\xA1\xAE\xBB\xC8\xD5\xE2\xEF\xFC	#0=JWdq~\x8B\x98\xA5\xA5\xB2\xBF\xCC\xD9\xE6\xF3��+'4AN[hu\x82\x8F\x9C\xA9\xB6\xC3\xD0\xDD\xEA\xF7				+	8	E	R	_	l	y	\x86	\x93	\xA0	\xAD	\xBA	\xC7	\xD4	\xE1	\xEE	\xFB
+
+
+"
+/
+<
+I
+V
+c
+p
+}
+\x8A
+\x97
+\xA4
+\xB1
+\xBE
+\xCB
+\xD8
+\xE5
+\xF2
+\xFF&3@MZgt\x81\x8E\x9B\xA8\xB5\xC2\xCF\xDC\xE9\xF6*7DDDDDDDDDDDDDQ^kx\x85\x92\x9F\xAC\xB9\xC6\xD3\xE0\xED\xFA+++!+.+;+H+U��������������������������������������������������������������$\xB6����������������\xF0��������������������\xF0����������������\xF8����������������"����������������(����������������0����������������H��������������
+hP����������������$\xB8����������������R\xDC����������������\xF8.��������������&��������������*��������������1��������������B��������������F��������������R������������
+����V��������������V��������������)h��������������\x91��������������\x95��������������\x9C����	����\xF0\xA0����	����\x90����	����\x98����	����"\xA6����	����\xC8����	����\xD0����	����\xE8����	��
+h\xF0����	����$'X����	����R'|����	����'\xCE����	����'\xD6����	����'\xE4��T��h��e�� ��A��h��e��m�� ��f��o��n��t�� ��b��e��l��o��n��g��s�� ��t��o�� ��t��h��e�� ��p��u��b��l��i��c�� ��d��o��m��a��i��n��.�� ��I��n�� ��j��u��r��i��s��d��i��c��t��i��o��n��s�� ��t��h��a��t�� ��d��o�� ��n��o��t�� ��r��e��c��o��g��n��i��z��e�� ��p��u��b��l��i��c�� ��d��o��m��a��i��n�� ��o��w��n��e��r��s��h��i��p�� ��o��f�� ��t��h��e��s��e�� ��f��i��l��e��s��,�� ��t��h��e�� ��f��o��l��l��o��w��i��n��g�� ��C��r��e��a��t��i��v��e�� ��C��o��m��m��o��n��s�� ��Z��e��r��o�� ��d��e��c��l��a��r��a��t��i��o��n�� ��a��p��p��l��i��e��s��:�� ��h��t��t��p��:��/��/��l��a��b��s��.��c��r��e��a��t��i��v��e��c��o��m��m��o��n��s��.��o��r��g��/��l��i��c��e��n��s��e��s��/��z��e��r��o��-��w��a��i��v��e��/��1��.��0��/��u��s��/��l��e��g��a��l��c��o��d��e��A��h��e��m��R��e��g��u��l��a��r��V��e��r��s��i��o��n�� ��1��.��5��0�� ��A��h��e��m��A��h��e��m��V��e��r��s��i��o��n�� ��1��.��5��0��A��h��e��m��T��h��e�� �
 �A��h��e��m�� ��f��o��n��t�� ��w��a��s�� ��d��e��v��e��l��o��p��e��d�� ��b��y�� ��T��o��d��d�� ��F��a��h��r��n��e��r�� ��a��n��d�� ��M��y��l��e��s�� ��C��.�� ��M��a��x��f��i��e��l��d�� ��t��o�� ��h��e��l��p�� ��t��e��s��t�� ��w��r��i��t��e��r��s�� ��d��e��v��e��l��o��p�� ��p��r��e��d��i��c��t��a��b��l��e�� ��t��e��s��t��s��.�� ��T��h��e�� ��u��n��i��t��s�� ��p��e��r�� ��e��m�� ��i��s�� ��1��0��0��0��,�� ��t��h��e�� ��a��d��v��a��n��c��e�� ��i��s�� ��8��0��0��,�� ��a��n��d�� ��
 t��h��e�� ��d��e��s��c��e��n��t�� ��i��s�� ��2��0��0��,�� ��t��h��e��r��e��b��y�� ��m��a��k��i��n��g�� ��t��h��e�� ��e��m�� ��s��q��u��a��r��e�� ��e��x��a��c��t��l��y�� ��s��q��u��a��r��e��.�� ��T��h��e�� ��g��l��y��p��h��s�� ��f��o��r�� ��m��o��s��t�� ��c��h��a��r��a��c��t��e��r��s�� ��i��s�� ��s��i��m��p��l��y�� ��a�� ��b��o��x�� ��w��h��i��c��h�� ��f��i��l��l��s�� ��t��h��i��s�� ��s��q��u��a��r��e��.�� ��T��h��e�� ��c��o��d��e��p��o��i��n��t��s�� ��m��a��p��p��e��d�� ��t��o�� ��t��h��i��s�� ��f��u��l��l�� ��s��q��u��a��r��e�� ��w��i��t��h�� ��a�� ��f��u��l��l�� ��a��d��v��a��n��c��e�� ��a��r��e�� ��t��h��e�� ��f��o��l��l��o��w��i��n��g�� ��r��a��n��g��e��s��:�� ��U��+��2��0��-��U��+��2��6��,�� ��U��+��2��8��-��U��+��6��F��,�� ��U��+��7��1��-��U��+��7��E��,�� ��U��+��A��0��-��U��+��C��8��,�� ��U��+��C��A��-��U��+��F��F��,�� ��U��+��1��3��1��,�� ��U��+��1��5��2��-��U��+��1��5��3��,�� ��U��+��1��7��8��,�� ��U��+��1��9��2��,�� ��U��+��2��C��6��-��U��+��2��C��7��,�� ��U��+��2��C��9��,
 �� ��U��+��2��D��8��-��U��+��2��D��D��,�� ��U��+��3��9��4��,�� ��U��+��3��A��5��,�� ��U��+��3��A��7��,�� ��U��+��3��A��9��,�� ��U��+��3��B��C��,�� ��U��+��3��C��0��,�� ��U��+��2��0��1��3��-��U��+��2��0��1��4��,�� ��U��+��2��0��1��8��-��U��+��2��0��1��A��,�� ��U��+��2��0��1��C��-��U��+��2��0��1��E��,�� ��U��+��2��0��2��0��-��U��+��2��0��2��2��,�� ��U��+��2��0��2��6��,�� ��U��+��2��0��3��0��,�� ��U��+��2��0��3��9��-��U��+��2��0��3��A��,�� ��U��+��2��0��4��4��,�� ��U��+��2��1��2��2��,�� ��U��+��2
 ��1��2��6��,�� ��U��+��2��2��0��2��,�� ��U��+��2��2��0��6��,�� ��U��+��2��2��0��F��,�� ��U��+��2��2��1��1��-��U��+��2��2��1��2��,�� ��U��+��2��2��1��9��-��U��+��2��2��1��A��,�� ��U��+��2��2��1��E��,�� ��U��+��2��2��2��B��,�� ��U��+��2��2��4��8��,�� ��U��+��2��2��6��0��,�� ��U��+��2��2��6��4��-��U��+��2��2��6��5��,�� ��U��+��2��2��F��2��,�� ��U��+��2��5��C��A��,�� ��U��+��3��0��0��7��,�� ��U��+��4��E��0��0��,�� ��U��+��4��E��0��3��,�� ��U��+��4��E��0��9��,�� ��U��+��4��E��5��D��,�� ��U��+��4��E��8��C��,�� ��U��+��4��E��9��4��,�� ��U��+��5��1��6��B��,�� ��U��+��5��1��6��D��,�� ��U��+��5��3��4��1��,�� ��U��+��5��6��D��7��,�� ��U��+��5��6��D��B��,�� ��U��+��5��7��1��F��,�� ��U��+��6��7��2��8��,�� ��U��+��6��C��3��4��,�� ��U��+��7��0��6��B��,�� ��U��+��9��1��D��1��,�� ��U��+��F��0��0��0��-��U��+��F��0��0��2��.�� ��T��h��e�� ��c��o��d��e��p��o��i��n��t��s�� ��w��h��i��c��h�� ��a��r��e�� ��m��a��p��p��e��d�� ��t��o�� ��s��o��m��e��t��h��i��n��g�� ��e��l��s��e�� ��a��r��e�� ��t��h��e�� ��f�
 �o��l��l��o��w��i��n��g��:�� ��"�� ��"�� ��(��U��+��2��0��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"��p��"�� ��(��U��+��7��0��)��:�� ��P��a��t��h�� ��h��a��s�� ��0�� ��a��s��c��e��n��t�� ��b��u��t�� ��f��u��l��l�� ��d��e��s��c��e��n��t��;�� ��"��\xC9��"�� ��(��U��+��C��9��)��:�� ��P��a��t��h�� ��h��a��s�� ��0�� ��d��e��s��c��e��n��t�� ��b��u��t�� ��f��u��l��l�� ��a��s��c��e��n��t��;�� ��N��o��n��-��b��r
 ��e��a��k��i��n��g�� ��s��p��a��c��e�� ��(��U��+��A��0��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o��-��w��i��d��t��h�� ��n��o��n��-��b��r��e��a��k��i��n��g�� ��s��p��a��c��e�� ��(��U��+��F��E��F��F��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��0�� ��a��d��v��a��n��c��e��;�� ��E��n�� ��s��p��a��c��e�� ��(��U��+��2��0��0��2��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��h��a��l��f�� ��a��d��v��a��n��c��e��;�� ��E��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��3��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��T��h��r��e��e��-��p��e��r��-��e��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��4��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��t��h��i��r��d�� ��a��d��v��a��n��c��e��;�� ��F��o��u��r��-��p��e��r��-��e��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��5��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��q��u��a��r��t��e��r�� ��a��d��v��a��n��c��e��;�� ��S��i��x��-��p��e��r��-��e��m�� �
 �s��p��a��c��e�� ��(��U��+��2��0��0��6��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��s��i��x��t��h�� ��a��d��v��a��n��c��e��;�� ��T��h��i��n�� ��s��p��a��c��e�� ��(��U��+��2��0��0��9��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��f��i��f��t��h�� ��a��d��v��a��n��c��e��;�� ��H��a��i��r�� ��s��p��a��c��e�� ��(��U��+��2��0��0��A��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��t��e��n��t��h�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��s��p��a��c��
 e�� ��(��U��+��2��0��0��B��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a��n��c��e��;�� ��I��d��e��o��g��r��a��p��h��i��c�� ��s��p��a��c��e�� ��(��U��+��3��0��0��0��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��n��o��n��-��j��o��i��n��e��r�� ��(��U��+��2��0��0��C��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��j��o��i��n��e��r�� ��(��U��+��2��0��0��D��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a��n��c��e��;�� ��G��r��e��e��k�� ��c��a��p��i��t��a��l�� ��l��e��t��t��e��r�� ��C��h��i�� ��(��U��+��3��A��7��)��:�� ��T��h��i��n�� ��h��o��r��i��z��o��n��t��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"j*��"�� ��(��U��+��6��A��2��A��)��:�� ��T��h��i��n�� ��h��o��r��i��z��o��n��t��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��G��r
 ��e��e��k�� ��c��a��p��i��t��a��l�� ��l��e��t��t��e��r�� ��U��p��s��i��l��o��n�� ��(��U��+��3��A��5��)��:�� ��T��h��i��n�� ��v��e��r��t��i��c��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"~\xB5��"�� ��(��U��+��7��E��B��5��)��:�� ��T��h��i��n�� ��v��e��r��t��i��c��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��.��h��t��t��p��:��/��/��w��w��w��.��w��3��c��.��o��r��g��h��t��t��p��:��/��/��d��e��v��.��w��
 3��.��o��r��g��/��C��S��S��/��f��o��n��t��s��/��a��h��e��m��/��C��O��P��Y��I��N��G��
+The Ahem font belongs to the public domain. In jurisdictions that do not recognize public domain ownership of these files, the following Creative Commons Zero declaration applies: http://labs.creativecommons.org/licenses/zero-waive/1.0/us/legalcodeAhemRegularVersion 1.50 AhemAhemVersion 1.50Ahemhttp://www.w3c.orghttp://dev.w3.org/CSS/fonts/ahem/COPYING
+AhemRegularAhem��T��h��e�� ��A��h��e��m�� ��f��o��n��t�� ��b��e��l��o��n��g��s�� ��t��o�� ��t��h��e�� ��p��u��b��l��i��c�� ��d��o��m��a��i��n��.�� ��I��n�� ��j��u��r��i��s��d��i��c��t��i��o��n��s�� ��t��h��a��t�� ��d��o�� ��n��o��t�� ��r��e��c��o��g��n��i��z��e�� ��p��u��b��l��i��c�� ��d��o��m��a��i��n�� ��o��w��n��e��r��s��h��i��p�� ��o��f�� ��t��h��e��s��e�� ��f��i��l��e��s��,�� ��t��h��e�� ��f��o��l��l��o��w��i��n��g�� ��C��r��e��a��t��i��v��e�� ��C��o��m��m��o��n��s�� ��Z��e��r��o�� ��d��e��c��l��a��r��a��t��i��o��n�� ��a��p��p��l��i��e��s��:�� ��h��t��t��p��:��/��/��l��a��b��s��.��c��r��e��a��t��i��v��e��c��o��m��m��o��n��s��.��o��r��g��/��l��i��c��e��n��s��e��s��/��z��e��r��o��-��w��a��i��v��e��/��1��.��0��/��u��s��/��l��e��g��a��l��c��o��d��e��A��h��e��m��R��e��g��u��l��a��r��V��e��r��s��i��o��n�� ��1��.��5��0�� ��A��h��e��m��A��h��e��m��V��e��r��s��i��o��n�� ��1��.��5��0��A��h��e��m��T��h��e�� ��A��h��e��m�� ��f��o��n��t�� ��w��a��s�� ��d��e��v��e��l��o��p��e��d�� ��b��y�� �
 �T��o��d��d�� ��F��a��h��r��n��e��r�� ��a��n��d�� ��M��y��l��e��s�� ��C��.�� ��M��a��x��f��i��e��l��d�� ��t��o�� ��h��e��l��p�� ��t��e��s��t�� ��w��r��i��t��e��r��s�� ��d��e��v��e��l��o��p�� ��p��r��e��d��i��c��t��a��b��l��e�� ��t��e��s��t��s��.�� ��T��h��e�� ��u��n��i��t��s�� ��p��e��r�� ��e��m�� ��i��s�� ��1��0��0��0��,�� ��t��h��e�� ��a��d��v��a��n��c��e�� ��i��s�� ��8��0��0��,�� ��a��n��d�� ��t��h��e�� ��d��e��s��c��e��n��t�� ��i��s�� ��2��0��0��,�� ��t��h��e��r��e��b��y�� ��m��a��k
 ��i��n��g�� ��t��h��e�� ��e��m�� ��s��q��u��a��r��e�� ��e��x��a��c��t��l��y�� ��s��q��u��a��r��e��.�� ��T��h��e�� ��g��l��y��p��h��s�� ��f��o��r�� ��m��o��s��t�� ��c��h��a��r��a��c��t��e��r��s�� ��i��s�� ��s��i��m��p��l��y�� ��a�� ��b��o��x�� ��w��h��i��c��h�� ��f��i��l��l��s�� ��t��h��i��s�� ��s��q��u��a��r��e��.�� ��T��h��e�� ��c��o��d��e��p��o��i��n��t��s�� ��m��a��p��p��e��d�� ��t��o�� ��t��h��i��s�� ��f��u��l��l�� ��s��q��u��a��r��e�� ��w��i��t��h�� ��a�� ��f��u��l��l�� ��a��d��v��a��n��c��e�� ��a��r��e�� ��t��h��e�� ��f��o��l��l��o��w��i��n��g�� ��r��a��n��g��e��s��:�� ��U��+��2��0��-��U��+��2��6��,�� ��U��+��2��8��-��U��+��6��F��,�� ��U��+��7��1��-��U��+��7��E��,�� ��U��+��A��0��-��U��+��C��8��,�� ��U��+��C��A��-��U��+��F��F��,�� ��U��+��1��3��1��,�� ��U��+��1��5��2��-��U��+��1��5��3��,�� ��U��+��1��7��8��,�� ��U��+��1��9��2��,�� ��U��+��2��C��6��-��U��+��2��C��7��,�� ��U��+��2��C��9��,�� ��U��+��2��D��8��-��U��+��2��D��D��,�� ��U��+��3��9��4��,�� ��U��+��3��A��5��,�� ��U��+�
 �3��A��7��,�� ��U��+��3��A��9��,�� ��U��+��3��B��C��,�� ��U��+��3��C��0��,�� ��U��+��2��0��1��3��-��U��+��2��0��1��4��,�� ��U��+��2��0��1��8��-��U��+��2��0��1��A��,�� ��U��+��2��0��1��C��-��U��+��2��0��1��E��,�� ��U��+��2��0��2��0��-��U��+��2��0��2��2��,�� ��U��+��2��0��2��6��,�� ��U��+��2��0��3��0��,�� ��U��+��2��0��3��9��-��U��+��2��0��3��A��,�� ��U��+��2��0��4��4��,�� ��U��+��2��1��2��2��,�� ��U��+��2��1��2��6��,�� ��U��+��2��2��0��2��,�� ��U��+��2��2��0��6��,�� ��U��+��2��2��0��F��,�� ��U��
 +��2��2��1��1��-��U��+��2��2��1��2��,�� ��U��+��2��2��1��9��-��U��+��2��2��1��A��,�� ��U��+��2��2��1��E��,�� ��U��+��2��2��2��B��,�� ��U��+��2��2��4��8��,�� ��U��+��2��2��6��0��,�� ��U��+��2��2��6��4��-��U��+��2��2��6��5��,�� ��U��+��2��2��F��2��,�� ��U��+��2��5��C��A��,�� ��U��+��3��0��0��7��,�� ��U��+��4��E��0��0��,�� ��U��+��4��E��0��3��,�� ��U��+��4��E��0��9��,�� ��U��+��4��E��5��D��,�� ��U��+��4��E��8��C��,�� ��U��+��4��E��9��4��,�� ��U��+��5��1��6��B��,�� ��U��+��5��1��6��D��,�� ��U��+��5��3��4��1��,�� ��U��+��5��6��D��7��,�� ��U��+��5��6��D��B��,�� ��U��+��5��7��1��F��,�� ��U��+��6��7��2��8��,�� ��U��+��6��C��3��4��,�� ��U��+��7��0��6��B��,�� ��U��+��9��1��D��1��,�� ��U��+��F��0��0��0��-��U��+��F��0��0��2��.�� ��T��h��e�� ��c��o��d��e��p��o��i��n��t��s�� ��w��h��i��c��h�� ��a��r��e�� ��m��a��p��p��e��d�� ��t��o�� ��s��o��m��e��t��h��i��n��g�� ��e��l��s��e�� ��a��r��e�� ��t��h��e�� ��f��o��l��l��o��w��i��n��g��:�� ��"�� ��"�� ��(��U��+��2��0��)��:�� ��N��o�� ��p��a��
 t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"��p��"�� ��(��U��+��7��0��)��:�� ��P��a��t��h�� ��h��a��s�� ��0�� ��a��s��c��e��n��t�� ��b��u��t�� ��f��u��l��l�� ��d��e��s��c��e��n��t��;�� ��"��\xC9��"�� ��(��U��+��C��9��)��:�� ��P��a��t��h�� ��h��a��s�� ��0�� ��d��e��s��c��e��n��t�� ��b��u��t�� ��f��u��l��l�� ��a��s��c��e��n��t��;�� ��N��o��n��-��b��r��e��a��k��i��n��g�� ��s��p��a��c��e�� ��(��U��+��A��0��)��:�� ��N��o�� ��p��a��t��h�� ��b��
 u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o��-��w��i��d��t��h�� ��n��o��n��-��b��r��e��a��k��i��n��g�� ��s��p��a��c��e�� ��(��U��+��F��E��F��F��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��0�� ��a��d��v��a��n��c��e��;�� ��E��n�� ��s��p��a��c��e�� ��(��U��+��2��0��0��2��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��h��a��l��f�� ��a��d��v��a��n��c��e��;�� ��E��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��3��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��T��h��r��e��e��-��p��e��r��-��e��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��4��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��t��h��i��r��d�� ��a��d��v��a��n��c��e��;�� ��F��o��u��r��-��p��e��r��-��e��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��5��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��q��u��a��r��t��e��r�� ��a��d��v��a��n��c��e��;�� ��S��i��x��-��p��e��r��-��e��m�� ��s��p��a��c��e�� ��(��U��+��2��0��0��6��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e
 �� ��s��i��x��t��h�� ��a��d��v��a��n��c��e��;�� ��T��h��i��n�� ��s��p��a��c��e�� ��(��U��+��2��0��0��9��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��f��i��f��t��h�� ��a��d��v��a��n��c��e��;�� ��H��a��i��r�� ��s��p��a��c��e�� ��(��U��+��2��0��0��A��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��o��n��e�� ��t��e��n��t��h�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��s��p��a��c��e�� ��(��U��+��2��0��0��B��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a
 ��n��c��e��;�� ��I��d��e��o��g��r��a��p��h��i��c�� ��s��p��a��c��e�� ��(��U��+��3��0��0��0��)��:�� ��N��o�� ��p��a��t��h�� ��b��u��t�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��n��o��n��-��j��o��i��n��e��r�� ��(��U��+��2��0��0��C��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a��n��c��e��;�� ��Z��e��r��o�� ��w��i��d��t��h�� ��j��o��i��n��e��r�� ��(��U��+��2��0��0��D��)��:�� ��N��o�� ��p��a��t��h�� ��a��n��d�� ��n��o�� ��a��d��v��a��n��c��e��;�� ��G��r��e��e��k�� ��c��a��p��i��t��a��l�� ��l��e��t��t��e��r�� ��C��h��i�� ��(��U��+��3��A��7��)��:�� ��T��h��i��n�� ��h��o��r��i��z��o��n��t��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"j*��"�� ��(��U��+��6��A��2��A��)��:�� ��T��h��i��n�� ��h��o��r��i��z��o��n��t��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��G��r��e��e��k�� ��c��a��p��i��t��a��l�� ��l��e��t��t��e��r�� ��U��p��s��i��l��o��n�� ��(��U��+�
 �3��A��5��)��:�� ��T��h��i��n�� ��v��e��r��t��i��c��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��;�� ��"~\xB5��"�� ��(��U��+��7��E��B��5��)��:�� ��T��h��i��n�� ��v��e��r��t��i��c��a��l�� ��s��t��r��i��p��e�� ��a��n��d�� ��f��u��l��l�� ��a��d��v��a��n��c��e��.��h��t��t��p��:��/��/��w��w��w��.��w��3��c��.��o��r��g��h��t��t��p��:��/��/��d��e��v��.��w��3��.��o��r��g��/��C��S��S��/��f��o��n��t��s��/��a��h��e��m��/��C��O��P��Y��I��N��G��
+��A��h��e��m��R��e��g��u��l��a��r��A��h��e��m������������������\xFF{������������������������������������������������������������	������+�������������������������������������� ��!��"��#��$��%��&��'��(��)��*��+��,��-��.��/��0��1��2��3��4��5��6��7��8��9��:��;��<��=��>��?��@��A��B��C��D��E��F��G��H��I��J��K��L��M��N��O��P��Q��R��S��T��U��V��W��X��Y��Z��[��\��]��^��_��`��a��b��c��d��e��f��g��h��i��j��k��l��m��n��o��p��q��r��s��t��u��v��w��x��y��z��{��|��}��~����\x80��\x81��\x83��\x84��\x85��\x86��\x88��\x89��\x8A��\x8B��\x8D��\x8E��\x90��\x91��\x93��\x96��\x97��\x9D��\x9E��\xA0��\xA1��\xA2��\xA3��\xA4��\xA9��\xAA��\xAC��\xAD��\xAE��\xAF��\xB6��\xB7��\xB8��\xBA��\xBD��\xC3��\xC7��\xC8��\xC9��\xCA��\xCB��\xCC��\xCD��\xCE��\xCF��\xD0��\xD1��\xD3��\xD4��\xD5��\xD6��\xD7��\xD8��\xD9��\xDA��\xDB��\xDC��\xDD��\xDE��\xDF��\xE0��\xE1��\xE8��\xE9��\xEA��\xEB��\xEC��\xED��\xEE��\xEF��\xF0��\xF1��\xF2��\xF3��\xF4��\xF5��\xF6��\xB0��\xB1��\xBB��\x
 A6��\xA8��\x9F��\x9B��\xB2��\xB3��\xC4��\xB4��\xB5��\xC5��\x82��\xC2��\x87��\xAB��\xC6��\xBE��\xBF��\xBC��\x8C��\x98��\x9A��\x99��\xA5��\x92��\x9C��\x8F��\x94��\x95��\xA7��\xB9��\xD2��\xC0��\xC1��	
++ !"#$%&'(NULLglyph243glyph204glyph205HTDELuniFEFFuni2002uni2003uni2004uni2005uni2006uni2009uni200Auni200Buni3000	afii61664afii301uni4E00uni4E8Cuni4E09uni56DBuni4E94uni516Duni4E03uni516Buni4E5Duni5341uni3007uni56D7uni706Buni6C34uni6728uni91D1uni571Funi03A7uni6A2Auni03A5uni7EB5��
\ No newline at end of file

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position-2-expected-mismatch.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position-2-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position-2-expected-mismatch.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position-2.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position-2.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position-2.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,67 @@
+<!DOCTYPE html><!-- webkit-test-runner [ spellCheckingDots=true ] -->
+<html>
+<head>
+
+<style>
+.editing {
+    font-family: 'Times New Roman';
+    font-size: 36px;
+    color: transparent;
+}
+</style>
+<script src="" language="_javascript_" type="text/_javascript_" ></script>
+
+<script>
+function editingTest() {
+    typeCharacterCommand('w');
+    typeCharacterCommand('a');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('e');
+    typeCharacterCommand('r');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('d');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('a');
+    typeCharacterCommand(' ');
+    let ascentSetter = document.createElement("div");
+    ascentSetter.style.width = "1px";
+    ascentSetter.style.height = "150px";
+    ascentSetter.style.display = "inline-block";
+    let root = document.getElementById("root");
+    root.appendChild(ascentSetter);
+    let baseline = ascentSetter.offsetTop + ascentSetter.offsetHeight;
+    let left = root.offsetLeft;
+    let width = ascentSetter.offsetLeft - left;
+    let fontSize = Number.parseInt(window.getComputedStyle(root).getPropertyValue("font-size"));
+    let blocker = document.createElement("div");
+    blocker.style.background = ""
+    blocker.style.position = "absolute";
+    blocker.style.left = `${left}px`;
+    blocker.style.top = `${baseline + 1 + fontSize * 0.11035}px`;
+    blocker.style.width = `${width}px`;
+    blocker.style.height = `${fontSize * 0.13247}px`;
+    document.body.appendChild(blocker);
+    root.blur();
+}
+
+</script>
+
+<title>Editing Test</title>
+</head>
+<body>
+<div contenteditable id="root" class="editing">
+<span id="test"></span>
+</div>
+
+<script>
+    if (window.internals)
+        internals.setContinuousSpellCheckingEnabled(true);
+    runEditingTest();
+</script>
+
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position-3-expected-mismatch.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position-3-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position-3-expected-mismatch.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position-3.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position-3.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position-3.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,67 @@
+<!DOCTYPE html><!-- webkit-test-runner [ spellCheckingDots=true ] -->
+<html>
+<head>
+
+<style>
+.editing {
+    font-family: 'Times New Roman';
+    font-size: 36px;
+    color: transparent;
+}
+</style>
+<script src="" language="_javascript_" type="text/_javascript_" ></script>
+
+<script>
+function editingTest() {
+    typeCharacterCommand('w');
+    typeCharacterCommand('a');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('e');
+    typeCharacterCommand('r');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('d');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('a');
+    typeCharacterCommand(' ');
+    let ascentSetter = document.createElement("div");
+    ascentSetter.style.width = "1px";
+    ascentSetter.style.height = "150px";
+    ascentSetter.style.display = "inline-block";
+    let root = document.getElementById("root");
+    root.appendChild(ascentSetter);
+    let baseline = ascentSetter.offsetTop + ascentSetter.offsetHeight;
+    let left = root.offsetLeft;
+    let width = ascentSetter.offsetLeft - left;
+    let fontSize = Number.parseInt(window.getComputedStyle(root).getPropertyValue("font-size"));
+    let blocker = document.createElement("div");
+    blocker.style.background = ""
+    blocker.style.position = "absolute";
+    blocker.style.left = `${left}px`;
+    blocker.style.top = `${baseline - 1 + fontSize * 0.11035}px`;
+    blocker.style.width = `${width}px`;
+    blocker.style.height = `${fontSize * 0.13247}px`;
+    document.body.appendChild(blocker);
+    root.blur();
+}
+
+</script>
+
+<title>Editing Test</title>
+</head>
+<body>
+<div contenteditable id="root" class="editing">
+<span id="test"></span>
+</div>
+
+<script>
+    if (window.internals)
+        internals.setContinuousSpellCheckingEnabled(true);
+    runEditingTest();
+</script>
+
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position-expected.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position-expected.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position-expected.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.editing {
+    font-family: 'Times New Roman';
+    font-size: 36px;
+}
+</style>
+</head>
+<body>
+<div>There should be no misspelling dots visible below (because they're covered up by a div)</div>
+<div contenteditable="" id="root" class="editing">wafewerewdfea&nbsp;<span id="test"></span><div style="background-color: black; width: 1px; height: 150px; display: inline-block; background-position: initial initial; background-repeat: initial initial;"></div></div>
+<script>
+    runEditingTest();
+</script><div style="background-color: black; position: absolute; left: 8px; top: 179.9726px; width: 237px; height: 4.7689200000000005px; background-position: initial initial; background-repeat: initial initial;"></div>
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-position.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-position.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-position.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,68 @@
+<!DOCTYPE html><!-- webkit-test-runner [ spellCheckingDots=true ] -->
+<html>
+<head>
+
+<style>
+.editing {
+    font-family: 'Times New Roman';
+    font-size: 36px;
+}
+</style>
+<script src="" language="_javascript_" type="text/_javascript_" ></script>
+
+<script>
+function editingTest() {
+    typeCharacterCommand('w');
+    typeCharacterCommand('a');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('e');
+    typeCharacterCommand('r');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('d');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('a');
+    typeCharacterCommand(' ');
+    let ascentSetter = document.createElement("div");
+    ascentSetter.style.background = ""
+    ascentSetter.style.width = "1px";
+    ascentSetter.style.height = "150px";
+    ascentSetter.style.display = "inline-block";
+    let root = document.getElementById("root");
+    root.appendChild(ascentSetter);
+    let baseline = ascentSetter.offsetTop + ascentSetter.offsetHeight;
+    let left = root.offsetLeft;
+    let width = ascentSetter.offsetLeft - left;
+    let fontSize = Number.parseInt(window.getComputedStyle(root).getPropertyValue("font-size"));
+    let blocker = document.createElement("div");
+    blocker.style.background = ""
+    blocker.style.position = "absolute";
+    blocker.style.left = `${left}px`;
+    blocker.style.top = `${baseline + fontSize * 0.11035}px`;
+    blocker.style.width = `${width}px`;
+    blocker.style.height = `${fontSize * 0.13247}px`;
+    document.body.appendChild(blocker);
+    root.blur();
+}
+
+</script>
+
+<title>Editing Test</title>
+</head>
+<body>
+<div>There should be no misspelling dots visible below (because they're covered up by a div)</div>
+<div contenteditable id="root" class="editing">
+<span id="test"></span>
+</div>
+
+<script>
+    if (window.internals)
+        internals.setContinuousSpellCheckingEnabled(true);
+    runEditingTest();
+</script>
+
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-repaint-expected.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-repaint-expected.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-repaint-expected.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Editing Test</title>
+</head>
+<body>
+This test passes if you don't see any dots below.
+</body>
+</html>

Added: trunk/LayoutTests/editing/spelling/spelling-dots-repaint.html (0 => 237834)


--- trunk/LayoutTests/editing/spelling/spelling-dots-repaint.html	                        (rev 0)
+++ trunk/LayoutTests/editing/spelling/spelling-dots-repaint.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -0,0 +1,59 @@
+<!DOCTYPE html><!-- webkit-test-runner [ spellCheckingDots=true ] -->
+<html>
+<head>
+
+<style>
+@font-face {
+    font-family: "WebFont";
+    src: url("resources/VerySmallDescentAhem.ttf") format("truetype");
+}
+.editing {
+    font: 36px "WebFont";
+}
+</style>
+<script src="" language="_javascript_" type="text/_javascript_" ></script>
+
+<script>
+function editingTest() {
+    typeCharacterCommand('w');
+    typeCharacterCommand('a');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('e');
+    typeCharacterCommand('r');
+    typeCharacterCommand('e');
+    typeCharacterCommand('w');
+    typeCharacterCommand('d');
+    typeCharacterCommand('f');
+    typeCharacterCommand('e');
+    typeCharacterCommand('a');
+    typeCharacterCommand(' ');
+    window.setTimeout(function() {
+        let root = document.getElementById("root");
+        root.parentElement.removeChild(root);
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }, 20);
+}
+
+</script>
+
+<title>Editing Test</title>
+</head>
+<body>
+This test passes if you don't see any dots below.
+<div contenteditable id="root" class="editing">
+<span id="test"></span>
+</div>
+
+<script>
+    if (window.internals)
+        internals.setContinuousSpellCheckingEnabled(true);
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+    runEditingTest();
+</script>
+
+</body>
+</html>

Modified: trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker-expected.html (237833 => 237834)


--- trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker-expected.html	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker-expected.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -15,6 +15,7 @@
     left: 0;
     width: 200px;
     font: 20px/1 Ahem;
+    line-height: 1.2;
 }
 </style>
 </head>

Modified: trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker.html (237833 => 237834)


--- trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker.html	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/LayoutTests/fast/writing-mode/english-bt-text-with-spelling-marker.html	2018-11-06 00:09:08 UTC (rev 237834)
@@ -11,6 +11,7 @@
 body {
     -webkit-writing-mode: horizontal-bt;
     font: 20px/1 Ahem;
+    line-height: 1.2;
 }
 
 #test {

Modified: trunk/Source/WebCore/ChangeLog (237833 => 237834)


--- trunk/Source/WebCore/ChangeLog	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/ChangeLog	2018-11-06 00:09:08 UTC (rev 237834)
@@ -1,3 +1,48 @@
+2018-11-05  Myles C. Maxfield  <[email protected]>
+
+        Spelling dots are drawn in the wrong place
+        https://bugs.webkit.org/show_bug.cgi?id=190764
+
+        Reviewed by Dean Jackson.
+
+        - Dots should not be clipped.
+        - Dots should be horizontally centered.
+        - Dots should be drawn behind the text.
+        - Distance from the baseline to the top of the dot should be 11.035% of font size.
+        - Dot diameter should be 13.247% of the font size.
+        - Distance between the dots (right side of the left dot to left side of the right dot) should be 9.457% of the font size.
+        - The "font size" used in these calculations should be clamped so it's 10px <= font size <= 40px.
+
+        Tests: editing/spelling/spelling-dots-position-2.html
+               editing/spelling/spelling-dots-position-3.html
+               editing/spelling/spelling-dots-position.html
+               editing/spelling/spelling-dots-repaint.html
+
+        * platform/graphics/cocoa/GraphicsContextCocoa.mm:
+        (WebCore::colorForMarkerLineStyle): Align iOS and macOS implementations.
+        (WebCore::GraphicsContext::drawDotsForDocumentMarker): Place the dots correctly.
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::addToLine): The KnownToHaveNoOverflow flag should be cleared if the element has spelling dots,
+            because there is no guarantee the spelling dots will lie inside the layout rect of the element.
+        (WebCore::InlineFlowBox::addTextBoxVisualOverflow): Update the repaint rects to include splling dot positions.
+        * rendering/InlineFlowBox.h: Comments should explain why, not say what.
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paint): Draw the dots behind the text.
+        (WebCore::InlineTextBox::hasMarkers const): Convenience.
+        (WebCore::InlineTextBox::paintPlatformDocumentMarkers): Refactor bounds information into a helper function.
+        (WebCore::InlineTextBox::calculateUnionOfAllDocumentMarkerBounds const): Use for repaint rect calculation.
+        (WebCore::InlineTextBox::calculateDocumentMarkerBounds const): Place the dots correctly.
+        (WebCore::InlineTextBox::paintPlatformDocumentMarker): Call the helper method.
+        (WebCore::InlineTextBox::collectMarkedTextsForDocumentMarkers const):
+        (WebCore::InlineTextBox::collectMarkedTextsForDocumentMarkers): Deleted.
+        * rendering/InlineTextBox.h: Declare the helper methods.
+        * rendering/SimpleLineLayout.cpp: Simple line layout doesn't know how to paint spelling dots, so make the presence of
+            spelling dots opt us out of SLL.
+        (WebCore::SimpleLineLayout::canUseForWithReason):
+        * rendering/SimpleLineLayoutCoverage.cpp:
+        (WebCore::SimpleLineLayout::printReason):
+        * rendering/SimpleLineLayoutCoverage.h: Add a new opt-out reason.
+
 2018-11-05  Dean Jackson  <[email protected]>
 
         Attempted build fix.

Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextCocoa.mm (237833 => 237834)


--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextCocoa.mm	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextCocoa.mm	2018-11-06 00:09:08 UTC (rev 237834)
@@ -185,7 +185,6 @@
 
 static CGColorRef colorForMarkerLineStyle(DocumentMarkerLineStyle::Mode style, bool useDarkMode)
 {
-#if PLATFORM(MAC)
     switch (style) {
     // Red
     case DocumentMarkerLineStyle::Mode::Spelling:
@@ -199,19 +198,6 @@
     case DocumentMarkerLineStyle::Mode::Grammar:
         return cachedCGColor(useDarkMode ? Color { 50, 215, 75, 217 } : Color { 25, 175, 50, 191 });
     }
-#else
-    UNUSED_PARAM(useDarkMode);
-    switch (style) {
-    case DocumentMarkerLineStyle::Mode::Spelling:
-        return [getUIColorClass() systemRedColor].CGColor;
-    case DocumentMarkerLineStyle::Mode::DictationAlternatives:
-    case DocumentMarkerLineStyle::Mode::TextCheckingDictationPhraseWithAlternatives:
-    case DocumentMarkerLineStyle::Mode::AutocorrectionReplacement:
-        return [getUIColorClass() systemBlueColor].CGColor;
-    case DocumentMarkerLineStyle::Mode::Grammar:
-        return [getUIColorClass() systemGreenColor].CGColor;
-    }
-#endif
 }
 
 void GraphicsContext::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
@@ -219,28 +205,33 @@
     if (paintingDisabled())
         return;
 
-    auto circleColor = colorForMarkerLineStyle(style.mode, style.shouldUseDarkAppearance);
+    // We want to find the number of full dots, so we're solving the equations:
+    // dotDiameter = height
+    // dotDiameter / dotGap = 13.247 / 9.457
+    // numberOfGaps = numberOfDots - 1
+    // dotDiameter * numberOfDots + dotGap * numberOfGaps = width
 
-    auto lineThickness = rect.height();
-    auto patternGapWidth = lineThickness / 3;
-    auto patternWidth = lineThickness + patternGapWidth;
-
-    FloatPoint offsetPoint = rect.location();
     auto width = rect.width();
-    float widthMod = fmodf(width, patternWidth);
-    if (patternWidth - widthMod > patternGapWidth) {
-        float gapIncludeWidth = 0;
-        if (width > patternWidth)
-            gapIncludeWidth = patternGapWidth;
-        offsetPoint.move(floor((widthMod + gapIncludeWidth) / 2), 0);
-        width -= widthMod;
-    }
+    auto dotDiameter = rect.height();
+    auto dotGap = dotDiameter * 9.457 / 13.247;
+    auto numberOfDots = (width + dotGap) / (dotDiameter + dotGap);
+    auto numberOfWholeDots = static_cast<unsigned>(numberOfDots);
+    auto numberOfWholeGaps = numberOfWholeDots - 1;
 
+    // Center the dots
+    auto offset = (width - (dotDiameter * numberOfWholeDots + dotGap * numberOfWholeGaps)) / 2;
+
+    auto circleColor = colorForMarkerLineStyle(style.mode, style.shouldUseDarkAppearance);
+
     CGContextRef platformContext = this->platformContext();
     CGContextStateSaver stateSaver { platformContext };
     CGContextSetFillColorWithColor(platformContext, circleColor);
-    for (int x = 0; x < width; x += patternWidth)
-        CGContextAddEllipseInRect(platformContext, CGRectMake(offsetPoint.x() + x, offsetPoint.y(), lineThickness, lineThickness));
+    for (unsigned i = 0; i < numberOfWholeDots; ++i) {
+        auto location = rect.location();
+        location.move(offset + i * (dotDiameter + dotGap), 0);
+        auto size = FloatSize(dotDiameter, dotDiameter);
+        CGContextAddEllipseInRect(platformContext, FloatRect(location, size));
+    }
     CGContextSetCompositeOperation(platformContext, kCGCompositeSover);
     CGContextFillPath(platformContext);
 }

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (237833 => 237834)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2018-11-06 00:09:08 UTC (rev 237834)
@@ -158,7 +158,12 @@
         const RenderStyle& childStyle = child->lineStyle();
         if (child->behavesLikeText()) {
             const RenderStyle* childStyle = &child->lineStyle();
-            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMark::None || childStyle->hasPositiveStrokeWidth())
+            bool hasMarkers = false;
+            if (is<InlineTextBox>(child)) {
+                const auto* textBox = downcast<InlineTextBox>(child);
+                hasMarkers = textBox->hasMarkers();
+            }
+            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMark::None || childStyle->hasPositiveStrokeWidth() || hasMarkers)
                 child->clearKnownToHaveNoOverflow();
         } else if (child->renderer().isReplaced()) {
             const RenderBox& box = downcast<RenderBox>(child->renderer());
@@ -928,6 +933,10 @@
     
     logicalVisualOverflow = LayoutRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
                                        logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
+
+    auto documentMarkerBounds = textBox.calculateUnionOfAllDocumentMarkerBounds();
+    documentMarkerBounds.move(textBox.logicalLeft(), textBox.logicalTop());
+    logicalVisualOverflow = unionRect(logicalVisualOverflow, LayoutRect(documentMarkerBounds));
                                     
     textBox.setLogicalOverflowRect(logicalVisualOverflow);
 }

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.h (237833 => 237834)


--- trunk/Source/WebCore/rendering/InlineFlowBox.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -292,8 +292,7 @@
     }
 
     void computeReplacedAndTextLineTopAndBottom(LayoutUnit& lineTop, LayoutUnit& lineBottom) const;
-    
-    // Used to calculate the underline offset for TextUnderlinePosition::Under.
+
     void maxLogicalBottomForTextDecorationLine(float& maxLogicalBottom, const RenderElement* decorationRenderer, OptionSet<TextDecoration>) const;
     void minLogicalTopForTextDecorationLine(float& minLogicalTop, const RenderElement* decorationRenderer, OptionSet<TextDecoration>) const;
 

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (237833 => 237834)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2018-11-06 00:09:08 UTC (rev 237834)
@@ -543,6 +543,9 @@
     if (paintInfo.phase == PaintPhase::Foreground)
         renderer().page().addRelevantRepaintedObject(&renderer(), IntRect(boxOrigin.x(), boxOrigin.y(), logicalWidth(), logicalHeight()));
 
+    if (paintInfo.phase == PaintPhase::Foreground)
+        paintPlatformDocumentMarkers(context, boxOrigin);
+
     // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).
     bool shouldPaintSelectionForeground = haveSelection && !useCustomUnderlines;
     Vector<MarkedText> markedTexts;
@@ -620,12 +623,8 @@
     }
 
     // 3. Paint fancy decorations, including composition underlines and platform-specific underlines for spelling errors, grammar errors, et cetera.
-    if (paintInfo.phase == PaintPhase::Foreground) {
-        paintPlatformDocumentMarkers(context, boxOrigin);
-
-        if (useCustomUnderlines)
-            paintCompositionUnderlines(paintInfo, boxOrigin);
-    }
+    if (paintInfo.phase == PaintPhase::Foreground && useCustomUnderlines)
+        paintCompositionUnderlines(paintInfo, boxOrigin);
     
     if (shouldRotate)
         context.concatCTM(rotation(boxRect, Counterclockwise));
@@ -665,12 +664,46 @@
     return { clampedOffset(start), clampedOffset(end) };
 }
 
+bool InlineTextBox::hasMarkers() const
+{
+    return collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration).size();
+}
+
 void InlineTextBox::paintPlatformDocumentMarkers(GraphicsContext& context, const FloatPoint& boxOrigin)
 {
+    // This must match calculateUnionOfAllDocumentMarkerBounds().
     for (auto& markedText : subdivide(collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration), OverlapStrategy::Frontmost))
         paintPlatformDocumentMarker(context, boxOrigin, markedText);
 }
 
+FloatRect InlineTextBox::calculateUnionOfAllDocumentMarkerBounds() const
+{
+    // This must match paintPlatformDocumentMarkers().
+    FloatRect result;
+    for (auto& markedText : subdivide(collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration), OverlapStrategy::Frontmost))
+        result = unionRect(result, calculateDocumentMarkerBounds(markedText));
+    return result;
+}
+
+FloatRect InlineTextBox::calculateDocumentMarkerBounds(const MarkedText& markedText) const
+{
+    auto& font = lineFont();
+    auto ascent = font.fontMetrics().ascent();
+    auto fontSize = std::min(std::max(font.size(), 10.0f), 40.0f);
+    auto y = ascent + 0.11035 * fontSize;
+    auto height = 0.13247 * fontSize;
+
+    // Avoid measuring the text when the entire line box is selected as an optimization.
+    if (markedText.startOffset || markedText.endOffset != clampedOffset(end() + 1)) {
+        TextRun run = createTextRun();
+        LayoutRect selectionRect = LayoutRect(0, y, 0, height);
+        lineFont().adjustSelectionRectForText(run, selectionRect, markedText.startOffset, markedText.endOffset);
+        return selectionRect;
+    }
+
+    return FloatRect(0, y, logicalWidth(), height);
+}
+
 void InlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const FloatPoint& boxOrigin, const MarkedText& markedText)
 {
     // Never print spelling/grammar markers (5327887)
@@ -680,27 +713,11 @@
     if (m_truncation == cFullTruncation)
         return;
 
-    float start = 0; // start of line to draw, relative to tx
-    float width = logicalWidth(); // how much line to draw
+    auto bounds = calculateDocumentMarkerBounds(markedText);
 
-    // Avoid measuring the text when the entire line box is selected as an optimization.
-    if (markedText.startOffset || markedText.endOffset != clampedOffset(end() + 1)) {
-        // Calculate start & width
-        int deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
-        int selHeight = selectionHeight();
-        FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
-        TextRun run = createTextRun();
-
-        LayoutRect selectionRect = LayoutRect(startPoint, FloatSize(0, selHeight));
-        lineFont().adjustSelectionRectForText(run, selectionRect, markedText.startOffset, markedText.endOffset);
-        IntRect markerRect = enclosingIntRect(selectionRect);
-        start = markerRect.x() - startPoint.x();
-        width = markerRect.width();
-    }
-
-    auto lineStyleForMarkedTextType = [&] (MarkedText::Type type) -> DocumentMarkerLineStyle {
+    auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
         bool shouldUseDarkAppearance = renderer().document().useDarkAppearance();
-        switch (type) {
+        switch (markedText.type) {
         case MarkedText::SpellingError:
             return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
         case MarkedText::GrammarError:
@@ -720,25 +737,8 @@
         }
     };
 
-    // IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to
-    // make sure to fit within those bounds.  This means the top pixel(s) of the underline will overlap the
-    // bottom pixel(s) of the glyphs in smaller font sizes.  The alternatives are to increase the line spacing (bad!!)
-    // or decrease the underline thickness.  The overlap is actually the most useful, and matches what AppKit does.
-    // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
-    // we pin to two pixels under the baseline.
-    int lineThickness = 3;
-    int baseline = lineStyle().fontMetrics().ascent();
-    int descent = logicalHeight() - baseline;
-    int underlineOffset;
-    if (descent <= (2 + lineThickness)) {
-        // Place the underline at the very bottom of the text in small/medium fonts.
-        underlineOffset = logicalHeight() - lineThickness;
-    } else {
-        // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
-        underlineOffset = baseline + 2;
-    }
-
-    context.drawDotsForDocumentMarker(FloatRect(boxOrigin.x() + start, boxOrigin.y() + underlineOffset, width, lineThickness), lineStyleForMarkedTextType(markedText.type));
+    bounds.moveBy(boxOrigin);
+    context.drawDotsForDocumentMarker(bounds, lineStyleForMarkedTextType());
 }
 
 auto InlineTextBox::computeStyleForUnmarkedMarkedText(const PaintInfo& paintInfo) const -> MarkedTextStyle
@@ -855,7 +855,7 @@
     return result;
 }
 
-Vector<MarkedText> InlineTextBox::collectMarkedTextsForDocumentMarkers(TextPaintPhase phase)
+Vector<MarkedText> InlineTextBox::collectMarkedTextsForDocumentMarkers(TextPaintPhase phase) const
 {
     ASSERT_ARG(phase, phase == TextPaintPhase::Background || phase == TextPaintPhase::Foreground || phase == TextPaintPhase::Decoration);
 

Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (237833 => 237834)


--- trunk/Source/WebCore/rendering/InlineTextBox.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -157,6 +157,10 @@
     virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
     virtual float positionForOffset(unsigned offset) const;
 
+    bool hasMarkers() const;
+    FloatRect calculateUnionOfAllDocumentMarkerBounds() const;
+    FloatRect calculateDocumentMarkerBounds(const MarkedText&) const;
+
 private:
     struct MarkedTextStyle;
     struct StyledMarkedText;
@@ -164,7 +168,7 @@
     enum class TextPaintPhase { Background, Foreground, Decoration };
 
     Vector<MarkedText> collectMarkedTextsForDraggedContent();
-    Vector<MarkedText> collectMarkedTextsForDocumentMarkers(TextPaintPhase);
+    Vector<MarkedText> collectMarkedTextsForDocumentMarkers(TextPaintPhase) const;
 
     MarkedTextStyle computeStyleForUnmarkedMarkedText(const PaintInfo&) const;
     StyledMarkedText resolveStyleForMarkedText(const MarkedText&, const MarkedTextStyle& baseStyle, const PaintInfo&);

Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (237833 => 237834)


--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2018-11-06 00:09:08 UTC (rev 237834)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "SimpleLineLayout.h"
 
+#include "DocumentMarkerController.h"
 #include "FontCache.h"
 #include "Frame.h"
 #include "GraphicsContext.h"
@@ -313,6 +314,9 @@
         if (child->selectionState() != RenderObject::SelectionNone)
             SET_REASON_AND_RETURN_IF_NEEDED(FlowChildIsSelected, reasons, includeReasons);
         if (is<RenderText>(*child)) {
+            const auto& renderText = downcast<RenderText>(*child);
+            if (!renderText.document().markers().markersFor(renderText.textNode()).isEmpty())
+                SET_REASON_AND_RETURN_IF_NEEDED(FlowIncludesDocumentMarkers, reasons, includeReasons);
             child = child->nextSibling();
             continue;
         }

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.cpp (237833 => 237834)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.cpp	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.cpp	2018-11-06 00:09:08 UTC (rev 237834)
@@ -193,8 +193,11 @@
         stream << "column with vertical-align != baseline";
         break;
     case MultiColumnFlowIsFloating:
-        stream << "column with floating objecgts";
+        stream << "column with floating objects";
         break;
+    case FlowIncludesDocumentMarkers:
+        stream << "text includes document markers";
+        break;
     case FlowTextIsEmpty:
     case FlowHasNoChild:
     case FlowHasNoParent:

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.h (237833 => 237834)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutCoverage.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -90,7 +90,8 @@
     MultiColumnFlowHasColumnSpanner       = 1LLU  << 52,
     MultiColumnFlowVerticalAlign          = 1LLU  << 53,
     MultiColumnFlowIsFloating             = 1LLU  << 54,
-    EndOfReasons                          = 1LLU  << 55
+    FlowIncludesDocumentMarkers           = 1LLU  << 55,
+    EndOfReasons                          = 1LLU  << 56
 };
 const unsigned NoReason = 0;
 

Modified: trunk/Tools/ChangeLog (237833 => 237834)


--- trunk/Tools/ChangeLog	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/ChangeLog	2018-11-06 00:09:08 UTC (rev 237834)
@@ -1,3 +1,29 @@
+2018-11-05  Myles C. Maxfield  <[email protected]>
+
+        Spelling dots are drawn in the wrong place
+        https://bugs.webkit.org/show_bug.cgi?id=190764
+
+        Reviewed by Dean Jackson.
+
+        Previously, it was impossible for WebKitTestRunner to draw spelling dots. This patch adds support for a header
+        at the top of test files, of the form <!-- webkit-test-runner [ spellCheckingDots=true ] --> which will cause
+        dots to be drawn.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::resetStateToConsistentValues):
+        (WTR::updateTestOptionsFromTestHeader):
+        (WTR::TestController::platformResetStateToConsistentValues):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestOptions.h:
+        (WTR::TestOptions::hasSameInitializationOptions const):
+        * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+        (WTR::TestController::cocoaResetStateToConsistentValues):
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+        * WebKitTestRunner/ios/TestControllerIOS.mm:
+        (WTR::TestController::platformResetStateToConsistentValues):
+        * WebKitTestRunner/mac/TestControllerMac.mm:
+        (WTR::TestController::platformResetStateToConsistentValues):
+
 2018-11-05  Chris Dumez  <[email protected]>
 
         Use same limit for page cache and suspended pages

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2018-11-06 00:09:08 UTC (rev 237834)
@@ -926,7 +926,7 @@
 
     setHidden(false);
 
-    platformResetStateToConsistentValues();
+    platformResetStateToConsistentValues(options);
 
     m_shouldDecideNavigationPolicyAfterDelay = false;
     m_shouldDecideResponsePolicyAfterDelay = false;
@@ -1237,6 +1237,8 @@
             testOptions.runSingly = parseBooleanTestHeaderValue(value);
         else if (key == "shouldIgnoreMetaViewport")
             testOptions.shouldIgnoreMetaViewport = parseBooleanTestHeaderValue(value);
+        else if (key == "spellCheckingDots")
+            testOptions.shouldShowSpellCheckingDots = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
     }
 }
@@ -2649,7 +2651,7 @@
     return context;
 }
 
-void TestController::platformResetStateToConsistentValues()
+void TestController::platformResetStateToConsistentValues(const TestOptions&)
 {
 }
 

Modified: trunk/Tools/WebKitTestRunner/TestController.h (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/TestController.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -283,10 +283,10 @@
     void platformCreateWebView(WKPageConfigurationRef, const TestOptions&);
     static PlatformWebView* platformCreateOtherPage(PlatformWebView* parentView, WKPageConfigurationRef, const TestOptions&);
     void platformResetPreferencesToConsistentValues();
-    void platformResetStateToConsistentValues();
+    void platformResetStateToConsistentValues(const TestOptions&);
 #if PLATFORM(COCOA)
     void cocoaPlatformInitialize();
-    void cocoaResetStateToConsistentValues();
+    void cocoaResetStateToConsistentValues(const TestOptions&);
 #endif
     void platformConfigureViewForTest(const TestInvocation&);
     void platformWillRunTest(const TestInvocation&);

Modified: trunk/Tools/WebKitTestRunner/TestOptions.h (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/TestOptions.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/TestOptions.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -63,6 +63,7 @@
     bool runSingly { false };
     bool checkForWorldLeaks { false };
     bool shouldIgnoreMetaViewport { false };
+    bool shouldShowSpellCheckingDots { false };
 
     float deviceScaleFactor { 1 };
     Vector<String> overrideLanguages;
@@ -103,7 +104,8 @@
             || jscOptions != options.jscOptions
             || runSingly != options.runSingly
             || checkForWorldLeaks != options.checkForWorldLeaks
-            || shouldIgnoreMetaViewport != options.shouldIgnoreMetaViewport)
+            || shouldIgnoreMetaViewport != options.shouldIgnoreMetaViewport
+            || shouldShowSpellCheckingDots != options.shouldShowSpellCheckingDots)
             return false;
 
         if (experimentalFeatures != options.experimentalFeatures)

Modified: trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm	2018-11-06 00:09:08 UTC (rev 237834)
@@ -203,7 +203,7 @@
         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate];
 }
 
-void TestController::cocoaResetStateToConsistentValues()
+void TestController::cocoaResetStateToConsistentValues(const TestOptions& options)
 {
 #if WK_API_ENABLED
     __block bool doneRemoving = false;
@@ -213,10 +213,15 @@
     platformRunUntil(doneRemoving, noTimeout);
     [[_WKUserContentExtensionStore defaultStore] _removeAllContentExtensions];
 
+
     if (auto* webView = mainWebView()) {
         TestRunnerWKWebView *platformView = webView->platformView();
         [platformView.configuration.userContentController _removeAllUserContentFilters];
         platformView._viewScale = 1;
+
+        // Toggle on before the test, and toggle off after the test.
+        if (options.shouldShowSpellCheckingDots)
+            [platformView toggleContinuousSpellChecking:nil];
     }
 #endif
 }

Modified: trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h	2018-11-06 00:09:08 UTC (rev 237834)
@@ -27,6 +27,10 @@
 
 #if WK_API_ENABLED
 
+@interface WKWebView(SpellChecking)
+- (IBAction)toggleContinuousSpellChecking:(id)sender;
+@end
+
 @interface TestRunnerWKWebView : WKWebView
 
 #if PLATFORM(IOS_FAMILY)

Modified: trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm	2018-11-06 00:09:08 UTC (rev 237834)
@@ -101,9 +101,9 @@
     WKPreferencesSetTextAutosizingEnabled(preferences, false);
 }
 
-void TestController::platformResetStateToConsistentValues()
+void TestController::platformResetStateToConsistentValues(const TestOptions& options)
 {
-    cocoaResetStateToConsistentValues();
+    cocoaResetStateToConsistentValues(options);
 
     [[UIDevice currentDevice] setOrientation:UIDeviceOrientationPortrait animated:NO];
     

Modified: trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm (237833 => 237834)


--- trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm	2018-11-05 23:59:35 UTC (rev 237833)
+++ trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm	2018-11-06 00:09:08 UTC (rev 237834)
@@ -102,9 +102,9 @@
 {
 }
 
-void TestController::platformResetStateToConsistentValues()
+void TestController::platformResetStateToConsistentValues(const TestOptions& options)
 {
-    cocoaResetStateToConsistentValues();
+    cocoaResetStateToConsistentValues(options);
 
     while ([NSApp nextEventMatchingMask:NSEventMaskGesture | NSEventMaskScrollWheel untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]) {
         // Clear out (and ignore) any pending gesture and scroll wheel events.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to