| 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 "core/paint/SVGInlineTextBoxPainter.h" | 5 #include "core/paint/SVGInlineTextBoxPainter.h" |
| 6 | 6 |
| 7 #include <memory> |
| 7 #include "core/editing/Editor.h" | 8 #include "core/editing/Editor.h" |
| 8 #include "core/editing/markers/DocumentMarkerController.h" | 9 #include "core/editing/markers/DocumentMarkerController.h" |
| 10 #include "core/editing/markers/TextMatchMarker.h" |
| 9 #include "core/frame/LocalFrame.h" | 11 #include "core/frame/LocalFrame.h" |
| 10 #include "core/layout/LayoutTheme.h" | 12 #include "core/layout/LayoutTheme.h" |
| 11 #include "core/layout/api/LineLayoutAPIShim.h" | 13 #include "core/layout/api/LineLayoutAPIShim.h" |
| 12 #include "core/layout/api/SelectionState.h" | 14 #include "core/layout/api/SelectionState.h" |
| 13 #include "core/layout/line/InlineFlowBox.h" | 15 #include "core/layout/line/InlineFlowBox.h" |
| 14 #include "core/layout/svg/LayoutSVGInlineText.h" | 16 #include "core/layout/svg/LayoutSVGInlineText.h" |
| 15 #include "core/layout/svg/SVGLayoutSupport.h" | 17 #include "core/layout/svg/SVGLayoutSupport.h" |
| 16 #include "core/layout/svg/SVGResourcesCache.h" | 18 #include "core/layout/svg/SVGResourcesCache.h" |
| 17 #include "core/layout/svg/line/SVGInlineTextBox.h" | 19 #include "core/layout/svg/line/SVGInlineTextBox.h" |
| 18 #include "core/paint/InlineTextBoxPainter.h" | 20 #include "core/paint/InlineTextBoxPainter.h" |
| 19 #include "core/paint/LayoutObjectDrawingRecorder.h" | 21 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 20 #include "core/paint/PaintInfo.h" | 22 #include "core/paint/PaintInfo.h" |
| 21 #include "core/paint/SVGPaintContext.h" | 23 #include "core/paint/SVGPaintContext.h" |
| 22 #include "core/style/AppliedTextDecoration.h" | 24 #include "core/style/AppliedTextDecoration.h" |
| 23 #include "core/style/ShadowList.h" | 25 #include "core/style/ShadowList.h" |
| 24 #include "platform/graphics/GraphicsContextStateSaver.h" | 26 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 25 #include <memory> | |
| 26 | 27 |
| 27 namespace blink { | 28 namespace blink { |
| 28 | 29 |
| 29 static inline bool textShouldBePainted( | 30 static inline bool textShouldBePainted( |
| 30 const LayoutSVGInlineText& textLayoutObject) { | 31 const LayoutSVGInlineText& textLayoutObject) { |
| 31 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which | 32 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which |
| 32 // returns "int(x + 0.5)". If the absolute font size on screen is below | 33 // returns "int(x + 0.5)". If the absolute font size on screen is below |
| 33 // x=0.5, don't render anything. | 34 // x=0.5, don't render anything. |
| 34 return textLayoutObject.scaledFont().getFontDescription().computedPixelSize(); | 35 return textLayoutObject.scaledFont().getFontDescription().computedPixelSize(); |
| 35 } | 36 } |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 !paintSelectedTextOnly) { | 539 !paintSelectedTextOnly) { |
| 539 PaintFlags flags; | 540 PaintFlags flags; |
| 540 if (setupTextPaint(paintInfo, style, resourceMode, flags)) { | 541 if (setupTextPaint(paintInfo, style, resourceMode, flags)) { |
| 541 paintText(paintInfo, textRun, fragment, endPosition, fragment.length, | 542 paintText(paintInfo, textRun, fragment, endPosition, fragment.length, |
| 542 flags); | 543 flags); |
| 543 } | 544 } |
| 544 } | 545 } |
| 545 } | 546 } |
| 546 | 547 |
| 547 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches( | 548 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches( |
| 548 const DocumentMarker& marker) const { | 549 const TextMatchMarker& marker) const { |
| 549 const Vector<SVGTextFragmentWithRange> emptyTextMatchList; | 550 const Vector<SVGTextFragmentWithRange> emptyTextMatchList; |
| 550 | 551 |
| 551 // SVG does not support grammar or spellcheck markers, so skip anything but | |
| 552 // TextMatch. | |
| 553 if (marker.type() != DocumentMarker::TextMatch) | |
| 554 return emptyTextMatchList; | |
| 555 | |
| 556 if (!inlineLayoutObject().frame()->editor().markedTextMatchesAreHighlighted()) | 552 if (!inlineLayoutObject().frame()->editor().markedTextMatchesAreHighlighted()) |
| 557 return emptyTextMatchList; | 553 return emptyTextMatchList; |
| 558 | 554 |
| 559 int markerStartPosition = | 555 int markerStartPosition = |
| 560 std::max<int>(marker.startOffset() - m_svgInlineTextBox.start(), 0); | 556 std::max<int>(marker.startOffset() - m_svgInlineTextBox.start(), 0); |
| 561 int markerEndPosition = | 557 int markerEndPosition = |
| 562 std::min<int>(marker.endOffset() - m_svgInlineTextBox.start(), | 558 std::min<int>(marker.endOffset() - m_svgInlineTextBox.start(), |
| 563 m_svgInlineTextBox.len()); | 559 m_svgInlineTextBox.len()); |
| 564 | 560 |
| 565 if (markerStartPosition >= markerEndPosition) | 561 if (markerStartPosition >= markerEndPosition) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 583 | 579 |
| 584 fragmentInfoList.push_back(SVGTextFragmentWithRange( | 580 fragmentInfoList.push_back(SVGTextFragmentWithRange( |
| 585 fragment, fragmentStartPosition, fragmentEndPosition)); | 581 fragment, fragmentStartPosition, fragmentEndPosition)); |
| 586 } | 582 } |
| 587 return fragmentInfoList; | 583 return fragmentInfoList; |
| 588 } | 584 } |
| 589 | 585 |
| 590 void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground( | 586 void SVGInlineTextBoxPainter::paintTextMatchMarkerForeground( |
| 591 const PaintInfo& paintInfo, | 587 const PaintInfo& paintInfo, |
| 592 const LayoutPoint& point, | 588 const LayoutPoint& point, |
| 593 const DocumentMarker& marker, | 589 const TextMatchMarker& marker, |
| 594 const ComputedStyle& style, | 590 const ComputedStyle& style, |
| 595 const Font& font) { | 591 const Font& font) { |
| 596 const Vector<SVGTextFragmentWithRange> textMatchInfoList = | 592 const Vector<SVGTextFragmentWithRange> textMatchInfoList = |
| 597 collectTextMatches(marker); | 593 collectTextMatches(marker); |
| 598 if (textMatchInfoList.isEmpty()) | 594 if (textMatchInfoList.isEmpty()) |
| 599 return; | 595 return; |
| 600 | 596 |
| 601 Color textColor = | 597 Color textColor = |
| 602 LayoutTheme::theme().platformTextSearchColor(marker.activeMatch()); | 598 LayoutTheme::theme().platformTextSearchColor(marker.activeMatch()); |
| 603 | 599 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 625 if (shouldPaintStroke) { | 621 if (shouldPaintStroke) { |
| 626 paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, | 622 paintText(paintInfo, textRun, fragment, textMatchInfo.startPosition, |
| 627 textMatchInfo.endPosition, strokeFlags); | 623 textMatchInfo.endPosition, strokeFlags); |
| 628 } | 624 } |
| 629 } | 625 } |
| 630 } | 626 } |
| 631 | 627 |
| 632 void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground( | 628 void SVGInlineTextBoxPainter::paintTextMatchMarkerBackground( |
| 633 const PaintInfo& paintInfo, | 629 const PaintInfo& paintInfo, |
| 634 const LayoutPoint& point, | 630 const LayoutPoint& point, |
| 635 const DocumentMarker& marker, | 631 const TextMatchMarker& marker, |
| 636 const ComputedStyle& style, | 632 const ComputedStyle& style, |
| 637 const Font& font) { | 633 const Font& font) { |
| 638 const Vector<SVGTextFragmentWithRange> textMatchInfoList = | 634 const Vector<SVGTextFragmentWithRange> textMatchInfoList = |
| 639 collectTextMatches(marker); | 635 collectTextMatches(marker); |
| 640 if (textMatchInfoList.isEmpty()) | 636 if (textMatchInfoList.isEmpty()) |
| 641 return; | 637 return; |
| 642 | 638 |
| 643 Color color = LayoutTheme::theme().platformTextSearchHighlightColor( | 639 Color color = LayoutTheme::theme().platformTextSearchHighlightColor( |
| 644 marker.activeMatch()); | 640 marker.activeMatch()); |
| 645 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { | 641 for (const SVGTextFragmentWithRange& textMatchInfo : textMatchInfoList) { |
| 646 const SVGTextFragment& fragment = textMatchInfo.fragment; | 642 const SVGTextFragment& fragment = textMatchInfo.fragment; |
| 647 | 643 |
| 648 GraphicsContextStateSaver stateSaver(paintInfo.context, false); | 644 GraphicsContextStateSaver stateSaver(paintInfo.context, false); |
| 649 if (fragment.isTransformed()) { | 645 if (fragment.isTransformed()) { |
| 650 stateSaver.save(); | 646 stateSaver.save(); |
| 651 paintInfo.context.concatCTM(fragment.buildFragmentTransform()); | 647 paintInfo.context.concatCTM(fragment.buildFragmentTransform()); |
| 652 } | 648 } |
| 653 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment( | 649 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment( |
| 654 fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, | 650 fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, |
| 655 style); | 651 style); |
| 656 paintInfo.context.setFillColor(color); | 652 paintInfo.context.setFillColor(color); |
| 657 paintInfo.context.fillRect(fragmentRect); | 653 paintInfo.context.fillRect(fragmentRect); |
| 658 } | 654 } |
| 659 } | 655 } |
| 660 | 656 |
| 661 } // namespace blink | 657 } // namespace blink |
| OLD | NEW |