Index: third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp |
diff --git a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp |
index 7e086cd149dff55c2bfd253a458424ddf5655e10..c227a1ccc2a8a6fcf649691020ca72ea5cb24fe3 100644 |
--- a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp |
+++ b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp |
@@ -65,11 +65,15 @@ void SVGInlineTextBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoin |
// TODO(chrishtr): passing the cull rect is incorrect. |
DrawingRecorder recorder(paintInfo.context, m_svgInlineTextBox, displayItemType, FloatRect(paintInfo.cullRect().m_rect)); |
InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers( |
- paintInfo.context, paintOffset, style, |
- textLayoutObject.scaledFont(), true); |
+ paintInfo, paintOffset, style, |
+ textLayoutObject.scaledFont(), DocumentMarkerPaintPhase::Background); |
if (!m_svgInlineTextBox.textFragments().isEmpty()) |
paintTextFragments(paintInfo, parentLayoutObject); |
+ |
+ InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers( |
+ paintInfo, paintOffset, style, |
+ textLayoutObject.scaledFont(), DocumentMarkerPaintPhase::Foreground); |
} |
} |
@@ -169,25 +173,17 @@ void SVGInlineTextBoxPainter::paintSelectionBackground(const PaintInfo& paintInf |
int startPosition, endPosition; |
m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); |
- int fragmentStartPosition = 0; |
- int fragmentEndPosition = 0; |
AffineTransform fragmentTransform; |
- unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); |
- for (unsigned i = 0; i < textFragmentsSize; ++i) { |
- const SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); |
- |
- fragmentStartPosition = startPosition; |
- fragmentEndPosition = endPosition; |
- if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) |
- continue; |
- |
+ const Vector<SVGTextFragmentWithRange> fragmentInfoList = collectFragmentsInRange(startPosition, endPosition); |
+ for (const SVGTextFragmentWithRange& fragmentWithRange : fragmentInfoList) { |
+ const SVGTextFragment& fragment = fragmentWithRange.fragment; |
GraphicsContextStateSaver stateSaver(paintInfo.context); |
fragment.buildFragmentTransform(fragmentTransform); |
if (!fragmentTransform.isIdentity()) |
paintInfo.context.concatCTM(fragmentTransform); |
paintInfo.context.setFillColor(backgroundColor); |
- paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style), backgroundColor); |
+ paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragment(fragment, fragmentWithRange.startPosition, fragmentWithRange.endPosition, style), backgroundColor); |
} |
} |
@@ -422,52 +418,97 @@ void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, const Comput |
} |
} |
-void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, const LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font& font) |
+Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches(DocumentMarker* marker) const |
{ |
- // SVG is only interested in the TextMatch markers. |
+ const Vector<SVGTextFragmentWithRange> emptyTextMatchList; |
+ |
+ // SVG does not support grammar or spellcheck markers, so skip anything but TextMatch. |
if (marker->type() != DocumentMarker::TextMatch) |
+ return emptyTextMatchList; |
+ |
+ if (!LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())->frame()->editor().markedTextMatchesAreHighlighted()) |
+ return emptyTextMatchList; |
+ |
+ int markerStartPosition = std::max<int>(marker->startOffset() - m_svgInlineTextBox.start(), 0); |
+ int markerEndPosition = std::min<int>(marker->endOffset() - m_svgInlineTextBox.start(), m_svgInlineTextBox.len()); |
+ |
+ if (markerStartPosition >= markerEndPosition) |
+ return emptyTextMatchList; |
+ |
+ return collectFragmentsInRange(markerStartPosition, markerEndPosition); |
+} |
+ |
+Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectFragmentsInRange(int startPosition, int endPosition) const |
+{ |
+ Vector<SVGTextFragmentWithRange> fragmentInfoList; |
+ const Vector<SVGTextFragment>& fragments = m_svgInlineTextBox.textFragments(); |
+ for (const SVGTextFragment& fragment : fragments) { |
+ // TODO(ramya.v): If these can't be negative we should use unsigned. |
+ int fragmentStartPosition = startPosition; |
+ int fragmentEndPosition = endPosition; |
+ if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) |
+ continue; |
+ |
+ fragmentInfoList.append(SVGTextFragmentWithRange(fragment, fragmentStartPosition, fragmentEndPosition)); |
+ } |
+ return fragmentInfoList; |
+} |
+ |
+void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paintInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) |
+{ |
+ const Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(marker); |
+ if (textMatchInfoList.isEmpty()) |
return; |
- LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); |
+ Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activeMatch()); |
+ |
+ SkPaint fillPaint; |
+ fillPaint.setColor(textColor.rgb()); |
+ fillPaint.setAntiAlias(true); |
+ |
+ SkPaint strokePaint; |
+ bool shouldPaintStroke = false; |
+ if (setupTextPaint(paintInfo, style, ApplyToStrokeMode, strokePaint)) { |
+ shouldPaintStroke = true; |
+ strokePaint.setLooper(nullptr); |
+ strokePaint.setColor(textColor.rgb()); |
+ } |
AffineTransform fragmentTransform; |
- for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->nextTextBox()) { |
- if (!box->isSVGInlineTextBox()) |
- continue; |
+ for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { |
+ const SVGTextFragment& fragment = textMatchInfo.fragment; |
+ GraphicsContextStateSaver stateSaver(paintInfo.context); |
+ fragment.buildFragmentTransform(fragmentTransform); |
+ if (!fragmentTransform.isIdentity()) |
+ paintInfo.context.concatCTM(fragmentTransform); |
- SVGInlineTextBox* textBox = toSVGInlineTextBox(box); |
+ TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); |
+ paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, fillPaint); |
+ if (shouldPaintStroke) |
+ paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, strokePaint); |
+ } |
+} |
- int markerStartPosition = std::max<int>(marker->startOffset() - textBox->start(), 0); |
- int markerEndPosition = std::min<int>(marker->endOffset() - textBox->start(), textBox->len()); |
+void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paintInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) |
+{ |
+ const Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(marker); |
+ if (textMatchInfoList.isEmpty()) |
+ return; |
- if (markerStartPosition >= markerEndPosition) |
- continue; |
+ Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker->activeMatch()); |
+ AffineTransform fragmentTransform; |
+ for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { |
+ const SVGTextFragment& fragment = textMatchInfo.fragment; |
- const Vector<SVGTextFragment>& fragments = textBox->textFragments(); |
- unsigned textFragmentsSize = fragments.size(); |
- for (unsigned i = 0; i < textFragmentsSize; ++i) { |
- const SVGTextFragment& fragment = fragments.at(i); |
- |
- int fragmentStartPosition = markerStartPosition; |
- int fragmentEndPosition = markerEndPosition; |
- if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) |
- continue; |
- |
- FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style); |
- fragment.buildFragmentTransform(fragmentTransform); |
- |
- // Draw the marker highlight. |
- if (LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())->frame()->editor().markedTextMatchesAreHighlighted()) { |
- Color color = marker->activeMatch() ? |
- LayoutTheme::theme().platformActiveTextSearchHighlightColor() : |
- LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); |
- GraphicsContextStateSaver stateSaver(context); |
- if (!fragmentTransform.isIdentity()) |
- context.concatCTM(fragmentTransform); |
- context.setFillColor(color); |
- context.fillRect(fragmentRect, color); |
- } |
+ GraphicsContextStateSaver stateSaver(paintInfo.context, false); |
+ fragment.buildFragmentTransform(fragmentTransform); |
+ if (!fragmentTransform.isIdentity()) { |
+ stateSaver.save(); |
+ paintInfo.context.concatCTM(fragmentTransform); |
} |
+ FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment(fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, style); |
+ paintInfo.context.setFillColor(color); |
+ paintInfo.context.fillRect(fragmentRect); |
} |
} |