| 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" | |
| 8 #include "core/editing/Editor.h" | 7 #include "core/editing/Editor.h" |
| 9 #include "core/editing/markers/CompositionMarker.h" | 8 #include "core/editing/markers/CompositionMarker.h" |
| 10 #include "core/editing/markers/DocumentMarkerController.h" | 9 #include "core/editing/markers/DocumentMarkerController.h" |
| 11 #include "core/editing/markers/TextMatchMarker.h" | 10 #include "core/editing/markers/TextMatchMarker.h" |
| 12 #include "core/frame/LocalFrame.h" | 11 #include "core/frame/LocalFrame.h" |
| 13 #include "core/layout/LayoutTextCombine.h" | 12 #include "core/layout/LayoutTextCombine.h" |
| 14 #include "core/layout/LayoutTheme.h" | 13 #include "core/layout/LayoutTheme.h" |
| 15 #include "core/layout/api/LineLayoutAPIShim.h" | 14 #include "core/layout/api/LineLayoutAPIShim.h" |
| 16 #include "core/layout/api/LineLayoutBox.h" | 15 #include "core/layout/api/LineLayoutBox.h" |
| 17 #include "core/layout/line/InlineTextBox.h" | 16 #include "core/layout/line/InlineTextBox.h" |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // expect PaintPhaseSelection. The existing haveSelection logic in paint() | 531 // expect PaintPhaseSelection. The existing haveSelection logic in paint() |
| 533 // tests for != PaintPhaseTextClip. | 532 // tests for != PaintPhaseTextClip. |
| 534 if (inline_text_box_.GetLineLayoutItem().Style()->Visibility() != | 533 if (inline_text_box_.GetLineLayoutItem().Style()->Visibility() != |
| 535 EVisibility::kVisible || | 534 EVisibility::kVisible || |
| 536 inline_text_box_.Truncation() == kCFullTruncation || | 535 inline_text_box_.Truncation() == kCFullTruncation || |
| 537 !inline_text_box_.Len()) | 536 !inline_text_box_.Len()) |
| 538 return false; | 537 return false; |
| 539 return true; | 538 return true; |
| 540 } | 539 } |
| 541 | 540 |
| 542 unsigned InlineTextBoxPainter::UnderlinePaintStart( | 541 unsigned InlineTextBoxPainter::MarkerPaintStart(const DocumentMarker& marker) { |
| 543 const CompositionUnderline& underline) { | |
| 544 DCHECK(inline_text_box_.Truncation() != kCFullTruncation); | 542 DCHECK(inline_text_box_.Truncation() != kCFullTruncation); |
| 545 DCHECK(inline_text_box_.Len()); | 543 DCHECK(inline_text_box_.Len()); |
| 546 | 544 |
| 547 // Start painting at the beginning of the text or the specified underline | 545 // Start painting at the beginning of the text or the specified underline |
| 548 // start offset, whichever is higher. | 546 // start offset, whichever is higher. |
| 549 unsigned paint_start = | 547 unsigned paint_start = |
| 550 std::max(inline_text_box_.Start(), underline.StartOffset()); | 548 std::max(inline_text_box_.Start(), marker.StartOffset()); |
| 551 // Cap the maximum paint start to (if no truncation) the last character, | 549 // Cap the maximum paint start to (if no truncation) the last character, |
| 552 // else the last character before the truncation ellipsis. | 550 // else the last character before the truncation ellipsis. |
| 553 return std::min(paint_start, (inline_text_box_.Truncation() == kCNoTruncation) | 551 return std::min(paint_start, (inline_text_box_.Truncation() == kCNoTruncation) |
| 554 ? inline_text_box_.end() | 552 ? inline_text_box_.end() |
| 555 : inline_text_box_.Start() + | 553 : inline_text_box_.Start() + |
| 556 inline_text_box_.Truncation() - 1); | 554 inline_text_box_.Truncation() - 1); |
| 557 } | 555 } |
| 558 | 556 |
| 559 unsigned InlineTextBoxPainter::UnderlinePaintEnd( | 557 unsigned InlineTextBoxPainter::MarkerPaintEnd(const DocumentMarker& marker) { |
| 560 const CompositionUnderline& underline) { | |
| 561 DCHECK(inline_text_box_.Truncation() != kCFullTruncation); | 558 DCHECK(inline_text_box_.Truncation() != kCFullTruncation); |
| 562 DCHECK(inline_text_box_.Len()); | 559 DCHECK(inline_text_box_.Len()); |
| 563 | 560 |
| 564 // End painting just past the end of the text or the specified underline end | 561 // End painting just past the end of the text or the specified underline end |
| 565 // offset, whichever is lower. | 562 // offset, whichever is lower. |
| 566 unsigned paint_end = std::min( | 563 unsigned paint_end = std::min( |
| 567 inline_text_box_.end() + 1, | 564 inline_text_box_.end() + 1, |
| 568 underline.EndOffset()); // end() points at the last char, not past it. | 565 marker.EndOffset()); // end() points at the last char, not past it. |
| 569 // Cap the maximum paint end to (if no truncation) one past the last | 566 // Cap the maximum paint end to (if no truncation) one past the last |
| 570 // character, else one past the last character before the truncation | 567 // character, else one past the last character before the truncation |
| 571 // ellipsis. | 568 // ellipsis. |
| 572 return std::min(paint_end, (inline_text_box_.Truncation() == kCNoTruncation) | 569 return std::min(paint_end, (inline_text_box_.Truncation() == kCNoTruncation) |
| 573 ? inline_text_box_.end() + 1 | 570 ? inline_text_box_.end() + 1 |
| 574 : inline_text_box_.Start() + | 571 : inline_text_box_.Start() + |
| 575 inline_text_box_.Truncation()); | 572 inline_text_box_.Truncation()); |
| 576 } | 573 } |
| 577 | 574 |
| 578 void InlineTextBoxPainter::PaintSingleCompositionBackgroundRun( | 575 void InlineTextBoxPainter::PaintSingleMarkerBackgroundRun( |
| 579 GraphicsContext& context, | 576 GraphicsContext& context, |
| 580 const LayoutPoint& box_origin, | 577 const LayoutPoint& box_origin, |
| 581 const ComputedStyle& style, | 578 const ComputedStyle& style, |
| 582 const Font& font, | 579 const Font& font, |
| 583 Color background_color, | 580 Color background_color, |
| 584 int start_pos, | 581 int start_pos, |
| 585 int end_pos) { | 582 int end_pos) { |
| 586 if (background_color == Color::kTransparent) | 583 if (background_color == Color::kTransparent) |
| 587 return; | 584 return; |
| 588 | 585 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 inline_text_box_.PaintTextMatchMarkerBackground( | 669 inline_text_box_.PaintTextMatchMarkerBackground( |
| 673 paint_info, box_origin, ToTextMatchMarker(marker), style, font); | 670 paint_info, box_origin, ToTextMatchMarker(marker), style, font); |
| 674 } else { | 671 } else { |
| 675 inline_text_box_.PaintTextMatchMarkerForeground( | 672 inline_text_box_.PaintTextMatchMarkerForeground( |
| 676 paint_info, box_origin, ToTextMatchMarker(marker), style, font); | 673 paint_info, box_origin, ToTextMatchMarker(marker), style, font); |
| 677 } | 674 } |
| 678 break; | 675 break; |
| 679 case DocumentMarker::kComposition: | 676 case DocumentMarker::kComposition: |
| 680 case DocumentMarker::kActiveSuggestion: { | 677 case DocumentMarker::kActiveSuggestion: { |
| 681 const StyleableMarker& styleable_marker = ToStyleableMarker(marker); | 678 const StyleableMarker& styleable_marker = ToStyleableMarker(marker); |
| 682 CompositionUnderline underline( | 679 if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) { |
| 683 styleable_marker.StartOffset(), styleable_marker.EndOffset(), | 680 PaintSingleMarkerBackgroundRun(paint_info.context, box_origin, style, |
| 684 styleable_marker.UnderlineColor(), styleable_marker.IsThick(), | 681 font, |
| 685 styleable_marker.BackgroundColor()); | 682 styleable_marker.BackgroundColor(), |
| 686 if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) | 683 MarkerPaintStart(styleable_marker), |
| 687 PaintSingleCompositionBackgroundRun( | 684 MarkerPaintEnd(styleable_marker)); |
| 688 paint_info.context, box_origin, style, font, | 685 } else { |
| 689 underline.BackgroundColor(), UnderlinePaintStart(underline), | 686 PaintStyleableMarkerUnderline(paint_info.context, box_origin, |
| 690 UnderlinePaintEnd(underline)); | 687 styleable_marker); |
| 691 else | 688 } |
| 692 PaintCompositionUnderline(paint_info.context, box_origin, underline); | |
| 693 } break; | 689 } break; |
| 694 default: | 690 default: |
| 695 NOTREACHED(); | 691 NOTREACHED(); |
| 696 } | 692 } |
| 697 } | 693 } |
| 698 } | 694 } |
| 699 | 695 |
| 700 namespace { | 696 namespace { |
| 701 | 697 |
| 702 #if !OS(MACOSX) | 698 #if !OS(MACOSX) |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 LayoutRect& rect) { | 1023 LayoutRect& rect) { |
| 1028 FloatRectOutsets outsets = FloatRectOutsets(); | 1024 FloatRectOutsets outsets = FloatRectOutsets(); |
| 1029 float space_width = inline_text_box_.NewlineSpaceWidth(); | 1025 float space_width = inline_text_box_.NewlineSpaceWidth(); |
| 1030 if (inline_text_box_.IsLeftToRightDirection()) | 1026 if (inline_text_box_.IsLeftToRightDirection()) |
| 1031 outsets.SetRight(space_width); | 1027 outsets.SetRight(space_width); |
| 1032 else | 1028 else |
| 1033 outsets.SetLeft(space_width); | 1029 outsets.SetLeft(space_width); |
| 1034 rect.Expand(outsets); | 1030 rect.Expand(outsets); |
| 1035 } | 1031 } |
| 1036 | 1032 |
| 1037 void InlineTextBoxPainter::PaintCompositionUnderline( | 1033 void InlineTextBoxPainter::PaintStyleableMarkerUnderline( |
| 1038 GraphicsContext& context, | 1034 GraphicsContext& context, |
| 1039 const LayoutPoint& box_origin, | 1035 const LayoutPoint& box_origin, |
| 1040 const CompositionUnderline& underline) { | 1036 const StyleableMarker& marker) { |
| 1041 if (underline.GetColor() == Color::kTransparent) | 1037 if (marker.UnderlineColor() == Color::kTransparent) |
| 1042 return; | 1038 return; |
| 1043 | 1039 |
| 1044 if (inline_text_box_.Truncation() == kCFullTruncation) | 1040 if (inline_text_box_.Truncation() == kCFullTruncation) |
| 1045 return; | 1041 return; |
| 1046 | 1042 |
| 1047 unsigned paint_start = UnderlinePaintStart(underline); | 1043 unsigned paint_start = MarkerPaintStart(marker); |
| 1048 unsigned paint_end = UnderlinePaintEnd(underline); | 1044 unsigned paint_end = MarkerPaintEnd(marker); |
| 1049 DCHECK_LT(paint_start, paint_end); | 1045 DCHECK_LT(paint_start, paint_end); |
| 1050 | 1046 |
| 1051 // start of line to draw | 1047 // start of line to draw |
| 1052 float start = | 1048 float start = |
| 1053 paint_start == inline_text_box_.Start() | 1049 paint_start == inline_text_box_.Start() |
| 1054 ? 0 | 1050 ? 0 |
| 1055 : inline_text_box_.GetLineLayoutItem().Width( | 1051 : inline_text_box_.GetLineLayoutItem().Width( |
| 1056 inline_text_box_.Start(), | 1052 inline_text_box_.Start(), |
| 1057 paint_start - inline_text_box_.Start(), | 1053 paint_start - inline_text_box_.Start(), |
| 1058 inline_text_box_.TextPos(), | 1054 inline_text_box_.TextPos(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 // thick. If there's not enough space the underline will touch or overlap | 1087 // thick. If there's not enough space the underline will touch or overlap |
| 1092 // characters. | 1088 // characters. |
| 1093 int line_thickness = 1; | 1089 int line_thickness = 1; |
| 1094 const SimpleFontData* font_data = | 1090 const SimpleFontData* font_data = |
| 1095 inline_text_box_.GetLineLayoutItem() | 1091 inline_text_box_.GetLineLayoutItem() |
| 1096 .Style(inline_text_box_.IsFirstLineStyle()) | 1092 .Style(inline_text_box_.IsFirstLineStyle()) |
| 1097 ->GetFont() | 1093 ->GetFont() |
| 1098 .PrimaryFont(); | 1094 .PrimaryFont(); |
| 1099 DCHECK(font_data); | 1095 DCHECK(font_data); |
| 1100 int baseline = font_data ? font_data->GetFontMetrics().Ascent() : 0; | 1096 int baseline = font_data ? font_data->GetFontMetrics().Ascent() : 0; |
| 1101 if (underline.Thick() && inline_text_box_.LogicalHeight() - baseline >= 2) | 1097 if (marker.IsThick() && inline_text_box_.LogicalHeight() - baseline >= 2) |
| 1102 line_thickness = 2; | 1098 line_thickness = 2; |
| 1103 | 1099 |
| 1104 // We need to have some space between underlines of subsequent clauses, | 1100 // We need to have some space between underlines of subsequent clauses, |
| 1105 // because some input methods do not use different underline styles for those. | 1101 // because some input methods do not use different underline styles for those. |
| 1106 // We make each line shorter, which has a harmless side effect of shortening | 1102 // We make each line shorter, which has a harmless side effect of shortening |
| 1107 // the first and last clauses, too. | 1103 // the first and last clauses, too. |
| 1108 start += 1; | 1104 start += 1; |
| 1109 width -= 2; | 1105 width -= 2; |
| 1110 | 1106 |
| 1111 context.SetStrokeColor(underline.GetColor()); | 1107 context.SetStrokeColor(marker.UnderlineColor()); |
| 1112 context.SetStrokeThickness(line_thickness); | 1108 context.SetStrokeThickness(line_thickness); |
| 1113 context.DrawLineForText( | 1109 context.DrawLineForText( |
| 1114 FloatPoint( | 1110 FloatPoint( |
| 1115 box_origin.X() + start, | 1111 box_origin.X() + start, |
| 1116 (box_origin.Y() + inline_text_box_.LogicalHeight() - line_thickness) | 1112 (box_origin.Y() + inline_text_box_.LogicalHeight() - line_thickness) |
| 1117 .ToFloat()), | 1113 .ToFloat()), |
| 1118 width); | 1114 width); |
| 1119 } | 1115 } |
| 1120 | 1116 |
| 1121 void InlineTextBoxPainter::PaintTextMatchMarkerForeground( | 1117 void InlineTextBoxPainter::PaintTextMatchMarkerForeground( |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 | 1178 |
| 1183 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), | 1179 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), |
| 1184 inline_text_box_.LogicalHeight())); | 1180 inline_text_box_.LogicalHeight())); |
| 1185 context.Clip(FloatRect(box_rect)); | 1181 context.Clip(FloatRect(box_rect)); |
| 1186 context.DrawHighlightForText(font, run, FloatPoint(box_origin), | 1182 context.DrawHighlightForText(font, run, FloatPoint(box_origin), |
| 1187 box_rect.Height().ToInt(), color, | 1183 box_rect.Height().ToInt(), color, |
| 1188 paint_offsets.first, paint_offsets.second); | 1184 paint_offsets.first, paint_offsets.second); |
| 1189 } | 1185 } |
| 1190 | 1186 |
| 1191 } // namespace blink | 1187 } // namespace blink |
| OLD | NEW |