Title: [282277] trunk/Source/WebCore
Revision
282277
Author
an...@apple.com
Date
2021-09-10 10:16:43 -0700 (Fri, 10 Sep 2021)

Log Message

Factor more text painting functions to TextBoxPainter
https://bugs.webkit.org/show_bug.cgi?id=230155

Reviewed by Alan Bujtas.

Composition underlines and document markers.

* WebCore.xcodeproj/project.pbxproj:
* rendering/LegacyInlineFlowBox.cpp:
(WebCore::LegacyInlineFlowBox::addTextBoxVisualOverflow):
* rendering/LegacyInlineTextBox.cpp:
(WebCore::LegacyInlineTextBox::paint):
(WebCore::LegacyInlineTextBox::paintPlatformDocumentMarkers): Deleted.
(WebCore::LegacyInlineTextBox::calculateUnionOfAllDocumentMarkerBounds const): Deleted.
(WebCore::LegacyInlineTextBox::calculateDocumentMarkerBounds const): Deleted.
(WebCore::LegacyInlineTextBox::paintPlatformDocumentMarker): Deleted.
(WebCore::LegacyInlineTextBox::paintCompositionUnderlines const): Deleted.
(WebCore::mirrorRTLSegment): Deleted.
(WebCore::LegacyInlineTextBox::paintCompositionUnderline const): Deleted.
* rendering/LegacyInlineTextBox.h:
* rendering/TextBoxPainter.cpp:
(WebCore::TextBoxPainter::paintCompositionUnderlines):
(WebCore::mirrorRTLSegment):
(WebCore::TextBoxPainter::paintCompositionUnderline):
(WebCore::TextBoxPainter::paintPlatformDocumentMarkers):
(WebCore::TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds):
(WebCore::TextBoxPainter::paintPlatformDocumentMarker):
(WebCore::TextBoxPainter::calculateDocumentMarkerBounds):
* rendering/TextBoxPainter.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282276 => 282277)


--- trunk/Source/WebCore/ChangeLog	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/ChangeLog	2021-09-10 17:16:43 UTC (rev 282277)
@@ -1,3 +1,35 @@
+2021-09-10  Antti Koivisto  <an...@apple.com>
+
+        Factor more text painting functions to TextBoxPainter
+        https://bugs.webkit.org/show_bug.cgi?id=230155
+
+        Reviewed by Alan Bujtas.
+
+        Composition underlines and document markers.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/LegacyInlineFlowBox.cpp:
+        (WebCore::LegacyInlineFlowBox::addTextBoxVisualOverflow):
+        * rendering/LegacyInlineTextBox.cpp:
+        (WebCore::LegacyInlineTextBox::paint):
+        (WebCore::LegacyInlineTextBox::paintPlatformDocumentMarkers): Deleted.
+        (WebCore::LegacyInlineTextBox::calculateUnionOfAllDocumentMarkerBounds const): Deleted.
+        (WebCore::LegacyInlineTextBox::calculateDocumentMarkerBounds const): Deleted.
+        (WebCore::LegacyInlineTextBox::paintPlatformDocumentMarker): Deleted.
+        (WebCore::LegacyInlineTextBox::paintCompositionUnderlines const): Deleted.
+        (WebCore::mirrorRTLSegment): Deleted.
+        (WebCore::LegacyInlineTextBox::paintCompositionUnderline const): Deleted.
+        * rendering/LegacyInlineTextBox.h:
+        * rendering/TextBoxPainter.cpp:
+        (WebCore::TextBoxPainter::paintCompositionUnderlines):
+        (WebCore::mirrorRTLSegment):
+        (WebCore::TextBoxPainter::paintCompositionUnderline):
+        (WebCore::TextBoxPainter::paintPlatformDocumentMarkers):
+        (WebCore::TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds):
+        (WebCore::TextBoxPainter::paintPlatformDocumentMarker):
+        (WebCore::TextBoxPainter::calculateDocumentMarkerBounds):
+        * rendering/TextBoxPainter.h:
+
 2021-09-10  Antoine Quint  <grao...@webkit.org>
 
         [Media Controls] Allow buttons in a controls bar to have standalone background tint

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (282276 => 282277)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-10 17:16:43 UTC (rev 282277)
@@ -32558,7 +32558,6 @@
 				318EAD4D1FA91380008CEF86 /* ImageBitmapRenderingContextSettings.h in Headers */,
 				B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
 				72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */,
-				E440DF5626EB53E0004AF06B /* TextBoxPainter.h in Headers */,
 				550640B02407587E00AAE045 /* ImageBufferCGBackend.h in Headers */,
 				2D7705C925528D34001D0C94 /* ImageBufferCGBitmapBackend.h in Headers */,
 				727A7F3A24078B84004D2931 /* ImageBufferIOSurfaceBackend.h in Headers */,
@@ -32710,7 +32709,6 @@
 				7C30D9841F815AEC00268356 /* JSAbortController.h in Headers */,
 				7C30D9861F815AEC00268356 /* JSAbortSignal.h in Headers */,
 				9355EF51253A4279006FF4A4 /* JSAbstractRange.h in Headers */,
-				41E6D71B26EA1A4600B765D6 /* RTCError.h in Headers */,
 				418F88050FF957AF0080F045 /* JSAbstractWorker.h in Headers */,
 				A1677E13213E03C600A08C34 /* JSAddressErrors.h in Headers */,
 				5704405A1E53936200356601 /* JSAesCbcCfbParams.h in Headers */,
@@ -34547,6 +34545,7 @@
 				4188D56326C551B1004858C8 /* RTCDtlsTransportState.h in Headers */,
 				078E092017D14D1C00420AA1 /* RTCDTMFSender.h in Headers */,
 				078E092117D14D1C00420AA1 /* RTCDTMFToneChangeEvent.h in Headers */,
+				41E6D71B26EA1A4600B765D6 /* RTCError.h in Headers */,
 				41AB979526E75A2E007C0FE6 /* RTCErrorDetailType.h in Headers */,
 				078E092317D14D1C00420AA1 /* RTCIceCandidate.h in Headers */,
 				078E094017D16E1C00420AA1 /* RTCIceCandidateDescriptor.h in Headers */,
@@ -35178,6 +35177,7 @@
 				CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */,
 				0F54DCE61881051D003EEDBB /* TextAutoSizing.h in Headers */,
 				B2C3DA340D006C1D00EF6F26 /* TextBoundaries.h in Headers */,
+				E440DF5626EB53E0004AF06B /* TextBoxPainter.h in Headers */,
 				E447F5B3266CF63D00133F00 /* TextBoxSelectableRange.h in Headers */,
 				A7151BD812F1558F005A0F64 /* TextCheckerClient.h in Headers */,
 				A77D0012133B0AEB00D6658C /* TextChecking.h in Headers */,

Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp (282276 => 282277)


--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-09-10 17:16:43 UTC (rev 282277)
@@ -41,6 +41,7 @@
 #include "RenderView.h"
 #include "Settings.h"
 #include "Text.h"
+#include "TextBoxPainter.h"
 #include <math.h>
 #include <wtf/IsoMallocInlines.h>
 
@@ -936,7 +937,7 @@
     
     logicalVisualOverflow = LayoutRect(logicalLeftVisualOverflow, logicalTopVisualOverflow, logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
 
-    auto documentMarkerBounds = textBox.calculateUnionOfAllDocumentMarkerBounds();
+    auto documentMarkerBounds = TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(textBox);
     documentMarkerBounds.move(textBox.logicalLeft(), textBox.logicalTop());
     logicalVisualOverflow = unionRect(logicalVisualOverflow, LayoutRect(documentMarkerBounds));
 

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (282276 => 282277)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-10 17:16:43 UTC (rev 282277)
@@ -459,8 +459,6 @@
         }
     }
 
-    GraphicsContext& context = paintInfo.context();
-
     const RenderStyle& lineStyle = this->lineStyle();
     
     localPaintOffset.move(0, lineStyle.isHorizontalWritingMode() ? 0 : -logicalHeight());
@@ -494,6 +492,7 @@
         markedTexts.appendVector(MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange, MarkedText::PaintPhase::Background));
 
 #if ENABLE(TEXT_SELECTION)
+        GraphicsContext& context = paintInfo.context();
         if (haveSelection && !useCustomUnderlines && !context.paintingDisabled()) {
             auto selectionMarkedText = createMarkedTextFromSelectionInBox(*this);
             if (!selectionMarkedText.isEmpty())
@@ -517,7 +516,7 @@
         renderer().page().addRelevantRepaintedObject(&renderer(), IntRect(boxOrigin.x(), boxOrigin.y(), logicalWidth(), logicalHeight()));
 
     if (paintInfo.phase == PaintPhase::Foreground)
-        paintPlatformDocumentMarkers(context, boxOrigin);
+        textBoxPainter.paintPlatformDocumentMarkers();
 
     // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).
     bool shouldPaintSelectionForeground = haveSelection && !useCustomUnderlines;
@@ -608,7 +607,7 @@
 
     // 3. Paint fancy decorations, including composition underlines and platform-specific underlines for spelling errors, grammar errors, et cetera.
     if (paintInfo.phase == PaintPhase::Foreground && useCustomUnderlines)
-        paintCompositionUnderlines(paintInfo, boxOrigin);    
+        textBoxPainter.paintCompositionUnderlines();
 }
 
 TextBoxSelectableRange LegacyInlineTextBox::selectableRange() const
@@ -651,80 +650,6 @@
     return MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration).size();
 }
 
-void LegacyInlineTextBox::paintPlatformDocumentMarkers(GraphicsContext& context, const FloatPoint& boxOrigin)
-{
-    // This must match calculateUnionOfAllDocumentMarkerBounds().
-    auto markedTexts = MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration);
-    for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
-        paintPlatformDocumentMarker(context, boxOrigin, markedText);
-}
-
-FloatRect LegacyInlineTextBox::calculateUnionOfAllDocumentMarkerBounds() const
-{
-    // This must match paintPlatformDocumentMarkers().
-    FloatRect result;
-    auto markedTexts = MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration);
-    for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
-        result = unionRect(result, calculateDocumentMarkerBounds(markedText));
-    return result;
-}
-
-FloatRect LegacyInlineTextBox::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 != selectableRange().clamp(end())) {
-        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 LegacyInlineTextBox::paintPlatformDocumentMarker(GraphicsContext& context, const FloatPoint& boxOrigin, const MarkedText& markedText)
-{
-    // Never print spelling/grammar markers (5327887)
-    if (renderer().document().printing())
-        return;
-
-    if (m_truncation == cFullTruncation)
-        return;
-
-    auto bounds = calculateDocumentMarkerBounds(markedText);
-
-    auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
-        bool shouldUseDarkAppearance = renderer().useDarkAppearance();
-        switch (markedText.type) {
-        case MarkedText::SpellingError:
-            return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
-        case MarkedText::GrammarError:
-            return { DocumentMarkerLineStyle::Mode::Grammar, shouldUseDarkAppearance };
-        case MarkedText::Correction:
-            return { DocumentMarkerLineStyle::Mode::AutocorrectionReplacement, shouldUseDarkAppearance };
-        case MarkedText::DictationAlternatives:
-            return { DocumentMarkerLineStyle::Mode::DictationAlternatives, shouldUseDarkAppearance };
-#if PLATFORM(IOS_FAMILY)
-        case MarkedText::DictationPhraseWithAlternatives:
-            // FIXME: Rename DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives and remove the PLATFORM(IOS_FAMILY)-guard.
-            return { DocumentMarkerLineStyle::Mode::TextCheckingDictationPhraseWithAlternatives, shouldUseDarkAppearance };
-#endif
-        default:
-            ASSERT_NOT_REACHED();
-            return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
-        }
-    };
-
-    bounds.moveBy(boxOrigin);
-    context.drawDotsForDocumentMarker(bounds, lineStyleForMarkedTextType());
-}
-
 FloatPoint LegacyInlineTextBox::textOriginFromBoxRect(const FloatRect& boxRect) const
 {
     FloatPoint textOrigin { boxRect.x(), boxRect.y() + lineFont().fontMetrics().ascent() };
@@ -739,85 +664,6 @@
     return textOrigin;
 }
 
-void LegacyInlineTextBox::paintCompositionUnderlines(PaintInfo& paintInfo, const FloatPoint& boxOrigin) const
-{
-    if (m_truncation == cFullTruncation)
-        return;
-
-    for (auto& underline : renderer().frame().editor().customCompositionUnderlines()) {
-        if (underline.endOffset <= m_start) {
-            // Underline is completely before this run. This might be an underline that sits
-            // before the first run we draw, or underlines that were within runs we skipped
-            // due to truncation.
-            continue;
-        }
-
-        if (underline.startOffset >= end())
-            break; // Underline is completely after this run, bail. A later run will paint it.
-
-        // Underline intersects this run. Paint it.
-        paintCompositionUnderline(paintInfo, boxOrigin, underline);
-
-        if (underline.endOffset > end())
-            break; // Underline also runs into the next run. Bail now, no more marker advancement.
-    }
-}
-
-static inline void mirrorRTLSegment(float logicalWidth, TextDirection direction, float& start, float width)
-{
-    if (direction == TextDirection::LTR)
-        return;
-    start = logicalWidth - width - start;
-}
-
-void LegacyInlineTextBox::paintCompositionUnderline(PaintInfo& paintInfo, const FloatPoint& boxOrigin, const CompositionUnderline& underline) const
-{
-    if (m_truncation == cFullTruncation)
-        return;
-    
-    float start = 0; // start of line to draw, relative to tx
-    float width = logicalWidth(); // how much line to draw
-    bool useWholeWidth = true;
-    unsigned paintStart = m_start;
-    unsigned paintEnd = end();
-    if (paintStart <= underline.startOffset) {
-        paintStart = underline.startOffset;
-        useWholeWidth = false;
-        start = renderer().width(m_start, paintStart - m_start, textPos(), isFirstLine());
-    }
-    if (paintEnd != underline.endOffset) {
-        paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
-        useWholeWidth = false;
-    }
-    if (m_truncation != cNoTruncation) {
-        paintEnd = std::min(paintEnd, (unsigned)m_start + m_truncation);
-        useWholeWidth = false;
-    }
-    if (!useWholeWidth) {
-        width = renderer().width(paintStart, paintEnd - paintStart, textPos() + start, isFirstLine());
-        mirrorRTLSegment(logicalWidth(), direction(), start, width);
-    }
-
-    // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
-    // All other marked text underlines are 1px thick.
-    // If there's not enough space the underline will touch or overlap characters.
-    int lineThickness = 1;
-    int baseline = lineStyle().fontMetrics().ascent();
-    if (underline.thick && logicalHeight() - baseline >= 2)
-        lineThickness = 2;
-
-    // We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those.
-    // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too.
-    start += 1;
-    width -= 2;
-
-    GraphicsContext& context = paintInfo.context();
-    Color underlineColor = underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer().style().visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : renderer().style().colorByApplyingColorFilter(underline.color);
-    context.setStrokeColor(underlineColor);
-    context.setStrokeThickness(lineThickness);
-    context.drawLineForText(FloatRect(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness, width, lineThickness), renderer().document().printing());
-}
-
 int LegacyInlineTextBox::caretMinOffset() const
 {
     return m_start;

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (282276 => 282277)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-10 17:16:43 UTC (rev 282277)
@@ -23,7 +23,6 @@
 #pragma once
 
 #include "LegacyInlineBox.h"
-#include "MarkedText.h"
 #include "RenderText.h"
 #include "TextRun.h"
 
@@ -30,13 +29,7 @@
 namespace WebCore {
 
 class RenderCombineText;
-class RenderedDocumentMarker;
-class TextPainter;
-struct CompositionUnderline;
-struct MarkedText;
-struct StyledMarkedText;
 struct TextBoxSelectableRange;
-struct TextPaintStyle;
 
 const unsigned short cNoTruncation = USHRT_MAX;
 const unsigned short cFullTruncation = USHRT_MAX - 1;
@@ -159,8 +152,6 @@
     virtual float positionForOffset(unsigned offset) const;
 
     bool hasMarkers() const;
-    FloatRect calculateUnionOfAllDocumentMarkerBounds() const;
-    FloatRect calculateDocumentMarkerBounds(const MarkedText&) const;
 
 private:
     friend class TextBoxPainter;
@@ -167,12 +158,6 @@
 
     FloatPoint textOriginFromBoxRect(const FloatRect&) const;
 
-    void paintPlatformDocumentMarker(GraphicsContext&, const FloatPoint& boxOrigin, const MarkedText&);
-    void paintPlatformDocumentMarkers(GraphicsContext&, const FloatPoint& boxOrigin);
-
-    void paintCompositionUnderlines(PaintInfo&, const FloatPoint& boxOrigin) const;
-    void paintCompositionUnderline(PaintInfo&, const FloatPoint& boxOrigin, const CompositionUnderline&) const;
-
     const RenderCombineText* combinedText() const;
     const FontCascade& lineFont() const;
 

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.cpp (282276 => 282277)


--- trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-10 17:16:43 UTC (rev 282277)
@@ -227,4 +227,155 @@
         context.concatCTM(rotation(m_boxRect, Counterclockwise));
 }
 
+void TextBoxPainter::paintCompositionUnderlines()
+{
+    if (m_textBox.truncation() == cFullTruncation)
+        return;
+
+    for (auto& underline : m_textBox.renderer().frame().editor().customCompositionUnderlines()) {
+        if (underline.endOffset <= m_textBox.start()) {
+            // Underline is completely before this run. This might be an underline that sits
+            // before the first run we draw, or underlines that were within runs we skipped
+            // due to truncation.
+            continue;
+        }
+
+        if (underline.startOffset >= m_textBox.end())
+            break; // Underline is completely after this run, bail. A later run will paint it.
+
+        // Underline intersects this run. Paint it.
+        paintCompositionUnderline(underline);
+
+        if (underline.endOffset > m_textBox.end())
+            break; // Underline also runs into the next run. Bail now, no more marker advancement.
+    }
 }
+
+static inline void mirrorRTLSegment(float logicalWidth, TextDirection direction, float& start, float width)
+{
+    if (direction == TextDirection::LTR)
+        return;
+    start = logicalWidth - width - start;
+}
+
+void TextBoxPainter::paintCompositionUnderline(const CompositionUnderline& underline)
+{
+    auto& renderer = m_textBox.renderer();
+
+    float start = 0; // start of line to draw, relative to tx
+    float width = m_textBox.logicalWidth(); // how much line to draw
+    bool useWholeWidth = true;
+    unsigned paintStart = m_textBox.start();
+    unsigned paintEnd = m_textBox.end();
+    if (paintStart <= underline.startOffset) {
+        paintStart = underline.startOffset;
+        useWholeWidth = false;
+        start = renderer.width(m_textBox.start(), paintStart - m_textBox.start(), m_textBox.textPos(), m_textBox.isFirstLine());
+    }
+    if (paintEnd != underline.endOffset) {
+        paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
+        useWholeWidth = false;
+    }
+    if (m_textBox.truncation() != cNoTruncation) {
+        paintEnd = std::min(paintEnd, m_textBox.start() + m_textBox.truncation());
+        useWholeWidth = false;
+    }
+    if (!useWholeWidth) {
+        width = renderer.width(paintStart, paintEnd - paintStart, m_textBox.textPos() + start, m_textBox.isFirstLine());
+        mirrorRTLSegment(m_textBox.logicalWidth(), m_textBox.direction(), start, width);
+    }
+
+    // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
+    // All other marked text underlines are 1px thick.
+    // If there's not enough space the underline will touch or overlap characters.
+    int lineThickness = 1;
+    int baseline = m_textBox.lineStyle().fontMetrics().ascent();
+    if (underline.thick && m_textBox.logicalHeight() - baseline >= 2)
+        lineThickness = 2;
+
+    // We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those.
+    // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too.
+    start += 1;
+    width -= 2;
+
+    GraphicsContext& context = m_paintInfo.context();
+    Color underlineColor = underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer.style().visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : renderer.style().colorByApplyingColorFilter(underline.color);
+    context.setStrokeColor(underlineColor);
+    context.setStrokeThickness(lineThickness);
+    context.drawLineForText(FloatRect(m_boxRect.x() + start, m_boxRect.y() + m_textBox.logicalHeight() - lineThickness, width, lineThickness), renderer.document().printing());
+}
+
+void TextBoxPainter::paintPlatformDocumentMarkers()
+{
+    auto markedTexts = MarkedText::collectForDocumentMarkers(m_textBox.renderer(), m_textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
+    for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
+        paintPlatformDocumentMarker(markedText);
+}
+
+FloatRect TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox& textBox)
+{
+    // This must match paintPlatformDocumentMarkers().
+    FloatRect result;
+    auto markedTexts = MarkedText::collectForDocumentMarkers(textBox.renderer(), textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
+    for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
+        result = unionRect(result, calculateDocumentMarkerBounds(textBox, markedText));
+    return result;
+}
+
+void TextBoxPainter::paintPlatformDocumentMarker(const MarkedText& markedText)
+{
+    // Never print spelling/grammar markers (5327887)
+    if (m_textBox.renderer().document().printing())
+        return;
+
+    if (m_textBox.truncation() == cFullTruncation)
+        return;
+
+    auto bounds = calculateDocumentMarkerBounds(m_textBox, markedText);
+
+    auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
+        bool shouldUseDarkAppearance = m_textBox.renderer().useDarkAppearance();
+        switch (markedText.type) {
+        case MarkedText::SpellingError:
+            return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
+        case MarkedText::GrammarError:
+            return { DocumentMarkerLineStyle::Mode::Grammar, shouldUseDarkAppearance };
+        case MarkedText::Correction:
+            return { DocumentMarkerLineStyle::Mode::AutocorrectionReplacement, shouldUseDarkAppearance };
+        case MarkedText::DictationAlternatives:
+            return { DocumentMarkerLineStyle::Mode::DictationAlternatives, shouldUseDarkAppearance };
+#if PLATFORM(IOS_FAMILY)
+        case MarkedText::DictationPhraseWithAlternatives:
+            // FIXME: Rename DocumentMarkerLineStyle::TextCheckingDictationPhraseWithAlternatives and remove the PLATFORM(IOS_FAMILY)-guard.
+            return { DocumentMarkerLineStyle::Mode::TextCheckingDictationPhraseWithAlternatives, shouldUseDarkAppearance };
+#endif
+        default:
+            ASSERT_NOT_REACHED();
+            return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
+        }
+    };
+
+    bounds.moveBy(m_boxRect.location());
+    m_paintInfo.context().drawDotsForDocumentMarker(bounds, lineStyleForMarkedTextType());
+}
+
+FloatRect TextBoxPainter::calculateDocumentMarkerBounds(const LegacyInlineTextBox& textBox, const MarkedText& markedText)
+{
+    auto& font = textBox.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 != textBox.selectableRange().clamp(textBox.end())) {
+        TextRun run = textBox.createTextRun();
+        LayoutRect selectionRect = LayoutRect(0, y, 0, height);
+        textBox.lineFont().adjustSelectionRectForText(run, selectionRect, markedText.startOffset, markedText.endOffset);
+        return selectionRect;
+    }
+
+    return FloatRect(0, y, textBox.logicalWidth(), height);
+}
+
+}

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.h (282276 => 282277)


--- trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-10 17:07:33 UTC (rev 282276)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-10 17:16:43 UTC (rev 282277)
@@ -28,9 +28,10 @@
 
 namespace WebCore {
 
-class FontCascade;
+class Color;
 class LegacyInlineTextBox;
-class RenderCombineText;
+struct CompositionUnderline;
+struct MarkedText;
 struct PaintInfo;
 struct StyledMarkedText;
 
@@ -43,10 +44,18 @@
     void paintBackground(const StyledMarkedText&);
     void paintForeground(const StyledMarkedText&);
     void paintDecoration(const StyledMarkedText&, const FloatRect& clipOutRect);
+    void paintCompositionUnderlines();
+    void paintPlatformDocumentMarkers();
 
+    static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
+
 private:
     enum class BackgroundStyle { Normal, Rounded };
     void paintBackground(unsigned startOffset, unsigned endOffset, const Color&, BackgroundStyle = BackgroundStyle::Normal);
+    void paintCompositionUnderline(const CompositionUnderline&);
+    void paintPlatformDocumentMarker(const MarkedText&);
+    
+    static FloatRect calculateDocumentMarkerBounds(const LegacyInlineTextBox&, const MarkedText&);
 
     const LegacyInlineTextBox& m_textBox;
     PaintInfo& m_paintInfo;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to