OLD | NEW |
---|---|
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 Loading... | |
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(), DocumentMarkerPaintPhase::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(), DocumentMarkerPaintPhase::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 Loading... | |
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 Loading... | |
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 const Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatch es(DocumentMarker* marker) |
426 { | 422 { |
427 // SVG is only interested in the TextMatch markers. | 423 const Vector<SVGTextFragmentWithRange> emptyTextMatchList; |
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 emptyTextMatchList; | |
428 | |
429 if (!LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem ())->frame()->editor().markedTextMatchesAreHighlighted()) | |
430 return emptyTextMatchList; | |
431 | |
432 int markerStartPosition = std::max<int>(marker->startOffset() - m_svgInlineT extBox.start(), 0); | |
433 int markerEndPosition = std::min<int>(marker->endOffset() - m_svgInlineTextB ox.start(), m_svgInlineTextBox.len()); | |
434 | |
435 if (markerStartPosition >= markerEndPosition) | |
436 return emptyTextMatchList; | |
437 | |
438 return collectFragmentsInRange(markerStartPosition, markerEndPosition); | |
439 } | |
440 | |
441 const Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectFragments InRange(int startPosition, int endPosition) | |
442 { | |
443 Vector<SVGTextFragmentWithRange> fragmentInfoList; | |
444 const Vector<SVGTextFragment>& fragments = m_svgInlineTextBox.textFragments( ); | |
445 for (const SVGTextFragment& fragment : fragments) { | |
446 // TODO(ramya.v): If these can't be negative we should use unsigned. | |
447 int fragmentStartPosition = startPosition; | |
448 int fragmentEndPosition = endPosition; | |
449 if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(frag ment, fragmentStartPosition, fragmentEndPosition)) | |
450 continue; | |
451 | |
452 fragmentInfoList.append(SVGTextFragmentWithRange(fragment, fragmentStart Position, fragmentEndPosition)); | |
453 } | |
454 return fragmentInfoList; | |
455 } | |
456 | |
457 void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) | |
458 { | |
459 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(mark er); | |
460 if (textMatchInfoList.isEmpty()) | |
429 return; | 461 return; |
430 | 462 |
431 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); | 463 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ eMatch()); |
464 | |
465 SkPaint fillPaint; | |
466 fillPaint.setColor(textColor.rgb()); | |
467 fillPaint.setAntiAlias(true); | |
468 | |
469 SkPaint strokePaint; | |
470 bool shouldApplyToStrokeMode = false; | |
fs
2015/12/21 12:00:01
Nit: shouldPaintStroke
ramya.v
2015/12/21 13:01:56
Done.
| |
471 if (setupTextPaint(paintInfo, style, ApplyToStrokeMode, strokePaint)) { | |
fs
2015/12/21 12:00:01
This will also apply text-shadow, so that should b
ramya.v
2015/12/21 13:01:56
Done.
| |
472 shouldApplyToStrokeMode = true; | |
473 strokePaint.setColor(textColor.rgb()); | |
474 } | |
432 | 475 |
433 AffineTransform fragmentTransform; | 476 AffineTransform fragmentTransform; |
434 for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->n extTextBox()) { | 477 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { |
435 if (!box->isSVGInlineTextBox()) | 478 const SVGTextFragment& fragment = textMatchInfo.fragment; |
436 continue; | 479 GraphicsContextStateSaver stateSaver(paintInfo.context); |
480 fragment.buildFragmentTransform(fragmentTransform); | |
481 if (!fragmentTransform.isIdentity()) | |
482 paintInfo.context.concatCTM(fragmentTransform); | |
437 | 483 |
438 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); | 484 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); |
439 | 485 paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, tex tMatchInfo.endPosition, fillPaint); |
440 int markerStartPosition = std::max<int>(marker->startOffset() - textBox- >start(), 0); | 486 if (shouldApplyToStrokeMode) |
441 int markerEndPosition = std::min<int>(marker->endOffset() - textBox->sta rt(), textBox->len()); | 487 paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, strokePaint); |
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 } | |
471 } | 488 } |
472 } | 489 } |
473 | 490 |
491 void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) | |
492 { | |
493 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(mark er); | |
494 if (textMatchInfoList.isEmpty()) | |
495 return; | |
496 | |
497 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker-> activeMatch()); | |
498 AffineTransform fragmentTransform; | |
499 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { | |
500 const SVGTextFragment& fragment = textMatchInfo.fragment; | |
501 | |
502 GraphicsContextStateSaver stateSaver(paintInfo.context, false); | |
503 fragment.buildFragmentTransform(fragmentTransform); | |
504 if (!fragmentTransform.isIdentity()) { | |
505 stateSaver.save(); | |
506 paintInfo.context.concatCTM(fragmentTransform); | |
507 } | |
508 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment (fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, style); | |
509 paintInfo.context.setFillColor(color); | |
510 paintInfo.context.fillRect(fragmentRect); | |
511 } | |
512 } | |
513 | |
474 } // namespace blink | 514 } // namespace blink |
OLD | NEW |