| 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/InlineTextBoxPainter.h" | 5 #include "core/paint/InlineTextBoxPainter.h" |
| 6 | 6 |
| 7 #include "core/editing/CompositionUnderline.h" | 7 #include "core/editing/CompositionUnderline.h" |
| 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" |
| 11 #include "core/frame/LocalFrame.h" | 11 #include "core/frame/LocalFrame.h" |
| 12 #include "core/layout/LayoutBlock.h" | 12 #include "core/layout/LayoutBlock.h" |
| 13 #include "core/layout/LayoutTextCombine.h" | 13 #include "core/layout/LayoutTextCombine.h" |
| 14 #include "core/layout/LayoutTheme.h" | 14 #include "core/layout/LayoutTheme.h" |
| 15 #include "core/layout/api/LineLayoutAPIShim.h" |
| 15 #include "core/layout/api/LineLayoutBox.h" | 16 #include "core/layout/api/LineLayoutBox.h" |
| 16 #include "core/layout/api/LineLayoutText.h" | 17 #include "core/layout/api/LineLayoutText.h" |
| 17 #include "core/layout/line/InlineTextBox.h" | 18 #include "core/layout/line/InlineTextBox.h" |
| 18 #include "core/paint/BoxPainter.h" | 19 #include "core/paint/BoxPainter.h" |
| 19 #include "core/paint/LineLayoutPaintShim.h" | |
| 20 #include "core/paint/PaintInfo.h" | 20 #include "core/paint/PaintInfo.h" |
| 21 #include "core/paint/TextPainter.h" | 21 #include "core/paint/TextPainter.h" |
| 22 #include "platform/graphics/GraphicsContextStateSaver.h" | 22 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 23 #include "platform/graphics/paint/DrawingRecorder.h" | 23 #include "platform/graphics/paint/DrawingRecorder.h" |
| 24 #include "wtf/Optional.h" | 24 #include "wtf/Optional.h" |
| 25 | 25 |
| 26 namespace blink { | 26 namespace blink { |
| 27 | 27 |
| 28 typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> InlineTextBoxBlobCacheMa
p; | 28 typedef WTF::HashMap<const InlineTextBox*, TextBlobPtr> InlineTextBoxBlobCacheMa
p; |
| 29 static InlineTextBoxBlobCacheMap* gTextBlobCache; | 29 static InlineTextBoxBlobCacheMap* gTextBlobCache; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 85 } |
| 86 | 86 |
| 87 // The text clip phase already has a LayoutObjectDrawingRecorder. Text clips
are initiated only in BoxPainter::paintFillLayer, | 87 // The text clip phase already has a LayoutObjectDrawingRecorder. Text clips
are initiated only in BoxPainter::paintFillLayer, |
| 88 // which is already within a LayoutObjectDrawingRecorder. | 88 // which is already within a LayoutObjectDrawingRecorder. |
| 89 Optional<DrawingRecorder> drawingRecorder; | 89 Optional<DrawingRecorder> drawingRecorder; |
| 90 if (paintInfo.phase != PaintPhaseTextClip) { | 90 if (paintInfo.phase != PaintPhaseTextClip) { |
| 91 if (DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_inl
ineTextBox, DisplayItem::paintPhaseToDrawingType(paintInfo.phase))) | 91 if (DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_inl
ineTextBox, DisplayItem::paintPhaseToDrawingType(paintInfo.phase))) |
| 92 return; | 92 return; |
| 93 LayoutRect paintRect(logicalVisualOverflow); | 93 LayoutRect paintRect(logicalVisualOverflow); |
| 94 m_inlineTextBox.logicalRectToPhysicalRect(paintRect); | 94 m_inlineTextBox.logicalRectToPhysicalRect(paintRect); |
| 95 if (paintInfo.phase != PaintPhaseSelection && (haveSelection || paintsMa
rkerHighlights(*LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayout
Item())))) | 95 if (paintInfo.phase != PaintPhaseSelection && (haveSelection || paintsMa
rkerHighlights(*LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutIt
em())))) |
| 96 paintRect.unite(m_inlineTextBox.localSelectionRect(m_inlineTextBox.s
tart(), m_inlineTextBox.start() + m_inlineTextBox.len())); | 96 paintRect.unite(m_inlineTextBox.localSelectionRect(m_inlineTextBox.s
tart(), m_inlineTextBox.start() + m_inlineTextBox.len())); |
| 97 paintRect.moveBy(adjustedPaintOffset); | 97 paintRect.moveBy(adjustedPaintOffset); |
| 98 drawingRecorder.emplace(paintInfo.context, m_inlineTextBox, DisplayItem:
:paintPhaseToDrawingType(paintInfo.phase), FloatRect(paintRect)); | 98 drawingRecorder.emplace(paintInfo.context, m_inlineTextBox, DisplayItem:
:paintPhaseToDrawingType(paintInfo.phase), FloatRect(paintRect)); |
| 99 } | 99 } |
| 100 | 100 |
| 101 if (m_inlineTextBox.truncation() != cNoTruncation) { | 101 if (m_inlineTextBox.truncation() != cNoTruncation) { |
| 102 if (m_inlineTextBox.lineLayoutItem().containingBlock().style()->isLeftTo
RightDirection() != m_inlineTextBox.isLeftToRightDirection()) { | 102 if (m_inlineTextBox.lineLayoutItem().containingBlock().style()->isLeftTo
RightDirection() != m_inlineTextBox.isLeftToRightDirection()) { |
| 103 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin | 103 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin |
| 104 // at which we start drawing text. | 104 // at which we start drawing text. |
| 105 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: | 105 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 120 const ComputedStyle& styleToUse = m_inlineTextBox.lineLayoutItem().styleRef(
m_inlineTextBox.isFirstLineStyle()); | 120 const ComputedStyle& styleToUse = m_inlineTextBox.lineLayoutItem().styleRef(
m_inlineTextBox.isFirstLineStyle()); |
| 121 | 121 |
| 122 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); | 122 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); |
| 123 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); | 123 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); |
| 124 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); | 124 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); |
| 125 | 125 |
| 126 bool shouldRotate = false; | 126 bool shouldRotate = false; |
| 127 LayoutTextCombine* combinedText = nullptr; | 127 LayoutTextCombine* combinedText = nullptr; |
| 128 if (!m_inlineTextBox.isHorizontal()) { | 128 if (!m_inlineTextBox.isHorizontal()) { |
| 129 if (styleToUse.hasTextCombine() && m_inlineTextBox.lineLayoutItem().isCo
mbineText()) { | 129 if (styleToUse.hasTextCombine() && m_inlineTextBox.lineLayoutItem().isCo
mbineText()) { |
| 130 combinedText = &toLayoutTextCombine(*LineLayoutPaintShim::layoutObje
ctFrom(m_inlineTextBox.lineLayoutItem())); | 130 combinedText = &toLayoutTextCombine(*LineLayoutAPIShim::layoutObject
From(m_inlineTextBox.lineLayoutItem())); |
| 131 if (!combinedText->isCombined()) | 131 if (!combinedText->isCombined()) |
| 132 combinedText = nullptr; | 132 combinedText = nullptr; |
| 133 } | 133 } |
| 134 if (combinedText) { | 134 if (combinedText) { |
| 135 combinedText->updateFont(); | 135 combinedText->updateFont(); |
| 136 boxRect.setWidth(combinedText->inlineWidthForLayout()); | 136 boxRect.setWidth(combinedText->inlineWidthForLayout()); |
| 137 } else { | 137 } else { |
| 138 shouldRotate = true; | 138 shouldRotate = true; |
| 139 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); | 139 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 // Determine text colors. | 143 // Determine text colors. |
| 144 const LayoutObject& textBoxLayoutObject = *LineLayoutPaintShim::layoutObject
From(m_inlineTextBox.lineLayoutItem()); | 144 const LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObjectFr
om(m_inlineTextBox.lineLayoutItem()); |
| 145 TextPainter::Style textStyle = TextPainter::textPaintingStyle(textBoxLayoutO
bject, styleToUse, paintInfo); | 145 TextPainter::Style textStyle = TextPainter::textPaintingStyle(textBoxLayoutO
bject, styleToUse, paintInfo); |
| 146 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(text
BoxLayoutObject, haveSelection, paintInfo, textStyle); | 146 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(text
BoxLayoutObject, haveSelection, paintInfo, textStyle); |
| 147 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); | 147 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); |
| 148 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; | 148 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; |
| 149 | 149 |
| 150 // Set our font. | 150 // Set our font. |
| 151 const Font& font = styleToUse.font(); | 151 const Font& font = styleToUse.font(); |
| 152 | 152 |
| 153 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); | 153 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); |
| 154 | 154 |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 | 738 |
| 739 LayoutUnit width = m_inlineTextBox.logicalWidth(); | 739 LayoutUnit width = m_inlineTextBox.logicalWidth(); |
| 740 if (m_inlineTextBox.truncation() != cNoTruncation) { | 740 if (m_inlineTextBox.truncation() != cNoTruncation) { |
| 741 width = m_inlineTextBox.lineLayoutItem().width(m_inlineTextBox.start(),
m_inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftT
oRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 741 width = m_inlineTextBox.lineLayoutItem().width(m_inlineTextBox.start(),
m_inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftT
oRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
| 742 if (!m_inlineTextBox.isLeftToRightDirection()) | 742 if (!m_inlineTextBox.isLeftToRightDirection()) |
| 743 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); | 743 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); |
| 744 } | 744 } |
| 745 | 745 |
| 746 // Get the text decoration colors. | 746 // Get the text decoration colors. |
| 747 LayoutObject::AppliedTextDecoration underline, overline, linethrough; | 747 LayoutObject::AppliedTextDecoration underline, overline, linethrough; |
| 748 LayoutObject& textBoxLayoutObject = *LineLayoutPaintShim::layoutObjectFrom(m
_inlineTextBox.lineLayoutItem()); | 748 LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObjectFrom(m_i
nlineTextBox.lineLayoutItem()); |
| 749 textBoxLayoutObject.getTextDecorations(deco, underline, overline, linethroug
h, true); | 749 textBoxLayoutObject.getTextDecorations(deco, underline, overline, linethroug
h, true); |
| 750 if (m_inlineTextBox.isFirstLineStyle()) | 750 if (m_inlineTextBox.isFirstLineStyle()) |
| 751 textBoxLayoutObject.getTextDecorations(deco, underline, overline, lineth
rough, true, true); | 751 textBoxLayoutObject.getTextDecorations(deco, underline, overline, lineth
rough, true, true); |
| 752 | 752 |
| 753 // Use a special function for underlines to get the positioning exactly righ
t. | 753 // Use a special function for underlines to get the positioning exactly righ
t. |
| 754 bool isPrinting = paintInfo.isPrinting(); | 754 bool isPrinting = paintInfo.isPrinting(); |
| 755 | 755 |
| 756 const ComputedStyle& styleToUse = textBoxLayoutObject.styleRef(m_inlineTextB
ox.isFirstLineStyle()); | 756 const ComputedStyle& styleToUse = textBoxLayoutObject.styleRef(m_inlineTextB
ox.isFirstLineStyle()); |
| 757 float baseline = styleToUse.fontMetrics().ascent(); | 757 float baseline = styleToUse.fontMetrics().ascent(); |
| 758 | 758 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 start += 1; | 823 start += 1; |
| 824 width -= 2; | 824 width -= 2; |
| 825 | 825 |
| 826 context.setStrokeColor(underline.color); | 826 context.setStrokeColor(underline.color); |
| 827 context.setStrokeThickness(lineThickness); | 827 context.setStrokeThickness(lineThickness); |
| 828 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m
_inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB
ox.lineLayoutItem().document().printing()); | 828 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m
_inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB
ox.lineLayoutItem().document().printing()); |
| 829 } | 829 } |
| 830 | 830 |
| 831 void InlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) | 831 void InlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) |
| 832 { | 832 { |
| 833 if (!LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())
->frame()->editor().markedTextMatchesAreHighlighted()) | 833 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())->
frame()->editor().markedTextMatchesAreHighlighted()) |
| 834 return; | 834 return; |
| 835 | 835 |
| 836 // TODO(ramya.v): Extract this into a helper function and share many copies
of this code. | 836 // TODO(ramya.v): Extract this into a helper function and share many copies
of this code. |
| 837 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 837 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
| 838 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 838 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
| 839 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 839 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
| 840 | 840 |
| 841 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ
eMatch()); | 841 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ
eMatch()); |
| 842 if (style.visitedDependentColor(CSSPropertyColor) == textColor) | 842 if (style.visitedDependentColor(CSSPropertyColor) == textColor) |
| 843 return; | 843 return; |
| 844 TextPainter::Style textStyle; | 844 TextPainter::Style textStyle; |
| 845 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textS
tyle.emphasisMarkColor = textColor; | 845 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textS
tyle.emphasisMarkColor = textColor; |
| 846 textStyle.strokeWidth = style.textStrokeWidth(); | 846 textStyle.strokeWidth = style.textStrokeWidth(); |
| 847 textStyle.shadow = 0; | 847 textStyle.shadow = 0; |
| 848 | 848 |
| 849 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); | 849 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); |
| 850 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); | 850 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); |
| 851 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m
_inlineTextBox.isHorizontal()); | 851 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m
_inlineTextBox.isHorizontal()); |
| 852 | 852 |
| 853 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); | 853 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); |
| 854 } | 854 } |
| 855 | 855 |
| 856 void InlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) | 856 void InlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) |
| 857 { | 857 { |
| 858 if (!LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())
->frame()->editor().markedTextMatchesAreHighlighted()) | 858 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())->
frame()->editor().markedTextMatchesAreHighlighted()) |
| 859 return; | 859 return; |
| 860 | 860 |
| 861 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on | 861 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on |
| 862 // the same word there are no pieces sticking out. | 862 // the same word there are no pieces sticking out. |
| 863 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 863 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
| 864 int selHeight = m_inlineTextBox.root().selectionHeight(); | 864 int selHeight = m_inlineTextBox.root().selectionHeight(); |
| 865 | 865 |
| 866 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 866 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
| 867 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 867 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
| 868 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 868 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
| 869 | 869 |
| 870 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker->
activeMatch()); | 870 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker->
activeMatch()); |
| 871 GraphicsContext& context = paintInfo.context; | 871 GraphicsContext& context = paintInfo.context; |
| 872 GraphicsContextStateSaver stateSaver(context); | 872 GraphicsContextStateSaver stateSaver(context); |
| 873 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toF
loat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); | 873 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toF
loat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); |
| 874 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(),
(boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); | 874 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(),
(boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); |
| 875 } | 875 } |
| 876 | 876 |
| 877 | 877 |
| 878 } // namespace blink | 878 } // namespace blink |
| OLD | NEW |