| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 const InlineTextBox* inline_text_box) { | 74 const InlineTextBox* inline_text_box) { |
| 75 bool first_line = inline_text_box->IsFirstLineStyle(); | 75 bool first_line = inline_text_box->IsFirstLineStyle(); |
| 76 for (LineLayoutItem current = inline_text_box->Parent()->GetLineLayoutItem(); | 76 for (LineLayoutItem current = inline_text_box->Parent()->GetLineLayoutItem(); |
| 77 ;) { | 77 ;) { |
| 78 if (current.IsLayoutBlock()) | 78 if (current.IsLayoutBlock()) |
| 79 return current; | 79 return current; |
| 80 if (!current.IsLayoutInline() || current.IsRubyText()) | 80 if (!current.IsLayoutInline() || current.IsRubyText()) |
| 81 return nullptr; | 81 return nullptr; |
| 82 | 82 |
| 83 const ComputedStyle& style_to_use = current.StyleRef(first_line); | 83 const ComputedStyle& style_to_use = current.StyleRef(first_line); |
| 84 if (style_to_use.GetTextDecoration() & kTextDecorationUnderline) | 84 if (EnumHasFlags(style_to_use.GetTextDecoration(), |
| 85 TextDecoration::kUnderline)) |
| 85 return current; | 86 return current; |
| 86 | 87 |
| 87 current = current.Parent(); | 88 current = current.Parent(); |
| 88 if (!current) | 89 if (!current) |
| 89 return current; | 90 return current; |
| 90 | 91 |
| 91 if (Node* node = current.GetNode()) { | 92 if (Node* node = current.GetNode()) { |
| 92 if (isHTMLAnchorElement(node) || node->HasTagName(HTMLNames::fontTag)) | 93 if (isHTMLAnchorElement(node) || node->HasTagName(HTMLNames::fontTag)) |
| 93 return current; | 94 return current; |
| 94 } | 95 } |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 ResolveUnderlinePosition(*decoration_info.style, &box); | 585 ResolveUnderlinePosition(*decoration_info.style, &box); |
| 585 bool flip_underline_and_overline = false; | 586 bool flip_underline_and_overline = false; |
| 586 if (underline_position == ResolvedUnderlinePosition::kOver) { | 587 if (underline_position == ResolvedUnderlinePosition::kOver) { |
| 587 flip_underline_and_overline = true; | 588 flip_underline_and_overline = true; |
| 588 underline_position = ResolvedUnderlinePosition::kUnder; | 589 underline_position = ResolvedUnderlinePosition::kUnder; |
| 589 } | 590 } |
| 590 | 591 |
| 591 for (const AppliedTextDecoration& decoration : decorations) { | 592 for (const AppliedTextDecoration& decoration : decorations) { |
| 592 TextDecoration lines = decoration.Lines(); | 593 TextDecoration lines = decoration.Lines(); |
| 593 if (flip_underline_and_overline) { | 594 if (flip_underline_and_overline) { |
| 594 lines = static_cast<TextDecoration>( | 595 lines ^= (TextDecoration::kUnderline | TextDecoration::kOverline); |
| 595 lines ^ (kTextDecorationUnderline | kTextDecorationOverline)); | |
| 596 } | 596 } |
| 597 if ((lines & kTextDecorationUnderline) && decoration_info.font_data) { | 597 if (EnumHasFlags(lines, TextDecoration::kUnderline) && |
| 598 decoration_info.font_data) { |
| 598 const int underline_offset = | 599 const int underline_offset = |
| 599 ComputeUnderlineOffset(underline_position, *decoration_info.style, | 600 ComputeUnderlineOffset(underline_position, *decoration_info.style, |
| 600 decoration_info.font_data->GetFontMetrics(), | 601 decoration_info.font_data->GetFontMetrics(), |
| 601 &box, decoration_info.thickness); | 602 &box, decoration_info.thickness); |
| 602 AppliedDecorationPainter decoration_painter( | 603 AppliedDecorationPainter decoration_painter( |
| 603 context, decoration_info, underline_offset, decoration, | 604 context, decoration_info, underline_offset, decoration, |
| 604 decoration_info.double_offset, 1); | 605 decoration_info.double_offset, 1); |
| 605 if (skip_intercepts) { | 606 if (skip_intercepts) { |
| 606 text_painter.ClipDecorationsStripe( | 607 text_painter.ClipDecorationsStripe( |
| 607 -decoration_info.baseline + | 608 -decoration_info.baseline + |
| 608 decoration_painter.DecorationBounds().Y() - | 609 decoration_painter.DecorationBounds().Y() - |
| 609 decoration_info.local_origin.Y(), | 610 decoration_info.local_origin.Y(), |
| 610 decoration_painter.DecorationBounds().Height(), | 611 decoration_painter.DecorationBounds().Height(), |
| 611 decoration_info.thickness); | 612 decoration_info.thickness); |
| 612 } | 613 } |
| 613 decoration_painter.Paint(); | 614 decoration_painter.Paint(); |
| 614 } | 615 } |
| 615 if (lines & kTextDecorationOverline) { | 616 if (EnumHasFlags(lines, TextDecoration::kOverline)) { |
| 616 const int overline_offset = | 617 const int overline_offset = |
| 617 ComputeOverlineOffset(*decoration_info.style, &box); | 618 ComputeOverlineOffset(*decoration_info.style, &box); |
| 618 AppliedDecorationPainter decoration_painter( | 619 AppliedDecorationPainter decoration_painter( |
| 619 context, decoration_info, overline_offset, decoration, | 620 context, decoration_info, overline_offset, decoration, |
| 620 -decoration_info.double_offset, 1); | 621 -decoration_info.double_offset, 1); |
| 621 if (skip_intercepts) { | 622 if (skip_intercepts) { |
| 622 text_painter.ClipDecorationsStripe( | 623 text_painter.ClipDecorationsStripe( |
| 623 -decoration_info.baseline + | 624 -decoration_info.baseline + |
| 624 decoration_painter.DecorationBounds().Y() - | 625 decoration_painter.DecorationBounds().Y() - |
| 625 decoration_info.local_origin.Y(), | 626 decoration_info.local_origin.Y(), |
| 626 decoration_painter.DecorationBounds().Height(), | 627 decoration_painter.DecorationBounds().Height(), |
| 627 decoration_info.thickness); | 628 decoration_info.thickness); |
| 628 } | 629 } |
| 629 decoration_painter.Paint(); | 630 decoration_painter.Paint(); |
| 630 } | 631 } |
| 631 // We could instead build a vector of the TextDecoration instances needing | 632 // We could instead build a vector of the TextDecoration instances needing |
| 632 // line-through but this is a rare case so better to avoid vector overhead. | 633 // line-through but this is a rare case so better to avoid vector overhead. |
| 633 has_line_through_decoration |= ((lines & kTextDecorationLineThrough) != 0); | 634 has_line_through_decoration |= |
| 635 EnumHasFlags(lines, TextDecoration::kLineThrough); |
| 634 } | 636 } |
| 635 } | 637 } |
| 636 | 638 |
| 637 static void PaintDecorationsOnlyLineThrough( | 639 static void PaintDecorationsOnlyLineThrough( |
| 638 TextPainter& text_painter, | 640 TextPainter& text_painter, |
| 639 const DecorationInfo& decoration_info, | 641 const DecorationInfo& decoration_info, |
| 640 const PaintInfo& paint_info, | 642 const PaintInfo& paint_info, |
| 641 const Vector<AppliedTextDecoration>& decorations) { | 643 const Vector<AppliedTextDecoration>& decorations) { |
| 642 GraphicsContext& context = paint_info.context; | 644 GraphicsContext& context = paint_info.context; |
| 643 GraphicsContextStateSaver state_saver(context); | 645 GraphicsContextStateSaver state_saver(context); |
| 644 context.SetStrokeThickness(decoration_info.thickness); | 646 context.SetStrokeThickness(decoration_info.thickness); |
| 645 for (const AppliedTextDecoration& decoration : decorations) { | 647 for (const AppliedTextDecoration& decoration : decorations) { |
| 646 TextDecoration lines = decoration.Lines(); | 648 TextDecoration lines = decoration.Lines(); |
| 647 if (lines & kTextDecorationLineThrough) { | 649 if (EnumHasFlags(lines, TextDecoration::kLineThrough)) { |
| 648 const float line_through_offset = 2 * decoration_info.baseline / 3; | 650 const float line_through_offset = 2 * decoration_info.baseline / 3; |
| 649 AppliedDecorationPainter decoration_painter( | 651 AppliedDecorationPainter decoration_painter( |
| 650 context, decoration_info, line_through_offset, decoration, | 652 context, decoration_info, line_through_offset, decoration, |
| 651 decoration_info.double_offset, 0); | 653 decoration_info.double_offset, 0); |
| 652 // No skip: ink for line-through, | 654 // No skip: ink for line-through, |
| 653 // compare https://github.com/w3c/csswg-drafts/issues/711 | 655 // compare https://github.com/w3c/csswg-drafts/issues/711 |
| 654 decoration_painter.Paint(); | 656 decoration_painter.Paint(); |
| 655 } | 657 } |
| 656 } | 658 } |
| 657 } | 659 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 emphasis_mark_position); | 855 emphasis_mark_position); |
| 854 if (combined_text) | 856 if (combined_text) |
| 855 text_painter.SetCombinedText(combined_text); | 857 text_painter.SetCombinedText(combined_text); |
| 856 if (inline_text_box_.Truncation() != kCNoTruncation && ltr != flow_is_ltr) | 858 if (inline_text_box_.Truncation() != kCNoTruncation && ltr != flow_is_ltr) |
| 857 text_painter.SetEllipsisOffset(inline_text_box_.Truncation()); | 859 text_painter.SetEllipsisOffset(inline_text_box_.Truncation()); |
| 858 | 860 |
| 859 if (!paint_selected_text_only) { | 861 if (!paint_selected_text_only) { |
| 860 // Paint text decorations except line-through. | 862 // Paint text decorations except line-through. |
| 861 DecorationInfo decoration_info; | 863 DecorationInfo decoration_info; |
| 862 bool has_line_through_decoration = false; | 864 bool has_line_through_decoration = false; |
| 863 if (style_to_use.TextDecorationsInEffect() != kTextDecorationNone && | 865 if (style_to_use.TextDecorationsInEffect() != TextDecoration::kNone && |
| 864 inline_text_box_.Truncation() != kCFullTruncation) { | 866 inline_text_box_.Truncation() != kCFullTruncation) { |
| 865 ComputeDecorationInfo(decoration_info, inline_text_box_, box_origin, | 867 ComputeDecorationInfo(decoration_info, inline_text_box_, box_origin, |
| 866 style_to_use.AppliedTextDecorations()); | 868 style_to_use.AppliedTextDecorations()); |
| 867 GraphicsContextStateSaver state_saver(context, false); | 869 GraphicsContextStateSaver state_saver(context, false); |
| 868 PrepareContextForDecoration(context, state_saver, | 870 PrepareContextForDecoration(context, state_saver, |
| 869 inline_text_box_.IsHorizontal(), text_style, | 871 inline_text_box_.IsHorizontal(), text_style, |
| 870 combined_text, box_rect); | 872 combined_text, box_rect); |
| 871 PaintDecorationsExceptLineThrough( | 873 PaintDecorationsExceptLineThrough( |
| 872 text_painter, has_line_through_decoration, inline_text_box_, | 874 text_painter, has_line_through_decoration, inline_text_box_, |
| 873 decoration_info, paint_info, style_to_use.AppliedTextDecorations()); | 875 decoration_info, paint_info, style_to_use.AppliedTextDecorations()); |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 | 1455 |
| 1454 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), | 1456 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), |
| 1455 inline_text_box_.LogicalHeight())); | 1457 inline_text_box_.LogicalHeight())); |
| 1456 context.Clip(FloatRect(box_rect)); | 1458 context.Clip(FloatRect(box_rect)); |
| 1457 context.DrawHighlightForText(font, run, FloatPoint(box_origin), | 1459 context.DrawHighlightForText(font, run, FloatPoint(box_origin), |
| 1458 box_rect.Height().ToInt(), color, | 1460 box_rect.Height().ToInt(), color, |
| 1459 paint_offsets.first, paint_offsets.second); | 1461 paint_offsets.first, paint_offsets.second); |
| 1460 } | 1462 } |
| 1461 | 1463 |
| 1462 } // namespace blink | 1464 } // namespace blink |
| OLD | NEW |