Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp

Issue 2615843002: Revert of Don't paint underline or selections over ellipsis in mixed-flow contexts (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 int selectionEnd = 0; 552 int selectionEnd = 0;
553 if (paintSelectedTextOnly || paintSelectedTextSeparately) 553 if (paintSelectedTextOnly || paintSelectedTextSeparately)
554 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd); 554 m_inlineTextBox.selectionStartEnd(selectionStart, selectionEnd);
555 555
556 bool respectHyphen = 556 bool respectHyphen =
557 selectionEnd == static_cast<int>(m_inlineTextBox.len()) && 557 selectionEnd == static_cast<int>(m_inlineTextBox.len()) &&
558 m_inlineTextBox.hasHyphen(); 558 m_inlineTextBox.hasHyphen();
559 if (respectHyphen) 559 if (respectHyphen)
560 selectionEnd = textRun.length(); 560 selectionEnd = textRun.length();
561 561
562 bool ltr = m_inlineTextBox.isLeftToRightDirection();
563 bool flowIsLTR =
564 m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection();
565 if (m_inlineTextBox.truncation() != cNoTruncation) { 562 if (m_inlineTextBox.truncation() != cNoTruncation) {
566 // In a mixed-direction flow the ellipsis is at the start of the text
567 // rather than at the end of it.
568 selectionStart = 563 selectionStart =
569 ltr == flowIsLTR 564 std::min<int>(selectionStart, m_inlineTextBox.truncation());
570 ? std::min<int>(selectionStart, m_inlineTextBox.truncation()) 565 selectionEnd = std::min<int>(selectionEnd, m_inlineTextBox.truncation());
571 : std::max<int>(selectionStart, m_inlineTextBox.truncation()); 566 length = m_inlineTextBox.truncation();
572 selectionEnd =
573 ltr == flowIsLTR
574 ? std::min<int>(selectionEnd, m_inlineTextBox.truncation())
575 : std::max<int>(selectionEnd, m_inlineTextBox.truncation());
576 length = ltr == flowIsLTR ? m_inlineTextBox.truncation() : textRun.length();
577 } 567 }
578 568
579 TextPainter textPainter(context, font, textRun, textOrigin, boxRect, 569 TextPainter textPainter(context, font, textRun, textOrigin, boxRect,
580 m_inlineTextBox.isHorizontal()); 570 m_inlineTextBox.isHorizontal());
581 TextEmphasisPosition emphasisMarkPosition; 571 TextEmphasisPosition emphasisMarkPosition;
582 bool hasTextEmphasis = 572 bool hasTextEmphasis =
583 m_inlineTextBox.getEmphasisMarkPosition(styleToUse, emphasisMarkPosition); 573 m_inlineTextBox.getEmphasisMarkPosition(styleToUse, emphasisMarkPosition);
584 if (hasTextEmphasis) 574 if (hasTextEmphasis)
585 textPainter.setEmphasisMark(styleToUse.textEmphasisMarkString(), 575 textPainter.setEmphasisMark(styleToUse.textEmphasisMarkString(),
586 emphasisMarkPosition); 576 emphasisMarkPosition);
587 if (combinedText) 577 if (combinedText)
588 textPainter.setCombinedText(combinedText); 578 textPainter.setCombinedText(combinedText);
589 if (m_inlineTextBox.truncation() != cNoTruncation && ltr != flowIsLTR)
590 textPainter.setEllipsisOffset(m_inlineTextBox.truncation());
591 579
592 if (!paintSelectedTextOnly) { 580 if (!paintSelectedTextOnly) {
593 int startOffset = 0; 581 int startOffset = 0;
594 int endOffset = length; 582 int endOffset = length;
583 if (paintSelectedTextSeparately && selectionStart < selectionEnd) {
584 startOffset = selectionEnd;
585 endOffset = selectionStart;
586 }
595 // Where the text and its flow have opposite directions then our offset into 587 // Where the text and its flow have opposite directions then our offset into
596 // the text given by |truncation| is at the start of the part that will be 588 // the text given by |truncation| is at the start of the part that will be
597 // visible. 589 // visible.
598 if (m_inlineTextBox.truncation() != cNoTruncation && ltr != flowIsLTR) { 590 if (m_inlineTextBox.truncation() != cNoTruncation &&
591 m_inlineTextBox.getLineLayoutItem()
592 .containingBlock()
593 .style()
594 ->isLeftToRightDirection() !=
595 m_inlineTextBox.isLeftToRightDirection()) {
599 startOffset = m_inlineTextBox.truncation(); 596 startOffset = m_inlineTextBox.truncation();
600 endOffset = textRun.length(); 597 endOffset = textRun.length();
601 } 598 }
602 599
603 if (paintSelectedTextSeparately && selectionStart < selectionEnd) {
604 startOffset = selectionEnd;
605 endOffset = selectionStart;
606 }
607
608 // FIXME: This cache should probably ultimately be held somewhere else. 600 // FIXME: This cache should probably ultimately be held somewhere else.
609 // A hashmap is convenient to avoid a memory hit when the 601 // A hashmap is convenient to avoid a memory hit when the
610 // RuntimeEnabledFeature is off. 602 // RuntimeEnabledFeature is off.
611 bool textBlobIsCacheable = startOffset == 0 && endOffset == length; 603 bool textBlobIsCacheable = startOffset == 0 && endOffset == length;
612 TextBlobPtr* cachedTextBlob = 0; 604 TextBlobPtr* cachedTextBlob = 0;
613 if (textBlobIsCacheable) 605 if (textBlobIsCacheable)
614 cachedTextBlob = addToTextBlobCache(m_inlineTextBox); 606 cachedTextBlob = addToTextBlobCache(m_inlineTextBox);
615 textPainter.paint(startOffset, endOffset, length, textStyle, 607 textPainter.paint(startOffset, endOffset, length, textStyle,
616 cachedTextBlob); 608 cachedTextBlob);
617 } 609 }
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); 938 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
947 939
948 // If the text is truncated, let the thing being painted in the truncation 940 // If the text is truncated, let the thing being painted in the truncation
949 // draw its own highlight. 941 // draw its own highlight.
950 unsigned start = m_inlineTextBox.start(); 942 unsigned start = m_inlineTextBox.start();
951 int length = m_inlineTextBox.len(); 943 int length = m_inlineTextBox.len();
952 bool ltr = m_inlineTextBox.isLeftToRightDirection(); 944 bool ltr = m_inlineTextBox.isLeftToRightDirection();
953 bool flowIsLTR = 945 bool flowIsLTR =
954 m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); 946 m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection();
955 if (m_inlineTextBox.truncation() != cNoTruncation) { 947 if (m_inlineTextBox.truncation() != cNoTruncation) {
956 // In a mixed-direction flow the ellipsis is at the start of the text 948 start = ltr == flowIsLTR ? m_inlineTextBox.start()
957 // so we need to start after it. Otherwise we just need to make sure 949 : m_inlineTextBox.truncation();
958 // the end of the text is where the ellipsis starts. 950 length = ltr == flowIsLTR
959 if (ltr != flowIsLTR) 951 ? m_inlineTextBox.truncation()
960 sPos = std::max<int>(sPos, m_inlineTextBox.truncation()); 952 : m_inlineTextBox.len() - m_inlineTextBox.truncation();
961 else
962 length = m_inlineTextBox.truncation();
963 } 953 }
964 StringView string(m_inlineTextBox.getLineLayoutItem().text(), start, 954 StringView string(m_inlineTextBox.getLineLayoutItem().text(), start,
965 static_cast<unsigned>(length)); 955 static_cast<unsigned>(length));
966 956
967 StringBuilder charactersWithHyphen; 957 StringBuilder charactersWithHyphen;
968 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen(); 958 bool respectHyphen = ePos == length && m_inlineTextBox.hasHyphen();
969 TextRun textRun = m_inlineTextBox.constructTextRun( 959 TextRun textRun = m_inlineTextBox.constructTextRun(
970 style, string, m_inlineTextBox.getLineLayoutItem().textLength() - 960 style, string, m_inlineTextBox.getLineLayoutItem().textLength() -
971 m_inlineTextBox.start(), 961 m_inlineTextBox.start(),
972 respectHyphen ? &charactersWithHyphen : 0); 962 respectHyphen ? &charactersWithHyphen : 0);
(...skipping 18 matching lines...) Expand all
991 int deltaY = roundToInt( 981 int deltaY = roundToInt(
992 m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWritingMode() 982 m_inlineTextBox.getLineLayoutItem().style()->isFlippedLinesWritingMode()
993 ? selectionBottom - m_inlineTextBox.logicalBottom() 983 ? selectionBottom - m_inlineTextBox.logicalBottom()
994 : m_inlineTextBox.logicalTop() - selectionTop); 984 : m_inlineTextBox.logicalTop() - selectionTop);
995 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop)); 985 int selHeight = std::max(0, roundToInt(selectionBottom - selectionTop));
996 986
997 FloatPoint localOrigin(boxRect.x().toFloat(), 987 FloatPoint localOrigin(boxRect.x().toFloat(),
998 (boxRect.y() - deltaY).toFloat()); 988 (boxRect.y() - deltaY).toFloat());
999 LayoutRect selectionRect = LayoutRect( 989 LayoutRect selectionRect = LayoutRect(
1000 font.selectionRectForText(textRun, localOrigin, selHeight, sPos, ePos)); 990 font.selectionRectForText(textRun, localOrigin, selHeight, sPos, ePos));
1001 // For line breaks, just painting a selection where the line break itself 991 if (m_inlineTextBox.hasWrappedSelectionNewline()
1002 // is rendered is sufficient. Don't select it if there's an ellipsis 992 // For line breaks, just painting a selection where the line break itself
1003 // there. 993 // is rendered is sufficient.
1004 if (m_inlineTextBox.hasWrappedSelectionNewline() && 994 && !m_inlineTextBox.isLineBreak())
1005 m_inlineTextBox.truncation() == cNoTruncation &&
1006 !m_inlineTextBox.isLineBreak())
1007 expandToIncludeNewlineForSelection(selectionRect); 995 expandToIncludeNewlineForSelection(selectionRect);
1008 996
1009 // Line breaks report themselves as having zero width for layout purposes, 997 // Line breaks report themselves as having zero width for layout purposes,
1010 // and so will end up positioned at (0, 0), even though we paint their 998 // and so will end up positioned at (0, 0), even though we paint their
1011 // selection highlight with character width. For RTL then, we have to 999 // selection highlight with character width. For RTL then, we have to
1012 // explicitly shift the selection rect over to paint in the right location. 1000 // explicitly shift the selection rect over to paint in the right location.
1013 if (!m_inlineTextBox.isLeftToRightDirection() && 1001 if (!m_inlineTextBox.isLeftToRightDirection() &&
1014 m_inlineTextBox.isLineBreak()) 1002 m_inlineTextBox.isLineBreak())
1015 selectionRect.move(-selectionRect.width(), LayoutUnit()); 1003 selectionRect.move(-selectionRect.width(), LayoutUnit());
1016 if (!flowIsLTR && !ltr && m_inlineTextBox.truncation() != cNoTruncation) 1004 if (!flowIsLTR && m_inlineTextBox.truncation() != cNoTruncation)
1017 selectionRect.move(m_inlineTextBox.logicalWidth() - selectionRect.width(), 1005 selectionRect.move(m_inlineTextBox.logicalWidth() - selectionRect.width(),
1018 LayoutUnit()); 1006 LayoutUnit());
1019 1007
1020 context.fillRect(FloatRect(selectionRect), c); 1008 context.fillRect(FloatRect(selectionRect), c);
1021 } 1009 }
1022 1010
1023 void InlineTextBoxPainter::expandToIncludeNewlineForSelection( 1011 void InlineTextBoxPainter::expandToIncludeNewlineForSelection(
1024 LayoutRect& rect) { 1012 LayoutRect& rect) {
1025 FloatRectOutsets outsets = FloatRectOutsets(); 1013 FloatRectOutsets outsets = FloatRectOutsets();
1026 float spaceWidth = m_inlineTextBox.newlineSpaceWidth(); 1014 float spaceWidth = m_inlineTextBox.newlineSpaceWidth();
(...skipping 16 matching lines...) Expand all
1043 GraphicsContextStateSaver stateSaver(context); 1031 GraphicsContextStateSaver stateSaver(context);
1044 1032
1045 LayoutPoint localOrigin(boxOrigin); 1033 LayoutPoint localOrigin(boxOrigin);
1046 1034
1047 LayoutUnit width = m_inlineTextBox.logicalWidth(); 1035 LayoutUnit width = m_inlineTextBox.logicalWidth();
1048 if (m_inlineTextBox.truncation() != cNoTruncation) { 1036 if (m_inlineTextBox.truncation() != cNoTruncation) {
1049 bool ltr = m_inlineTextBox.isLeftToRightDirection(); 1037 bool ltr = m_inlineTextBox.isLeftToRightDirection();
1050 bool flowIsLTR = 1038 bool flowIsLTR =
1051 m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); 1039 m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection();
1052 width = LayoutUnit(m_inlineTextBox.getLineLayoutItem().width( 1040 width = LayoutUnit(m_inlineTextBox.getLineLayoutItem().width(
1053 ltr == flowIsLTR 1041 ltr == flowIsLTR ? m_inlineTextBox.start()
1054 ? m_inlineTextBox.start() 1042 : m_inlineTextBox.truncation(),
1055 : m_inlineTextBox.start() + m_inlineTextBox.truncation(),
1056 ltr == flowIsLTR ? m_inlineTextBox.truncation() 1043 ltr == flowIsLTR ? m_inlineTextBox.truncation()
1057 : m_inlineTextBox.len() - m_inlineTextBox.truncation(), 1044 : m_inlineTextBox.len() - m_inlineTextBox.truncation(),
1058 m_inlineTextBox.textPos(), 1045 m_inlineTextBox.textPos(),
1059 flowIsLTR ? TextDirection::Ltr : TextDirection::Rtl, 1046 flowIsLTR ? TextDirection::Ltr : TextDirection::Rtl,
1060 m_inlineTextBox.isFirstLineStyle())); 1047 m_inlineTextBox.isFirstLineStyle()));
1061 if (!flowIsLTR) 1048 if (!flowIsLTR)
1062 localOrigin.move(m_inlineTextBox.logicalWidth() - width, LayoutUnit()); 1049 localOrigin.move(m_inlineTextBox.logicalWidth() - width, LayoutUnit());
1063 } 1050 }
1064 1051
1065 LayoutObject& textBoxLayoutObject = inlineLayoutObject(); 1052 LayoutObject& textBoxLayoutObject = inlineLayoutObject();
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 1276
1290 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), 1277 LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(),
1291 m_inlineTextBox.logicalHeight())); 1278 m_inlineTextBox.logicalHeight()));
1292 context.clip(FloatRect(boxRect)); 1279 context.clip(FloatRect(boxRect));
1293 context.drawHighlightForText(font, run, FloatPoint(boxOrigin), 1280 context.drawHighlightForText(font, run, FloatPoint(boxOrigin),
1294 boxRect.height().toInt(), color, 1281 boxRect.height().toInt(), color,
1295 paintOffsets.first, paintOffsets.second); 1282 paintOffsets.first, paintOffsets.second);
1296 } 1283 }
1297 1284
1298 } // namespace blink 1285 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698