Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Side by Side Diff: third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp

Issue 1468913002: Find In Page hides the text when text color matches text search hightlight color. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/paint/SVGInlineTextBoxPainter.h" 6 #include "core/paint/SVGInlineTextBoxPainter.h"
7 7
8 #include "core/editing/Editor.h" 8 #include "core/editing/Editor.h"
9 #include "core/editing/markers/DocumentMarkerController.h" 9 #include "core/editing/markers/DocumentMarkerController.h"
10 #include "core/editing/markers/RenderedDocumentMarker.h" 10 #include "core/editing/markers/RenderedDocumentMarker.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 return; 58 return;
59 59
60 DisplayItem::Type displayItemType = DisplayItem::paintPhaseToDrawingType(pai ntInfo.phase); 60 DisplayItem::Type displayItemType = DisplayItem::paintPhaseToDrawingType(pai ntInfo.phase);
61 if (!DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_svgInl ineTextBox, displayItemType)) { 61 if (!DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_svgInl ineTextBox, displayItemType)) {
62 LayoutObject& parentLayoutObject = *LineLayoutPaintShim::layoutObjectFro m(m_svgInlineTextBox.parent()->lineLayoutItem()); 62 LayoutObject& parentLayoutObject = *LineLayoutPaintShim::layoutObjectFro m(m_svgInlineTextBox.parent()->lineLayoutItem());
63 const ComputedStyle& style = parentLayoutObject.styleRef(); 63 const ComputedStyle& style = parentLayoutObject.styleRef();
64 64
65 // TODO(chrishtr): passing the cull rect is incorrect. 65 // TODO(chrishtr): passing the cull rect is incorrect.
66 DrawingRecorder recorder(paintInfo.context, m_svgInlineTextBox, displayI temType, FloatRect(paintInfo.cullRect().m_rect)); 66 DrawingRecorder recorder(paintInfo.context, m_svgInlineTextBox, displayI temType, FloatRect(paintInfo.cullRect().m_rect));
67 InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers( 67 InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers(
68 paintInfo.context, paintOffset, style, 68 paintInfo, paintOffset, style,
69 textLayoutObject.scaledFont(), true); 69 textLayoutObject.scaledFont(), InlineTextBoxPainter::DocumentMarkerP aintPhase::Background);
70 70
71 if (!m_svgInlineTextBox.textFragments().isEmpty()) 71 if (!m_svgInlineTextBox.textFragments().isEmpty())
72 paintTextFragments(paintInfo, parentLayoutObject); 72 paintTextFragments(paintInfo, parentLayoutObject);
73
74 InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers(
75 paintInfo, paintOffset, style,
76 textLayoutObject.scaledFont(), InlineTextBoxPainter::DocumentMarkerP aintPhase::Foreground);
73 } 77 }
74 } 78 }
75 79
76 void SVGInlineTextBoxPainter::paintTextFragments(const PaintInfo& paintInfo, Lay outObject& parentLayoutObject) 80 void SVGInlineTextBoxPainter::paintTextFragments(const PaintInfo& paintInfo, Lay outObject& parentLayoutObject)
77 { 81 {
78 const ComputedStyle& style = parentLayoutObject.styleRef(); 82 const ComputedStyle& style = parentLayoutObject.styleRef();
79 const SVGComputedStyle& svgStyle = style.svgStyle(); 83 const SVGComputedStyle& svgStyle = style.svgStyle();
80 84
81 bool hasFill = svgStyle.hasFill(); 85 bool hasFill = svgStyle.hasFill();
82 bool hasVisibleStroke = svgStyle.hasVisibleStroke(); 86 bool hasVisibleStroke = svgStyle.hasVisibleStroke();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 166
163 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); 167 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem()));
164 if (!textShouldBePainted(textLayoutObject)) 168 if (!textShouldBePainted(textLayoutObject))
165 return; 169 return;
166 170
167 const ComputedStyle& style = m_svgInlineTextBox.parent()->lineLayoutItem().s tyleRef(); 171 const ComputedStyle& style = m_svgInlineTextBox.parent()->lineLayoutItem().s tyleRef();
168 172
169 int startPosition, endPosition; 173 int startPosition, endPosition;
170 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); 174 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition);
171 175
172 int fragmentStartPosition = 0;
173 int fragmentEndPosition = 0;
174 AffineTransform fragmentTransform; 176 AffineTransform fragmentTransform;
175 unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); 177 Vector<SVGTextFragmentWithRange> fragmentInfoList = collectFragmentsInRange( startPosition, endPosition);
176 for (unsigned i = 0; i < textFragmentsSize; ++i) { 178 for (const SVGTextFragmentWithRange& fragmentWithRange : fragmentInfoList) {
177 const SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at( i); 179 const SVGTextFragment& fragment = fragmentWithRange.fragment;
178
179 fragmentStartPosition = startPosition;
180 fragmentEndPosition = endPosition;
181 if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(frag ment, fragmentStartPosition, fragmentEndPosition))
182 continue;
183
184 GraphicsContextStateSaver stateSaver(paintInfo.context); 180 GraphicsContextStateSaver stateSaver(paintInfo.context);
185 fragment.buildFragmentTransform(fragmentTransform); 181 fragment.buildFragmentTransform(fragmentTransform);
186 if (!fragmentTransform.isIdentity()) 182 if (!fragmentTransform.isIdentity())
187 paintInfo.context.concatCTM(fragmentTransform); 183 paintInfo.context.concatCTM(fragmentTransform);
188 184
189 paintInfo.context.setFillColor(backgroundColor); 185 paintInfo.context.setFillColor(backgroundColor);
190 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragme nt(fragment, fragmentStartPosition, fragmentEndPosition, style), backgroundColor ); 186 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragme nt(fragment, fragmentWithRange.startPosition, fragmentWithRange.endPosition, sty le), backgroundColor);
191 } 187 }
192 } 188 }
193 189
194 static inline LayoutObject* findLayoutObjectDefininingTextDecoration(InlineFlowB ox* parentBox) 190 static inline LayoutObject* findLayoutObjectDefininingTextDecoration(InlineFlowB ox* parentBox)
195 { 191 {
196 // Lookup first layout object in parent hierarchy which has text-decoration set. 192 // Lookup first layout object in parent hierarchy which has text-decoration set.
197 LayoutObject* layoutObject = 0; 193 LayoutObject* layoutObject = 0;
198 while (parentBox) { 194 while (parentBox) {
199 layoutObject = LineLayoutPaintShim::layoutObjectFrom(parentBox->lineLayo utItem()); 195 layoutObject = LineLayoutPaintShim::layoutObjectFrom(parentBox->lineLayo utItem());
200 196
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 411 }
416 412
417 // Eventually draw text using regular style from the end position of the sel ection to the end of the current chunk part 413 // Eventually draw text using regular style from the end position of the sel ection to the end of the current chunk part
418 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl y) { 414 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl y) {
419 SkPaint paint; 415 SkPaint paint;
420 if (setupTextPaint(paintInfo, style, resourceMode, paint)) 416 if (setupTextPaint(paintInfo, style, resourceMode, paint))
421 paintText(paintInfo, textRun, fragment, endPosition, fragment.length , paint); 417 paintText(paintInfo, textRun, fragment, endPosition, fragment.length , paint);
422 } 418 }
423 } 419 }
424 420
425 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, con st LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font& font) 421 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches(con st PaintInfo& paintInfo, DocumentMarker* marker)
fs 2015/12/18 11:35:17 |paintInfo| isn't used.
ramya.v 2015/12/21 08:13:49 Done.
426 { 422 {
427 // SVG is only interested in the TextMatch markers. 423 Vector<SVGTextFragmentWithRange> textMatchInfoList;
424
425 // SVG does not support grammar or spellcheck markers, so skip anything but TextMatch.
428 if (marker->type() != DocumentMarker::TextMatch) 426 if (marker->type() != DocumentMarker::TextMatch)
427 return textMatchInfoList;
428
429 if (!LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem ())->frame()->editor().markedTextMatchesAreHighlighted())
430 return textMatchInfoList;
431
432 int markerStartPosition = std::max<int>(marker->startOffset() - m_svgInlineT extBox.start(), 0);
pdr. 2015/12/19 02:39:45 Can these be negative? If not, lets use unsigned (
ramya.v 2015/12/21 08:13:49 This would depend on collectFragmentsInRange, mapS
fs 2015/12/21 12:00:01 I believe this one can - the only guarantee (made
433 int markerEndPosition = std::min<int>(marker->endOffset() - m_svgInlineTextB ox.start(), m_svgInlineTextBox.len());
434
435 if (markerStartPosition >= markerEndPosition)
436 return textMatchInfoList;
437
438 textMatchInfoList = collectFragmentsInRange(markerStartPosition, markerEndPo sition);
fs 2015/12/18 11:35:17 Could just make this a tail-call ("return collectF
ramya.v 2015/12/21 08:13:49 Done.
439 return textMatchInfoList;
440 }
441
442 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectFragmentsInRang e(int startPosition, int endPosition)
443 {
444 Vector<SVGTextFragmentWithRange> fragmentInfoList;
445 const Vector<SVGTextFragment>& fragments = m_svgInlineTextBox.textFragments( );
446 unsigned textFragmentsSize = fragments.size();
447 for (unsigned i = 0; i < textFragmentsSize; ++i) {
fs 2015/12/18 11:35:17 Use range-based for-loop.
ramya.v 2015/12/21 08:13:49 Done.
448 const SVGTextFragment& fragment = fragments.at(i);
449
450 int fragmentStartPosition = startPosition;
451 int fragmentEndPosition = endPosition;
452 if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(frag ment, fragmentStartPosition, fragmentEndPosition))
453 continue;
454
455 fragmentInfoList.append(SVGTextFragmentWithRange(fragment, fragmentStart Position, fragmentEndPosition));
456 }
457 return fragmentInfoList;
458 }
459
460 void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font)
461 {
462 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(pain tInfo, marker);
463 if (textMatchInfoList.isEmpty())
429 return; 464 return;
430 465
431 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); 466 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ eMatch());
467 AffineTransform fragmentTransform;
468 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) {
469 const SVGTextFragment& fragment = textMatchInfo.fragment;
470 GraphicsContextStateSaver stateSaver(paintInfo.context);
471 fragment.buildFragmentTransform(fragmentTransform);
472 if (!fragmentTransform.isIdentity())
473 paintInfo.context.concatCTM(fragmentTransform);
432 474
433 AffineTransform fragmentTransform; 475 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment);
434 for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->n extTextBox()) { 476 SkPaint paint;
435 if (!box->isSVGInlineTextBox()) 477 if (setupTextPaint(paintInfo, style, ApplyToFillMode, paint)) {
fs 2015/12/18 11:35:17 Since this does not depend on anything within the
ramya.v 2015/12/21 08:13:49 Moved setupPaint out of loop. As with other browse
fs 2015/12/21 12:00:01 That's odd... It does look like it happens for the
ramya.v 2015/12/21 13:01:55 To file a bug, same test case, if I directly load
fs 2015/12/21 13:13:24 Ok, so it's in the test-runner only... better make
436 continue; 478 paint.setColor(textColor.rgb());
437 479 paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, paint);
438 SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
439
440 int markerStartPosition = std::max<int>(marker->startOffset() - textBox- >start(), 0);
441 int markerEndPosition = std::min<int>(marker->endOffset() - textBox->sta rt(), textBox->len());
442
443 if (markerStartPosition >= markerEndPosition)
444 continue;
445
446 const Vector<SVGTextFragment>& fragments = textBox->textFragments();
447 unsigned textFragmentsSize = fragments.size();
448 for (unsigned i = 0; i < textFragmentsSize; ++i) {
449 const SVGTextFragment& fragment = fragments.at(i);
450
451 int fragmentStartPosition = markerStartPosition;
452 int fragmentEndPosition = markerEndPosition;
453 if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
454 continue;
455
456 FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragm ent, fragmentStartPosition, fragmentEndPosition, style);
457 fragment.buildFragmentTransform(fragmentTransform);
458
459 // Draw the marker highlight.
460 if (LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLay outItem())->frame()->editor().markedTextMatchesAreHighlighted()) {
461 Color color = marker->activeMatch() ?
462 LayoutTheme::theme().platformActiveTextSearchHighlightColor( ) :
463 LayoutTheme::theme().platformInactiveTextSearchHighlightColo r();
464 GraphicsContextStateSaver stateSaver(context);
465 if (!fragmentTransform.isIdentity())
466 context.concatCTM(fragmentTransform);
467 context.setFillColor(color);
468 context.fillRect(fragmentRect, color);
469 }
470 } 480 }
471 } 481 }
472 } 482 }
473 483
484 void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font)
485 {
486 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(pain tInfo, marker);
487 if (textMatchInfoList.isEmpty())
488 return;
489
490 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker-> activeMatch());
491 AffineTransform fragmentTransform;
492 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) {
493 const SVGTextFragment& fragment = textMatchInfo.fragment;
494 GraphicsContextStateSaver stateSaver(paintInfo.context);
495 fragment.buildFragmentTransform(fragmentTransform);
496 if (!fragmentTransform.isIdentity())
497 paintInfo.context.concatCTM(fragmentTransform);
498 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment (fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, style);
499 paintInfo.context.setFillColor(color);
500 paintInfo.context.fillRect(fragmentRect, color);
fs 2015/12/18 11:35:17 Passing color to fillRect is redundant with setFil
ramya.v 2015/12/21 08:13:49 Done.
501 }
502 }
503
474 } // namespace blink 504 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698