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

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: eae review 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 // Round() looks more logical but Floor() produces better results in
113 // positive/negative offsets, in horizontal/vertical flows, on Win/Mac/Linux.
114 int offset_int = (farthest - logical_top).Floor();
115
116 // Gaps are not needed for TextTop because it generally has internal
117 // leadings.
118 if (position_type == LineVerticalPositionType::TextTop)
119 return offset_int;
120 return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
125 } 121 }
126 122
127 static int ComputeUnderlineOffsetForRoman( 123 static int ComputeUnderlineOffsetForRoman(
128 const FontMetrics& font_metrics, 124 const FontMetrics& font_metrics,
129 const float text_decoration_thickness) { 125 const float text_decoration_thickness) {
130 // Compute the gap between the font and the underline. Use at least one 126 // 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. 127 // pixel gap, if underline is thick then use a bigger gap.
132 int gap = 0; 128 int gap = 0;
133 129
134 // Underline position of zero means draw underline on Baseline Position, 130 // Underline position of zero means draw underline on Baseline Position,
135 // in Blink we need at least 1-pixel gap to adding following check. 131 // in Blink we need at least 1-pixel gap to adding following check.
136 // Positive underline Position means underline should be drawn above baseline 132 // Positive underline Position means underline should be drawn above baseline
137 // and negative value means drawing below baseline, negating the value as in 133 // and negative value means drawing below baseline, negating the value as in
138 // Blink downward Y-increases. 134 // Blink downward Y-increases.
139 135
140 if (font_metrics.UnderlinePosition()) 136 if (font_metrics.UnderlinePosition())
141 gap = -font_metrics.UnderlinePosition(); 137 gap = -font_metrics.UnderlinePosition();
142 else 138 else
143 gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f)); 139 gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f));
144 140
145 // Position underline near the alphabetic baseline. 141 // Position underline near the alphabetic baseline.
146 return font_metrics.Ascent() + gap; 142 return font_metrics.Ascent() + gap;
147 } 143 }
148 144
149 static int ComputeUnderlineOffset(ResolvedUnderlinePosition underline_position, 145 static int ComputeUnderlineOffset(ResolvedUnderlinePosition underline_position,
150 const ComputedStyle& style, 146 const ComputedStyle& style,
151 const FontMetrics& font_metrics, 147 const FontMetrics& font_metrics,
152 const InlineTextBox* inline_text_box, 148 const InlineTextBox* inline_text_box,
149 LineLayoutItem decorating_box,
153 const float text_decoration_thickness) { 150 const float text_decoration_thickness) {
154 switch (underline_position) { 151 switch (underline_position) {
155 default: 152 default:
156 NOTREACHED(); 153 NOTREACHED();
157 // Fall through. 154 // Fall through.
158 case ResolvedUnderlinePosition::kRoman: 155 case ResolvedUnderlinePosition::kRoman:
159 return ComputeUnderlineOffsetForRoman(font_metrics, 156 return ComputeUnderlineOffsetForRoman(font_metrics,
160 text_decoration_thickness); 157 text_decoration_thickness);
161 case ResolvedUnderlinePosition::kUnder: 158 case ResolvedUnderlinePosition::kUnder:
162 // Position underline at the under edge of the lowest element's 159 // Position underline at the under edge of the lowest element's
163 // content box. 160 // content box.
164 return ComputeUnderlineOffsetForUnder(style, inline_text_box); 161 return ComputeUnderlineOffsetForUnder(
162 style, inline_text_box, decorating_box, text_decoration_thickness,
163 LineVerticalPositionType::BottomOfEmHeight);
165 } 164 }
166 } 165 }
167 166
168 static bool ShouldSetDecorationAntialias( 167 static bool ShouldSetDecorationAntialias(
169 const Vector<AppliedTextDecoration>& decorations) { 168 const Vector<AppliedTextDecoration>& decorations) {
170 for (const AppliedTextDecoration& decoration : decorations) { 169 for (const AppliedTextDecoration& decoration : decorations) {
171 TextDecorationStyle decoration_style = decoration.Style(); 170 TextDecorationStyle decoration_style = decoration.Style();
172 if (decoration_style == kTextDecorationStyleDotted || 171 if (decoration_style == kTextDecorationStyleDotted ||
173 decoration_style == kTextDecorationStyleDashed) 172 decoration_style == kTextDecorationStyleDashed)
174 return true; 173 return true;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 STACK_ALLOCATED(); 225 STACK_ALLOCATED();
227 226
228 LayoutUnit width; 227 LayoutUnit width;
229 FloatPoint local_origin; 228 FloatPoint local_origin;
230 bool antialias; 229 bool antialias;
231 float baseline; 230 float baseline;
232 const ComputedStyle* style; 231 const ComputedStyle* style;
233 const SimpleFontData* font_data; 232 const SimpleFontData* font_data;
234 float thickness; 233 float thickness;
235 float double_offset; 234 float double_offset;
235 FontBaseline baseline_type;
236 ResolvedUnderlinePosition underline_position;
237 // Decorating box: https://drafts.csswg.org/css-text-decor-3/#decorating-box
238 LineLayoutItem decorating_box;
236 }; 239 };
237 240
238 class AppliedDecorationPainter final { 241 class AppliedDecorationPainter final {
239 STACK_ALLOCATED(); 242 STACK_ALLOCATED();
240 243
241 public: 244 public:
242 AppliedDecorationPainter(GraphicsContext& context, 245 AppliedDecorationPainter(GraphicsContext& context,
243 const DecorationInfo& decoration_info, 246 const DecorationInfo& decoration_info,
244 float start_point_y_offset, 247 float start_point_y_offset,
245 const AppliedTextDecoration& decoration, 248 const AppliedTextDecoration& decoration,
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 505
503 static void RestoreContextFromDecoration(GraphicsContext& context, 506 static void RestoreContextFromDecoration(GraphicsContext& context,
504 const LayoutTextCombine* combined_text, 507 const LayoutTextCombine* combined_text,
505 const LayoutRect& box_rect) { 508 const LayoutRect& box_rect) {
506 if (combined_text) { 509 if (combined_text) {
507 context.ConcatCTM( 510 context.ConcatCTM(
508 TextPainter::Rotation(box_rect, TextPainter::kCounterclockwise)); 511 TextPainter::Rotation(box_rect, TextPainter::kCounterclockwise));
509 } 512 }
510 } 513 }
511 514
515 static float ComputeDecorationThickness(const ComputedStyle* style,
516 const SimpleFontData* font_data) {
517 // Set the thick of the line to be 10% (or something else ?)of the computed
518 // font size and not less than 1px. Using computedFontSize should take care
519 // of zoom as well.
520
521 // Update Underline thickness, in case we have Faulty Font Metrics calculating
522 // underline thickness by old method.
523 float text_decoration_thickness = 0.0;
524 int font_height_int = 0;
525 if (font_data) {
526 text_decoration_thickness =
527 font_data->GetFontMetrics().UnderlineThickness();
528 font_height_int = font_data->GetFontMetrics().Height();
529 }
530 if ((text_decoration_thickness == 0.f) ||
531 (text_decoration_thickness >= (font_height_int >> 1))) {
532 text_decoration_thickness = std::max(1.f, style->ComputedFontSize() / 10.f);
533 }
534 return text_decoration_thickness;
535 }
536
512 static void ComputeDecorationInfo( 537 static void ComputeDecorationInfo(
513 DecorationInfo& decoration_info, 538 DecorationInfo& decoration_info,
514 const InlineTextBox& box, 539 const InlineTextBox& box,
515 const LayoutPoint& box_origin, 540 const LayoutPoint& box_origin,
516 const Vector<AppliedTextDecoration>& decorations) { 541 const Vector<AppliedTextDecoration>& decorations) {
517 LayoutPoint local_origin = LayoutPoint(box_origin); 542 LayoutPoint local_origin = LayoutPoint(box_origin);
518 LayoutUnit width = box.LogicalWidth(); 543 LayoutUnit width = box.LogicalWidth();
519 if (box.Truncation() != kCNoTruncation) { 544 if (box.Truncation() != kCNoTruncation) {
520 bool ltr = box.IsLeftToRightDirection(); 545 bool ltr = box.IsLeftToRightDirection();
521 bool flow_is_ltr = 546 bool flow_is_ltr =
522 box.GetLineLayoutItem().Style()->IsLeftToRightDirection(); 547 box.GetLineLayoutItem().Style()->IsLeftToRightDirection();
523 width = LayoutUnit(box.GetLineLayoutItem().Width( 548 width = LayoutUnit(box.GetLineLayoutItem().Width(
524 ltr == flow_is_ltr ? box.Start() : box.Start() + box.Truncation(), 549 ltr == flow_is_ltr ? box.Start() : box.Start() + box.Truncation(),
525 ltr == flow_is_ltr ? box.Truncation() : box.Len() - box.Truncation(), 550 ltr == flow_is_ltr ? box.Truncation() : box.Len() - box.Truncation(),
526 box.TextPos(), flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl, 551 box.TextPos(), flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl,
527 box.IsFirstLineStyle())); 552 box.IsFirstLineStyle()));
528 if (!flow_is_ltr) { 553 if (!flow_is_ltr) {
529 local_origin.Move(box.LogicalWidth() - width, LayoutUnit()); 554 local_origin.Move(box.LogicalWidth() - width, LayoutUnit());
530 } 555 }
531 } 556 }
532 decoration_info.width = width; 557 decoration_info.width = width;
533 decoration_info.local_origin = FloatPoint(local_origin); 558 decoration_info.local_origin = FloatPoint(local_origin);
534 559
535 decoration_info.antialias = ShouldSetDecorationAntialias(decorations); 560 decoration_info.antialias = ShouldSetDecorationAntialias(decorations);
536 561
537 decoration_info.style = 562 decoration_info.style =
538 LineLayoutAPIShim::LayoutObjectFrom(box.GetLineLayoutItem()) 563 LineLayoutAPIShim::LayoutObjectFrom(box.GetLineLayoutItem())
539 ->Style(box.IsFirstLineStyle()); 564 ->Style(box.IsFirstLineStyle());
565 decoration_info.baseline_type = box.Root().BaselineType();
566 decoration_info.underline_position = ResolveUnderlinePosition(
567 *decoration_info.style, decoration_info.baseline_type);
568
540 decoration_info.font_data = decoration_info.style->GetFont().PrimaryFont(); 569 decoration_info.font_data = decoration_info.style->GetFont().PrimaryFont();
541 DCHECK(decoration_info.font_data); 570 DCHECK(decoration_info.font_data);
542 decoration_info.baseline = 571 decoration_info.baseline =
543 decoration_info.font_data 572 decoration_info.font_data
544 ? decoration_info.font_data->GetFontMetrics().FloatAscent() 573 ? decoration_info.font_data->GetFontMetrics().FloatAscent()
545 : 0; 574 : 0;
546 575
547 // Set the thick of the line to be 10% (or something else ?)of the computed 576 if (decoration_info.underline_position == ResolvedUnderlinePosition::kRoman) {
548 // font size and not less than 1px. Using computedFontSize should take care 577 decoration_info.thickness = ComputeDecorationThickness(
549 // of zoom as well. 578 decoration_info.style, decoration_info.font_data);
550 579 } else {
551 // Update Underline thickness, in case we have Faulty Font Metrics calculating 580 // Compute decorating box. Position and thickness are computed from the
552 // underline thickness by old method. 581 // decorating box.
553 float text_decoration_thickness = 0.0; 582 // Only for non-Roman for now for the performance implications.
554 int font_height_int = 0; 583 // https:// drafts.csswg.org/css-text-decor-3/#decorating-box
555 if (decoration_info.font_data) { 584 decoration_info.decorating_box = EnclosingUnderlineObject(&box);
556 text_decoration_thickness = 585 if (decoration_info.decorating_box) {
557 decoration_info.font_data->GetFontMetrics().UnderlineThickness(); 586 decoration_info.thickness = ComputeDecorationThickness(
558 font_height_int = 587 decoration_info.decorating_box.Style(),
559 (int)(decoration_info.font_data->GetFontMetrics().FloatHeight() + 0.5); 588 decoration_info.decorating_box.Style()->GetFont().PrimaryFont());
589 } else {
590 decoration_info.thickness = ComputeDecorationThickness(
591 decoration_info.style, decoration_info.font_data);
592 }
560 } 593 }
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 594
568 // Offset between lines - always non-zero, so lines never cross each other. 595 // Offset between lines - always non-zero, so lines never cross each other.
569 decoration_info.double_offset = text_decoration_thickness + 1.f; 596 decoration_info.double_offset = decoration_info.thickness + 1.f;
570 } 597 }
571 598
572 static void PaintDecorationsExceptLineThrough( 599 static void PaintDecorationsExceptLineThrough(
573 TextPainter& text_painter, 600 TextPainter& text_painter,
574 bool& has_line_through_decoration, 601 bool& has_line_through_decoration,
575 const InlineTextBox& box, 602 const InlineTextBox& box,
576 const DecorationInfo& decoration_info, 603 const DecorationInfo& decoration_info,
577 const PaintInfo& paint_info, 604 const PaintInfo& paint_info,
578 const Vector<AppliedTextDecoration>& decorations) { 605 const Vector<AppliedTextDecoration>& decorations) {
579 GraphicsContext& context = paint_info.context; 606 GraphicsContext& context = paint_info.context;
580 GraphicsContextStateSaver state_saver(context); 607 GraphicsContextStateSaver state_saver(context);
581 context.SetStrokeThickness(decoration_info.thickness); 608 context.SetStrokeThickness(decoration_info.thickness);
582 bool skip_intercepts = 609 bool skip_intercepts =
583 decoration_info.style->GetTextDecorationSkip() & kTextDecorationSkipInk; 610 decoration_info.style->GetTextDecorationSkip() & kTextDecorationSkipInk;
584 611
585 // text-underline-position may flip underline and overline. 612 // text-underline-position may flip underline and overline.
586 ResolvedUnderlinePosition underline_position = 613 ResolvedUnderlinePosition underline_position =
587 ResolveUnderlinePosition(*decoration_info.style, &box); 614 decoration_info.underline_position;
588 bool flip_underline_and_overline = false; 615 bool flip_underline_and_overline = false;
589 if (underline_position == ResolvedUnderlinePosition::kOver) { 616 if (underline_position == ResolvedUnderlinePosition::kOver) {
590 flip_underline_and_overline = true; 617 flip_underline_and_overline = true;
591 underline_position = ResolvedUnderlinePosition::kUnder; 618 underline_position = ResolvedUnderlinePosition::kUnder;
592 } 619 }
593 620
594 for (const AppliedTextDecoration& decoration : decorations) { 621 for (const AppliedTextDecoration& decoration : decorations) {
595 TextDecoration lines = decoration.Lines(); 622 TextDecoration lines = decoration.Lines();
596 if (flip_underline_and_overline) { 623 if (flip_underline_and_overline) {
597 lines = static_cast<TextDecoration>( 624 lines = static_cast<TextDecoration>(
598 lines ^ (kTextDecorationUnderline | kTextDecorationOverline)); 625 lines ^ (kTextDecorationUnderline | kTextDecorationOverline));
599 } 626 }
600 if ((lines & kTextDecorationUnderline) && decoration_info.font_data) { 627 if ((lines & kTextDecorationUnderline) && decoration_info.font_data) {
601 const int underline_offset = 628 const int underline_offset = ComputeUnderlineOffset(
602 ComputeUnderlineOffset(underline_position, *decoration_info.style, 629 underline_position, *decoration_info.style,
603 decoration_info.font_data->GetFontMetrics(), 630 decoration_info.font_data->GetFontMetrics(), &box,
604 &box, decoration_info.thickness); 631 decoration_info.decorating_box, decoration_info.thickness);
605 AppliedDecorationPainter decoration_painter( 632 AppliedDecorationPainter decoration_painter(
606 context, decoration_info, underline_offset, decoration, 633 context, decoration_info, underline_offset, decoration,
607 decoration_info.double_offset, 1); 634 decoration_info.double_offset, 1);
608 if (skip_intercepts) { 635 if (skip_intercepts) {
609 text_painter.ClipDecorationsStripe( 636 text_painter.ClipDecorationsStripe(
610 -decoration_info.baseline + 637 -decoration_info.baseline +
611 decoration_painter.DecorationBounds().Y() - 638 decoration_painter.DecorationBounds().Y() -
612 decoration_info.local_origin.Y(), 639 decoration_info.local_origin.Y(),
613 decoration_painter.DecorationBounds().Height(), 640 decoration_painter.DecorationBounds().Height(),
614 decoration_info.thickness); 641 decoration_info.thickness);
615 } 642 }
616 decoration_painter.Paint(); 643 decoration_painter.Paint();
617 } 644 }
618 if (lines & kTextDecorationOverline) { 645 if (lines & kTextDecorationOverline) {
619 const int overline_offset = 646 const int overline_offset = ComputeUnderlineOffsetForUnder(
620 ComputeOverlineOffset(*decoration_info.style, &box); 647 *decoration_info.style, &box, decoration_info.decorating_box,
648 decoration_info.thickness,
649 flip_underline_and_overline ? LineVerticalPositionType::TopOfEmHeight
650 : LineVerticalPositionType::TextTop);
621 AppliedDecorationPainter decoration_painter( 651 AppliedDecorationPainter decoration_painter(
622 context, decoration_info, overline_offset, decoration, 652 context, decoration_info, overline_offset, decoration,
623 -decoration_info.double_offset, 1); 653 -decoration_info.double_offset, 1);
624 if (skip_intercepts) { 654 if (skip_intercepts) {
625 text_painter.ClipDecorationsStripe( 655 text_painter.ClipDecorationsStripe(
626 -decoration_info.baseline + 656 -decoration_info.baseline +
627 decoration_painter.DecorationBounds().Y() - 657 decoration_painter.DecorationBounds().Y() -
628 decoration_info.local_origin.Y(), 658 decoration_info.local_origin.Y(),
629 decoration_painter.DecorationBounds().Height(), 659 decoration_painter.DecorationBounds().Height(),
630 decoration_info.thickness); 660 decoration_info.thickness);
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 1601
1572 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), 1602 LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(),
1573 inline_text_box_.LogicalHeight())); 1603 inline_text_box_.LogicalHeight()));
1574 context.Clip(FloatRect(box_rect)); 1604 context.Clip(FloatRect(box_rect));
1575 context.DrawHighlightForText(font, run, FloatPoint(box_origin), 1605 context.DrawHighlightForText(font, run, FloatPoint(box_origin),
1576 box_rect.Height().ToInt(), color, 1606 box_rect.Height().ToInt(), color,
1577 paint_offsets.first, paint_offsets.second); 1607 paint_offsets.first, paint_offsets.second);
1578 } 1608 }
1579 1609
1580 } // namespace blink 1610 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698