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;