Chromium Code Reviews| 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(), true); |
| 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(), false); | |
|
fs
2015/12/17 10:10:55
Maybe we should change this 'background' bool to a
ramya.v
2015/12/18 03:43:33
Done.
| |
| 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 = collectFragments(startPo sition, endPosition); |
| 178 unsigned textFragmentsSize = fragmentInfoList.size(); | |
| 176 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 179 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
|
fs
2015/12/17 10:10:55
Using a range-based loop here would be an improvem
ramya.v
2015/12/18 03:43:32
Done.
| |
| 177 const SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at( i); | 180 SVGTextFragmentWithRange& fragmentInfo = fragmentInfoList.at(i); |
| 178 | 181 const SVGTextFragment& fragment = *(fragmentInfo.fragment); |
| 179 fragmentStartPosition = startPosition; | |
| 180 fragmentEndPosition = endPosition; | |
| 181 if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(frag ment, fragmentStartPosition, fragmentEndPosition)) | |
| 182 continue; | |
| 183 | 182 |
| 184 GraphicsContextStateSaver stateSaver(paintInfo.context); | 183 GraphicsContextStateSaver stateSaver(paintInfo.context); |
| 185 fragment.buildFragmentTransform(fragmentTransform); | 184 fragment.buildFragmentTransform(fragmentTransform); |
| 186 if (!fragmentTransform.isIdentity()) | 185 if (!fragmentTransform.isIdentity()) |
| 187 paintInfo.context.concatCTM(fragmentTransform); | 186 paintInfo.context.concatCTM(fragmentTransform); |
| 188 | 187 |
| 189 paintInfo.context.setFillColor(backgroundColor); | 188 paintInfo.context.setFillColor(backgroundColor); |
| 190 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragme nt(fragment, fragmentStartPosition, fragmentEndPosition, style), backgroundColor ); | 189 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragme nt(fragment, fragmentInfo.fragmentStartPosition, fragmentInfo.fragmentEndPositio n, style), backgroundColor); |
| 191 } | 190 } |
| 192 } | 191 } |
| 193 | 192 |
| 194 static inline LayoutObject* findLayoutObjectDefininingTextDecoration(InlineFlowB ox* parentBox) | 193 static inline LayoutObject* findLayoutObjectDefininingTextDecoration(InlineFlowB ox* parentBox) |
| 195 { | 194 { |
| 196 // Lookup first layout object in parent hierarchy which has text-decoration set. | 195 // Lookup first layout object in parent hierarchy which has text-decoration set. |
| 197 LayoutObject* layoutObject = 0; | 196 LayoutObject* layoutObject = 0; |
| 198 while (parentBox) { | 197 while (parentBox) { |
| 199 layoutObject = LineLayoutPaintShim::layoutObjectFrom(parentBox->lineLayo utItem()); | 198 layoutObject = LineLayoutPaintShim::layoutObjectFrom(parentBox->lineLayo utItem()); |
| 200 | 199 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 StyleDifference diff; | 393 StyleDifference diff; |
| 395 diff.setNeedsPaintInvalidationObject(); | 394 diff.setNeedsPaintInvalidationObject(); |
| 396 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, style); | 395 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, style); |
| 397 } | 396 } |
| 398 | 397 |
| 399 // Eventually draw text using regular style from the end position of the sel ection to the end of the current chunk part | 398 // Eventually draw text using regular style from the end position of the sel ection to the end of the current chunk part |
| 400 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl y) | 399 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl y) |
| 401 paintTextWithShadows(paintInfo, style, textRun, fragment, endPosition, f ragment.length, resourceMode); | 400 paintTextWithShadows(paintInfo, style, textRun, fragment, endPosition, f ragment.length, resourceMode); |
| 402 } | 401 } |
| 403 | 402 |
| 404 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, con st LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font& font) | 403 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches(con st PaintInfo& paintInfo, DocumentMarker* marker) |
| 405 { | 404 { |
| 406 // SVG is only interested in the TextMatch markers. | 405 Vector<SVGTextFragmentWithRange> textMatchInfoList; |
| 406 | |
| 407 // SVG does not support grammar or spellcheck markers, so skip anything but TextMatch. | |
| 407 if (marker->type() != DocumentMarker::TextMatch) | 408 if (marker->type() != DocumentMarker::TextMatch) |
| 408 return; | 409 return textMatchInfoList; |
| 410 | |
| 411 if (!LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem ())->frame()->editor().markedTextMatchesAreHighlighted()) | |
| 412 return textMatchInfoList; | |
| 409 | 413 |
| 410 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); | 414 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); |
| 411 | 415 |
| 412 AffineTransform fragmentTransform; | |
| 413 for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->n extTextBox()) { | 416 for (InlineTextBox* box = textLayoutObject.firstTextBox(); box; box = box->n extTextBox()) { |
|
fs
2015/12/17 10:10:54
I still don't think this additional nesting is nee
ramya.v
2015/12/18 03:43:32
Done.
| |
| 414 if (!box->isSVGInlineTextBox()) | 417 if (!box->isSVGInlineTextBox()) |
| 415 continue; | 418 continue; |
| 416 | 419 |
| 417 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); | 420 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); |
| 418 | 421 |
| 419 int markerStartPosition = std::max<int>(marker->startOffset() - textBox- >start(), 0); | 422 int markerStartPosition = std::max<int>(marker->startOffset() - textBox- >start(), 0); |
| 420 int markerEndPosition = std::min<int>(marker->endOffset() - textBox->sta rt(), textBox->len()); | 423 int markerEndPosition = std::min<int>(marker->endOffset() - textBox->sta rt(), textBox->len()); |
| 421 | 424 |
| 422 if (markerStartPosition >= markerEndPosition) | 425 if (markerStartPosition >= markerEndPosition) |
| 423 continue; | 426 continue; |
| 424 | 427 |
| 425 const Vector<SVGTextFragment>& fragments = textBox->textFragments(); | 428 Vector<SVGTextFragmentWithRange> fragmentList = collectFragments(markerS tartPosition, markerEndPosition); |
| 426 unsigned textFragmentsSize = fragments.size(); | 429 unsigned textFragmentsSize = fragmentList.size(); |
| 427 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 430 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 428 const SVGTextFragment& fragment = fragments.at(i); | 431 textMatchInfoList.append(fragmentList.at(i)); |
|
fs
2015/12/17 10:10:55
Use appendVector or appendRange instead. Per above
ramya.v
2015/12/18 03:43:32
Done.
| |
| 432 } | |
| 433 } | |
| 434 return textMatchInfoList; | |
| 435 } | |
| 429 | 436 |
| 430 int fragmentStartPosition = markerStartPosition; | 437 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectFragments(int s tartPosition, int endPosition) |
|
fs
2015/12/17 10:10:54
collectFragmentsInRange or something more narrow l
ramya.v
2015/12/18 03:43:33
Done.
| |
| 431 int fragmentEndPosition = markerEndPosition; | 438 { |
| 432 if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) | 439 Vector<SVGTextFragmentWithRange> fragmentInfoList; |
| 433 continue; | 440 const Vector<SVGTextFragment>& fragments = m_svgInlineTextBox.textFragments( ); |
| 441 unsigned textFragmentsSize = fragments.size(); | |
| 442 for (unsigned i = 0; i < textFragmentsSize; ++i) { | |
|
fs
2015/12/17 10:10:55
Use a range-based for-loop.
ramya.v
2015/12/18 03:43:32
Done.
| |
| 443 const SVGTextFragment& fragment = fragments.at(i); | |
| 434 | 444 |
| 435 FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragm ent, fragmentStartPosition, fragmentEndPosition, style); | 445 int fragmentStartPosition = startPosition; |
| 436 fragment.buildFragmentTransform(fragmentTransform); | 446 int fragmentEndPosition = endPosition; |
| 447 if (!m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates(frag ment, fragmentStartPosition, fragmentEndPosition)) | |
| 448 continue; | |
| 437 | 449 |
| 438 // Draw the marker highlight. | 450 SVGTextFragmentWithRange fragmentInfo; |
| 439 if (LineLayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.lineLay outItem())->frame()->editor().markedTextMatchesAreHighlighted()) { | 451 fragmentInfo.fragment = &fragment; |
| 440 Color color = marker->activeMatch() ? | 452 fragmentInfo.fragmentStartPosition = fragmentStartPosition; |
| 441 LayoutTheme::theme().platformActiveTextSearchHighlightColor( ) : | 453 fragmentInfo.fragmentEndPosition = fragmentEndPosition; |
| 442 LayoutTheme::theme().platformInactiveTextSearchHighlightColo r(); | 454 |
| 443 GraphicsContextStateSaver stateSaver(context); | 455 fragmentInfoList.append(fragmentInfo); |
|
fs
2015/12/17 10:10:55
With a constructor for SVGTextFragmentWithRange, t
ramya.v
2015/12/18 03:43:33
Done.
| |
| 444 if (!fragmentTransform.isIdentity()) | 456 } |
| 445 context.concatCTM(fragmentTransform); | 457 return fragmentInfoList; |
| 446 context.setFillColor(color); | 458 } |
| 447 context.fillRect(fragmentRect, color); | 459 |
| 448 } | 460 void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) |
| 449 } | 461 { |
| 462 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(pain tInfo, marker); | |
| 463 unsigned textFragmentsSize = textMatchInfoList.size(); | |
| 464 if (textFragmentsSize == 0) | |
| 465 return; | |
| 466 | |
| 467 Color textColor = marker->activeMatch() ? | |
|
fs
2015/12/17 10:10:55
Same comment as for other instances of this.
ramya.v
2015/12/18 03:43:33
Done.
| |
| 468 LayoutTheme::theme().platformTextSearchColor(true) : | |
| 469 LayoutTheme::theme().platformTextSearchColor(false); | |
| 470 | |
| 471 AffineTransform fragmentTransform; | |
| 472 for (unsigned i = 0; i < textFragmentsSize; ++i) { | |
|
fs
2015/12/17 10:10:55
Use range-based for-loop.
ramya.v
2015/12/18 03:43:33
Done.
| |
| 473 SVGTextFragmentWithRange& textMatchInfo = textMatchInfoList.at(i); | |
| 474 const SVGTextFragment& fragment = *(textMatchInfo.fragment); | |
| 475 GraphicsContextStateSaver stateSaver(paintInfo.context); | |
| 476 fragment.buildFragmentTransform(fragmentTransform); | |
| 477 if (!fragmentTransform.isIdentity()) | |
| 478 paintInfo.context.concatCTM(fragmentTransform); | |
| 479 RefPtr<ComputedStyle> markerStyle = ComputedStyle::clone(style); | |
| 480 markerStyle->setFillPaintColor(textColor); | |
| 481 TextRun textRun = m_svgInlineTextBox.constructTextRun(*markerStyle, frag ment); | |
| 482 paintTextWithShadows(paintInfo, *markerStyle, textRun, fragment, textMat chInfo.fragmentStartPosition, textMatchInfo.fragmentEndPosition, ApplyToFillMode ); | |
| 483 } | |
| 484 } | |
| 485 | |
| 486 void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& pa intInfo, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font& font) | |
| 487 { | |
| 488 Vector<SVGTextFragmentWithRange> textMatchInfoList = collectTextMatches(pain tInfo, marker); | |
| 489 unsigned textFragmentsSize = textMatchInfoList.size(); | |
| 490 if (textFragmentsSize == 0) | |
| 491 return; | |
| 492 | |
| 493 Color color = marker->activeMatch() ? | |
|
fs
2015/12/17 10:10:55
Again.
ramya.v
2015/12/18 03:43:32
Done.
| |
| 494 LayoutTheme::theme().platformTextSearchHighlightColor(true) : | |
| 495 LayoutTheme::theme().platformTextSearchHighlightColor(false); | |
| 496 | |
| 497 AffineTransform fragmentTransform; | |
| 498 for (unsigned i = 0; i < textFragmentsSize; ++i) { | |
|
fs
2015/12/17 10:10:54
Use range-based for-loop.
ramya.v
2015/12/18 03:43:33
Done.
| |
| 499 SVGTextFragmentWithRange& textMatchInfo = textMatchInfoList.at(i); | |
| 500 const SVGTextFragment& fragment = *(textMatchInfo.fragment); | |
| 501 GraphicsContextStateSaver stateSaver(paintInfo.context); | |
| 502 fragment.buildFragmentTransform(fragmentTransform); | |
| 503 if (!fragmentTransform.isIdentity()) | |
| 504 paintInfo.context.concatCTM(fragmentTransform); | |
| 505 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment (fragment, textMatchInfo.fragmentStartPosition, textMatchInfo.fragmentEndPositio n, style); | |
| 506 paintInfo.context.setFillColor(color); | |
| 507 paintInfo.context.fillRect(fragmentRect, color); | |
| 450 } | 508 } |
| 451 } | 509 } |
| 452 | 510 |
| 453 } // namespace blink | 511 } // namespace blink |
| OLD | NEW |