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

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

Issue 2337373002: Update composition underline start/end constraints. (Closed)
Patch Set: Don't remove early-out on full truncation. Created 4 years, 3 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698