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

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

Issue 2643413002: Fix 'text-underline-position: under' to use em height ascent/descent (Closed)
Patch Set: Rebaseline Created 3 years, 7 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 25 matching lines...) Expand all
36 const unsigned end_offset = 36 const unsigned end_offset =
37 std::min(marker.EndOffset() - text_box.Start(), text_box.Len()); 37 std::min(marker.EndOffset() - text_box.Start(), text_box.Len());
38 return std::make_pair(start_offset, end_offset); 38 return std::make_pair(start_offset, end_offset);
39 } 39 }
40 } 40 }
41 41
42 enum class ResolvedUnderlinePosition { kRoman, kUnder, kOver }; 42 enum class ResolvedUnderlinePosition { kRoman, kUnder, kOver };
43 43
44 static ResolvedUnderlinePosition ResolveUnderlinePosition( 44 static ResolvedUnderlinePosition ResolveUnderlinePosition(
45 const ComputedStyle& style, 45 const ComputedStyle& style,
46 const InlineTextBox* inline_text_box) { 46 FontBaseline baseline_type) {
47 // |auto| should resolve to |under| to avoid drawing through glyphs in 47 // |auto| should resolve to |under| to avoid drawing through glyphs in
48 // scripts where it would not be appropriate (e.g., ideographs.) 48 // scripts where it would not be appropriate (e.g., ideographs.)
49 // However, this has performance implications. For now, we only work with 49 // However, this has performance implications. For now, we only work with
50 // vertical text. 50 // vertical text.
51 switch (inline_text_box->Root().BaselineType()) { 51 switch (baseline_type) {
52 default:
53 NOTREACHED();
54 // Fall though.
55 case kAlphabeticBaseline: 52 case kAlphabeticBaseline:
56 switch (style.GetTextUnderlinePosition()) { 53 switch (style.GetTextUnderlinePosition()) {
57 default:
58 NOTREACHED();
59 // Fall though.
60 case kTextUnderlinePositionAuto: 54 case kTextUnderlinePositionAuto:
61 return ResolvedUnderlinePosition::kRoman; 55 return ResolvedUnderlinePosition::kRoman;
62 case kTextUnderlinePositionUnder: 56 case kTextUnderlinePositionUnder:
63 return ResolvedUnderlinePosition::kUnder; 57 return ResolvedUnderlinePosition::kUnder;
64 } 58 }
65 break; 59 break;
66 case kIdeographicBaseline: 60 case kIdeographicBaseline:
67 // Compute language-appropriate default underline position. 61 // Compute language-appropriate default underline position.
68 // https://drafts.csswg.org/css-text-decor-3/#default-stylesheet 62 // https://drafts.csswg.org/css-text-decor-3/#default-stylesheet
69 UScriptCode script = style.GetFontDescription().GetScript(); 63 UScriptCode script = style.GetFontDescription().GetScript();
70 if (script == USCRIPT_KATAKANA_OR_HIRAGANA || script == USCRIPT_HANGUL) 64 if (script == USCRIPT_KATAKANA_OR_HIRAGANA || script == USCRIPT_HANGUL)
71 return ResolvedUnderlinePosition::kOver; 65 return ResolvedUnderlinePosition::kOver;
72 return ResolvedUnderlinePosition::kUnder; 66 return ResolvedUnderlinePosition::kUnder;
73 } 67 }
68 NOTREACHED();
69 return ResolvedUnderlinePosition::kRoman;
74 } 70 }
75 71
76 static LineLayoutItem EnclosingUnderlineObject( 72 static LineLayoutItem EnclosingUnderlineObject(
77 const InlineTextBox* inline_text_box) { 73 const InlineTextBox* inline_text_box) {
78 bool first_line = inline_text_box->IsFirstLineStyle(); 74 bool first_line = inline_text_box->IsFirstLineStyle();
79 for (LineLayoutItem current = inline_text_box->Parent()->GetLineLayoutItem(); 75 for (LineLayoutItem current = inline_text_box->Parent()->GetLineLayoutItem();
80 ;) { 76 ;) {
81 if (current.IsLayoutBlock()) 77 if (current.IsLayoutBlock())
82 return current; 78 return current;
83 if (!current.IsLayoutInline() || current.IsRubyText()) 79 if (!current.IsLayoutInline() || current.IsRubyText())
84 return nullptr; 80 return nullptr;
85 81
86 const ComputedStyle& style_to_use = current.StyleRef(first_line); 82 const ComputedStyle& style_to_use = current.StyleRef(first_line);
87 if (style_to_use.GetTextDecoration() & kTextDecorationUnderline) 83 if (style_to_use.GetTextDecoration() & kTextDecorationUnderline)
88 return current; 84 return current;
89 85
90 current = current.Parent(); 86 current = current.Parent();
91 if (!current) 87 if (!current)
92 return current; 88 return current;
93 89
94 if (Node* node = current.GetNode()) { 90 if (Node* node = current.GetNode()) {
95 if (isHTMLAnchorElement(node) || node->HasTagName(HTMLNames::fontTag)) 91 if (isHTMLAnchorElement(node) || node->HasTagName(HTMLNames::fontTag))
96 return current; 92 return current;
97 } 93 }
98 } 94 }
99 } 95 }
100 96
101 static int ComputeUnderlineOffsetForUnder(const ComputedStyle& style, 97 static int ComputeUnderlineOffsetForUnder(
102 const InlineTextBox* inline_text_box, 98 const ComputedStyle& style,
103 bool is_overline = false) { 99 const InlineTextBox* inline_text_box,
100 LineLayoutItem decorating_box,
101 float text_decoration_thickness,
102 LineVerticalPositionType position_type) {
104 const RootInlineBox& root = inline_text_box->Root(); 103 const RootInlineBox& root = inline_text_box->Root();
105 LineLayoutItem decoration_object = EnclosingUnderlineObject(inline_text_box); 104 FontBaseline baseline_type = root.BaselineType();
106 LayoutUnit offset; 105 LayoutUnit offset = inline_text_box->OffsetTo(position_type, baseline_type);
107 if (style.IsFlippedLinesWritingMode()) {
108 LayoutUnit position = inline_text_box->LogicalTop();
109 offset =
110 position - root.MinLogicalTopForUnderline(decoration_object, position);
111 } else {
112 LayoutUnit position = inline_text_box->LogicalBottom();
113 offset = root.MaxLogicalBottomForUnderline(decoration_object, position) -
114 position;
115 }
116 if (is_overline)
117 return std::min(-offset, LayoutUnit()).ToInt();
118 return (inline_text_box->LogicalHeight() + std::max(offset, LayoutUnit()))
119 .ToInt();
120 }
121 106
122 static int ComputeOverlineOffset(const ComputedStyle& style, 107 // Compute offset to the farthest position of the decorating box.
123 const InlineTextBox* inline_text_box) { 108 LayoutUnit logical_top = inline_text_box->LogicalTop();
124 return ComputeUnderlineOffsetForUnder(style, inline_text_box, true); 109 LayoutUnit position = logical_top + offset;
110 LayoutUnit farthest = root.FarthestPositionForUnderline(
111 decorating_box, position_type, baseline_type, position);
112 int offset_int = (farthest - logical_top).ToInt();
eae 2017/05/01 16:21:48 Is flooring the desired behavior here? If so pleas
kojii 2017/05/02 22:56:52 Tested Round() and Floor() but Floor() looks bette
113
114 // Gaps are not needed for TextTop because it generally has internal
115 // leadings.
116 if (position_type == LineVerticalPositionType::TextTop)
117 return offset_int;
118 return !IsOverSide(position_type) ? offset_int + 1 : offset_int - 1;
125 } 119 }
126 120
127 static int ComputeUnderlineOffsetForRoman( 121 static int ComputeUnderlineOffsetForRoman(
128 const FontMetrics& font_metrics, 122 const FontMetrics& font_metrics,
129 const float text_decoration_thickness) { 123 const float text_decoration_thickness) {
130 // Compute the gap between the font and the underline. Use at least one 124 // Compute the gap between the font and the underline. Use at least one
131 // pixel gap, if underline is thick then use a bigger gap. 125 // pixel gap, if underline is thick then use a bigger gap.
132 int gap = 0; 126 int gap = 0;
133 127
134 // Underline position of zero means draw underline on Baseline Position, 128 // Underline position of zero means draw underline on Baseline Position,
135 // in Blink we need at least 1-pixel gap to adding following check. 129 // in Blink we need at least 1-pixel gap to adding following check.
136 // Positive underline Position means underline should be drawn above baseline 130 // Positive underline Position means underline should be drawn above baseline
137 // and negative value means drawing below baseline, negating the value as in 131 // and negative value means drawing below baseline, negating the value as in
138 // Blink downward Y-increases. 132 // Blink downward Y-increases.
139 133
140 if (font_metrics.UnderlinePosition()) 134 if (font_metrics.UnderlinePosition())
141 gap = -font_metrics.UnderlinePosition(); 135 gap = -font_metrics.UnderlinePosition();
142 else 136 else
143 gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f)); 137 gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f));
144 138
145 // Position underline near the alphabetic baseline. 139 // Position underline near the alphabetic baseline.
146 return font_metrics.Ascent() + gap; 140 return font_metrics.Ascent() + gap;
147 } 141 }
148 142
149 static int ComputeUnderlineOffset(ResolvedUnderlinePosition underline_position, 143 static int ComputeUnderlineOffset(ResolvedUnderlinePosition underline_position,
150 const ComputedStyle& style, 144 const ComputedStyle& style,
151 const FontMetrics& font_metrics, 145 const FontMetrics& font_metrics,
152 const InlineTextBox* inline_text_box, 146 const InlineTextBox* inline_text_box,
147 LineLayoutItem decorating_box,
153 const float text_decoration_thickness) { 148 const float text_decoration_thickness) {
154 switch (underline_position) { 149 switch (underline_position) {
155 default: 150 default:
156 NOTREACHED(); 151 NOTREACHED();
157 // Fall through. 152 // Fall through.
158 case ResolvedUnderlinePosition::kRoman: 153 case ResolvedUnderlinePosition::kRoman:
159 return ComputeUnderlineOffsetForRoman(font_metrics, 154 return ComputeUnderlineOffsetForRoman(font_metrics,
160 text_decoration_thickness); 155 text_decoration_thickness);
161 case ResolvedUnderlinePosition::kUnder: 156 case ResolvedUnderlinePosition::kUnder:
162 // Position underline at the under edge of the lowest element's 157 // Position underline at the under edge of the lowest element's
163 // content box. 158 // content box.
164 return ComputeUnderlineOffsetForUnder(style, inline_text_box); 159 return ComputeUnderlineOffsetForUnder(
160 style, inline_text_box, decorating_box, text_decoration_thickness,
161 LineVerticalPositionType::BottomOfEmHeight);
165 } 162 }
166 } 163 }
167 164
168 static bool ShouldSetDecorationAntialias( 165 static bool ShouldSetDecorationAntialias(
169 const Vector<AppliedTextDecoration>& decorations) { 166 const Vector<AppliedTextDecoration>& decorations) {
170 for (const AppliedTextDecoration& decoration : decorations) { 167 for (const AppliedTextDecoration& decoration : decorations) {
171 TextDecorationStyle decoration_style = decoration.Style(); 168 TextDecorationStyle decoration_style = decoration.Style();
172 if (decoration_style == kTextDecorationStyleDotted || 169 if (decoration_style == kTextDecorationStyleDotted ||
173 decoration_style == kTextDecorationStyleDashed) 170 decoration_style == kTextDecorationStyleDashed)
174 return true; 171 return true;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 STACK_ALLOCATED(); 223 STACK_ALLOCATED();
227 224
228 LayoutUnit width; 225 LayoutUnit width;
229 FloatPoint local_origin; 226 FloatPoint local_origin;
230 bool antialias; 227 bool antialias;
231 float baseline; 228 float baseline;
232 const ComputedStyle* style; 229 const ComputedStyle* style;
233 const SimpleFontData* font_data; 230 const SimpleFontData* font_data;
234 float thickness; 231 float thickness;
235 float double_offset; 232 float double_offset;
233 FontBaseline baseline_type;
234 ResolvedUnderlinePosition underline_position;
235 // Decorating box: https://drafts.csswg.org/css-text-decor-3/#decorating-box
236 LineLayoutItem decorating_box;
236 }; 237 };
237 238
238 class AppliedDecorationPainter final { 239 class AppliedDecorationPainter final {
239 STACK_ALLOCATED(); 240 STACK_ALLOCATED();
240 241
241 public: 242 public:
242 AppliedDecorationPainter(GraphicsContext& context, 243 AppliedDecorationPainter(GraphicsContext& context,
243 const DecorationInfo& decoration_info, 244 const DecorationInfo& decoration_info,
244 float start_point_y_offset, 245 float start_point_y_offset,
245 const AppliedTextDecoration& decoration, 246 const AppliedTextDecoration& decoration,
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 503
503 static void RestoreContextFromDecoration(GraphicsContext& context, 504 static void RestoreContextFromDecoration(GraphicsContext& context,
504 const LayoutTextCombine* combined_text, 505 const LayoutTextCombine* combined_text,
505 const LayoutRect& box_rect) { 506 const LayoutRect& box_rect) {
506 if (combined_text) { 507 if (combined_text) {
507 context.ConcatCTM( 508 context.ConcatCTM(
508 TextPainter::Rotation(box_rect, TextPainter::kCounterclockwise)); 509 TextPainter::Rotation(box_rect, TextPainter::kCounterclockwise));
509 } 510 }
510 } 511 }
511 512
513 static float ComputeDecorationThickness(const ComputedStyle* style,
514 const SimpleFontData* font_data) {
515 // Set the thick of the line to be 10% (or something else ?)of the computed
516 // font size and not less than 1px. Using computedFontSize should take care
517 // of zoom as well.
518
519 // Update Underline thickness, in case we have Faulty Font Metrics calculating
520 // underline thickness by old method.
521 float text_decoration_thickness = 0.0;
522 int font_height_int = 0;
523 if (font_data) {
524 text_decoration_thickness =
525 font_data->GetFontMetrics().UnderlineThickness();
526 font_height_int = (int)(font_data->GetFontMetrics().FloatHeight() + 0.5);
eae 2017/05/01 16:21:48 Please add a comment explaining this logic (especi
kojii 2017/05/02 22:56:52 Done, didn't pay much attention when I moved this
527 }
528 if ((text_decoration_thickness == 0.f) ||
529 (text_decoration_thickness >= (font_height_int >> 1))) {
530 text_decoration_thickness = std::max(1.f, style->ComputedFontSize() / 10.f);
531 }
532 return text_decoration_thickness;
533 }
534
512 static void ComputeDecorationInfo( 535 static void ComputeDecorationInfo(
513 DecorationInfo& decoration_info, 536 DecorationInfo& decoration_info,
514 const InlineTextBox& box, 537 const InlineTextBox& box,
515 const LayoutPoint& box_origin, 538 const LayoutPoint& box_origin,
516 const Vector<AppliedTextDecoration>& decorations) { 539 const Vector<AppliedTextDecoration>& decorations) {
517 LayoutPoint local_origin = LayoutPoint(box_origin); 540 LayoutPoint local_origin = LayoutPoint(box_origin);
518 LayoutUnit width = box.LogicalWidth(); 541 LayoutUnit width = box.LogicalWidth();
519 if (box.Truncation() != kCNoTruncation) { 542 if (box.Truncation() != kCNoTruncation) {
520 bool ltr = box.IsLeftToRightDirection(); 543 bool ltr = box.IsLeftToRightDirection();
521 bool flow_is_ltr = 544 bool flow_is_ltr =
522 box.GetLineLayoutItem().Style()->IsLeftToRightDirection(); 545 box.GetLineLayoutItem().Style()->IsLeftToRightDirection();
523 width = LayoutUnit(box.GetLineLayoutItem().Width( 546 width = LayoutUnit(box.GetLineLayoutItem().Width(
524 ltr == flow_is_ltr ? box.Start() : box.Start() + box.Truncation(), 547 ltr == flow_is_ltr ? box.Start() : box.Start() + box.Truncation(),
525 ltr == flow_is_ltr ? box.Truncation() : box.Len() - box.Truncation(), 548 ltr == flow_is_ltr ? box.Truncation() : box.Len() - box.Truncation(),
526 box.TextPos(), flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl, 549 box.TextPos(), flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl,
527 box.IsFirstLineStyle())); 550 box.IsFirstLineStyle()));
528 if (!flow_is_ltr) { 551 if (!flow_is_ltr) {
529 local_origin.Move(box.LogicalWidth() - width, LayoutUnit()); 552 local_origin.Move(box.LogicalWidth() - width, LayoutUnit());
530 } 553 }
531 } 554 }
532 decoration_info.width = width; 555 decoration_info.width = width;
533 decoration_info.local_origin = FloatPoint(local_origin); 556 decoration_info.local_origin = FloatPoint(local_origin);
534 557
535 decoration_info.antialias = ShouldSetDecorationAntialias(decorations); 558 decoration_info.antialias = ShouldSetDecorationAntialias(decorations);
536 559
537 decoration_info.style = 560 decoration_info.style =
538 LineLayoutAPIShim::LayoutObjectFrom(box.GetLineLayoutItem()) 561 LineLayoutAPIShim::LayoutObjectFrom(box.GetLineLayoutItem())
539 ->Style(box.IsFirstLineStyle()); 562 ->Style(box.IsFirstLineStyle());
563 decoration_info.baseline_type = box.Root().BaselineType();
564 decoration_info.underline_position = ResolveUnderlinePosition(
565 *decoration_info.style, decoration_info.baseline_type);
566
540 decoration_info.font_data = decoration_info.style->GetFont().PrimaryFont(); 567 decoration_info.font_data = decoration_info.style->GetFont().PrimaryFont();
541 DCHECK(decoration_info.font_data); 568 DCHECK(decoration_info.font_data);
542 decoration_info.baseline = 569 decoration_info.baseline =
543 decoration_info.font_data 570 decoration_info.font_data
544 ? decoration_info.font_data->GetFontMetrics().FloatAscent() 571 ? decoration_info.font_data->GetFontMetrics().FloatAscent()
545 : 0; 572 : 0;
546 573
547 // Set the thick of the line to be 10% (or something else ?)of the computed 574 if (decoration_info.underline_position == ResolvedUnderlinePosition::kRoman) {
548 // font size and not less than 1px. Using computedFontSize should take care 575 decoration_info.thickness = ComputeDecorationThickness(
549 // of zoom as well. 576 decoration_info.style, decoration_info.font_data);
550 577 } else {
551 // Update Underline thickness, in case we have Faulty Font Metrics calculating 578 // Compute decorating box. Position and thickness are computed from the
552 // underline thickness by old method. 579 // decorating box.
553 float text_decoration_thickness = 0.0; 580 // Only for non-Roman for now for the performance implications.
554 int font_height_int = 0; 581 // https:// drafts.csswg.org/css-text-decor-3/#decorating-box
555 if (decoration_info.font_data) { 582 decoration_info.decorating_box = EnclosingUnderlineObject(&box);
556 text_decoration_thickness = 583 if (decoration_info.decorating_box) {
557 decoration_info.font_data->GetFontMetrics().UnderlineThickness(); 584 decoration_info.thickness = ComputeDecorationThickness(
558 font_height_int = 585 decoration_info.decorating_box.Style(),
559 (int)(decoration_info.font_data->GetFontMetrics().FloatHeight() + 0.5); 586 decoration_info.decorating_box.Style()->GetFont().PrimaryFont());
587 } else {
588 decoration_info.thickness = ComputeDecorationThickness(
589 decoration_info.style, decoration_info.font_data);
590 }
560 } 591 }
561 if ((text_decoration_thickness == 0.f) ||
562 (text_decoration_thickness >= (font_height_int >> 1))) {
563 text_decoration_thickness =
564 std::max(1.f, decoration_info.style->ComputedFontSize() / 10.f);
565 }
566 decoration_info.thickness = text_decoration_thickness;
567 592
568 // Offset between lines - always non-zero, so lines never cross each other. 593 // Offset between lines - always non-zero, so lines never cross each other.
569 decoration_info.double_offset = text_decoration_thickness + 1.f; 594 decoration_info.double_offset = decoration_info.thickness + 1.f;
570 } 595 }
571 596
572 static void PaintDecorationsExceptLineThrough( 597 static void PaintDecorationsExceptLineThrough(
573 TextPainter& text_painter, 598 TextPainter& text_painter,
574 bool& has_line_through_decoration, 599 bool& has_line_through_decoration,
575 const InlineTextBox& box, 600 const InlineTextBox& box,
576 const DecorationInfo& decoration_info, 601 const DecorationInfo& decoration_info,
577 const PaintInfo& paint_info, 602 const PaintInfo& paint_info,
578 const Vector<AppliedTextDecoration>& decorations) { 603 const Vector<AppliedTextDecoration>& decorations) {
579 GraphicsContext& context = paint_info.context; 604 GraphicsContext& context = paint_info.context;
580 GraphicsContextStateSaver state_saver(context); 605 GraphicsContextStateSaver state_saver(context);
581 context.SetStrokeThickness(decoration_info.thickness); 606 context.SetStrokeThickness(decoration_info.thickness);
582 bool skip_intercepts = 607 bool skip_intercepts =
583 decoration_info.style->GetTextDecorationSkip() & kTextDecorationSkipInk; 608 decoration_info.style->GetTextDecorationSkip() & kTextDecorationSkipInk;
584 609
585 // text-underline-position may flip underline and overline. 610 // text-underline-position may flip underline and overline.
586 ResolvedUnderlinePosition underline_position = 611 ResolvedUnderlinePosition underline_position =
587 ResolveUnderlinePosition(*decoration_info.style, &box); 612 decoration_info.underline_position;
588 bool flip_underline_and_overline = false; 613 bool flip_underline_and_overline = false;
589 if (underline_position == ResolvedUnderlinePosition::kOver) { 614 if (underline_position == ResolvedUnderlinePosition::kOver) {
590 flip_underline_and_overline = true; 615 flip_underline_and_overline = true;
591 underline_position = ResolvedUnderlinePosition::kUnder; 616 underline_position = ResolvedUnderlinePosition::kUnder;
592 } 617 }
593 618
594 for (const AppliedTextDecoration& decoration : decorations) { 619 for (const AppliedTextDecoration& decoration : decorations) {
595 TextDecoration lines = decoration.Lines(); 620 TextDecoration lines = decoration.Lines();
596 if (flip_underline_and_overline) { 621 if (flip_underline_and_overline) {
597 lines = static_cast<TextDecoration>( 622 lines = static_cast<TextDecoration>(
598 lines ^ (kTextDecorationUnderline | kTextDecorationOverline)); 623 lines ^ (kTextDecorationUnderline | kTextDecorationOverline));
599 } 624 }
600 if ((lines & kTextDecorationUnderline) && decoration_info.font_data) { 625 if ((lines & kTextDecorationUnderline) && decoration_info.font_data) {
601 const int underline_offset = 626 const int underline_offset = ComputeUnderlineOffset(
602 ComputeUnderlineOffset(underline_position, *decoration_info.style, 627 underline_position, *decoration_info.style,
603 decoration_info.font_data->GetFontMetrics(), 628 decoration_info.font_data->GetFontMetrics(), &box,
604 &box, decoration_info.thickness); 629 decoration_info.decorating_box, decoration_info.thickness);
605 AppliedDecorationPainter decoration_painter( 630 AppliedDecorationPainter decoration_painter(
606 context, decoration_info, underline_offset, decoration, 631 context, decoration_info, underline_offset, decoration,
607 decoration_info.double_offset, 1); 632 decoration_info.double_offset, 1);
608 if (skip_intercepts) { 633 if (skip_intercepts) {
609 text_painter.ClipDecorationsStripe( 634 text_painter.ClipDecorationsStripe(
610 -decoration_info.baseline + 635 -decoration_info.baseline +
611 decoration_painter.DecorationBounds().Y() - 636 decoration_painter.DecorationBounds().Y() -
612 decoration_info.local_origin.Y(), 637 decoration_info.local_origin.Y(),
613 decoration_painter.DecorationBounds().Height(), 638 decoration_painter.DecorationBounds().Height(),
614 decoration_info.thickness); 639 decoration_info.thickness);
615 } 640 }
616 decoration_painter.Paint(); 641 decoration_painter.Paint();
617 } 642 }
618 if (lines & kTextDecorationOverline) { 643 if (lines & kTextDecorationOverline) {
619 const int overline_offset = 644 const int overline_offset = ComputeUnderlineOffsetForUnder(
620 ComputeOverlineOffset(*decoration_info.style, &box); 645 *decoration_info.style, &box, decoration_info.decorating_box,
646 decoration_info.thickness,
647 flip_underline_and_overline ? LineVerticalPositionType::TopOfEmHeight
648 : LineVerticalPositionType::TextTop);
621 AppliedDecorationPainter decoration_painter( 649 AppliedDecorationPainter decoration_painter(
622 context, decoration_info, overline_offset, decoration, 650 context, decoration_info, overline_offset, decoration,
623 -decoration_info.double_offset, 1); 651 -decoration_info.double_offset, 1);
624 if (skip_intercepts) { 652 if (skip_intercepts) {
625 text_painter.ClipDecorationsStripe( 653 text_painter.ClipDecorationsStripe(
626 -decoration_info.baseline + 654 -decoration_info.baseline +
627 decoration_painter.DecorationBounds().Y() - 655 decoration_painter.DecorationBounds().Y() -
628 decoration_info.local_origin.Y(), 656 decoration_info.local_origin.Y(),
629 decoration_painter.DecorationBounds().Height(), 657 decoration_painter.DecorationBounds().Height(),
630 decoration_info.thickness); 658 decoration_info.thickness);
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 1599
1572 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), 1600 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(),
1573 inline_text_box_.LogicalHeight())); 1601 inline_text_box_.LogicalHeight()));
1574 context.Clip(FloatRect(box_rect)); 1602 context.Clip(FloatRect(box_rect));
1575 context.DrawHighlightForText(font, run, FloatPoint(box_origin), 1603 context.DrawHighlightForText(font, run, FloatPoint(box_origin),
1576 box_rect.Height().ToInt(), color, 1604 box_rect.Height().ToInt(), color,
1577 paint_offsets.first, paint_offsets.second); 1605 paint_offsets.first, paint_offsets.second);
1578 } 1606 }
1579 1607
1580 } // namespace blink 1608 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698