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

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc

Issue 2745973002: [LayoutNG] Implement atomic inlines for LayoutNGInline (Closed)
Patch Set: Resolved merge conflicts Created 3 years, 9 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/ng_line_builder.h" 5 #include "core/layout/ng/ng_line_builder.h"
6 6
7 #include "core/layout/BidiRun.h" 7 #include "core/layout/BidiRun.h"
8 #include "core/layout/LayoutBlockFlow.h" 8 #include "core/layout/LayoutBlockFlow.h"
9 #include "core/layout/line/LineInfo.h" 9 #include "core/layout/line/LineInfo.h"
10 #include "core/layout/line/RootInlineBox.h" 10 #include "core/layout/line/RootInlineBox.h"
11 #include "core/layout/ng/ng_bidi_paragraph.h" 11 #include "core/layout/ng/ng_bidi_paragraph.h"
12 #include "core/layout/ng/ng_box_fragment.h"
12 #include "core/layout/ng/ng_constraint_space.h" 13 #include "core/layout/ng/ng_constraint_space.h"
14 #include "core/layout/ng/ng_constraint_space_builder.h"
13 #include "core/layout/ng/ng_fragment_builder.h" 15 #include "core/layout/ng/ng_fragment_builder.h"
14 #include "core/layout/ng/ng_inline_node.h" 16 #include "core/layout/ng/ng_inline_node.h"
15 #include "core/layout/ng/ng_length_utils.h" 17 #include "core/layout/ng/ng_length_utils.h"
16 #include "core/layout/ng/ng_text_fragment.h" 18 #include "core/layout/ng/ng_text_fragment.h"
17 #include "core/style/ComputedStyle.h" 19 #include "core/style/ComputedStyle.h"
18 #include "platform/text/BidiRunList.h" 20 #include "platform/text/BidiRunList.h"
19 21
20 namespace blink { 22 namespace blink {
21 23
22 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box, 24 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
23 NGConstraintSpace* constraint_space, 25 NGConstraintSpace* constraint_space,
24 NGFragmentBuilder* containing_block_builder) 26 NGFragmentBuilder* containing_block_builder)
25 : inline_box_(inline_box), 27 : inline_box_(inline_box),
26 constraint_space_(constraint_space), 28 constraint_space_(constraint_space),
27 containing_block_builder_(containing_block_builder), 29 containing_block_builder_(containing_block_builder),
28 baseline_type_(constraint_space->WritingMode() ==
29 NGWritingMode::kHorizontalTopBottom
30 ? FontBaseline::AlphabeticBaseline
31 : FontBaseline::IdeographicBaseline),
32 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_), 30 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_),
33 container_layout_result_(nullptr) 31 container_layout_result_(nullptr),
32 is_horizontal_writing_mode_(
33 blink::IsHorizontalWritingMode(constraint_space->WritingMode()))
34 #if DCHECK_IS_ON() 34 #if DCHECK_IS_ON()
35 , 35 ,
36 is_bidi_reordered_(false) 36 is_bidi_reordered_(false)
37 #endif 37 #endif
38 { 38 {
39 if (!is_horizontal_writing_mode_)
40 baseline_type_ = FontBaseline::IdeographicBaseline;
39 } 41 }
40 42
41 bool NGLineBuilder::CanFitOnLine() const { 43 bool NGLineBuilder::CanFitOnLine() const {
42 LayoutUnit available_size = current_opportunity_.InlineSize(); 44 LayoutUnit available_size = current_opportunity_.InlineSize();
43 if (available_size == NGSizeIndefinite) 45 if (available_size == NGSizeIndefinite)
44 return true; 46 return true;
45 return end_position_ <= available_size; 47 return end_position_ <= available_size;
46 } 48 }
47 49
48 bool NGLineBuilder::HasItems() const { 50 bool NGLineBuilder::HasItems() const {
(...skipping 22 matching lines...) Expand all
71 DCHECK_GT(new_end_offset, end_offset_); 73 DCHECK_GT(new_end_offset, end_offset_);
72 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 74 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
73 DCHECK_LE(new_end_offset, items.back().EndOffset()); 75 DCHECK_LE(new_end_offset, items.back().EndOffset());
74 76
75 // SetEnd() while |new_end_offset| is beyond the current last item. 77 // SetEnd() while |new_end_offset| is beyond the current last item.
76 unsigned last_index = last_index_; 78 unsigned last_index = last_index_;
77 const NGLayoutInlineItem* item = &items[last_index]; 79 const NGLayoutInlineItem* item = &items[last_index];
78 if (new_end_offset > item->EndOffset()) { 80 if (new_end_offset > item->EndOffset()) {
79 if (end_offset_ < item->EndOffset()) { 81 if (end_offset_ < item->EndOffset()) {
80 SetEnd(item->EndOffset(), 82 SetEnd(item->EndOffset(),
81 item->InlineSize(end_offset_, item->EndOffset())); 83 InlineSize(*item, end_offset_, item->EndOffset()));
82 } 84 }
83 item = &items[++last_index]; 85 item = &items[++last_index];
84 86
85 while (new_end_offset > item->EndOffset()) { 87 while (new_end_offset > item->EndOffset()) {
86 SetEnd(item->EndOffset(), item->InlineSize()); 88 SetEnd(item->EndOffset(), InlineSize(*item));
87 item = &items[++last_index]; 89 item = &items[++last_index];
88 } 90 }
89 } 91 }
90 92
91 SetEnd(new_end_offset, item->InlineSize(end_offset_, new_end_offset)); 93 SetEnd(new_end_offset, InlineSize(*item, end_offset_, new_end_offset));
92 } 94 }
93 95
94 void NGLineBuilder::SetEnd(unsigned new_end_offset, 96 void NGLineBuilder::SetEnd(unsigned new_end_offset,
95 LayoutUnit inline_size_since_current_end) { 97 LayoutUnit inline_size_since_current_end) {
96 DCHECK_GT(new_end_offset, end_offset_); 98 DCHECK_GT(new_end_offset, end_offset_);
97 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 99 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
98 DCHECK_LE(new_end_offset, items.back().EndOffset()); 100 DCHECK_LE(new_end_offset, items.back().EndOffset());
99 101
100 // |new_end_offset| should be in the current item or next. 102 // |new_end_offset| should be in the current item or next.
101 // TODO(kojii): Reconsider this restriction if needed. 103 // TODO(kojii): Reconsider this restriction if needed.
(...skipping 18 matching lines...) Expand all
120 void NGLineBuilder::SetBreakOpportunity() { 122 void NGLineBuilder::SetBreakOpportunity() {
121 last_break_opportunity_index_ = last_index_; 123 last_break_opportunity_index_ = last_index_;
122 last_break_opportunity_offset_ = end_offset_; 124 last_break_opportunity_offset_ = end_offset_;
123 last_break_opportunity_position_ = end_position_; 125 last_break_opportunity_position_ = end_position_;
124 } 126 }
125 127
126 void NGLineBuilder::SetStartOfHangables(unsigned offset) { 128 void NGLineBuilder::SetStartOfHangables(unsigned offset) {
127 // TODO(kojii): Implement. 129 // TODO(kojii): Implement.
128 } 130 }
129 131
132 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item) {
133 if (item.IsAtomicInlineLevel())
134 return InlineSizeFromLayout(item);
135 return item.InlineSize();
136 }
137
138 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item,
139 unsigned start_offset,
140 unsigned end_offset) {
141 if (item.StartOffset() == start_offset && item.EndOffset() == end_offset &&
142 item.IsAtomicInlineLevel())
143 return InlineSizeFromLayout(item);
144 return item.InlineSize(start_offset, end_offset);
145 }
146
147 LayoutUnit NGLineBuilder::InlineSizeFromLayout(const NGLayoutInlineItem& item) {
148 return NGBoxFragment(ConstraintSpace().WritingMode(),
149 toNGPhysicalBoxFragment(
150 LayoutItem(item)->PhysicalFragment().get()))
151 .InlineSize();
152 }
153
154 const NGLayoutResult* NGLineBuilder::LayoutItem(
155 const NGLayoutInlineItem& item) {
156 // Returns the cached NGLayoutResult if available.
157 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
158 if (layout_results_.isEmpty())
159 layout_results_.resize(items.size());
160 unsigned index = std::distance(items.begin(), &item);
161 RefPtr<NGLayoutResult>* layout_result = &layout_results_[index];
162 if (*layout_result)
163 return layout_result->get();
164
165 DCHECK(item.IsAtomicInlineLevel());
166 NGBlockNode* node = new NGBlockNode(item.GetLayoutObject());
167 // TODO(kojii): Keep node in NGLayoutInlineItem.
168 const ComputedStyle& style = node->Style();
169 NGConstraintSpaceBuilder constraint_space_builder(&ConstraintSpace());
170 RefPtr<NGConstraintSpace> constraint_space =
171 constraint_space_builder.SetIsNewFormattingContext(true)
172 .SetIsShrinkToFit(true)
173 .SetTextDirection(style.direction())
174 .ToConstraintSpace(FromPlatformWritingMode(style.getWritingMode()));
175 *layout_result = node->Layout(constraint_space.get());
176 return layout_result->get();
177 }
178
130 void NGLineBuilder::CreateLine() { 179 void NGLineBuilder::CreateLine() {
131 if (HasItemsAfterLastBreakOpportunity()) 180 if (HasItemsAfterLastBreakOpportunity())
132 SetBreakOpportunity(); 181 SetBreakOpportunity();
133 CreateLineUpToLastBreakOpportunity(); 182 CreateLineUpToLastBreakOpportunity();
134 } 183 }
135 184
136 void NGLineBuilder::CreateLineUpToLastBreakOpportunity() { 185 void NGLineBuilder::CreateLineUpToLastBreakOpportunity() {
137 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 186 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
138 187
139 // Create a list of LineItemChunk from |start| and |last_break_opportunity|. 188 // Create a list of LineItemChunk from |start| and |last_break_opportunity|.
140 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public 189 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public
141 // API is more finalized. It does not fit well with the current API. 190 // API is more finalized. It does not fit well with the current API.
142 Vector<LineItemChunk, 32> line_item_chunks; 191 Vector<LineItemChunk, 32> line_item_chunks;
143 unsigned start_offset = start_offset_; 192 unsigned start_offset = start_offset_;
144 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) { 193 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) {
145 const NGLayoutInlineItem& item = items[i]; 194 const NGLayoutInlineItem& item = items[i];
146 unsigned end_offset = 195 unsigned end_offset =
147 std::min(item.EndOffset(), last_break_opportunity_offset_); 196 std::min(item.EndOffset(), last_break_opportunity_offset_);
148 line_item_chunks.push_back( 197 line_item_chunks.push_back(
149 LineItemChunk{i, start_offset, end_offset, 198 LineItemChunk{i, start_offset, end_offset,
150 item.InlineSize(start_offset, end_offset)}); 199 InlineSize(item, start_offset, end_offset)});
151 start_offset = end_offset; 200 start_offset = end_offset;
152 } 201 }
153 202
154 if (inline_box_->IsBidiEnabled()) 203 if (inline_box_->IsBidiEnabled())
155 BidiReorder(&line_item_chunks); 204 BidiReorder(&line_item_chunks);
156 205
157 PlaceItems(line_item_chunks); 206 PlaceItems(line_item_chunks);
158 207
159 // Prepare for the next line. 208 // Prepare for the next line.
160 // Move |start| to |last_break_opportunity|, keeping items after 209 // Move |start| to |last_break_opportunity|, keeping items after
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // estimation turned out to be different. 277 // estimation turned out to be different.
229 LayoutUnit estimated_baseline = 278 LayoutUnit estimated_baseline =
230 content_size_ + LayoutUnit(block_metrics.ascent_and_leading); 279 content_size_ + LayoutUnit(block_metrics.ascent_and_leading);
231 280
232 for (const auto& line_item_chunk : line_item_chunks) { 281 for (const auto& line_item_chunk : line_item_chunks) {
233 const NGLayoutInlineItem& item = items[line_item_chunk.index]; 282 const NGLayoutInlineItem& item = items[line_item_chunk.index];
234 // Skip bidi controls. 283 // Skip bidi controls.
235 if (!item.GetLayoutObject()) 284 if (!item.GetLayoutObject())
236 continue; 285 continue;
237 286
238 LayoutUnit top, height; 287 LayoutUnit block_start;
239 const ComputedStyle* style = item.Style(); 288 const ComputedStyle* style = item.Style();
240 if (style) { 289 if (style) {
290 DCHECK(item.GetLayoutObject()->isText());
241 // |InlineTextBoxPainter| sets the baseline at |top + 291 // |InlineTextBoxPainter| sets the baseline at |top +
242 // ascent-of-primary-font|. Compute |top| to match. 292 // ascent-of-primary-font|. Compute |top| to match.
243 InlineItemMetrics metrics(*style, baseline_type_); 293 InlineItemMetrics metrics(*style, baseline_type_);
244 top = estimated_baseline - LayoutUnit(metrics.ascent); 294 block_start = estimated_baseline - LayoutUnit(metrics.ascent);
245 height = LayoutUnit(metrics.ascent + metrics.descent); 295 LayoutUnit line_height = LayoutUnit(metrics.ascent + metrics.descent);
246 line_box_data.UpdateMaxAscentAndDescent(metrics); 296 line_box_data.UpdateMaxAscentAndDescent(metrics);
247 297
248 // Take all used fonts into account if 'line-height: normal'. 298 // Take all used fonts into account if 'line-height: normal'.
249 if (style->lineHeight().isNegative()) 299 if (style->lineHeight().isNegative())
250 AccumulateUsedFonts(item, line_item_chunk, &line_box_data); 300 AccumulateUsedFonts(item, line_item_chunk, &line_box_data);
301
302 // The direction of a fragment is the CSS direction to resolve logical
303 // properties, not the resolved bidi direction.
304 text_builder.SetDirection(style->direction())
305 .SetInlineSize(line_item_chunk.inline_size)
306 .SetInlineOverflow(line_item_chunk.inline_size)
307 .SetBlockSize(line_height)
308 .SetBlockOverflow(line_height);
251 } else { 309 } else {
252 LayoutObject* layout_object = item.GetLayoutObject(); 310 LayoutObject* layout_object = item.GetLayoutObject();
253 if (layout_object->isOutOfFlowPositioned()) { 311 if (layout_object->isOutOfFlowPositioned()) {
254 if (containing_block_builder_) { 312 if (containing_block_builder_) {
255 // Absolute positioning blockifies the box's display type. 313 // Absolute positioning blockifies the box's display type.
256 // https://drafts.csswg.org/css-display/#transformations 314 // https://drafts.csswg.org/css-display/#transformations
257 containing_block_builder_->AddOutOfFlowChildCandidate( 315 containing_block_builder_->AddOutOfFlowChildCandidate(
258 new NGBlockNode(layout_object), 316 new NGBlockNode(layout_object),
259 NGLogicalOffset(line_box_data.inline_size, content_size_)); 317 NGLogicalOffset(line_box_data.inline_size, content_size_));
260 } 318 }
261 continue; 319 continue;
262 } else if (layout_object->isFloating()) { 320 } else if (layout_object->isFloating()) {
263 // TODO(kojii): Implement float. 321 // TODO(kojii): Implement float.
264 DLOG(ERROR) << "Floats in inline not implemented yet."; 322 DLOG(ERROR) << "Floats in inline not implemented yet.";
265 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert. 323 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert.
266 layout_object->clearNeedsLayout(); 324 layout_object->clearNeedsLayout();
267 continue; 325 continue;
268 } 326 }
269 DCHECK(layout_object->isAtomicInlineLevel()); 327 block_start = PlaceAtomicInline(item, estimated_baseline, &line_box_data,
270 // TODO(kojii): Implement atomic inline. 328 &text_builder);
271 style = layout_object->style();
272 top = content_size_;
273 } 329 }
274 330
275 // The direction of a fragment is the CSS direction to resolve logical
276 // properties, not the resolved bidi direction.
277 text_builder.SetDirection(style->direction())
278 .SetInlineSize(line_item_chunk.inline_size)
279 .SetInlineOverflow(line_item_chunk.inline_size)
280 .SetBlockSize(height)
281 .SetBlockOverflow(height);
282 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 331 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
283 line_item_chunk.index, line_item_chunk.start_offset, 332 line_item_chunk.index, line_item_chunk.start_offset,
284 line_item_chunk.end_offset); 333 line_item_chunk.end_offset);
285 334
286 NGLogicalOffset logical_offset( 335 NGLogicalOffset logical_offset(
287 line_box_data.inline_size + current_opportunity_.InlineStartOffset() - 336 line_box_data.inline_size + current_opportunity_.InlineStartOffset() -
288 ConstraintSpace().BfcOffset().inline_offset, 337 ConstraintSpace().BfcOffset().inline_offset,
289 top); 338 block_start);
290 container_builder_.AddChild(std::move(text_fragment), logical_offset); 339 container_builder_.AddChild(std::move(text_fragment), logical_offset);
291 line_box_data.inline_size += line_item_chunk.inline_size; 340 line_box_data.inline_size += line_item_chunk.inline_size;
292 } 341 }
293 342
294 if (fragment_start_index == container_builder_.Children().size()) { 343 if (fragment_start_index == container_builder_.Children().size()) {
295 // The line was empty. Remove the LineBoxData. 344 // The line was empty. Remove the LineBoxData.
296 line_box_data_list_.shrink(line_box_data_list_.size() - 1); 345 line_box_data_list_.shrink(line_box_data_list_.size() - 1);
297 return; 346 return;
298 } 347 }
299 348
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 HashSet<const SimpleFontData*> fallback_fonts; 410 HashSet<const SimpleFontData*> fallback_fonts;
362 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 411 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
363 line_item_chunk.end_offset); 412 line_item_chunk.end_offset);
364 for (const auto& fallback_font : fallback_fonts) { 413 for (const auto& fallback_font : fallback_fonts) {
365 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(), 414 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(),
366 baseline_type_); 415 baseline_type_);
367 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics); 416 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics);
368 } 417 }
369 } 418 }
370 419
420 LayoutUnit NGLineBuilder::PlaceAtomicInline(const NGLayoutInlineItem& item,
421 LayoutUnit estimated_baseline,
422 LineBoxData* line_box_data,
423 NGFragmentBuilder* text_builder) {
424 NGBoxFragment fragment(
425 ConstraintSpace().WritingMode(),
426 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get()));
427 // TODO(kojii): Margin and border in block progression not implemented yet.
428 LayoutUnit block_size = fragment.BlockSize();
429
430 // TODO(kojii): Try to eliminate the wrapping text fragment and use the
431 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow|
432 // requires a text fragment.
433 text_builder->SetInlineSize(fragment.InlineSize())
434 .SetInlineOverflow(fragment.InlineOverflow())
435 .SetBlockSize(block_size)
436 .SetBlockOverflow(fragment.BlockOverflow());
437
438 // TODO(kojii): Add baseline position to NGPhysicalFragment.
439 LayoutBox* box = toLayoutBox(item.GetLayoutObject());
440 LineDirectionMode line_direction_mode =
441 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine
442 : LineDirectionMode::VerticalLine;
443 bool is_first_line = line_box_data_list_.size() == 1;
444 int baseline_offset =
445 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode);
446 LayoutUnit block_start = estimated_baseline - baseline_offset;
447
448 line_box_data->max_ascent_and_leading =
449 std::max<float>(baseline_offset, line_box_data->max_ascent_and_leading);
450 line_box_data->max_descent_and_leading = std::max<float>(
451 block_size - baseline_offset, line_box_data->max_descent_and_leading);
452
453 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
454 // Floats are ok because atomic inlines are BFC?
455
456 return block_start;
457 }
458
371 void NGLineBuilder::FindNextLayoutOpportunity() { 459 void NGLineBuilder::FindNextLayoutOpportunity() {
372 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 460 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
373 iter_offset.block_offset += content_size_; 461 iter_offset.block_offset += content_size_;
374 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset); 462 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
375 NGLayoutOpportunity opportunity = iter->Next(); 463 NGLayoutOpportunity opportunity = iter->Next();
376 if (!opportunity.IsEmpty()) 464 if (!opportunity.IsEmpty())
377 current_opportunity_ = opportunity; 465 current_opportunity_ = opportunity;
378 } 466 }
379 467
380 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() { 468 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (layout_object->isText()) { 510 if (layout_object->isText()) {
423 unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; 511 unsigned text_offset = text_offsets[text_fragment->ItemIndex()];
424 run = new BidiRun(text_fragment->StartOffset() - text_offset, 512 run = new BidiRun(text_fragment->StartOffset() - text_offset,
425 text_fragment->EndOffset() - text_offset, 513 text_fragment->EndOffset() - text_offset,
426 item.BidiLevel(), LineLayoutItem(layout_object)); 514 item.BidiLevel(), LineLayoutItem(layout_object));
427 layout_object->clearNeedsLayout(); 515 layout_object->clearNeedsLayout();
428 } else { 516 } else {
429 DCHECK(layout_object->isAtomicInlineLevel()); 517 DCHECK(layout_object->isAtomicInlineLevel());
430 run = 518 run =
431 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object)); 519 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object));
432 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert.
433 layout_object->clearNeedsLayout();
434 } 520 }
435 bidi_runs.addRun(run); 521 bidi_runs.addRun(run);
436 fragments_for_bidi_runs.push_back(text_fragment); 522 fragments_for_bidi_runs.push_back(text_fragment);
437 } 523 }
438 // TODO(kojii): bidi needs to find the logical last run. 524 // TODO(kojii): bidi needs to find the logical last run.
439 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun()); 525 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun());
440 526
441 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the 527 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the
442 // RootInlineBox are set to Bidirun::m_box. 528 // RootInlineBox are set to Bidirun::m_box.
443 line_info.setEmpty(false); 529 line_info.setEmpty(false);
444 // TODO(kojii): Implement setFirstLine, LastLine, etc. 530 // TODO(kojii): Implement setFirstLine, LastLine, etc.
445 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info); 531 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info);
446 532
447 // Copy fragments data to InlineBoxes. 533 // Copy fragments data to InlineBoxes.
448 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount()); 534 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount());
449 BidiRun* run = bidi_runs.firstRun(); 535 BidiRun* run = bidi_runs.firstRun();
450 for (auto* physical_fragment : fragments_for_bidi_runs) { 536 for (auto* physical_fragment : fragments_for_bidi_runs) {
451 DCHECK(run); 537 DCHECK(run);
452 NGTextFragment fragment(ConstraintSpace().WritingMode(), 538 NGTextFragment fragment(ConstraintSpace().WritingMode(),
453 toNGPhysicalTextFragment(physical_fragment)); 539 toNGPhysicalTextFragment(physical_fragment));
454 InlineBox* inline_box = run->m_box; 540 InlineBox* inline_box = run->m_box;
455 inline_box->setLogicalWidth(fragment.InlineSize()); 541 inline_box->setLogicalWidth(fragment.InlineSize());
456 inline_box->setLogicalLeft(fragment.InlineOffset()); 542 inline_box->setLogicalLeft(fragment.InlineOffset());
457 inline_box->setLogicalTop(fragment.BlockOffset()); 543 inline_box->setLogicalTop(fragment.BlockOffset());
544 if (inline_box->getLineLayoutItem().isBox()) {
545 LineLayoutBox box(inline_box->getLineLayoutItem());
546 box.setLocation(inline_box->location());
547 }
458 run = run->next(); 548 run = run->next();
459 } 549 }
460 DCHECK(!run); 550 DCHECK(!run);
461 551
462 // Copy LineBoxData to RootInlineBox. 552 // Copy LineBoxData to RootInlineBox.
463 line_box->setLogicalWidth(line_box_data.inline_size); 553 line_box->setLogicalWidth(line_box_data.inline_size);
554 line_box->setLogicalTop(line_box_data.top_with_leading);
464 LayoutUnit baseline_position = 555 LayoutUnit baseline_position =
465 line_box_data.top_with_leading + 556 line_box_data.top_with_leading +
466 LayoutUnit(line_box_data.max_ascent_and_leading); 557 LayoutUnit(line_box_data.max_ascent_and_leading);
467 line_box->setLineTopBottomPositions( 558 line_box->setLineTopBottomPositions(
468 baseline_position - LayoutUnit(line_box_data.max_ascent), 559 baseline_position - LayoutUnit(line_box_data.max_ascent),
469 baseline_position + LayoutUnit(line_box_data.max_descent), 560 baseline_position + LayoutUnit(line_box_data.max_descent),
470 line_box_data.top_with_leading, 561 line_box_data.top_with_leading,
471 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 562 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading));
472 563
473 bidi_runs.deleteRuns(); 564 bidi_runs.deleteRuns();
474 fragments_for_bidi_runs.clear(); 565 fragments_for_bidi_runs.clear();
475 } 566 }
476 } 567 }
477 } // namespace blink 568 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/ng/ng_line_builder.h ('k') | third_party/WebKit/Source/core/layout/ng/ng_writing_mode.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698