OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/layout/ng/inline/ng_inline_box_state.h" | 5 #include "core/layout/ng/inline/ng_inline_box_state.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_inline_node.h" | 7 #include "core/layout/ng/inline/ng_inline_node.h" |
8 #include "core/layout/ng/inline/ng_line_box_fragment_builder.h" | 8 #include "core/layout/ng/inline/ng_line_box_fragment_builder.h" |
9 #include "core/layout/ng/inline/ng_text_fragment_builder.h" | 9 #include "core/layout/ng/inline/ng_text_fragment_builder.h" |
10 #include "core/style/ComputedStyle.h" | 10 #include "core/style/ComputedStyle.h" |
11 | 11 |
12 namespace blink { | 12 namespace blink { |
13 | 13 |
14 void NGInlineBoxState::ComputeTextMetrics(const NGInlineItem& item, | 14 void NGInlineBoxState::ComputeTextMetrics(const ComputedStyle& style, |
15 FontBaseline baseline_type) { | 15 FontBaseline baseline_type) { |
16 const ComputedStyle& style = *item.Style(); | |
17 text_metrics = NGLineHeightMetrics(style, baseline_type); | 16 text_metrics = NGLineHeightMetrics(style, baseline_type); |
18 text_top = -text_metrics.ascent; | 17 text_top = -text_metrics.ascent; |
19 text_metrics.AddLeading(style.ComputedLineHeightAsFixed()); | 18 text_metrics.AddLeading(style.ComputedLineHeightAsFixed()); |
20 metrics.Unite(text_metrics); | 19 metrics.Unite(text_metrics); |
21 | 20 |
22 include_used_fonts = style.LineHeight().IsNegative(); | 21 include_used_fonts = style.LineHeight().IsNegative(); |
23 } | 22 } |
24 | 23 |
| 24 void NGInlineBoxState::AccumulateUsedFonts(const NGInlineItem& item, |
| 25 unsigned start, |
| 26 unsigned end, |
| 27 FontBaseline baseline_type) { |
| 28 HashSet<const SimpleFontData*> fallback_fonts; |
| 29 item.GetFallbackFonts(&fallback_fonts, start, end); |
| 30 for (const auto& fallback_font : fallback_fonts) { |
| 31 NGLineHeightMetrics fallback_metrics(fallback_font->GetFontMetrics(), |
| 32 baseline_type); |
| 33 fallback_metrics.AddLeading( |
| 34 fallback_font->GetFontMetrics().FixedLineSpacing()); |
| 35 metrics.Unite(fallback_metrics); |
| 36 } |
| 37 } |
| 38 |
25 NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems( | 39 NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems( |
26 const ComputedStyle* line_style) { | 40 const ComputedStyle* line_style, |
| 41 FontBaseline baseline_type) { |
27 if (stack_.IsEmpty()) { | 42 if (stack_.IsEmpty()) { |
28 // For the first line, push a box state for the line itself. | 43 // For the first line, push a box state for the line itself. |
29 stack_.Resize(1); | 44 stack_.Resize(1); |
30 NGInlineBoxState* box = &stack_.back(); | 45 NGInlineBoxState* box = &stack_.back(); |
31 box->fragment_start = 0; | 46 box->fragment_start = 0; |
32 box->style = line_style; | 47 } else { |
33 return box; | 48 // For the following lines, clear states that are not shared across lines. |
| 49 for (auto& box : stack_) { |
| 50 box.fragment_start = 0; |
| 51 box.metrics = NGLineHeightMetrics(); |
| 52 DCHECK(box.pending_descendants.IsEmpty()); |
| 53 } |
34 } | 54 } |
35 | 55 |
36 // For the following lines, clear states that are not shared across lines. | 56 // Initialize the box state for the line box. |
37 for (auto& box : stack_) { | 57 NGInlineBoxState& line_box = LineBoxState(); |
38 box.fragment_start = 0; | 58 line_box.style = line_style; |
39 box.metrics = NGLineHeightMetrics(); | 59 |
40 DCHECK(box.pending_descendants.IsEmpty()); | 60 // Use a "strut" (a zero-width inline box with the element's font and |
41 } | 61 // line height properties) as the initial metrics for the line box. |
| 62 // https://drafts.csswg.org/css2/visudet.html#strut |
| 63 line_box.ComputeTextMetrics(*line_style, baseline_type); |
| 64 |
42 return &stack_.back(); | 65 return &stack_.back(); |
43 } | 66 } |
44 | 67 |
45 NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( | 68 NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( |
46 const NGInlineItem& item, | 69 const NGInlineItem& item, |
47 NGLineBoxFragmentBuilder* line_box, | 70 NGLineBoxFragmentBuilder* line_box, |
48 NGTextFragmentBuilder* text_builder) { | 71 NGTextFragmentBuilder* text_builder) { |
49 stack_.Resize(stack_.size() + 1); | 72 stack_.Resize(stack_.size() + 1); |
50 NGInlineBoxState* box = &stack_.back(); | 73 NGInlineBoxState* box = &stack_.back(); |
51 box->fragment_start = line_box->Children().size(); | 74 box->fragment_start = line_box->Children().size(); |
(...skipping 13 matching lines...) Expand all Loading... |
65 stack_.pop_back(); | 88 stack_.pop_back(); |
66 return &stack_.back(); | 89 return &stack_.back(); |
67 } | 90 } |
68 | 91 |
69 void NGInlineLayoutStateStack::OnEndPlaceItems( | 92 void NGInlineLayoutStateStack::OnEndPlaceItems( |
70 NGLineBoxFragmentBuilder* line_box) { | 93 NGLineBoxFragmentBuilder* line_box) { |
71 for (auto it = stack_.rbegin(); it != stack_.rend(); ++it) { | 94 for (auto it = stack_.rbegin(); it != stack_.rend(); ++it) { |
72 NGInlineBoxState* box = &(*it); | 95 NGInlineBoxState* box = &(*it); |
73 EndBoxState(box, line_box); | 96 EndBoxState(box, line_box); |
74 } | 97 } |
75 line_box->UniteMetrics(stack_.front().metrics); | 98 |
| 99 DCHECK(!LineBoxState().metrics.IsEmpty()); |
| 100 line_box->SetMetrics(LineBoxState().metrics); |
76 } | 101 } |
77 | 102 |
78 void NGInlineLayoutStateStack::EndBoxState(NGInlineBoxState* box, | 103 void NGInlineLayoutStateStack::EndBoxState(NGInlineBoxState* box, |
79 NGLineBoxFragmentBuilder* line_box) { | 104 NGLineBoxFragmentBuilder* line_box) { |
80 ApplyBaselineShift(box, line_box); | 105 ApplyBaselineShift(box, line_box); |
81 | 106 |
82 // Unite the metrics to the parent box. | 107 // Unite the metrics to the parent box. |
83 if (box != stack_.begin()) { | 108 if (box != stack_.begin()) { |
84 box[-1].metrics.Unite(box->metrics); | 109 box[-1].metrics.Unite(box->metrics); |
85 } | 110 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 box[-1].pending_descendants.push_back(NGPendingPositions{ | 189 box[-1].pending_descendants.push_back(NGPendingPositions{ |
165 box->fragment_start, fragment_end, box->metrics, vertical_align}); | 190 box->fragment_start, fragment_end, box->metrics, vertical_align}); |
166 return; | 191 return; |
167 } | 192 } |
168 box->metrics.Move(baseline_shift); | 193 box->metrics.Move(baseline_shift); |
169 line_box->MoveChildrenInBlockDirection(baseline_shift, box->fragment_start, | 194 line_box->MoveChildrenInBlockDirection(baseline_shift, box->fragment_start, |
170 fragment_end); | 195 fragment_end); |
171 } | 196 } |
172 | 197 |
173 } // namespace blink | 198 } // namespace blink |
OLD | NEW |