Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/InlineTextBoxPainter.h" | 5 #include "core/paint/InlineTextBoxPainter.h" |
| 6 | 6 |
| 7 #include "core/editing/CompositionUnderline.h" | 7 #include "core/editing/CompositionUnderline.h" |
| 8 #include "core/editing/Editor.h" | 8 #include "core/editing/Editor.h" |
| 9 #include "core/editing/markers/DocumentMarkerController.h" | 9 #include "core/editing/markers/DocumentMarkerController.h" |
| 10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 // tests for != PaintPhaseTextClip. | 258 // tests for != PaintPhaseTextClip. |
| 259 if (m_inlineTextBox.getLineLayoutItem().style()->visibility() != EVisibility ::Visible | 259 if (m_inlineTextBox.getLineLayoutItem().style()->visibility() != EVisibility ::Visible |
| 260 || m_inlineTextBox.truncation() == cFullTruncation | 260 || m_inlineTextBox.truncation() == cFullTruncation |
| 261 || !m_inlineTextBox.len()) | 261 || !m_inlineTextBox.len()) |
| 262 return false; | 262 return false; |
| 263 return true; | 263 return true; |
| 264 } | 264 } |
| 265 | 265 |
| 266 unsigned InlineTextBoxPainter::underlinePaintStart(const CompositionUnderline& u nderline) | 266 unsigned InlineTextBoxPainter::underlinePaintStart(const CompositionUnderline& u nderline) |
| 267 { | 267 { |
| 268 return std::max(static_cast<unsigned>(m_inlineTextBox.start()), underline.st artOffset); | 268 DCHECK(m_inlineTextBox.truncation() != cFullTruncation); |
| 269 DCHECK(m_inlineTextBox.len()); | |
| 270 | |
| 271 // Start painting at the beginning of the text or the specified underline | |
| 272 // start offset, whichever is higher. | |
| 273 unsigned paintStart = std::max(m_inlineTextBox.start(), underline.startOffse t); | |
| 274 // Cap the maximum paint start to (if no truncation) the last character, | |
| 275 // else the last character before the truncation ellipsis. | |
| 276 return std::min(paintStart, (m_inlineTextBox.truncation() == cNoTruncation) ? | |
| 277 m_inlineTextBox.end() : m_inlineTextBox.start() + m_inlineTextBox.trunca tion() - 1); | |
|
kojii
2016/09/14 05:21:31
Is this safe when truncation() is 0? Maybe it'd ne
wkorman
2016/09/14 19:34:47
It should not occur, let's see:
- m_truncation is
| |
| 269 } | 278 } |
| 270 | 279 |
| 271 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und erline) | 280 unsigned InlineTextBoxPainter::underlinePaintEnd(const CompositionUnderline& und erline) |
| 272 { | 281 { |
| 282 DCHECK(m_inlineTextBox.truncation() != cFullTruncation); | |
| 283 DCHECK(m_inlineTextBox.len()); | |
| 284 | |
| 285 // End painting just past the end of the text or the specified underline end | |
| 286 // offset, whichever is lower. | |
| 273 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset) ; // end() points at the last char, not past it. | 287 unsigned paintEnd = std::min(m_inlineTextBox.end() + 1, underline.endOffset) ; // end() points at the last char, not past it. |
| 274 if (m_inlineTextBox.truncation() != cNoTruncation) | 288 // Cap the maximum paint end to (if no truncation) one past the last |
| 275 paintEnd = std::min(paintEnd, static_cast<unsigned>(m_inlineTextBox.star t() + m_inlineTextBox.truncation())); | 289 // character, else one past the last character before the truncation |
| 276 return paintEnd; | 290 // ellipsis. |
| 291 return std::min(paintEnd, (m_inlineTextBox.truncation() == cNoTruncation) ? | |
| 292 m_inlineTextBox.end() + 1 : m_inlineTextBox.start() + m_inlineTextBox.tr uncation()); | |
| 277 } | 293 } |
| 278 | 294 |
| 279 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext& context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f ont, Color backgroundColor, int startPos, int endPos) | 295 void InlineTextBoxPainter::paintSingleCompositionBackgroundRun(GraphicsContext& context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& f ont, Color backgroundColor, int startPos, int endPos) |
| 280 { | 296 { |
| 281 if (backgroundColor == Color::transparent) | 297 if (backgroundColor == Color::transparent) |
| 282 return; | 298 return; |
| 283 | 299 |
| 284 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0) ; | 300 int sPos = std::max(startPos - static_cast<int>(m_inlineTextBox.start()), 0) ; |
| 285 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat ic_cast<int>(m_inlineTextBox.len())); | 301 int ePos = std::min(endPos - static_cast<int>(m_inlineTextBox.start()), stat ic_cast<int>(m_inlineTextBox.len())); |
| 286 if (sPos >= ePos) | 302 if (sPos >= ePos) |
| 287 return; | 303 return; |
| 288 | 304 |
| 289 int deltaY = (m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWri tingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalB ottom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop()). toInt(); | 305 int deltaY = (m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWri tingMode() ? m_inlineTextBox.root().selectionBottom() - m_inlineTextBox.logicalB ottom() : m_inlineTextBox.logicalTop() - m_inlineTextBox.root().selectionTop()). toInt(); |
| 290 int selHeight = m_inlineTextBox.root().selectionHeight().toInt(); | 306 int selHeight = m_inlineTextBox.root().selectionHeight().toInt(); |
| 291 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de ltaY); | 307 FloatPoint localOrigin(boxOrigin.x().toFloat(), boxOrigin.y().toFloat() - de ltaY); |
| 292 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style), localOrigin, selHeight, backgroundColor, sPos, ePos); | 308 context.drawHighlightForText(font, m_inlineTextBox.constructTextRun(style), localOrigin, selHeight, backgroundColor, sPos, ePos); |
| 293 } | 309 } |
| 294 | 310 |
| 295 void InlineTextBoxPainter::paintDocumentMarkers(const PaintInfo& paintInfo, cons t LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, Document MarkerPaintPhase markerPaintPhase) | 311 void InlineTextBoxPainter::paintDocumentMarkers(const PaintInfo& paintInfo, cons t LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font, Document MarkerPaintPhase markerPaintPhase) |
| 296 { | 312 { |
| 297 if (!m_inlineTextBox.getLineLayoutItem().node()) | 313 if (!m_inlineTextBox.getLineLayoutItem().node()) |
| 298 return; | 314 return; |
| 299 | 315 |
| 316 DCHECK(m_inlineTextBox.truncation() != cFullTruncation); | |
| 317 DCHECK(m_inlineTextBox.len()); | |
| 318 | |
| 300 DocumentMarkerVector markers = m_inlineTextBox.getLineLayoutItem().document( ).markers().markersFor(m_inlineTextBox.getLineLayoutItem().node()); | 319 DocumentMarkerVector markers = m_inlineTextBox.getLineLayoutItem().document( ).markers().markersFor(m_inlineTextBox.getLineLayoutItem().node()); |
| 301 DocumentMarkerVector::const_iterator markerIt = markers.begin(); | 320 DocumentMarkerVector::const_iterator markerIt = markers.begin(); |
| 302 | 321 |
| 303 // Give any document markers that touch this run a chance to draw before the text has been drawn. | 322 // Give any document markers that touch this run a chance to draw before the text has been drawn. |
| 304 // Note end() points at the last char, not one past it like endOffset and ra nges do. | 323 // Note end() points at the last char, not one past it like endOffset and ra nges do. |
| 305 for ( ; markerIt != markers.end(); ++markerIt) { | 324 for ( ; markerIt != markers.end(); ++markerIt) { |
| 306 DocumentMarker* marker = *markerIt; | 325 DocumentMarker* marker = *markerIt; |
| 307 | 326 |
| 308 // Paint either the background markers or the foreground markers, but no t both | 327 // Paint either the background markers or the foreground markers, but no t both |
| 309 switch (marker->type()) { | 328 switch (marker->type()) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 unsigned start = m_inlineTextBox.start(); | 473 unsigned start = m_inlineTextBox.start(); |
| 455 int length = m_inlineTextBox.len(); | 474 int length = m_inlineTextBox.len(); |
| 456 bool ltr = m_inlineTextBox.isLeftToRightDirection(); | 475 bool ltr = m_inlineTextBox.isLeftToRightDirection(); |
| 457 bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightD irection(); | 476 bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightD irection(); |
| 458 if (m_inlineTextBox.truncation() != cNoTruncation) { | 477 if (m_inlineTextBox.truncation() != cNoTruncation) { |
| 459 start = ltr == flowIsLTR ? m_inlineTextBox.start() : m_inlineTextBox.tru ncation(); | 478 start = ltr == flowIsLTR ? m_inlineTextBox.start() : m_inlineTextBox.tru ncation(); |
| 460 length = ltr == flowIsLTR ? m_inlineTextBox.truncation() : m_inlineTextB ox.len() - m_inlineTextBox.truncation(); | 479 length = ltr == flowIsLTR ? m_inlineTextBox.truncation() : m_inlineTextB ox.len() - m_inlineTextBox.truncation(); |
| 461 } | 480 } |
| 462 StringView string(m_inlineTextBox.getLineLayoutItem().text(), start, static_ cast<unsigned>(length)); | 481 StringView string(m_inlineTextBox.getLineLayoutItem().text(), start, static_ cast<unsigned>(length)); |
| 463 | 482 |
| 464 | |
| 465 StringBuilder charactersWithHyphen; | 483 StringBuilder charactersWithHyphen; |
| 466 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); | 484 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); |
| 467 TextRun textRun = m_inlineTextBox.constructTextRun(style, string, m_inlineTe xtBox.getLineLayoutItem().textLength() - m_inlineTextBox.start(), respectHyphen ? &charactersWithHyphen : 0); | 485 TextRun textRun = m_inlineTextBox.constructTextRun(style, string, m_inlineTe xtBox.getLineLayoutItem().textLength() - m_inlineTextBox.start(), respectHyphen ? &charactersWithHyphen : 0); |
| 468 if (respectHyphen) | 486 if (respectHyphen) |
| 469 ePos = textRun.length(); | 487 ePos = textRun.length(); |
| 470 | 488 |
| 471 GraphicsContextStateSaver stateSaver(context); | 489 GraphicsContextStateSaver stateSaver(context); |
| 472 | 490 |
| 473 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { | 491 if (options == InlineTextBoxPainter::PaintOptions::CombinedText) { |
| 474 ASSERT(combinedText); | 492 ASSERT(combinedText); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext& context, c onst LayoutPoint& boxOrigin, const CompositionUnderline& underline) | 810 void InlineTextBoxPainter::paintCompositionUnderline(GraphicsContext& context, c onst LayoutPoint& boxOrigin, const CompositionUnderline& underline) |
| 793 { | 811 { |
| 794 if (underline.color == Color::transparent) | 812 if (underline.color == Color::transparent) |
| 795 return; | 813 return; |
| 796 | 814 |
| 797 if (m_inlineTextBox.truncation() == cFullTruncation) | 815 if (m_inlineTextBox.truncation() == cFullTruncation) |
| 798 return; | 816 return; |
| 799 | 817 |
| 800 unsigned paintStart = underlinePaintStart(underline); | 818 unsigned paintStart = underlinePaintStart(underline); |
| 801 unsigned paintEnd = underlinePaintEnd(underline); | 819 unsigned paintEnd = underlinePaintEnd(underline); |
| 820 DCHECK_LT(paintStart, paintEnd); | |
| 802 | 821 |
| 803 // start of line to draw | 822 // start of line to draw |
| 804 float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ? 0 : | 823 float start = paintStart == m_inlineTextBox.start() ? 0 : |
| 805 m_inlineTextBox.getLineLayoutItem().width(m_inlineTextBox.start(), paint Start - m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLe ftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 824 m_inlineTextBox.getLineLayoutItem().width(m_inlineTextBox.start(), paint Start - m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLe ftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); |
| 806 // how much line to draw | 825 // how much line to draw |
| 807 float width; | 826 float width; |
| 808 bool ltr = m_inlineTextBox.isLeftToRightDirection(); | 827 bool ltr = m_inlineTextBox.isLeftToRightDirection(); |
| 809 bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightD irection(); | 828 bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightD irection(); |
| 810 if (paintStart == static_cast<unsigned>(m_inlineTextBox.start()) && paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) { | 829 if (paintStart == m_inlineTextBox.start() && paintEnd == m_inlineTextBox.end () + 1) { |
| 811 width = m_inlineTextBox.logicalWidth().toFloat(); | 830 width = m_inlineTextBox.logicalWidth().toFloat(); |
| 812 } else { | 831 } else { |
| 813 width = m_inlineTextBox.getLineLayoutItem().width(ltr == flowIsLTR ? pai ntStart : paintEnd, ltr == flowIsLTR ? paintEnd - paintStart : m_inlineTextBox.l en() - paintEnd, LayoutUnit(m_inlineTextBox.textPos() + start), flowIsLTR ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); | 832 unsigned paintFrom = ltr == flowIsLTR ? paintStart : paintEnd; |
| 833 unsigned paintLength = ltr == flowIsLTR ? paintEnd - paintStart : m_inli neTextBox.start() + m_inlineTextBox.len() - paintEnd; | |
| 834 width = m_inlineTextBox.getLineLayoutItem().width(paintFrom, paintLength , | |
| 835 LayoutUnit(m_inlineTextBox.textPos() + start), flowIsLTR ? LTR : RTL , m_inlineTextBox.isFirstLineStyle()); | |
| 814 } | 836 } |
| 815 // In RTL mode, start and width are computed from the right end of the text box: | 837 // In RTL mode, start and width are computed from the right end of the text box: |
| 816 // starting at |logicalWidth| - |start| and continuing left by |width| to | 838 // starting at |logicalWidth| - |start| and continuing left by |width| to |
| 817 // |logicalWidth| - |start| - |width|. We will draw that line, but | 839 // |logicalWidth| - |start| - |width|. We will draw that line, but |
| 818 // backwards: |logicalWidth| - |start| - |width| to |logicalWidth| - |start| . | 840 // backwards: |logicalWidth| - |start| - |width| to |logicalWidth| - |start| . |
| 819 if (!flowIsLTR) | 841 if (!flowIsLTR) |
| 820 start = m_inlineTextBox.logicalWidth().toFloat() - width - start; | 842 start = m_inlineTextBox.logicalWidth().toFloat() - width - start; |
| 821 | 843 |
| 822 | |
| 823 // Thick marked text underlines are 2px thick as long as there is room for t he 2px line under the baseline. | 844 // Thick marked text underlines are 2px thick as long as there is room for t he 2px line under the baseline. |
| 824 // All other marked text underlines are 1px thick. | 845 // All other marked text underlines are 1px thick. |
| 825 // If there's not enough space the underline will touch or overlap character s. | 846 // If there's not enough space the underline will touch or overlap character s. |
| 826 int lineThickness = 1; | 847 int lineThickness = 1; |
| 827 int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isF irstLineStyle())->getFontMetrics().ascent(); | 848 int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isF irstLineStyle())->getFontMetrics().ascent(); |
| 828 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) | 849 if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2) |
| 829 lineThickness = 2; | 850 lineThickness = 2; |
| 830 | 851 |
| 831 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those. | 852 // We need to have some space between underlines of subsequent clauses, beca use some input methods do not use different underline styles for those. |
| 832 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. | 853 // We make each line shorter, which has a harmless side effect of shortening the first and last clauses, too. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 874 | 895 |
| 875 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker-> activeMatch()); | 896 Color color = LayoutTheme::theme().platformTextSearchHighlightColor(marker-> activeMatch()); |
| 876 GraphicsContext& context = paintInfo.context; | 897 GraphicsContext& context = paintInfo.context; |
| 877 GraphicsContextStateSaver stateSaver(context); | 898 GraphicsContextStateSaver stateSaver(context); |
| 878 | 899 |
| 879 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i nlineTextBox.logicalHeight())); | 900 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_i nlineTextBox.logicalHeight())); |
| 880 context.clip(FloatRect(boxRect)); | 901 context.clip(FloatRect(boxRect)); |
| 881 context.drawHighlightForText(font, run, FloatPoint(boxOrigin), boxRect.heigh t().toInt(), color, sPos, ePos); | 902 context.drawHighlightForText(font, run, FloatPoint(boxOrigin), boxRect.heigh t().toInt(), color, sPos, ePos); |
| 882 } | 903 } |
| 883 | 904 |
| 884 | |
| 885 } // namespace blink | 905 } // namespace blink |
| OLD | NEW |