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" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 if (!paintInfo.cullRect().intersectsHorizontalRange(logicalStart, logica
lStart + logicalExtent)) | 71 if (!paintInfo.cullRect().intersectsHorizontalRange(logicalStart, logica
lStart + logicalExtent)) |
72 return; | 72 return; |
73 } else { | 73 } else { |
74 if (!paintInfo.cullRect().intersectsVerticalRange(logicalStart, logicalS
tart + logicalExtent)) | 74 if (!paintInfo.cullRect().intersectsVerticalRange(logicalStart, logicalS
tart + logicalExtent)) |
75 return; | 75 return; |
76 } | 76 } |
77 | 77 |
78 bool isPrinting = paintInfo.isPrinting(); | 78 bool isPrinting = paintInfo.isPrinting(); |
79 | 79 |
80 // Determine whether or not we're selected. | 80 // Determine whether or not we're selected. |
81 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.selectionState() != SelectionNone; | 81 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.getSelectionState() != SelectionNone; |
82 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { | 82 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { |
83 // When only painting the selection, don't bother to paint if there is n
one. | 83 // When only painting the selection, don't bother to paint if there is n
one. |
84 return; | 84 return; |
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(*LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutIt
em())))) | 95 if (paintInfo.phase != PaintPhaseSelection && (haveSelection || paintsMa
rkerHighlights(*LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.getLineLayou
tItem())))) |
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.getLineLayoutItem().containingBlock().style()->isLef
tToRightDirection() != 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: |
106 // |Hello|CBA| -> |...He|CBA| | 106 // |Hello|CBA| -> |...He|CBA| |
107 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing | 107 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing |
108 // farther to the right. | 108 // farther to the right. |
109 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the | 109 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the |
110 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| | 110 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| |
111 LayoutUnit widthOfVisibleText = LayoutUnit(m_inlineTextBox.lineLayou
tItem().width( | 111 LayoutUnit widthOfVisibleText = LayoutUnit(m_inlineTextBox.getLineLa
youtItem().width( |
112 m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineT
extBox.textPos(), | 112 m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineT
extBox.textPos(), |
113 m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTe
xtBox.isFirstLineStyle())); | 113 m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTe
xtBox.isFirstLineStyle())); |
114 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; | 114 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; |
115 // FIXME: The hit testing logic also needs to take this translation
into account. | 115 // FIXME: The hit testing logic also needs to take this translation
into account. |
116 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, LayoutUnit()); | 116 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, LayoutUnit()); |
117 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); | 117 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 GraphicsContext& context = paintInfo.context; | 121 GraphicsContext& context = paintInfo.context; |
122 const ComputedStyle& styleToUse = m_inlineTextBox.lineLayoutItem().styleRef(
m_inlineTextBox.isFirstLineStyle()); | 122 const ComputedStyle& styleToUse = m_inlineTextBox.getLineLayoutItem().styleR
ef(m_inlineTextBox.isFirstLineStyle()); |
123 | 123 |
124 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); | 124 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); |
125 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); | 125 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); |
126 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); | 126 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); |
127 | 127 |
128 bool shouldRotate = false; | 128 bool shouldRotate = false; |
129 LayoutTextCombine* combinedText = nullptr; | 129 LayoutTextCombine* combinedText = nullptr; |
130 if (!m_inlineTextBox.isHorizontal()) { | 130 if (!m_inlineTextBox.isHorizontal()) { |
131 if (styleToUse.hasTextCombine() && m_inlineTextBox.lineLayoutItem().isCo
mbineText()) { | 131 if (styleToUse.hasTextCombine() && m_inlineTextBox.getLineLayoutItem().i
sCombineText()) { |
132 combinedText = &toLayoutTextCombine(*LineLayoutAPIShim::layoutObject
From(m_inlineTextBox.lineLayoutItem())); | 132 combinedText = &toLayoutTextCombine(*LineLayoutAPIShim::layoutObject
From(m_inlineTextBox.getLineLayoutItem())); |
133 if (!combinedText->isCombined()) | 133 if (!combinedText->isCombined()) |
134 combinedText = nullptr; | 134 combinedText = nullptr; |
135 } | 135 } |
136 if (combinedText) { | 136 if (combinedText) { |
137 combinedText->updateFont(); | 137 combinedText->updateFont(); |
138 boxRect.setWidth(combinedText->inlineWidthForLayout()); | 138 boxRect.setWidth(combinedText->inlineWidthForLayout()); |
139 } else { | 139 } else { |
140 shouldRotate = true; | 140 shouldRotate = true; |
141 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); | 141 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 // Determine text colors. | 145 // Determine text colors. |
146 TextPainter::Style textStyle = TextPainter::textPaintingStyle(m_inlineTextBo
x.lineLayoutItem(), styleToUse, paintInfo); | 146 TextPainter::Style textStyle = TextPainter::textPaintingStyle(m_inlineTextBo
x.getLineLayoutItem(), styleToUse, paintInfo); |
147 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(m_in
lineTextBox.lineLayoutItem(), haveSelection, paintInfo, textStyle); | 147 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(m_in
lineTextBox.getLineLayoutItem(), haveSelection, paintInfo, textStyle); |
148 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); | 148 bool paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection); |
149 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; | 149 bool paintSelectedTextSeparately = !paintSelectedTextOnly && textStyle != se
lectionStyle; |
150 | 150 |
151 // Set our font. | 151 // Set our font. |
152 const Font& font = styleToUse.font(); | 152 const Font& font = styleToUse.font(); |
153 | 153 |
154 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); | 154 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); |
155 | 155 |
156 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection | 156 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
include selection |
157 // and composition highlights. | 157 // and composition highlights. |
158 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { | 158 if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseT
extClip && !isPrinting) { |
159 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font, DocumentMar
kerPaintPhase::Background); | 159 paintDocumentMarkers(paintInfo, boxOrigin, styleToUse, font, DocumentMar
kerPaintPhase::Background); |
160 | 160 |
161 const LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObje
ctFrom(m_inlineTextBox.lineLayoutItem()); | 161 const LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObje
ctFrom(m_inlineTextBox.getLineLayoutItem()); |
162 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) { | 162 if (haveSelection && !paintsCompositionMarkers(textBoxLayoutObject)) { |
163 if (combinedText) | 163 if (combinedText) |
164 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText>
(context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); | 164 paintSelection<InlineTextBoxPainter::PaintOptions::CombinedText>
(context, boxRect, styleToUse, font, selectionStyle.fillColor, combinedText); |
165 else | 165 else |
166 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte
xt, boxRect, styleToUse, font, selectionStyle.fillColor); | 166 paintSelection<InlineTextBoxPainter::PaintOptions::Normal>(conte
xt, boxRect, styleToUse, font, selectionStyle.fillColor); |
167 } | 167 } |
168 } | 168 } |
169 | 169 |
170 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). | 170 // 2. Now paint the foreground, including text and decorations like underlin
e/overline (in quirks mode only). |
171 int length = m_inlineTextBox.len(); | 171 int length = m_inlineTextBox.len(); |
172 StringView string = m_inlineTextBox.lineLayoutItem().text().createView(); | 172 StringView string = m_inlineTextBox.getLineLayoutItem().text().createView(); |
173 ASSERT(m_inlineTextBox.start() + length <= string.length()); | 173 ASSERT(m_inlineTextBox.start() + length <= string.length()); |
174 if (static_cast<unsigned>(length) != string.length() || m_inlineTextBox.star
t()) | 174 if (static_cast<unsigned>(length) != string.length() || m_inlineTextBox.star
t()) |
175 string.narrow(m_inlineTextBox.start(), length); | 175 string.narrow(m_inlineTextBox.start(), length); |
176 int maximumLength = m_inlineTextBox.lineLayoutItem().textLength() - m_inline
TextBox.start(); | 176 int maximumLength = m_inlineTextBox.getLineLayoutItem().textLength() - m_inl
ineTextBox.start(); |
177 | 177 |
178 StringBuilder charactersWithHyphen; | 178 StringBuilder charactersWithHyphen; |
179 TextRun textRun = m_inlineTextBox.constructTextRun(styleToUse, font, string,
maximumLength, m_inlineTextBox.hasHyphen() ? &charactersWithHyphen : 0); | 179 TextRun textRun = m_inlineTextBox.constructTextRun(styleToUse, font, string,
maximumLength, m_inlineTextBox.hasHyphen() ? &charactersWithHyphen : 0); |
180 if (m_inlineTextBox.hasHyphen()) | 180 if (m_inlineTextBox.hasHyphen()) |
181 length = textRun.length(); | 181 length = textRun.length(); |
182 | 182 |
183 int selectionStart = 0; | 183 int selectionStart = 0; |
184 int selectionEnd = 0; | 184 int selectionEnd = 0; |
185 if (paintSelectedTextOnly || paintSelectedTextSeparately) | 185 if (paintSelectedTextOnly || paintSelectedTextSeparately) |
186 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd); | 186 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) | 253 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) |
254 { | 254 { |
255 // When painting selection, we want to include a highlight when the | 255 // When painting selection, we want to include a highlight when the |
256 // selection spans line breaks. In other cases such as invisible elements | 256 // selection spans line breaks. In other cases such as invisible elements |
257 // or those with no text that are not line breaks, we can skip painting | 257 // or those with no text that are not line breaks, we can skip painting |
258 // wholesale. | 258 // wholesale. |
259 // TODO(wkorman): Constrain line break painting to appropriate paint phase. | 259 // TODO(wkorman): Constrain line break painting to appropriate paint phase. |
260 // This code path is only called in PaintPhaseForeground whereas we would | 260 // This code path is only called in PaintPhaseForeground whereas we would |
261 // expect PaintPhaseSelection. The existing haveSelection logic in paint() | 261 // expect PaintPhaseSelection. The existing haveSelection logic in paint() |
262 // tests for != PaintPhaseTextClip. | 262 // tests for != PaintPhaseTextClip. |
263 if (m_inlineTextBox.lineLayoutItem().style()->visibility() != VISIBLE | 263 if (m_inlineTextBox.getLineLayoutItem().style()->visibility() != VISIBLE |
264 || m_inlineTextBox.truncation() == cFullTruncation | 264 || m_inlineTextBox.truncation() == cFullTruncation |
265 || !m_inlineTextBox.len()) | 265 || !m_inlineTextBox.len()) |
266 return false; | 266 return false; |
267 return true; | 267 return true; |
268 } | 268 } |
269 | 269 |
270 unsigned InlineTextBoxPainter::underlinePaintStart(const CompositionUnderline& u
nderline) | 270 unsigned InlineTextBoxPainter::underlinePaintStart(const CompositionUnderline& u
nderline) |
271 { | 271 { |
272 return std::max(static_cast<unsigned>(m_inlineTextBox.start()), underline.st
artOffset); | 272 return std::max(static_cast<unsigned>(m_inlineTextBox.start()), underline.st
artOffset); |
273 } | 273 } |
274 | 274 |
275 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und
erline) | 275 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und
erline) |
276 { | 276 { |
277 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. | 277 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. |
278 if (m_inlineTextBox.truncation() != cNoTruncation) | 278 if (m_inlineTextBox.truncation() != cNoTruncation) |
279 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); | 279 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); |
280 return paintEnd; | 280 return paintEnd; |
281 } | 281 } |
282 | 282 |
283 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext&
context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f
ont, Color backgroundColor, int startPos, int endPos) | 283 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext&
context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f
ont, Color backgroundColor, int startPos, int endPos) |
284 { | 284 { |
285 if (backgroundColor == Color::transparent) | 285 if (backgroundColor == Color::transparent) |
286 return; | 286 return; |
287 | 287 |
288 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; | 288 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; |
289 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); | 289 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); |
290 if (sPos >= ePos) | 290 if (sPos >= ePos) |
291 return; | 291 return; |
292 | 292 |
293 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 293 int deltaY = m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWrit
ingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBo
ttom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
294 int selHeight = m_inlineTextBox.root().selectionHeight(); | 294 int selHeight = m_inlineTextBox.root().selectionHeight(); |
295 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de
ltaY); | 295 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de
ltaY); |
296 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style, f
ont), localOrigin, selHeight, backgroundColor, sPos, ePos); | 296 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style, f
ont), localOrigin, selHeight, backgroundColor, sPos, ePos); |
297 } | 297 } |
298 | 298 |
299 void InlineTextBoxPainter::paintDocumentMarkers(const PaintInfo& paintInfo, cons
t LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, Document
MarkerPaintPhase markerPaintPhase) | 299 void InlineTextBoxPainter::paintDocumentMarkers(const PaintInfo& paintInfo, cons
t LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, Document
MarkerPaintPhase markerPaintPhase) |
300 { | 300 { |
301 if (!m_inlineTextBox.lineLayoutItem().node()) | 301 if (!m_inlineTextBox.getLineLayoutItem().node()) |
302 return; | 302 return; |
303 | 303 |
304 DocumentMarkerVector markers = m_inlineTextBox.lineLayoutItem().document().m
arkers().markersFor(m_inlineTextBox.lineLayoutItem().node()); | 304 DocumentMarkerVector markers = m_inlineTextBox.getLineLayoutItem().document(
).markers().markersFor(m_inlineTextBox.getLineLayoutItem().node()); |
305 DocumentMarkerVector::const_iterator markerIt = markers.begin(); | 305 DocumentMarkerVector::const_iterator markerIt = markers.begin(); |
306 | 306 |
307 // Give any document markers that touch this run a chance to draw before the
text has been drawn. | 307 // Give any document markers that touch this run a chance to draw before the
text has been drawn. |
308 // Note end() points at the last char, not one past it like endOffset and ra
nges do. | 308 // Note end() points at the last char, not one past it like endOffset and ra
nges do. |
309 for ( ; markerIt != markers.end(); ++markerIt) { | 309 for ( ; markerIt != markers.end(); ++markerIt) { |
310 DocumentMarker* marker = *markerIt; | 310 DocumentMarker* marker = *markerIt; |
311 | 311 |
312 // Paint either the background markers or the foreground markers, but no
t both | 312 // Paint either the background markers or the foreground markers, but no
t both |
313 switch (marker->type()) { | 313 switch (marker->type()) { |
314 case DocumentMarker::Grammar: | 314 case DocumentMarker::Grammar: |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 return GraphicsContext::DocumentMarkerGrammarLineStyle; | 371 return GraphicsContext::DocumentMarkerGrammarLineStyle; |
372 default: | 372 default: |
373 ASSERT_NOT_REACHED(); | 373 ASSERT_NOT_REACHED(); |
374 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 374 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
375 } | 375 } |
376 } | 376 } |
377 | 377 |
378 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext& context, const L
ayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const
Font& font, bool grammar) | 378 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext& context, const L
ayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const
Font& font, bool grammar) |
379 { | 379 { |
380 // Never print spelling/grammar markers (5327887) | 380 // Never print spelling/grammar markers (5327887) |
381 if (m_inlineTextBox.lineLayoutItem().document().printing()) | 381 if (m_inlineTextBox.getLineLayoutItem().document().printing()) |
382 return; | 382 return; |
383 | 383 |
384 if (m_inlineTextBox.truncation() == cFullTruncation) | 384 if (m_inlineTextBox.truncation() == cFullTruncation) |
385 return; | 385 return; |
386 | 386 |
387 LayoutUnit start; // start of line to draw, relative to tx | 387 LayoutUnit start; // start of line to draw, relative to tx |
388 LayoutUnit width = m_inlineTextBox.logicalWidth(); // how much line to draw | 388 LayoutUnit width = m_inlineTextBox.logicalWidth(); // how much line to draw |
389 | 389 |
390 // Determine whether we need to measure text | 390 // Determine whether we need to measure text |
391 bool markerSpansWholeBox = true; | 391 bool markerSpansWholeBox = true; |
392 if (m_inlineTextBox.start() <= marker->startOffset()) | 392 if (m_inlineTextBox.start() <= marker->startOffset()) |
393 markerSpansWholeBox = false; | 393 markerSpansWholeBox = false; |
394 if ((m_inlineTextBox.end() + 1) != marker->endOffset()) // end points at the
last char, not past it | 394 if ((m_inlineTextBox.end() + 1) != marker->endOffset()) // end points at the
last char, not past it |
395 markerSpansWholeBox = false; | 395 markerSpansWholeBox = false; |
396 if (m_inlineTextBox.truncation() != cNoTruncation) | 396 if (m_inlineTextBox.truncation() != cNoTruncation) |
397 markerSpansWholeBox = false; | 397 markerSpansWholeBox = false; |
398 | 398 |
399 if (!markerSpansWholeBox || grammar) { | 399 if (!markerSpansWholeBox || grammar) { |
400 int startPosition = std::max<int>(marker->startOffset() - m_inlineTextBo
x.start(), 0); | 400 int startPosition = std::max<int>(marker->startOffset() - m_inlineTextBo
x.start(), 0); |
401 int endPosition = std::min<int>(marker->endOffset() - static_cast<int>(m
_inlineTextBox.start()), m_inlineTextBox.len()); | 401 int endPosition = std::min<int>(marker->endOffset() - static_cast<int>(m
_inlineTextBox.start()), m_inlineTextBox.len()); |
402 | 402 |
403 if (m_inlineTextBox.truncation() != cNoTruncation) | 403 if (m_inlineTextBox.truncation() != cNoTruncation) |
404 endPosition = std::min<int>(endPosition, m_inlineTextBox.truncation(
)); | 404 endPosition = std::min<int>(endPosition, m_inlineTextBox.truncation(
)); |
405 | 405 |
406 // Calculate start & width | 406 // Calculate start & width |
407 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWri
tingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalB
ottom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 407 int deltaY = m_inlineTextBox.getLineLayoutItem().style()->isFlippedLines
WritingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logic
alBottom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(
); |
408 int selHeight = m_inlineTextBox.root().selectionHeight(); | 408 int selHeight = m_inlineTextBox.root().selectionHeight(); |
409 LayoutPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); | 409 LayoutPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); |
410 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 410 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
411 | 411 |
412 // FIXME: Convert the document markers to float rects. | 412 // FIXME: Convert the document markers to float rects. |
413 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, Flo
atPoint(startPoint), selHeight, startPosition, endPosition)); | 413 IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, Flo
atPoint(startPoint), selHeight, startPosition, endPosition)); |
414 start = markerRect.x() - startPoint.x(); | 414 start = markerRect.x() - startPoint.x(); |
415 width = LayoutUnit(markerRect.width()); | 415 width = LayoutUnit(markerRect.width()); |
416 } | 416 } |
417 | 417 |
418 // IMPORTANT: The misspelling underline is not considered when calculating t
he text bounds, so we have to | 418 // IMPORTANT: The misspelling underline is not considered when calculating t
he text bounds, so we have to |
419 // make sure to fit within those bounds. This means the top pixel(s) of the
underline will overlap the | 419 // make sure to fit within those bounds. This means the top pixel(s) of the
underline will overlap the |
420 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar
e to increase the line spacing (bad!!) | 420 // bottom pixel(s) of the glyphs in smaller font sizes. The alternatives ar
e to increase the line spacing (bad!!) |
421 // or decrease the underline thickness. The overlap is actually the most us
eful, and matches what AppKit does. | 421 // or decrease the underline thickness. The overlap is actually the most us
eful, and matches what AppKit does. |
422 // So, we generally place the underline at the bottom of the text, but in la
rger fonts that's not so good so | 422 // So, we generally place the underline at the bottom of the text, but in la
rger fonts that's not so good so |
423 // we pin to two pixels under the baseline. | 423 // we pin to two pixels under the baseline. |
424 int lineThickness = misspellingLineThickness; | 424 int lineThickness = misspellingLineThickness; |
425 int baseline = m_inlineTextBox.lineLayoutItem().style(m_inlineTextBox.isFirs
tLineStyle())->fontMetrics().ascent(); | 425 int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isF
irstLineStyle())->fontMetrics().ascent(); |
426 int descent = m_inlineTextBox.logicalHeight() - baseline; | 426 int descent = m_inlineTextBox.logicalHeight() - baseline; |
427 int underlineOffset; | 427 int underlineOffset; |
428 if (descent <= (lineThickness + 2)) { | 428 if (descent <= (lineThickness + 2)) { |
429 // Place the underline at the very bottom of the text in small/medium fo
nts. | 429 // Place the underline at the very bottom of the text in small/medium fo
nts. |
430 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; | 430 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; |
431 } else { | 431 } else { |
432 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. | 432 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. |
433 underlineOffset = baseline + 2; | 433 underlineOffset = baseline + 2; |
434 } | 434 } |
435 context.drawLineForDocumentMarker(FloatPoint((boxOrigin.x() + start).toFloat
(), (boxOrigin.y() + underlineOffset).toFloat()), width.toFloat(), lineStyleForM
arkerType(marker->type())); | 435 context.drawLineForDocumentMarker(FloatPoint((boxOrigin.x() + start).toFloat
(), (boxOrigin.y() + underlineOffset).toFloat()), width.toFloat(), lineStyleForM
arkerType(marker->type())); |
436 } | 436 } |
437 | 437 |
438 template <InlineTextBoxPainter::PaintOptions options> | 438 template <InlineTextBoxPainter::PaintOptions options> |
439 void InlineTextBoxPainter::paintSelection(GraphicsContext& context, const Layout
Rect& boxRect, const ComputedStyle& style, const Font& font, Color textColor, La
youtTextCombine* combinedText) | 439 void InlineTextBoxPainter::paintSelection(GraphicsContext& context, const Layout
Rect& boxRect, const ComputedStyle& style, const Font& font, Color textColor, La
youtTextCombine* combinedText) |
440 { | 440 { |
441 // See if we have a selection to paint at all. | 441 // See if we have a selection to paint at all. |
442 int sPos, ePos; | 442 int sPos, ePos; |
443 m_inlineTextBox.selectionStartEnd(sPos, ePos); | 443 m_inlineTextBox.selectionStartEnd(sPos, ePos); |
444 if (sPos >= ePos) | 444 if (sPos >= ePos) |
445 return; | 445 return; |
446 | 446 |
447 Color c = m_inlineTextBox.lineLayoutItem().selectionBackgroundColor(); | 447 Color c = m_inlineTextBox.getLineLayoutItem().selectionBackgroundColor(); |
448 if (!c.alpha()) | 448 if (!c.alpha()) |
449 return; | 449 return; |
450 | 450 |
451 // If the text color ends up being the same as the selection background, inv
ert the selection | 451 // If the text color ends up being the same as the selection background, inv
ert the selection |
452 // background. | 452 // background. |
453 if (textColor == c) | 453 if (textColor == c) |
454 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); | 454 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); |
455 | 455 |
456 // If the text is truncated, let the thing being painted in the truncation | 456 // If the text is truncated, let the thing being painted in the truncation |
457 // draw its own highlight. | 457 // draw its own highlight. |
458 int length = m_inlineTextBox.truncation() != cNoTruncation ? m_inlineTextBox
.truncation() : m_inlineTextBox.len(); | 458 int length = m_inlineTextBox.truncation() != cNoTruncation ? m_inlineTextBox
.truncation() : m_inlineTextBox.len(); |
459 StringView string = m_inlineTextBox.lineLayoutItem().text().createView(); | 459 StringView string = m_inlineTextBox.getLineLayoutItem().text().createView(); |
460 | 460 |
461 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) | 461 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) |
462 string.narrow(m_inlineTextBox.start(), length); | 462 string.narrow(m_inlineTextBox.start(), length); |
463 | 463 |
464 StringBuilder charactersWithHyphen; | 464 StringBuilder charactersWithHyphen; |
465 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); | 465 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); |
466 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.lineLayoutItem().textLength() - m_inlineTextBox.start(), respectHyph
en ? &charactersWithHyphen : 0); | 466 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.getLineLayoutItem().textLength() - m_inlineTextBox.start(), respectH
yphen ? &charactersWithHyphen : 0); |
467 if (respectHyphen) | 467 if (respectHyphen) |
468 ePos = textRun.length(); | 468 ePos = textRun.length(); |
469 | 469 |
470 GraphicsContextStateSaver stateSaver(context); | 470 GraphicsContextStateSaver stateSaver(context); |
471 | 471 |
472 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { | 472 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { |
473 ASSERT(combinedText); | 473 ASSERT(combinedText); |
474 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow | 474 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow |
475 LayoutRect clipRect(boxRect); | 475 LayoutRect clipRect(boxRect); |
476 combinedText->transformLayoutRect(clipRect); | 476 combinedText->transformLayoutRect(clipRect); |
477 context.clip(FloatRect(clipRect)); | 477 context.clip(FloatRect(clipRect)); |
478 combinedText->transformToInlineCoordinates(context, boxRect); | 478 combinedText->transformToInlineCoordinates(context, boxRect); |
479 context.drawHighlightForText(font, textRun, FloatPoint(boxRect.location(
)), boxRect.height(), c, sPos, ePos); | 479 context.drawHighlightForText(font, textRun, FloatPoint(boxRect.location(
)), boxRect.height(), c, sPos, ePos); |
480 return; | 480 return; |
481 } | 481 } |
482 | 482 |
483 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); | 483 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); |
484 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTop(); | 484 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTop(); |
485 | 485 |
486 int deltaY = roundToInt(m_inlineTextBox.lineLayoutItem().style()->isFlippedL
inesWritingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inline
TextBox.logicalTop() - selectionTop); | 486 int deltaY = roundToInt(m_inlineTextBox.getLineLayoutItem().style()->isFlipp
edLinesWritingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inl
ineTextBox.logicalTop() - selectionTop); |
487 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); | 487 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); |
488 | 488 |
489 FloatPoint localOrigin(boxRect.x().toFloat(), (boxRect.y() - deltaY).toFloat
()); | 489 FloatPoint localOrigin(boxRect.x().toFloat(), (boxRect.y() - deltaY).toFloat
()); |
490 LayoutRect selectionRect = LayoutRect(font.selectionRectForText(textRun, loc
alOrigin, selHeight, sPos, ePos)); | 490 LayoutRect selectionRect = LayoutRect(font.selectionRectForText(textRun, loc
alOrigin, selHeight, sPos, ePos)); |
491 if (m_inlineTextBox.hasWrappedSelectionNewline() | 491 if (m_inlineTextBox.hasWrappedSelectionNewline() |
492 // For line breaks, just painting a selection where the line break itsel
f is rendered is sufficient. | 492 // For line breaks, just painting a selection where the line break itsel
f is rendered is sufficient. |
493 && !m_inlineTextBox.isLineBreak()) | 493 && !m_inlineTextBox.isLineBreak()) |
494 expandToIncludeNewlineForSelection(selectionRect); | 494 expandToIncludeNewlineForSelection(selectionRect); |
495 | 495 |
496 // Line breaks report themselves as having zero width for layout purposes, | 496 // Line breaks report themselves as having zero width for layout purposes, |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 if (m_inlineTextBox.truncation() == cFullTruncation) | 731 if (m_inlineTextBox.truncation() == cFullTruncation) |
732 return; | 732 return; |
733 | 733 |
734 GraphicsContext& context = paintInfo.context; | 734 GraphicsContext& context = paintInfo.context; |
735 GraphicsContextStateSaver stateSaver(context); | 735 GraphicsContextStateSaver stateSaver(context); |
736 | 736 |
737 LayoutPoint localOrigin(boxOrigin); | 737 LayoutPoint localOrigin(boxOrigin); |
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 = LayoutUnit(m_inlineTextBox.lineLayoutItem().width( | 741 width = LayoutUnit(m_inlineTextBox.getLineLayoutItem().width( |
742 m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextB
ox.textPos(), | 742 m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextB
ox.textPos(), |
743 m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBo
x.isFirstLineStyle())); | 743 m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBo
x.isFirstLineStyle())); |
744 if (!m_inlineTextBox.isLeftToRightDirection()) | 744 if (!m_inlineTextBox.isLeftToRightDirection()) |
745 localOrigin.move(m_inlineTextBox.logicalWidth() - width, LayoutUnit(
)); | 745 localOrigin.move(m_inlineTextBox.logicalWidth() - width, LayoutUnit(
)); |
746 } | 746 } |
747 | 747 |
748 // Get the text decoration colors. | 748 // Get the text decoration colors. |
749 LayoutObject::AppliedTextDecoration underline, overline, linethrough; | 749 LayoutObject::AppliedTextDecoration underline, overline, linethrough; |
750 LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObjectFrom(m_i
nlineTextBox.lineLayoutItem()); | 750 LayoutObject& textBoxLayoutObject = *LineLayoutAPIShim::layoutObjectFrom(m_i
nlineTextBox.getLineLayoutItem()); |
751 textBoxLayoutObject.getTextDecorations(deco, underline, overline, linethroug
h, true); | 751 textBoxLayoutObject.getTextDecorations(deco, underline, overline, linethroug
h, true); |
752 if (m_inlineTextBox.isFirstLineStyle()) | 752 if (m_inlineTextBox.isFirstLineStyle()) |
753 textBoxLayoutObject.getTextDecorations(deco, underline, overline, lineth
rough, true, true); | 753 textBoxLayoutObject.getTextDecorations(deco, underline, overline, lineth
rough, true, true); |
754 | 754 |
755 // Use a special function for underlines to get the positioning exactly righ
t. | 755 // Use a special function for underlines to get the positioning exactly righ
t. |
756 bool isPrinting = paintInfo.isPrinting(); | 756 bool isPrinting = paintInfo.isPrinting(); |
757 | 757 |
758 const ComputedStyle& styleToUse = textBoxLayoutObject.styleRef(m_inlineTextB
ox.isFirstLineStyle()); | 758 const ComputedStyle& styleToUse = textBoxLayoutObject.styleRef(m_inlineTextB
ox.isFirstLineStyle()); |
759 float baseline = styleToUse.fontMetrics().ascent(); | 759 float baseline = styleToUse.fontMetrics().ascent(); |
760 | 760 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 return; | 793 return; |
794 | 794 |
795 if (m_inlineTextBox.truncation() == cFullTruncation) | 795 if (m_inlineTextBox.truncation() == cFullTruncation) |
796 return; | 796 return; |
797 | 797 |
798 unsigned paintStart = underlinePaintStart(underline); | 798 unsigned paintStart = underlinePaintStart(underline); |
799 unsigned paintEnd = underlinePaintEnd(underline); | 799 unsigned paintEnd = underlinePaintEnd(underline); |
800 | 800 |
801 // start of line to draw | 801 // start of line to draw |
802 float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ?
0 : | 802 float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ?
0 : |
803 m_inlineTextBox.lineLayoutItem().width(m_inlineTextBox.start(), paintSta
rt - m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftT
oRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 803 m_inlineTextBox.getLineLayoutItem().width(m_inlineTextBox.start(), paint
Start - m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLe
ftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
804 // how much line to draw | 804 // how much line to draw |
805 float width = (paintStart == static_cast<unsigned>(m_inlineTextBox.start())
&& paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) ? m_inlineTextB
ox.logicalWidth().toFloat() : | 805 float width = (paintStart == static_cast<unsigned>(m_inlineTextBox.start())
&& paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) ? m_inlineTextB
ox.logicalWidth().toFloat() : |
806 m_inlineTextBox.lineLayoutItem().width(paintStart, paintEnd - paintStart
, LayoutUnit(m_inlineTextBox.textPos() + start), m_inlineTextBox.isLeftToRightDi
rection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 806 m_inlineTextBox.getLineLayoutItem().width(paintStart, paintEnd - paintSt
art, LayoutUnit(m_inlineTextBox.textPos() + start), m_inlineTextBox.isLeftToRigh
tDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
807 // In RTL mode, start and width are computed from the right end of the text
box: | 807 // In RTL mode, start and width are computed from the right end of the text
box: |
808 // starting at |logicalWidth| - |start| and continuing left by |width| to | 808 // starting at |logicalWidth| - |start| and continuing left by |width| to |
809 // |logicalWidth| - |start| - |width|. We will draw that line, but | 809 // |logicalWidth| - |start| - |width|. We will draw that line, but |
810 // backwards: |logicalWidth| - |start| - |width| to |logicalWidth| - |start|
. | 810 // backwards: |logicalWidth| - |start| - |width| to |logicalWidth| - |start|
. |
811 if (!m_inlineTextBox.isLeftToRightDirection()) | 811 if (!m_inlineTextBox.isLeftToRightDirection()) |
812 start = m_inlineTextBox.logicalWidth().toFloat() - width - start; | 812 start = m_inlineTextBox.logicalWidth().toFloat() - width - start; |
813 | 813 |
814 | 814 |
815 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. | 815 // Thick marked text underlines are 2px thick as long as there is room for t
he 2px line under the baseline. |
816 // All other marked text underlines are 1px thick. | 816 // All other marked text underlines are 1px thick. |
817 // If there's not enough space the underline will touch or overlap character
s. | 817 // If there's not enough space the underline will touch or overlap character
s. |
818 int lineThickness = 1; | 818 int lineThickness = 1; |
819 int baseline = m_inlineTextBox.lineLayoutItem().style(m_inlineTextBox.isFirs
tLineStyle())->fontMetrics().ascent(); | 819 int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isF
irstLineStyle())->fontMetrics().ascent(); |
820 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) | 820 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) |
821 lineThickness = 2; | 821 lineThickness = 2; |
822 | 822 |
823 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. | 823 // We need to have some space between underlines of subsequent clauses, beca
use some input methods do not use different underline styles for those. |
824 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. | 824 // We make each line shorter, which has a harmless side effect of shortening
the first and last clauses, too. |
825 start += 1; | 825 start += 1; |
826 width -= 2; | 826 width -= 2; |
827 | 827 |
828 context.setStrokeColor(underline.color); | 828 context.setStrokeColor(underline.color); |
829 context.setStrokeThickness(lineThickness); | 829 context.setStrokeThickness(lineThickness); |
830 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m
_inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB
ox.lineLayoutItem().document().printing()); | 830 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m
_inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB
ox.getLineLayoutItem().document().printing()); |
831 } | 831 } |
832 | 832 |
833 void InlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) | 833 void InlineTextBoxPainter::paintTextMatchMarkerForeground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) |
834 { | 834 { |
835 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())->
frame()->editor().markedTextMatchesAreHighlighted()) | 835 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.getLineLayoutItem()
)->frame()->editor().markedTextMatchesAreHighlighted()) |
836 return; | 836 return; |
837 | 837 |
838 // TODO(ramya.v): Extract this into a helper function and share many copies
of this code. | 838 // TODO(ramya.v): Extract this into a helper function and share many copies
of this code. |
839 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 839 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
840 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 840 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
841 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 841 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
842 | 842 |
843 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ
eMatch()); | 843 Color textColor = LayoutTheme::theme().platformTextSearchColor(marker->activ
eMatch()); |
844 if (style.visitedDependentColor(CSSPropertyColor) == textColor) | 844 if (style.visitedDependentColor(CSSPropertyColor) == textColor) |
845 return; | 845 return; |
846 TextPainter::Style textStyle; | 846 TextPainter::Style textStyle; |
847 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textS
tyle.emphasisMarkColor = textColor; | 847 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor = textS
tyle.emphasisMarkColor = textColor; |
848 textStyle.strokeWidth = style.textStrokeWidth(); | 848 textStyle.strokeWidth = style.textStrokeWidth(); |
849 textStyle.shadow = 0; | 849 textStyle.shadow = 0; |
850 | 850 |
851 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); | 851 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); |
852 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); | 852 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asc
ent()); |
853 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m
_inlineTextBox.isHorizontal()); | 853 TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m
_inlineTextBox.isHorizontal()); |
854 | 854 |
855 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); | 855 textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0); |
856 } | 856 } |
857 | 857 |
858 void InlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) | 858 void InlineTextBoxPainter::paintTextMatchMarkerBackground(const PaintInfo& paint
Info, const LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle&
style, const Font& font) |
859 { | 859 { |
860 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())->
frame()->editor().markedTextMatchesAreHighlighted()) | 860 if (!LineLayoutAPIShim::layoutObjectFrom(m_inlineTextBox.getLineLayoutItem()
)->frame()->editor().markedTextMatchesAreHighlighted()) |
861 return; | 861 return; |
862 | 862 |
863 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on | 863 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on |
864 // the same word there are no pieces sticking out. | 864 // the same word there are no pieces sticking out. |
865 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 865 int deltaY = m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWrit
ingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBo
ttom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
866 int selHeight = m_inlineTextBox.root().selectionHeight(); | 866 int selHeight = m_inlineTextBox.root().selectionHeight(); |
867 | 867 |
868 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 868 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
869 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 869 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
870 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 870 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
871 | 871 |
872 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker->
activeMatch()); | 872 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker->
activeMatch()); |
873 GraphicsContext& context = paintInfo.context; | 873 GraphicsContext& context = paintInfo.context; |
874 GraphicsContextStateSaver stateSaver(context); | 874 GraphicsContextStateSaver stateSaver(context); |
875 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toF
loat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); | 875 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toF
loat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); |
876 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(),
(boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); | 876 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(),
(boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); |
877 } | 877 } |
878 | 878 |
879 | 879 |
880 } // namespace blink | 880 } // namespace blink |
OLD | NEW |