Changeset 278621 in webkit
- Timestamp:
- Jun 8, 2021, 11:02:20 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/rendering/LegacyInlineTextBox.cpp (modified) (11 diffs)
-
Source/WebCore/rendering/LegacyInlineTextBox.h (modified) (3 diffs)
-
Source/WebCore/rendering/MarkedText.cpp (modified) (4 diffs)
-
Source/WebCore/rendering/MarkedText.h (modified) (3 diffs)
-
Source/WebCore/rendering/MarkedTextStyle.cpp (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebCore/MarkedText.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r278620 r278621 1 2021-06-08 Antti Koivisto <antti@apple.com> 2 3 Factor MarkedText collection out of LegacyInlineTextBox 4 https://bugs.webkit.org/show_bug.cgi?id=226731 5 6 Reviewed by Sam Weinig. 7 8 Move more code out from the legacy inline classes. 9 10 * rendering/LegacyInlineTextBox.cpp: 11 (WebCore::LegacyInlineTextBox::paint): 12 (WebCore::LegacyInlineTextBox::hasMarkers const): 13 (WebCore::LegacyInlineTextBox::paintPlatformDocumentMarkers): 14 (WebCore::LegacyInlineTextBox::calculateUnionOfAllDocumentMarkerBounds const): 15 (WebCore::LegacyInlineTextBox::paintMarkedTexts): 16 (WebCore::LegacyInlineTextBox::highlightStartEnd const): Deleted. 17 (WebCore::LegacyInlineTextBox::collectMarkedTextsForDraggedContent): Deleted. 18 (WebCore::LegacyInlineTextBox::collectMarkedTextsForDocumentMarkers const): Deleted. 19 (WebCore::LegacyInlineTextBox::collectMarkedTextsForHighlights const): Deleted. 20 * rendering/LegacyInlineTextBox.h: 21 (WebCore::LegacyInlineTextBox::paintMarkedTexts): 22 * rendering/MarkedText.cpp: 23 (WebCore::MarkedText::subdivide): 24 (WebCore::MarkedText::collectForHighlights): 25 (WebCore::MarkedText::collectForDocumentMarkers): 26 (WebCore::MarkedText::collectForDraggedContent): 27 (WebCore::subdivide): Deleted. 28 * rendering/MarkedText.h: 29 (WebCore::MarkedText::operator== const): 30 * rendering/MarkedTextStyle.cpp: 31 (WebCore::subdivideAndResolveStyle): 32 1 33 2021-06-08 Truitt Savell <tsavell@apple.com> 2 34 -
trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp
r278561 r278621 37 37 38 38 #include "HighlightData.h" 39 #include "HighlightRegister.h"40 39 #include "HitTestResult.h" 41 40 #include "ImageBuffer.h" … … 493 492 paintCompositionBackground(paintInfo, boxOrigin); 494 493 495 Vector<MarkedText> markedTexts = collectMarkedTextsForDocumentMarkers(TextPaintPhase::Background); 496 auto highlightMarkedTexts = collectMarkedTextsForHighlights(TextPaintPhase::Background); 497 if (!highlightMarkedTexts.isEmpty()) 498 markedTexts.appendVector(WTFMove(highlightMarkedTexts)); 494 auto selectableRange = this->selectableRange(); 495 496 Vector<MarkedText> markedTexts; 497 markedTexts.appendVector(MarkedText::collectForDocumentMarkers(renderer(), selectableRange, MarkedText::PaintPhase::Background)); 498 markedTexts.appendVector(MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange, MarkedText::PaintPhase::Background)); 499 499 500 #if ENABLE(TEXT_SELECTION) 500 501 if (haveSelection && !useCustomUnderlines && !context.paintingDisabled()) { … … 509 510 auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areBackgroundMarkedTextStylesEqual); 510 511 511 paintMarkedTexts(paintInfo, TextPaintPhase::Background, boxRect, coalescedStyledMarkedTexts);512 paintMarkedTexts(paintInfo, MarkedText::PaintPhase::Background, boxRect, coalescedStyledMarkedTexts); 512 513 } 513 514 … … 526 527 Vector<MarkedText> markedTexts; 527 528 if (paintInfo.phase != PaintPhase::Selection) { 529 auto selectableRange = this->selectableRange(); 530 528 531 // The marked texts for the gaps between document markers and selection are implicitly created by subdividing the entire line. 529 auto selectableRange = this->selectableRange();530 532 markedTexts.append({ selectableRange.clamp(m_start), selectableRange.clamp(end()), MarkedText::Unmarked }); 533 531 534 if (!isPrinting) { 532 markedTexts.appendVector(collectMarkedTextsForDocumentMarkers(TextPaintPhase::Foreground)); 533 auto highlightMarkedTexts = collectMarkedTextsForHighlights(TextPaintPhase::Foreground); 534 if (!highlightMarkedTexts.isEmpty()) 535 markedTexts.appendVector(WTFMove(highlightMarkedTexts)); 535 markedTexts.appendVector(MarkedText::collectForDocumentMarkers(renderer(), selectableRange, MarkedText::PaintPhase::Foreground)); 536 markedTexts.appendVector(MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange, MarkedText::PaintPhase::Foreground)); 536 537 537 538 bool shouldPaintDraggedContent = !(paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)); 538 539 if (shouldPaintDraggedContent) { 539 auto markedTextsForDraggedContent = collectMarkedTextsForDraggedContent();540 auto markedTextsForDraggedContent = MarkedText::collectForDraggedContent(renderer(), selectableRange); 540 541 if (!markedTextsForDraggedContent.isEmpty()) { 541 542 shouldPaintSelectionForeground = false; … … 565 566 auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areForegroundMarkedTextStylesEqual); 566 567 567 paintMarkedTexts(paintInfo, TextPaintPhase::Foreground, boxRect, coalescedStyledMarkedTexts);568 paintMarkedTexts(paintInfo, MarkedText::PaintPhase::Foreground, boxRect, coalescedStyledMarkedTexts); 568 569 569 570 // Paint decorations 570 571 auto textDecorations = lineStyle.textDecorationsInEffect(); 571 bool highlightDecorations = ! collectMarkedTextsForHighlights(TextPaintPhase::Decoration).isEmpty();572 bool highlightDecorations = !MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange(), MarkedText::PaintPhase::Decoration).isEmpty(); 572 573 bool lineDecorations = !textDecorations.isEmpty(); 573 574 if ((lineDecorations || highlightDecorations) && paintInfo.phase != PaintPhase::Selection) { … … 604 605 auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areDecorationMarkedTextStylesEqual); 605 606 606 paintMarkedTexts(paintInfo, TextPaintPhase::Decoration, boxRect, coalescedStyledMarkedTexts, textDecorationSelectionClipOutRect);607 paintMarkedTexts(paintInfo, MarkedText::PaintPhase::Decoration, boxRect, coalescedStyledMarkedTexts, textDecorationSelectionClipOutRect); 607 608 } 608 609 … … 650 651 } 651 652 652 std::pair<unsigned, unsigned> LegacyInlineTextBox::highlightStartEnd(HighlightData& rangeData) const653 {654 return rangeData.rangeForTextBox(renderer(), selectableRange());655 }656 657 653 bool LegacyInlineTextBox::hasMarkers() const 658 654 { 659 return collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration).size();655 return MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration).size(); 660 656 } 661 657 … … 663 659 { 664 660 // This must match calculateUnionOfAllDocumentMarkerBounds(). 665 for (auto& markedText : subdivide(collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration), OverlapStrategy::Frontmost)) 661 auto markedTexts = MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration); 662 for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost)) 666 663 paintPlatformDocumentMarker(context, boxOrigin, markedText); 667 664 } … … 671 668 // This must match paintPlatformDocumentMarkers(). 672 669 FloatRect result; 673 for (auto& markedText : subdivide(collectMarkedTextsForDocumentMarkers(TextPaintPhase::Decoration), OverlapStrategy::Frontmost)) 670 auto markedTexts = MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration); 671 for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost)) 674 672 result = unionRect(result, calculateDocumentMarkerBounds(markedText)); 675 673 return result; … … 732 730 } 733 731 734 Vector<MarkedText> LegacyInlineTextBox::collectMarkedTextsForDraggedContent()735 {736 using DraggendContentRange = std::pair<unsigned, unsigned>;737 auto draggedContentRanges = renderer().draggedContentRangesBetweenOffsets(m_start, m_start + m_len);738 739 Vector<MarkedText> result = draggedContentRanges.map([this] (const DraggendContentRange& range) -> MarkedText {740 auto [clampedStart, clampedEnd] = selectableRange().clamp(range.first, range.second);741 return { clampedStart, clampedEnd, MarkedText::DraggedContent };742 });743 return result;744 }745 746 Vector<MarkedText> LegacyInlineTextBox::collectMarkedTextsForDocumentMarkers(TextPaintPhase phase) const747 {748 ASSERT_ARG(phase, phase == TextPaintPhase::Background || phase == TextPaintPhase::Foreground || phase == TextPaintPhase::Decoration);749 750 if (!renderer().textNode())751 return { };752 753 Vector<RenderedDocumentMarker*> markers = renderer().document().markers().markersFor(*renderer().textNode());754 755 auto markedTextTypeForMarkerType = [] (DocumentMarker::MarkerType type) {756 switch (type) {757 case DocumentMarker::Spelling:758 return MarkedText::SpellingError;759 case DocumentMarker::Grammar:760 return MarkedText::GrammarError;761 case DocumentMarker::CorrectionIndicator:762 return MarkedText::Correction;763 case DocumentMarker::TextMatch:764 return MarkedText::TextMatch;765 case DocumentMarker::DictationAlternatives:766 return MarkedText::DictationAlternatives;767 #if PLATFORM(IOS_FAMILY)768 case DocumentMarker::DictationPhraseWithAlternatives:769 return MarkedText::DictationPhraseWithAlternatives;770 #endif771 default:772 return MarkedText::Unmarked;773 }774 };775 776 Vector<MarkedText> markedTexts;777 markedTexts.reserveInitialCapacity(markers.size());778 779 // Give any document markers that touch this run a chance to draw before the text has been drawn.780 // Note end() points at the last char, not one past it like endOffset and ranges do.781 for (auto* marker : markers) {782 // Collect either the background markers or the foreground markers, but not both783 switch (marker->type()) {784 case DocumentMarker::Grammar:785 case DocumentMarker::Spelling:786 case DocumentMarker::CorrectionIndicator:787 case DocumentMarker::Replacement:788 case DocumentMarker::DictationAlternatives:789 #if PLATFORM(IOS_FAMILY)790 // FIXME: Remove the PLATFORM(IOS_FAMILY)-guard.791 case DocumentMarker::DictationPhraseWithAlternatives:792 #endif793 if (phase != TextPaintPhase::Decoration)794 continue;795 break;796 case DocumentMarker::TextMatch:797 if (!renderer().frame().editor().markedTextMatchesAreHighlighted())798 continue;799 if (phase == TextPaintPhase::Decoration)800 continue;801 break;802 #if ENABLE(TELEPHONE_NUMBER_DETECTION)803 case DocumentMarker::TelephoneNumber:804 if (!renderer().frame().editor().markedTextMatchesAreHighlighted())805 continue;806 if (phase != TextPaintPhase::Background)807 continue;808 break;809 #endif810 default:811 continue;812 }813 814 if (marker->endOffset() <= start()) {815 // Marker is completely before this run. This might be a marker that sits before the816 // first run we draw, or markers that were within runs we skipped due to truncation.817 continue;818 }819 820 if (marker->startOffset() >= end()) {821 // Marker is completely after this run, bail. A later run will paint it.822 break;823 }824 825 // Marker intersects this run. Collect it.826 switch (marker->type()) {827 case DocumentMarker::Spelling:828 case DocumentMarker::CorrectionIndicator:829 case DocumentMarker::DictationAlternatives:830 case DocumentMarker::Grammar:831 #if PLATFORM(IOS_FAMILY)832 // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS_FAMILY)-guard.833 case DocumentMarker::DictationPhraseWithAlternatives:834 #endif835 case DocumentMarker::TextMatch: {836 auto [clampedStart, clampedEnd] = selectableRange().clamp(marker->startOffset(), marker->endOffset());837 markedTexts.uncheckedAppend({ clampedStart, clampedEnd, markedTextTypeForMarkerType(marker->type()), marker });838 break;839 }840 case DocumentMarker::Replacement:841 break;842 #if ENABLE(TELEPHONE_NUMBER_DETECTION)843 case DocumentMarker::TelephoneNumber:844 break;845 #endif846 default:847 ASSERT_NOT_REACHED();848 }849 }850 return markedTexts;851 }852 853 Vector<MarkedText> LegacyInlineTextBox::collectMarkedTextsForHighlights(TextPaintPhase phase) const854 {855 ASSERT_ARG(phase, phase == TextPaintPhase::Background || phase == TextPaintPhase::Foreground || phase == TextPaintPhase::Decoration);856 UNUSED_PARAM(phase);857 if (!renderer().textNode())858 return { };859 860 Vector<MarkedText> markedTexts;861 HighlightData highlightData;862 if (RuntimeEnabledFeatures::sharedFeatures().highlightAPIEnabled()) {863 auto& parentRenderer = parent()->renderer();864 auto& parentStyle = parentRenderer.style();865 if (auto highlightRegister = renderer().document().highlightRegisterIfExists()) {866 for (auto& highlight : highlightRegister->map()) {867 auto renderStyle = parentRenderer.getUncachedPseudoStyle({ PseudoId::Highlight, highlight.key }, &parentStyle);868 if (!renderStyle)869 continue;870 if (renderStyle->textDecorationsInEffect().isEmpty() && phase == TextPaintPhase::Decoration)871 continue;872 for (auto& rangeData : highlight.value->rangesData()) {873 if (!highlightData.setRenderRange(rangeData))874 continue;875 876 auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData);877 if (highlightStart < highlightEnd)878 markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key });879 }880 }881 }882 }883 #if ENABLE(APP_HIGHLIGHTS)884 if (auto appHighlightRegister = renderer().document().appHighlightRegisterIfExists()) {885 if (appHighlightRegister->highlightsVisibility() == HighlightVisibility::Visible) {886 for (auto& highlight : appHighlightRegister->map()) {887 for (auto& rangeData : highlight.value->rangesData()) {888 if (!highlightData.setRenderRange(rangeData))889 continue;890 891 auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData);892 if (highlightStart < highlightEnd)893 markedTexts.append({ highlightStart, highlightEnd, MarkedText::AppHighlight });894 }895 }896 }897 }898 #endif899 return markedTexts;900 }901 902 732 FloatPoint LegacyInlineTextBox::textOriginFromBoxRect(const FloatRect& boxRect) const 903 733 { … … 914 744 } 915 745 916 void LegacyInlineTextBox::paintMarkedTexts(PaintInfo& paintInfo, TextPaintPhase phase, const FloatRect& boxRect, const Vector<StyledMarkedText>& markedTexts, const FloatRect& decorationClipOutRect)746 void LegacyInlineTextBox::paintMarkedTexts(PaintInfo& paintInfo, MarkedText::PaintPhase phase, const FloatRect& boxRect, const Vector<StyledMarkedText>& markedTexts, const FloatRect& decorationClipOutRect) 917 747 { 918 748 switch (phase) { 919 case TextPaintPhase::Background:749 case MarkedText::PaintPhase::Background: 920 750 for (auto& markedText : markedTexts) 921 751 paintMarkedTextBackground(paintInfo, boxRect.location(), markedText.style.backgroundColor, markedText.startOffset, markedText.endOffset); 922 752 return; 923 case TextPaintPhase::Foreground:753 case MarkedText::PaintPhase::Foreground: 924 754 for (auto& markedText : markedTexts) 925 755 paintMarkedTextForeground(paintInfo, boxRect, markedText); 926 756 return; 927 case TextPaintPhase::Decoration:757 case MarkedText::PaintPhase::Decoration: 928 758 for (auto& markedText : markedTexts) 929 759 paintMarkedTextDecoration(paintInfo, boxRect, decorationClipOutRect, markedText); -
trunk/Source/WebCore/rendering/LegacyInlineTextBox.h
r278561 r278621 24 24 25 25 #include "LegacyInlineBox.h" 26 #include "MarkedText.h" 26 27 #include "RenderText.h" 27 28 #include "TextRun.h" … … 124 125 bool isSelectable(unsigned startPosition, unsigned endPosition) const; 125 126 std::pair<unsigned, unsigned> selectionStartEnd() const; 126 std::pair<unsigned, unsigned> highlightStartEnd(HighlightData&) const;127 127 128 128 protected: … … 164 164 165 165 private: 166 enum class TextPaintPhase { Background, Foreground, Decoration };167 168 Vector<MarkedText> collectMarkedTextsForDraggedContent();169 Vector<MarkedText> collectMarkedTextsForDocumentMarkers(TextPaintPhase) const;170 Vector<MarkedText> collectMarkedTextsForHighlights(TextPaintPhase) const;171 172 166 FloatPoint textOriginFromBoxRect(const FloatRect&) const; 173 167 174 void paintMarkedTexts(PaintInfo&, TextPaintPhase, const FloatRect& boxRect, const Vector<StyledMarkedText>&, const FloatRect& decorationClipOutRect = { });168 void paintMarkedTexts(PaintInfo&, MarkedText::PaintPhase, const FloatRect& boxRect, const Vector<StyledMarkedText>&, const FloatRect& decorationClipOutRect = { }); 175 169 176 170 void paintPlatformDocumentMarker(GraphicsContext&, const FloatPoint& boxOrigin, const MarkedText&); -
trunk/Source/WebCore/rendering/MarkedText.cpp
r278253 r278621 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "MarkedText.h" 28 28 29 #include "Document.h" 30 #include "DocumentMarkerController.h" 31 #include "Editor.h" 32 #include "ElementRuleCollector.h" 33 #include "HighlightRegister.h" 34 #include "RenderBoxModelObject.h" 35 #include "RenderText.h" 36 #include "RenderedDocumentMarker.h" 37 #include "RuntimeEnabledFeatures.h" 29 38 #include <algorithm> 30 39 #include <wtf/HashSet.h> … … 32 41 namespace WebCore { 33 42 34 Vector<MarkedText> subdivide(const Vector<MarkedText>& markedTexts, OverlapStrategy overlapStrategy)43 Vector<MarkedText> MarkedText::subdivide(const Vector<MarkedText>& markedTexts, OverlapStrategy overlapStrategy) 35 44 { 36 45 if (markedTexts.isEmpty()) … … 94 103 } 95 104 96 } 97 98 105 Vector<MarkedText> MarkedText::collectForHighlights(RenderText& renderer, RenderBoxModelObject& parentRenderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase) 106 { 107 Vector<MarkedText> markedTexts; 108 HighlightData highlightData; 109 if (RuntimeEnabledFeatures::sharedFeatures().highlightAPIEnabled()) { 110 auto& parentStyle = parentRenderer.style(); 111 if (auto highlightRegister = renderer.document().highlightRegisterIfExists()) { 112 for (auto& highlight : highlightRegister->map()) { 113 auto renderStyle = parentRenderer.getUncachedPseudoStyle({ PseudoId::Highlight, highlight.key }, &parentStyle); 114 if (!renderStyle) 115 continue; 116 if (renderStyle->textDecorationsInEffect().isEmpty() && phase == PaintPhase::Decoration) 117 continue; 118 for (auto& rangeData : highlight.value->rangesData()) { 119 if (!highlightData.setRenderRange(rangeData)) 120 continue; 121 122 auto [highlightStart, highlightEnd] = highlightData.rangeForTextBox(renderer, selectableRange); 123 if (highlightStart < highlightEnd) 124 markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key }); 125 } 126 } 127 } 128 } 129 #if ENABLE(APP_HIGHLIGHTS) 130 if (auto appHighlightRegister = renderer.document().appHighlightRegisterIfExists()) { 131 if (appHighlightRegister->highlightsVisibility() == HighlightVisibility::Visible) { 132 for (auto& highlight : appHighlightRegister->map()) { 133 for (auto& rangeData : highlight.value->rangesData()) { 134 if (!highlightData.setRenderRange(rangeData)) 135 continue; 136 137 auto [highlightStart, highlightEnd] = highlightData.rangeForTextBox(renderer, selectableRange); 138 if (highlightStart < highlightEnd) 139 markedTexts.append({ highlightStart, highlightEnd, MarkedText::AppHighlight }); 140 } 141 } 142 } 143 } 144 #endif 145 return markedTexts; 146 } 147 148 Vector<MarkedText> MarkedText::collectForDocumentMarkers(RenderText& renderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase) 149 { 150 if (!renderer.textNode()) 151 return { }; 152 153 Vector<RenderedDocumentMarker*> markers = renderer.document().markers().markersFor(*renderer.textNode()); 154 155 auto markedTextTypeForMarkerType = [] (DocumentMarker::MarkerType type) { 156 switch (type) { 157 case DocumentMarker::Spelling: 158 return MarkedText::SpellingError; 159 case DocumentMarker::Grammar: 160 return MarkedText::GrammarError; 161 case DocumentMarker::CorrectionIndicator: 162 return MarkedText::Correction; 163 case DocumentMarker::TextMatch: 164 return MarkedText::TextMatch; 165 case DocumentMarker::DictationAlternatives: 166 return MarkedText::DictationAlternatives; 167 #if PLATFORM(IOS_FAMILY) 168 case DocumentMarker::DictationPhraseWithAlternatives: 169 return MarkedText::DictationPhraseWithAlternatives; 170 #endif 171 default: 172 return MarkedText::Unmarked; 173 } 174 }; 175 176 Vector<MarkedText> markedTexts; 177 markedTexts.reserveInitialCapacity(markers.size()); 178 179 // Give any document markers that touch this run a chance to draw before the text has been drawn. 180 // Note end() points at the last char, not one past it like endOffset and ranges do. 181 for (auto* marker : markers) { 182 // Collect either the background markers or the foreground markers, but not both 183 switch (marker->type()) { 184 case DocumentMarker::Grammar: 185 case DocumentMarker::Spelling: 186 case DocumentMarker::CorrectionIndicator: 187 case DocumentMarker::Replacement: 188 case DocumentMarker::DictationAlternatives: 189 #if PLATFORM(IOS_FAMILY) 190 // FIXME: Remove the PLATFORM(IOS_FAMILY)-guard. 191 case DocumentMarker::DictationPhraseWithAlternatives: 192 #endif 193 if (phase != MarkedText::PaintPhase::Decoration) 194 continue; 195 break; 196 case DocumentMarker::TextMatch: 197 if (!renderer.frame().editor().markedTextMatchesAreHighlighted()) 198 continue; 199 if (phase == MarkedText::PaintPhase::Decoration) 200 continue; 201 break; 202 #if ENABLE(TELEPHONE_NUMBER_DETECTION) 203 case DocumentMarker::TelephoneNumber: 204 if (!renderer.frame().editor().markedTextMatchesAreHighlighted()) 205 continue; 206 if (phase != MarkedText::PaintPhase::Background) 207 continue; 208 break; 209 #endif 210 default: 211 continue; 212 } 213 214 if (marker->endOffset() <= selectableRange.start) { 215 // Marker is completely before this run. This might be a marker that sits before the 216 // first run we draw, or markers that were within runs we skipped due to truncation. 217 continue; 218 } 219 220 if (marker->startOffset() >= selectableRange.start + selectableRange.length) { 221 // Marker is completely after this run, bail. A later run will paint it. 222 break; 223 } 224 225 // Marker intersects this run. Collect it. 226 switch (marker->type()) { 227 case DocumentMarker::Spelling: 228 case DocumentMarker::CorrectionIndicator: 229 case DocumentMarker::DictationAlternatives: 230 case DocumentMarker::Grammar: 231 #if PLATFORM(IOS_FAMILY) 232 // FIXME: See <rdar://problem/8933352>. Also, remove the PLATFORM(IOS_FAMILY)-guard. 233 case DocumentMarker::DictationPhraseWithAlternatives: 234 #endif 235 case DocumentMarker::TextMatch: { 236 auto [clampedStart, clampedEnd] = selectableRange.clamp(marker->startOffset(), marker->endOffset()); 237 markedTexts.uncheckedAppend({ clampedStart, clampedEnd, markedTextTypeForMarkerType(marker->type()), marker }); 238 break; 239 } 240 case DocumentMarker::Replacement: 241 break; 242 #if ENABLE(TELEPHONE_NUMBER_DETECTION) 243 case DocumentMarker::TelephoneNumber: 244 break; 245 #endif 246 default: 247 ASSERT_NOT_REACHED(); 248 } 249 } 250 return markedTexts; 251 } 252 253 Vector<MarkedText> MarkedText::collectForDraggedContent(RenderText& renderer, const TextBoxSelectableRange& selectableRange) 254 { 255 auto draggedContentRanges = renderer.draggedContentRangesBetweenOffsets(selectableRange.start, selectableRange.start + selectableRange.length); 256 257 return draggedContentRanges.map([&](const auto& range) -> MarkedText { 258 return { selectableRange.clamp(range.first), selectableRange.clamp(range.second), MarkedText::DraggedContent }; 259 }); 260 } 261 262 } -
trunk/Source/WebCore/rendering/MarkedText.h
r270362 r278621 31 31 namespace WebCore { 32 32 33 class RenderBoxModelObject; 34 class RenderText; 33 35 class RenderedDocumentMarker; 36 struct TextBoxSelectableRange; 34 37 35 38 struct MarkedText { … … 53 56 DraggedContent, 54 57 }; 58 59 enum class PaintPhase { 60 Background, 61 Foreground, 62 Decoration 63 }; 64 65 enum class OverlapStrategy { 66 None, 67 Frontmost 68 }; 69 55 70 unsigned startOffset; 56 71 unsigned endOffset; … … 65 80 return startOffset == other.startOffset && endOffset == other.endOffset && type == other.type && marker == other.marker && highlightName == other.highlightName; 66 81 } 82 83 WEBCORE_EXPORT static Vector<MarkedText> subdivide(const Vector<MarkedText>&, OverlapStrategy = OverlapStrategy::None); 84 85 static Vector<MarkedText> collectForDocumentMarkers(RenderText&, const TextBoxSelectableRange&, PaintPhase); 86 static Vector<MarkedText> collectForHighlights(RenderText&, RenderBoxModelObject& parentRenderer, const TextBoxSelectableRange&, PaintPhase); 87 static Vector<MarkedText> collectForDraggedContent(RenderText&, const TextBoxSelectableRange&); 67 88 }; 68 69 enum class OverlapStrategy { None, Frontmost };70 WEBCORE_EXPORT Vector<MarkedText> subdivide(const Vector<MarkedText>&, OverlapStrategy = OverlapStrategy::None);71 89 72 90 } -
trunk/Source/WebCore/rendering/MarkedTextStyle.cpp
r274700 r278621 132 132 } 133 133 134 auto markedTexts = subdivide(textsToSubdivide);134 auto markedTexts = MarkedText::subdivide(textsToSubdivide); 135 135 ASSERT(!markedTexts.isEmpty()); 136 136 if (UNLIKELY(markedTexts.isEmpty())) -
trunk/Tools/ChangeLog
r278616 r278621 1 2021-06-08 Antti Koivisto <antti@apple.com> 2 3 Factor MarkedText collection out of LegacyInlineTextBox 4 https://bugs.webkit.org/show_bug.cgi?id=226731 5 6 Reviewed by Sam Weinig. 7 8 * TestWebKitAPI/Tests/WebCore/MarkedText.cpp: 9 (TestWebKitAPI::TEST): 10 1 11 2021-06-08 Sam Weinig <weinig@apple.com> 2 12 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/MarkedText.cpp
r270362 r278621 81 81 TEST(MarkedText, SubdivideEmpty) 82 82 { 83 EXPECT_EQ(0U, subdivide({ }).size());84 EXPECT_EQ(0U, subdivide({ },OverlapStrategy::Frontmost).size());83 EXPECT_EQ(0U, MarkedText::subdivide({ }).size()); 84 EXPECT_EQ(0U, MarkedText::subdivide({ }, MarkedText::OverlapStrategy::Frontmost).size()); 85 85 } 86 86 … … 88 88 { 89 89 MarkedText markedText { 0, 9, MarkedText::SpellingError }; 90 auto results = subdivide({ markedText });90 auto results = MarkedText::subdivide({ markedText }); 91 91 ASSERT_EQ(1U, results.size()); 92 92 EXPECT_EQ(markedText, results[0]); … … 100 100 MarkedText { 22, 32, MarkedText::SpellingError }, 101 101 }; 102 auto results = subdivide(expectedMarkedTexts);102 auto results = MarkedText::subdivide(expectedMarkedTexts); 103 103 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 104 104 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) … … 123 123 MarkedText { 41, 45, MarkedText::SpellingError }, 124 124 }; 125 auto results = subdivide(markedTexts);125 auto results = MarkedText::subdivide(markedTexts); 126 126 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 127 127 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) … … 144 144 MarkedText { 41, 45, MarkedText::SpellingError }, 145 145 }; 146 auto results = subdivide(markedTexts,OverlapStrategy::Frontmost);146 auto results = MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost); 147 147 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 148 148 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) … … 175 175 MarkedText { 59, 63, MarkedText::GrammarError }, 176 176 }; 177 auto results = subdivide(markedTexts,OverlapStrategy::Frontmost);177 auto results = MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost); 178 178 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 179 179 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) … … 196 196 MarkedText { 50, 60, MarkedText::Selection }, 197 197 }; 198 auto results = subdivide(markedTexts);198 auto results = MarkedText::subdivide(markedTexts); 199 199 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 200 200 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) … … 215 215 MarkedText { 50, 60, MarkedText::Selection }, 216 216 }; 217 auto results = subdivide(markedTexts,OverlapStrategy::Frontmost);218 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 219 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) 220 EXPECT_EQ(expectedMarkedTexts[i], results[i]); 221 } 222 223 } 217 auto results = MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost); 218 ASSERT_EQ(expectedMarkedTexts.size(), results.size()); 219 for (size_t i = 0; i < expectedMarkedTexts.size(); ++i) 220 EXPECT_EQ(expectedMarkedTexts[i], results[i]); 221 } 222 223 }
Note:
See TracChangeset
for help on using the changeset viewer.