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 |