| 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 |