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 |