OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/paint/InlineTextBoxPainter.h" | 6 #include "core/paint/InlineTextBoxPainter.h" |
7 | 7 |
8 #include "core/editing/CompositionUnderline.h" | 8 #include "core/editing/CompositionUnderline.h" |
9 #include "core/editing/Editor.h" | 9 #include "core/editing/Editor.h" |
10 #include "core/editing/markers/DocumentMarkerController.h" | 10 #include "core/editing/markers/DocumentMarkerController.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.selectionState() != SelectionNone; | 82 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
m_inlineTextBox.selectionState() != SelectionNone; |
83 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { | 83 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { |
84 // When only painting the selection, don't bother to paint if there is n
one. | 84 // When only painting the selection, don't bother to paint if there is n
one. |
85 return; | 85 return; |
86 } | 86 } |
87 | 87 |
88 // The text clip phase already has a LayoutObjectDrawingRecorder. Text clips
are initiated only in BoxPainter::paintLayerExtended, | 88 // The text clip phase already has a LayoutObjectDrawingRecorder. Text clips
are initiated only in BoxPainter::paintLayerExtended, |
89 // which is already within a LayoutObjectDrawingRecorder. | 89 // which is already within a LayoutObjectDrawingRecorder. |
90 Optional<DrawingRecorder> drawingRecorder; | 90 Optional<DrawingRecorder> drawingRecorder; |
91 if (paintInfo.phase != PaintPhaseTextClip) { | 91 if (paintInfo.phase != PaintPhaseTextClip) { |
92 if (DrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_in
lineTextBox, DisplayItem::paintPhaseToDrawingType(paintInfo.phase))) | 92 if (DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_inl
ineTextBox, DisplayItem::paintPhaseToDrawingType(paintInfo.phase))) |
93 return; | 93 return; |
94 LayoutRect paintRect(logicalVisualOverflow); | 94 LayoutRect paintRect(logicalVisualOverflow); |
95 m_inlineTextBox.logicalRectToPhysicalRect(paintRect); | 95 m_inlineTextBox.logicalRectToPhysicalRect(paintRect); |
96 if (paintInfo.phase != PaintPhaseSelection && (haveSelection || paintsMa
rkerHighlights(*LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayout
Item())))) | 96 if (paintInfo.phase != PaintPhaseSelection && (haveSelection || paintsMa
rkerHighlights(*LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayout
Item())))) |
97 paintRect.unite(m_inlineTextBox.localSelectionRect(m_inlineTextBox.s
tart(), m_inlineTextBox.start() + m_inlineTextBox.len())); | 97 paintRect.unite(m_inlineTextBox.localSelectionRect(m_inlineTextBox.s
tart(), m_inlineTextBox.start() + m_inlineTextBox.len())); |
98 paintRect.moveBy(adjustedPaintOffset); | 98 paintRect.moveBy(adjustedPaintOffset); |
99 drawingRecorder.emplace(*paintInfo.context, m_inlineTextBox, DisplayItem
::paintPhaseToDrawingType(paintInfo.phase), FloatRect(paintRect)); | 99 drawingRecorder.emplace(paintInfo.context, m_inlineTextBox, DisplayItem:
:paintPhaseToDrawingType(paintInfo.phase), FloatRect(paintRect)); |
100 } | 100 } |
101 | 101 |
102 if (m_inlineTextBox.truncation() != cNoTruncation) { | 102 if (m_inlineTextBox.truncation() != cNoTruncation) { |
103 if (m_inlineTextBox.lineLayoutItem().containingBlock().style()->isLeftTo
RightDirection() != m_inlineTextBox.isLeftToRightDirection()) { | 103 if (m_inlineTextBox.lineLayoutItem().containingBlock().style()->isLeftTo
RightDirection() != m_inlineTextBox.isLeftToRightDirection()) { |
104 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin | 104 // Make the visible fragment of text hug the edge closest to the res
t of the run by moving the origin |
105 // at which we start drawing text. | 105 // at which we start drawing text. |
106 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: | 106 // e.g. In the case of LTR text truncated in an RTL Context, the cor
rect behavior is: |
107 // |Hello|CBA| -> |...He|CBA| | 107 // |Hello|CBA| -> |...He|CBA| |
108 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing | 108 // In order to draw the fragment "He" aligned to the right edge of i
t's box, we need to start drawing |
109 // farther to the right. | 109 // farther to the right. |
110 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the | 110 // NOTE: WebKit's behavior differs from that of IE which appears to
just overlay the ellipsis on top of the |
111 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| | 111 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| |
112 LayoutUnit widthOfVisibleText = m_inlineTextBox.lineLayoutItem().wid
th(m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextBox.textPo
s(), m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFir
stLineStyle()); | 112 LayoutUnit widthOfVisibleText = m_inlineTextBox.lineLayoutItem().wid
th(m_inlineTextBox.start(), m_inlineTextBox.truncation(), m_inlineTextBox.textPo
s(), m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFir
stLineStyle()); |
113 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; | 113 LayoutUnit widthOfHiddenText = m_inlineTextBox.logicalWidth() - widt
hOfVisibleText; |
114 // FIXME: The hit testing logic also needs to take this translation
into account. | 114 // FIXME: The hit testing logic also needs to take this translation
into account. |
115 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, 0); | 115 LayoutSize truncationOffset(m_inlineTextBox.isLeftToRightDirection()
? widthOfHiddenText : -widthOfHiddenText, 0); |
116 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); | 116 adjustedPaintOffset.move(m_inlineTextBox.isHorizontal() ? truncation
Offset : truncationOffset.transposedSize()); |
117 } | 117 } |
118 } | 118 } |
119 | 119 |
120 GraphicsContext* context = paintInfo.context; | 120 GraphicsContext& context = paintInfo.context; |
121 const ComputedStyle& styleToUse = m_inlineTextBox.lineLayoutItem().styleRef(
m_inlineTextBox.isFirstLineStyle()); | 121 const ComputedStyle& styleToUse = m_inlineTextBox.lineLayoutItem().styleRef(
m_inlineTextBox.isFirstLineStyle()); |
122 | 122 |
123 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); | 123 LayoutPoint boxOrigin(m_inlineTextBox.locationIncludingFlipping()); |
124 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); | 124 boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y()); |
125 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); | 125 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i
nlineTextBox.logicalHeight())); |
126 | 126 |
127 bool shouldRotate = false; | 127 bool shouldRotate = false; |
128 LayoutTextCombine* combinedText = nullptr; | 128 LayoutTextCombine* combinedText = nullptr; |
129 if (!m_inlineTextBox.isHorizontal()) { | 129 if (!m_inlineTextBox.isHorizontal()) { |
130 if (styleToUse.hasTextCombine() && m_inlineTextBox.lineLayoutItem().isCo
mbineText()) { | 130 if (styleToUse.hasTextCombine() && m_inlineTextBox.lineLayoutItem().isCo
mbineText()) { |
131 combinedText = &toLayoutTextCombine(*LineLayoutPaintShim::layoutObje
ctFrom(m_inlineTextBox.lineLayoutItem())); | 131 combinedText = &toLayoutTextCombine(*LineLayoutPaintShim::layoutObje
ctFrom(m_inlineTextBox.lineLayoutItem())); |
132 if (!combinedText->isCombined()) | 132 if (!combinedText->isCombined()) |
133 combinedText = nullptr; | 133 combinedText = nullptr; |
134 } | 134 } |
135 if (combinedText) { | 135 if (combinedText) { |
136 combinedText->updateFont(); | 136 combinedText->updateFont(); |
137 boxRect.setWidth(combinedText->inlineWidthForLayout()); | 137 boxRect.setWidth(combinedText->inlineWidthForLayout()); |
138 } else { | 138 } else { |
139 shouldRotate = true; | 139 shouldRotate = true; |
140 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Clock
wise)); | 140 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 // Determine text colors. | 144 // Determine text colors. |
145 const LayoutObject& textBoxLayoutObject = *LineLayoutPaintShim::layoutObject
From(m_inlineTextBox.lineLayoutItem()); | 145 const LayoutObject& textBoxLayoutObject = *LineLayoutPaintShim::layoutObject
From(m_inlineTextBox.lineLayoutItem()); |
146 TextPainter::Style textStyle = TextPainter::textPaintingStyle(textBoxLayoutO
bject, styleToUse, paintInfo); | 146 TextPainter::Style textStyle = TextPainter::textPaintingStyle(textBoxLayoutO
bject, styleToUse, paintInfo); |
147 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(text
BoxLayoutObject, haveSelection, paintInfo, textStyle); | 147 TextPainter::Style selectionStyle = TextPainter::selectionPaintingStyle(text
BoxLayoutObject, 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 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 bool textBlobIsCacheable = selectionStart == 0 && selectionEnd == length
; | 226 bool textBlobIsCacheable = selectionStart == 0 && selectionEnd == length
; |
227 TextBlobPtr* cachedTextBlob = 0; | 227 TextBlobPtr* cachedTextBlob = 0; |
228 if (textBlobIsCacheable) | 228 if (textBlobIsCacheable) |
229 cachedTextBlob = addToTextBlobCache(m_inlineTextBox); | 229 cachedTextBlob = addToTextBlobCache(m_inlineTextBox); |
230 textPainter.paint(selectionStart, selectionEnd, length, selectionStyle,
cachedTextBlob); | 230 textPainter.paint(selectionStart, selectionEnd, length, selectionStyle,
cachedTextBlob); |
231 } | 231 } |
232 | 232 |
233 // Paint decorations | 233 // Paint decorations |
234 TextDecoration textDecorations = styleToUse.textDecorationsInEffect(); | 234 TextDecoration textDecorations = styleToUse.textDecorationsInEffect(); |
235 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { | 235 if (textDecorations != TextDecorationNone && !paintSelectedTextOnly) { |
236 GraphicsContextStateSaver stateSaver(*context, false); | 236 GraphicsContextStateSaver stateSaver(context, false); |
237 TextPainter::updateGraphicsContext(context, textStyle, m_inlineTextBox.i
sHorizontal(), stateSaver); | 237 TextPainter::updateGraphicsContext(context, textStyle, m_inlineTextBox.i
sHorizontal(), stateSaver); |
238 if (combinedText) | 238 if (combinedText) |
239 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Clock
wise)); | 239 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Clockw
ise)); |
240 paintDecoration(paintInfo, boxOrigin, textDecorations); | 240 paintDecoration(paintInfo, boxOrigin, textDecorations); |
241 if (combinedText) | 241 if (combinedText) |
242 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Count
erclockwise)); | 242 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counte
rclockwise)); |
243 } | 243 } |
244 | 244 |
245 if (paintInfo.phase == PaintPhaseForeground) | 245 if (paintInfo.phase == PaintPhaseForeground) |
246 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); | 246 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
247 | 247 |
248 if (shouldRotate) | 248 if (shouldRotate) |
249 context->concatCTM(TextPainter::rotation(boxRect, TextPainter::Countercl
ockwise)); | 249 context.concatCTM(TextPainter::rotation(boxRect, TextPainter::Counterclo
ckwise)); |
250 } | 250 } |
251 | 251 |
252 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) | 252 bool InlineTextBoxPainter::shouldPaintTextBox(const PaintInfo& paintInfo) |
253 { | 253 { |
254 // When painting selection, we want to include a highlight when the | 254 // When painting selection, we want to include a highlight when the |
255 // selection spans line breaks. In other cases such as invisible elements | 255 // selection spans line breaks. In other cases such as invisible elements |
256 // or those with no text that are not line breaks, we can skip painting | 256 // or those with no text that are not line breaks, we can skip painting |
257 // wholesale. | 257 // wholesale. |
258 // TODO(wkorman): Constrain line break painting to appropriate paint phase. | 258 // TODO(wkorman): Constrain line break painting to appropriate paint phase. |
259 // This code path is only called in PaintPhaseForeground whereas we would | 259 // This code path is only called in PaintPhaseForeground whereas we would |
(...skipping 15 matching lines...) Expand all Loading... |
275 } | 275 } |
276 | 276 |
277 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und
erline) | 277 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und
erline) |
278 { | 278 { |
279 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. | 279 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset)
; // end() points at the last char, not past it. |
280 if (m_inlineTextBox.truncation() != cNoTruncation) | 280 if (m_inlineTextBox.truncation() != cNoTruncation) |
281 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); | 281 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star
t() + m_inlineTextBox.truncation())); |
282 return paintEnd; | 282 return paintEnd; |
283 } | 283 } |
284 | 284 |
285 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext*
context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f
ont, Color backgroundColor, int startPos, int endPos) | 285 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext&
context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f
ont, Color backgroundColor, int startPos, int endPos) |
286 { | 286 { |
287 if (backgroundColor == Color::transparent) | 287 if (backgroundColor == Color::transparent) |
288 return; | 288 return; |
289 | 289 |
290 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; | 290 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0)
; |
291 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); | 291 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat
ic_cast<int>(m_inlineTextBox.len())); |
292 if (sPos >= ePos) | 292 if (sPos >= ePos) |
293 return; | 293 return; |
294 | 294 |
295 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 295 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
296 int selHeight = m_inlineTextBox.root().selectionHeight(); | 296 int selHeight = m_inlineTextBox.root().selectionHeight(); |
297 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de
ltaY); | 297 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de
ltaY); |
298 context->drawHighlightForText(font, m_inlineTextBox.constructTextRun(style,
font), localOrigin, selHeight, backgroundColor, sPos, ePos); | 298 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style, f
ont), localOrigin, selHeight, backgroundColor, sPos, ePos); |
299 } | 299 } |
300 | 300 |
301 void InlineTextBoxPainter::paintDocumentMarkers(GraphicsContext* pt, const Layou
tPoint& boxOrigin, const ComputedStyle& style, const Font& font, bool background
) | 301 void InlineTextBoxPainter::paintDocumentMarkers(GraphicsContext& context, const
LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, bool backg
round) |
302 { | 302 { |
303 if (!m_inlineTextBox.lineLayoutItem().node()) | 303 if (!m_inlineTextBox.lineLayoutItem().node()) |
304 return; | 304 return; |
305 | 305 |
306 DocumentMarkerVector markers = m_inlineTextBox.lineLayoutItem().document().m
arkers().markersFor(m_inlineTextBox.lineLayoutItem().node()); | 306 DocumentMarkerVector markers = m_inlineTextBox.lineLayoutItem().document().m
arkers().markersFor(m_inlineTextBox.lineLayoutItem().node()); |
307 DocumentMarkerVector::const_iterator markerIt = markers.begin(); | 307 DocumentMarkerVector::const_iterator markerIt = markers.begin(); |
308 | 308 |
309 // Give any document markers that touch this run a chance to draw before the
text has been drawn. | 309 // Give any document markers that touch this run a chance to draw before the
text has been drawn. |
310 // Note end() points at the last char, not one past it like endOffset and ra
nges do. | 310 // Note end() points at the last char, not one past it like endOffset and ra
nges do. |
311 for ( ; markerIt != markers.end(); ++markerIt) { | 311 for ( ; markerIt != markers.end(); ++markerIt) { |
(...skipping 22 matching lines...) Expand all Loading... |
334 continue; | 334 continue; |
335 } | 335 } |
336 if (marker->startOffset() > m_inlineTextBox.end()) { | 336 if (marker->startOffset() > m_inlineTextBox.end()) { |
337 // marker is completely after this run, bail. A later run will pain
t it. | 337 // marker is completely after this run, bail. A later run will pain
t it. |
338 break; | 338 break; |
339 } | 339 } |
340 | 340 |
341 // marker intersects this run. Paint it. | 341 // marker intersects this run. Paint it. |
342 switch (marker->type()) { | 342 switch (marker->type()) { |
343 case DocumentMarker::Spelling: | 343 case DocumentMarker::Spelling: |
344 m_inlineTextBox.paintDocumentMarker(pt, boxOrigin, marker, style, fo
nt, false); | 344 m_inlineTextBox.paintDocumentMarker(context, boxOrigin, marker, styl
e, font, false); |
345 break; | 345 break; |
346 case DocumentMarker::Grammar: | 346 case DocumentMarker::Grammar: |
347 m_inlineTextBox.paintDocumentMarker(pt, boxOrigin, marker, style, fo
nt, true); | 347 m_inlineTextBox.paintDocumentMarker(context, boxOrigin, marker, styl
e, font, true); |
348 break; | 348 break; |
349 case DocumentMarker::TextMatch: | 349 case DocumentMarker::TextMatch: |
350 m_inlineTextBox.paintTextMatchMarker(pt, boxOrigin, marker, style, f
ont); | 350 m_inlineTextBox.paintTextMatchMarker(context, boxOrigin, marker, sty
le, font); |
351 break; | 351 break; |
352 case DocumentMarker::Composition: | 352 case DocumentMarker::Composition: |
353 { | 353 { |
354 CompositionUnderline underline(marker->startOffset(), marker->en
dOffset(), marker->underlineColor(), marker->thick(), marker->backgroundColor())
; | 354 CompositionUnderline underline(marker->startOffset(), marker->en
dOffset(), marker->underlineColor(), marker->thick(), marker->backgroundColor())
; |
355 if (background) | 355 if (background) |
356 paintSingleCompositionBackgroundRun(pt, boxOrigin, style, fo
nt, underline.backgroundColor, underlinePaintStart(underline), underlinePaintEnd
(underline)); | 356 paintSingleCompositionBackgroundRun(context, boxOrigin, styl
e, font, underline.backgroundColor, underlinePaintStart(underline), underlinePai
ntEnd(underline)); |
357 else | 357 else |
358 paintCompositionUnderline(pt, boxOrigin, underline); | 358 paintCompositionUnderline(context, boxOrigin, underline); |
359 } | 359 } |
360 break; | 360 break; |
361 default: | 361 default: |
362 ASSERT_NOT_REACHED(); | 362 ASSERT_NOT_REACHED(); |
363 } | 363 } |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) | 367 static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
arker::MarkerType markerType) |
368 { | 368 { |
369 switch (markerType) { | 369 switch (markerType) { |
370 case DocumentMarker::Spelling: | 370 case DocumentMarker::Spelling: |
371 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 371 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
372 case DocumentMarker::Grammar: | 372 case DocumentMarker::Grammar: |
373 return GraphicsContext::DocumentMarkerGrammarLineStyle; | 373 return GraphicsContext::DocumentMarkerGrammarLineStyle; |
374 default: | 374 default: |
375 ASSERT_NOT_REACHED(); | 375 ASSERT_NOT_REACHED(); |
376 return GraphicsContext::DocumentMarkerSpellingLineStyle; | 376 return GraphicsContext::DocumentMarkerSpellingLineStyle; |
377 } | 377 } |
378 } | 378 } |
379 | 379 |
380 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext* pt, const Layout
Point& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Font
& font, bool grammar) | 380 void InlineTextBoxPainter::paintDocumentMarker(GraphicsContext& context, const L
ayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const
Font& font, bool grammar) |
381 { | 381 { |
382 // Never print spelling/grammar markers (5327887) | 382 // Never print spelling/grammar markers (5327887) |
383 if (m_inlineTextBox.lineLayoutItem().document().printing()) | 383 if (m_inlineTextBox.lineLayoutItem().document().printing()) |
384 return; | 384 return; |
385 | 385 |
386 if (m_inlineTextBox.truncation() == cFullTruncation) | 386 if (m_inlineTextBox.truncation() == cFullTruncation) |
387 return; | 387 return; |
388 | 388 |
389 LayoutUnit start = 0; // start of line to draw, relative to tx | 389 LayoutUnit start = 0; // start of line to draw, relative to tx |
390 LayoutUnit width = m_inlineTextBox.logicalWidth(); // how much line to draw | 390 LayoutUnit width = m_inlineTextBox.logicalWidth(); // how much line to draw |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 int baseline = m_inlineTextBox.lineLayoutItem().style(m_inlineTextBox.isFirs
tLineStyle())->fontMetrics().ascent(); | 427 int baseline = m_inlineTextBox.lineLayoutItem().style(m_inlineTextBox.isFirs
tLineStyle())->fontMetrics().ascent(); |
428 int descent = m_inlineTextBox.logicalHeight() - baseline; | 428 int descent = m_inlineTextBox.logicalHeight() - baseline; |
429 int underlineOffset; | 429 int underlineOffset; |
430 if (descent <= (lineThickness + 2)) { | 430 if (descent <= (lineThickness + 2)) { |
431 // Place the underline at the very bottom of the text in small/medium fo
nts. | 431 // Place the underline at the very bottom of the text in small/medium fo
nts. |
432 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; | 432 underlineOffset = m_inlineTextBox.logicalHeight() - lineThickness; |
433 } else { | 433 } else { |
434 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. | 434 // In larger fonts, though, place the underline up near the baseline to
prevent a big gap. |
435 underlineOffset = baseline + 2; | 435 underlineOffset = baseline + 2; |
436 } | 436 } |
437 pt->drawLineForDocumentMarker(FloatPoint((boxOrigin.x() + start).toFloat(),
(boxOrigin.y() + underlineOffset).toFloat()), width.toFloat(), lineStyleForMarke
rType(marker->type())); | 437 context.drawLineForDocumentMarker(FloatPoint((boxOrigin.x() + start).toFloat
(), (boxOrigin.y() + underlineOffset).toFloat()), width.toFloat(), lineStyleForM
arkerType(marker->type())); |
438 } | 438 } |
439 | 439 |
440 template <InlineTextBoxPainter::PaintOptions options> | 440 template <InlineTextBoxPainter::PaintOptions options> |
441 void InlineTextBoxPainter::paintSelection(GraphicsContext* context, const Layout
Rect& boxRect, const ComputedStyle& style, const Font& font, Color textColor, La
youtTextCombine* combinedText) | 441 void InlineTextBoxPainter::paintSelection(GraphicsContext& context, const Layout
Rect& boxRect, const ComputedStyle& style, const Font& font, Color textColor, La
youtTextCombine* combinedText) |
442 { | 442 { |
443 // See if we have a selection to paint at all. | 443 // See if we have a selection to paint at all. |
444 int sPos, ePos; | 444 int sPos, ePos; |
445 m_inlineTextBox.selectionStartEnd(sPos, ePos); | 445 m_inlineTextBox.selectionStartEnd(sPos, ePos); |
446 if (sPos >= ePos) | 446 if (sPos >= ePos) |
447 return; | 447 return; |
448 | 448 |
449 Color c = m_inlineTextBox.lineLayoutItem().selectionBackgroundColor(); | 449 Color c = m_inlineTextBox.lineLayoutItem().selectionBackgroundColor(); |
450 if (!c.alpha()) | 450 if (!c.alpha()) |
451 return; | 451 return; |
(...skipping 10 matching lines...) Expand all Loading... |
462 | 462 |
463 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) | 463 if (string.length() != static_cast<unsigned>(length) || m_inlineTextBox.star
t()) |
464 string.narrow(m_inlineTextBox.start(), length); | 464 string.narrow(m_inlineTextBox.start(), length); |
465 | 465 |
466 StringBuilder charactersWithHyphen; | 466 StringBuilder charactersWithHyphen; |
467 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); | 467 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); |
468 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.lineLayoutItem().textLength() - m_inlineTextBox.start(), respectHyph
en ? &charactersWithHyphen : 0); | 468 TextRun textRun = m_inlineTextBox.constructTextRun(style, font, string, m_in
lineTextBox.lineLayoutItem().textLength() - m_inlineTextBox.start(), respectHyph
en ? &charactersWithHyphen : 0); |
469 if (respectHyphen) | 469 if (respectHyphen) |
470 ePos = textRun.length(); | 470 ePos = textRun.length(); |
471 | 471 |
472 GraphicsContextStateSaver stateSaver(*context); | 472 GraphicsContextStateSaver stateSaver(context); |
473 | 473 |
474 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { | 474 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { |
475 ASSERT(combinedText); | 475 ASSERT(combinedText); |
476 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow | 476 // We can't use the height of m_inlineTextBox because LayoutTextCombine'
s inlineTextBox is horizontal within vertical flow |
477 LayoutRect clipRect(boxRect); | 477 LayoutRect clipRect(boxRect); |
478 combinedText->transformLayoutRect(clipRect); | 478 combinedText->transformLayoutRect(clipRect); |
479 context->clip(FloatRect(clipRect)); | 479 context.clip(FloatRect(clipRect)); |
480 combinedText->transformToInlineCoordinates(*context, boxRect); | 480 combinedText->transformToInlineCoordinates(context, boxRect); |
481 context->drawHighlightForText(font, textRun, FloatPoint(boxRect.location
()), boxRect.height(), c, sPos, ePos); | 481 context.drawHighlightForText(font, textRun, FloatPoint(boxRect.location(
)), boxRect.height(), c, sPos, ePos); |
482 return; | 482 return; |
483 } | 483 } |
484 | 484 |
485 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); | 485 LayoutUnit selectionBottom = m_inlineTextBox.root().selectionBottom(); |
486 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTopAdjustedForPrec
edingBlock(); | 486 LayoutUnit selectionTop = m_inlineTextBox.root().selectionTopAdjustedForPrec
edingBlock(); |
487 | 487 |
488 int deltaY = roundToInt(m_inlineTextBox.lineLayoutItem().style()->isFlippedL
inesWritingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inline
TextBox.logicalTop() - selectionTop); | 488 int deltaY = roundToInt(m_inlineTextBox.lineLayoutItem().style()->isFlippedL
inesWritingMode() ? selectionBottom - m_inlineTextBox.logicalBottom() : m_inline
TextBox.logicalTop() - selectionTop); |
489 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); | 489 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); |
490 | 490 |
491 FloatPoint localOrigin(boxRect.x().toFloat(), (boxRect.y() - deltaY).toFloat
()); | 491 FloatPoint localOrigin(boxRect.x().toFloat(), (boxRect.y() - deltaY).toFloat
()); |
492 LayoutRect selectionRect = LayoutRect(font.selectionRectForText(textRun, loc
alOrigin, selHeight, sPos, ePos)); | 492 LayoutRect selectionRect = LayoutRect(font.selectionRectForText(textRun, loc
alOrigin, selHeight, sPos, ePos)); |
493 if (m_inlineTextBox.hasWrappedSelectionNewline() | 493 if (m_inlineTextBox.hasWrappedSelectionNewline() |
494 // For line breaks, just painting a selection where the line break itsel
f is rendered is sufficient. | 494 // For line breaks, just painting a selection where the line break itsel
f is rendered is sufficient. |
495 && !m_inlineTextBox.isLineBreak()) | 495 && !m_inlineTextBox.isLineBreak()) |
496 expandToIncludeNewlineForSelection(selectionRect); | 496 expandToIncludeNewlineForSelection(selectionRect); |
497 | 497 |
498 // Line breaks report themselves as having zero width for layout purposes, | 498 // Line breaks report themselves as having zero width for layout purposes, |
499 // and so will end up positioned at (0, 0), even though we paint their | 499 // and so will end up positioned at (0, 0), even though we paint their |
500 // selection highlight with character width. For RTL then, we have to | 500 // selection highlight with character width. For RTL then, we have to |
501 // explicitly shift the selection rect over to paint in the right location. | 501 // explicitly shift the selection rect over to paint in the right location. |
502 if (!m_inlineTextBox.isLeftToRightDirection() && m_inlineTextBox.isLineBreak
()) | 502 if (!m_inlineTextBox.isLeftToRightDirection() && m_inlineTextBox.isLineBreak
()) |
503 selectionRect.move(-selectionRect.width(), 0); | 503 selectionRect.move(-selectionRect.width(), 0); |
504 | 504 |
505 context->fillRect(FloatRect(selectionRect), c); | 505 context.fillRect(FloatRect(selectionRect), c); |
506 } | 506 } |
507 | 507 |
508 void InlineTextBoxPainter::expandToIncludeNewlineForSelection(LayoutRect& rect) | 508 void InlineTextBoxPainter::expandToIncludeNewlineForSelection(LayoutRect& rect) |
509 { | 509 { |
510 FloatRectOutsets outsets = FloatRectOutsets(); | 510 FloatRectOutsets outsets = FloatRectOutsets(); |
511 float spaceWidth = m_inlineTextBox.newlineSpaceWidth(); | 511 float spaceWidth = m_inlineTextBox.newlineSpaceWidth(); |
512 if (m_inlineTextBox.isLeftToRightDirection()) | 512 if (m_inlineTextBox.isLeftToRightDirection()) |
513 outsets.setRight(spaceWidth); | 513 outsets.setRight(spaceWidth); |
514 else | 514 else |
515 outsets.setLeft(spaceWidth); | 515 outsets.setLeft(spaceWidth); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 * . . | | 622 * . . | |
623 * . . | controlPointDistance | 623 * . . | controlPointDistance |
624 * | | 624 * | |
625 * | | 625 * | |
626 * + - | 626 * + - |
627 * controlPoint2 | 627 * controlPoint2 |
628 * | 628 * |
629 * |-----------| | 629 * |-----------| |
630 * step | 630 * step |
631 */ | 631 */ |
632 static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, Fl
oatPoint p2, float strokeThickness) | 632 static void strokeWavyTextDecoration(GraphicsContext& context, FloatPoint p1, Fl
oatPoint p2, float strokeThickness) |
633 { | 633 { |
634 context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strok
eStyle()); | 634 context.adjustLineToPixelBoundaries(p1, p2, strokeThickness, context.strokeS
tyle()); |
635 | 635 |
636 Path path; | 636 Path path; |
637 path.moveTo(p1); | 637 path.moveTo(p1); |
638 | 638 |
639 // Distance between decoration's axis and Bezier curve's control points. | 639 // Distance between decoration's axis and Bezier curve's control points. |
640 // The height of the curve is based on this distance. Use a minimum of 6 pix
els distance since | 640 // The height of the curve is based on this distance. Use a minimum of 6 pix
els distance since |
641 // the actual curve passes approximately at half of that distance, that is 3
pixels. | 641 // the actual curve passes approximately at half of that distance, that is 3
pixels. |
642 // The minimum height of the curve is also approximately 3 pixels. Increases
the curve's height | 642 // The minimum height of the curve is also approximately 3 pixels. Increases
the curve's height |
643 // as strockThickness increases to make the curve looks better. | 643 // as strockThickness increases to make the curve looks better. |
644 float controlPointDistance = 3 * std::max<float>(2, strokeThickness); | 644 float controlPointDistance = 3 * std::max<float>(2, strokeThickness); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 FloatPoint controlPoint2(0, yAxis - controlPointDistance); | 695 FloatPoint controlPoint2(0, yAxis - controlPointDistance); |
696 | 696 |
697 for (float x = x1; x + 2 * step <= x2;) { | 697 for (float x = x1; x + 2 * step <= x2;) { |
698 controlPoint1.setX(x + step); | 698 controlPoint1.setX(x + step); |
699 controlPoint2.setX(x + step); | 699 controlPoint2.setX(x + step); |
700 x += 2 * step; | 700 x += 2 * step; |
701 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); | 701 path.addBezierCurveTo(controlPoint1, controlPoint2, FloatPoint(x, yA
xis)); |
702 } | 702 } |
703 } | 703 } |
704 | 704 |
705 context->setShouldAntialias(true); | 705 context.setShouldAntialias(true); |
706 context->strokePath(path); | 706 context.strokePath(path); |
707 } | 707 } |
708 | 708 |
709 static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, f
loat width, float doubleOffset, int wavyOffsetFactor, | 709 static void paintAppliedDecoration(GraphicsContext& context, FloatPoint start, f
loat width, float doubleOffset, int wavyOffsetFactor, |
710 LayoutObject::AppliedTextDecoration decoration, float thickness, bool antial
iasDecoration, bool isPrinting) | 710 LayoutObject::AppliedTextDecoration decoration, float thickness, bool antial
iasDecoration, bool isPrinting) |
711 { | 711 { |
712 context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style)); | 712 context.setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style)); |
713 context->setStrokeColor(decoration.color); | 713 context.setStrokeColor(decoration.color); |
714 | 714 |
715 switch (decoration.style) { | 715 switch (decoration.style) { |
716 case TextDecorationStyleWavy: | 716 case TextDecorationStyleWavy: |
717 strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * w
avyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), th
ickness); | 717 strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * w
avyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), th
ickness); |
718 break; | 718 break; |
719 case TextDecorationStyleDotted: | 719 case TextDecorationStyleDotted: |
720 case TextDecorationStyleDashed: | 720 case TextDecorationStyleDashed: |
721 context->setShouldAntialias(antialiasDecoration); | 721 context.setShouldAntialias(antialiasDecoration); |
722 // Fall through | 722 // Fall through |
723 default: | 723 default: |
724 context->drawLineForText(FloatPoint(start), width, isPrinting); | 724 context.drawLineForText(FloatPoint(start), width, isPrinting); |
725 | 725 |
726 if (decoration.style == TextDecorationStyleDouble) | 726 if (decoration.style == TextDecorationStyleDouble) |
727 context->drawLineForText(start + FloatPoint(0, doubleOffset), width,
isPrinting); | 727 context.drawLineForText(start + FloatPoint(0, doubleOffset), width,
isPrinting); |
728 } | 728 } |
729 } | 729 } |
730 | 730 |
731 void InlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, const Lay
outPoint& boxOrigin, TextDecoration deco) | 731 void InlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, const Lay
outPoint& boxOrigin, TextDecoration deco) |
732 { | 732 { |
733 if (m_inlineTextBox.truncation() == cFullTruncation) | 733 if (m_inlineTextBox.truncation() == cFullTruncation) |
734 return; | 734 return; |
735 | 735 |
736 GraphicsContext* context = paintInfo.context; | 736 GraphicsContext& context = paintInfo.context; |
737 GraphicsContextStateSaver stateSaver(*context); | 737 GraphicsContextStateSaver stateSaver(context); |
738 | 738 |
739 LayoutPoint localOrigin(boxOrigin); | 739 LayoutPoint localOrigin(boxOrigin); |
740 | 740 |
741 LayoutUnit width = m_inlineTextBox.logicalWidth(); | 741 LayoutUnit width = m_inlineTextBox.logicalWidth(); |
742 if (m_inlineTextBox.truncation() != cNoTruncation) { | 742 if (m_inlineTextBox.truncation() != cNoTruncation) { |
743 width = m_inlineTextBox.lineLayoutItem().width(m_inlineTextBox.start(),
m_inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftT
oRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 743 width = m_inlineTextBox.lineLayoutItem().width(m_inlineTextBox.start(),
m_inlineTextBox.truncation(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftT
oRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
744 if (!m_inlineTextBox.isLeftToRightDirection()) | 744 if (!m_inlineTextBox.isLeftToRightDirection()) |
745 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); | 745 localOrigin.move(m_inlineTextBox.logicalWidth() - width, 0); |
746 } | 746 } |
747 | 747 |
(...skipping 12 matching lines...) Expand all Loading... |
760 | 760 |
761 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. | 761 // Set the thick of the line to be 10% (or something else ?)of the computed
font size and not less than 1px. |
762 // Using computedFontSize should take care of zoom as well. | 762 // Using computedFontSize should take care of zoom as well. |
763 | 763 |
764 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. | 764 // Update Underline thickness, in case we have Faulty Font Metrics calculati
ng underline thickness by old method. |
765 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness(
); | 765 float textDecorationThickness = styleToUse.fontMetrics().underlineThickness(
); |
766 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5); | 766 int fontHeightInt = (int)(styleToUse.fontMetrics().floatHeight() + 0.5); |
767 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) | 767 if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHei
ghtInt >> 1))) |
768 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() /
10.f); | 768 textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() /
10.f); |
769 | 769 |
770 context->setStrokeThickness(textDecorationThickness); | 770 context.setStrokeThickness(textDecorationThickness); |
771 | 771 |
772 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde
rline.style, linethrough.style); | 772 bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, unde
rline.style, linethrough.style); |
773 | 773 |
774 // Offset between lines - always non-zero, so lines never cross each other. | 774 // Offset between lines - always non-zero, so lines never cross each other. |
775 float doubleOffset = textDecorationThickness + 1.f; | 775 float doubleOffset = textDecorationThickness + 1.f; |
776 | 776 |
777 if (deco & TextDecorationUnderline) { | 777 if (deco & TextDecorationUnderline) { |
778 const int underlineOffset = computeUnderlineOffset(styleToUse.textUnderl
inePosition(), styleToUse.fontMetrics(), &m_inlineTextBox, textDecorationThickne
ss); | 778 const int underlineOffset = computeUnderlineOffset(styleToUse.textUnderl
inePosition(), styleToUse.fontMetrics(), &m_inlineTextBox, textDecorationThickne
ss); |
779 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0,
underlineOffset), width.toFloat(), doubleOffset, 1, underline, textDecorationThi
ckness, antialiasDecoration, isPrinting); | 779 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0,
underlineOffset), width.toFloat(), doubleOffset, 1, underline, textDecorationThi
ckness, antialiasDecoration, isPrinting); |
780 } | 780 } |
781 if (deco & TextDecorationOverline) { | 781 if (deco & TextDecorationOverline) { |
782 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFloat()
, -doubleOffset, 1, overline, textDecorationThickness, antialiasDecoration, isPr
inting); | 782 paintAppliedDecoration(context, FloatPoint(localOrigin), width.toFloat()
, -doubleOffset, 1, overline, textDecorationThickness, antialiasDecoration, isPr
inting); |
783 } | 783 } |
784 if (deco & TextDecorationLineThrough) { | 784 if (deco & TextDecorationLineThrough) { |
785 const float lineThroughOffset = 2 * baseline / 3; | 785 const float lineThroughOffset = 2 * baseline / 3; |
786 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0,
lineThroughOffset), width.toFloat(), doubleOffset, 0, linethrough, textDecoratio
nThickness, antialiasDecoration, isPrinting); | 786 paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0,
lineThroughOffset), width.toFloat(), doubleOffset, 0, linethrough, textDecoratio
nThickness, antialiasDecoration, isPrinting); |
787 } | 787 } |
788 } | 788 } |
789 | 789 |
790 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext* ctx, const
LayoutPoint& boxOrigin, const CompositionUnderline& underline) | 790 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext& context, c
onst LayoutPoint& boxOrigin, const CompositionUnderline& underline) |
791 { | 791 { |
792 if (underline.color == Color::transparent) | 792 if (underline.color == Color::transparent) |
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 |
(...skipping 17 matching lines...) Expand all Loading... |
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.lineLayoutItem().style(m_inlineTextBox.isFirs
tLineStyle())->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 ctx->setStrokeColor(underline.color); | 828 context.setStrokeColor(underline.color); |
829 ctx->setStrokeThickness(lineThickness); | 829 context.setStrokeThickness(lineThickness); |
830 ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m_in
lineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextBox.
lineLayoutItem().document().printing()); | 830 context.drawLineForText(FloatPoint(boxOrigin.x() + start, (boxOrigin.y() + m
_inlineTextBox.logicalHeight() - lineThickness).toFloat()), width, m_inlineTextB
ox.lineLayoutItem().document().printing()); |
831 } | 831 } |
832 | 832 |
833 void InlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* pt, const Layou
tPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, const Fon
t& font) | 833 void InlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, const
LayoutPoint& boxOrigin, DocumentMarker* marker, const ComputedStyle& style, cons
t Font& font) |
834 { | 834 { |
835 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on | 835 // Use same y positioning and height as for selection, so that when the sele
ction and this highlight are on |
836 // the same word there are no pieces sticking out. | 836 // the same word there are no pieces sticking out. |
837 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); | 837 int deltaY = m_inlineTextBox.lineLayoutItem().style()->isFlippedLinesWriting
Mode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalBotto
m() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop(); |
838 int selHeight = m_inlineTextBox.root().selectionHeight(); | 838 int selHeight = m_inlineTextBox.root().selectionHeight(); |
839 | 839 |
840 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); | 840 int sPos = std::max(marker->startOffset() - m_inlineTextBox.start(), (unsign
ed)0); |
841 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); | 841 int ePos = std::min(marker->endOffset() - m_inlineTextBox.start(), m_inlineT
extBox.len()); |
842 TextRun run = m_inlineTextBox.constructTextRun(style, font); | 842 TextRun run = m_inlineTextBox.constructTextRun(style, font); |
843 | 843 |
844 // Optionally highlight the text | 844 // Optionally highlight the text |
845 if (LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())-
>frame()->editor().markedTextMatchesAreHighlighted()) { | 845 if (LineLayoutPaintShim::layoutObjectFrom(m_inlineTextBox.lineLayoutItem())-
>frame()->editor().markedTextMatchesAreHighlighted()) { |
846 Color color = marker->activeMatch() ? | 846 Color color = marker->activeMatch() ? |
847 LayoutTheme::theme().platformActiveTextSearchHighlightColor() : | 847 LayoutTheme::theme().platformActiveTextSearchHighlightColor() : |
848 LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); | 848 LayoutTheme::theme().platformInactiveTextSearchHighlightColor(); |
849 GraphicsContextStateSaver stateSaver(*pt); | 849 GraphicsContextStateSaver stateSaver(context); |
850 pt->clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY).toF
loat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); | 850 context.clip(FloatRect(boxOrigin.x().toFloat(), (boxOrigin.y() - deltaY)
.toFloat(), m_inlineTextBox.logicalWidth().toFloat(), selHeight)); |
851 pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat(),
(boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); | 851 context.drawHighlightForText(font, run, FloatPoint(boxOrigin.x().toFloat
(), (boxOrigin.y() - deltaY).toFloat()), selHeight, color, sPos, ePos); |
852 | 852 |
853 // Also Highlight the text with color:transparent | 853 // Also Highlight the text with color:transparent |
854 if (style.visitedDependentColor(CSSPropertyColor) == Color::transparent)
{ | 854 if (style.visitedDependentColor(CSSPropertyColor) == Color::transparent)
{ |
855 int length = m_inlineTextBox.len(); | 855 int length = m_inlineTextBox.len(); |
856 TextPainter::Style textStyle; | 856 TextPainter::Style textStyle; |
857 // When we use the text as a clip, we only care about the alpha, thu
s we make all the colors black. | 857 // When we use the text as a clip, we only care about the alpha, thu
s we make all the colors black. |
858 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor
= textStyle.emphasisMarkColor = Color::black; | 858 textStyle.currentColor = textStyle.fillColor = textStyle.strokeColor
= textStyle.emphasisMarkColor = Color::black; |
859 textStyle.strokeWidth = style.textStrokeWidth(); | 859 textStyle.strokeWidth = style.textStrokeWidth(); |
860 textStyle.shadow = 0; | 860 textStyle.shadow = 0; |
861 | 861 |
862 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidt
h(), m_inlineTextBox.logicalHeight())); | 862 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidt
h(), m_inlineTextBox.logicalHeight())); |
863 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetri
cs().ascent()); | 863 LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetri
cs().ascent()); |
864 TextPainter textPainter(pt, font, run, textOrigin, boxRect, m_inline
TextBox.isHorizontal()); | 864 TextPainter textPainter(context, font, run, textOrigin, boxRect, m_i
nlineTextBox.isHorizontal()); |
865 | 865 |
866 textPainter.paint(sPos, ePos, length, textStyle, 0); | 866 textPainter.paint(sPos, ePos, length, textStyle, 0); |
867 } | 867 } |
868 } | 868 } |
869 } | 869 } |
870 | 870 |
871 | 871 |
872 } // namespace blink | 872 } // namespace blink |
OLD | NEW |