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

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: 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_constraint_space.h" 12 #include "core/layout/ng/ng_constraint_space.h"
13 #include "core/layout/ng/ng_fragment_builder.h" 13 #include "core/layout/ng/ng_fragment_builder.h"
14 #include "core/layout/ng/ng_inline_node.h" 14 #include "core/layout/ng/ng_inline_node.h"
15 #include "core/layout/ng/ng_length_utils.h" 15 #include "core/layout/ng/ng_length_utils.h"
16 #include "core/layout/ng/ng_text_fragment.h" 16 #include "core/layout/ng/ng_text_fragment.h"
17 #include "core/style/ComputedStyle.h" 17 #include "core/style/ComputedStyle.h"
18 #include "platform/text/BidiRunList.h" 18 #include "platform/text/BidiRunList.h"
19 19
20 namespace blink { 20 namespace blink {
21 21
22 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box, 22 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
23 NGConstraintSpace* constraint_space, 23 NGConstraintSpace* constraint_space,
24 NGFragmentBuilder* containing_block_builder) 24 NGFragmentBuilder* containing_block_builder)
25 : inline_box_(inline_box), 25 : inline_box_(inline_box),
26 constraint_space_(constraint_space), 26 constraint_space_(constraint_space),
27 containing_block_builder_(containing_block_builder), 27 containing_block_builder_(containing_block_builder),
28 baseline_type_(constraint_space->WritingMode() == 28 is_horizontal_writing_mode_(
29 NGWritingMode::kHorizontalTopBottom 29 blink::IsHorizontalWritingMode(constraint_space->WritingMode()))
30 ? FontBaseline::AlphabeticBaseline
31 : FontBaseline::IdeographicBaseline)
32 #if DCHECK_IS_ON() 30 #if DCHECK_IS_ON()
33 , 31 ,
34 is_bidi_reordered_(false) 32 is_bidi_reordered_(false)
35 #endif 33 #endif
36 { 34 {
35 if (!is_horizontal_writing_mode_)
36 baseline_type_ = FontBaseline::IdeographicBaseline;
37 } 37 }
38 38
39 bool NGLineBuilder::CanFitOnLine() const { 39 bool NGLineBuilder::CanFitOnLine() const {
40 LayoutUnit available_size = current_opportunity_.InlineSize(); 40 LayoutUnit available_size = current_opportunity_.InlineSize();
41 if (available_size == NGSizeIndefinite) 41 if (available_size == NGSizeIndefinite)
42 return true; 42 return true;
43 return end_position_ <= available_size; 43 return end_position_ <= available_size;
44 } 44 }
45 45
46 bool NGLineBuilder::HasItems() const { 46 bool NGLineBuilder::HasItems() const {
(...skipping 22 matching lines...) Expand all
69 DCHECK_GT(new_end_offset, end_offset_); 69 DCHECK_GT(new_end_offset, end_offset_);
70 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 70 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
71 DCHECK_LE(new_end_offset, items.back().EndOffset()); 71 DCHECK_LE(new_end_offset, items.back().EndOffset());
72 72
73 // SetEnd() while |new_end_offset| is beyond the current last item. 73 // SetEnd() while |new_end_offset| is beyond the current last item.
74 unsigned last_index = last_index_; 74 unsigned last_index = last_index_;
75 const NGLayoutInlineItem* item = &items[last_index]; 75 const NGLayoutInlineItem* item = &items[last_index];
76 if (new_end_offset > item->EndOffset()) { 76 if (new_end_offset > item->EndOffset()) {
77 if (end_offset_ < item->EndOffset()) { 77 if (end_offset_ < item->EndOffset()) {
78 SetEnd(item->EndOffset(), 78 SetEnd(item->EndOffset(),
79 item->InlineSize(end_offset_, item->EndOffset())); 79 InlineSize(*item, end_offset_, item->EndOffset()));
80 } 80 }
81 item = &items[++last_index]; 81 item = &items[++last_index];
82 82
83 while (new_end_offset > item->EndOffset()) { 83 while (new_end_offset > item->EndOffset()) {
84 SetEnd(item->EndOffset(), item->InlineSize()); 84 SetEnd(item->EndOffset(), InlineSize(*item));
85 item = &items[++last_index]; 85 item = &items[++last_index];
86 } 86 }
87 } 87 }
88 88
89 SetEnd(new_end_offset, item->InlineSize(end_offset_, new_end_offset)); 89 SetEnd(new_end_offset, InlineSize(*item, end_offset_, new_end_offset));
90 } 90 }
91 91
92 void NGLineBuilder::SetEnd(unsigned new_end_offset, 92 void NGLineBuilder::SetEnd(unsigned new_end_offset,
93 LayoutUnit inline_size_since_current_end) { 93 LayoutUnit inline_size_since_current_end) {
94 DCHECK_GT(new_end_offset, end_offset_); 94 DCHECK_GT(new_end_offset, end_offset_);
95 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 95 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
96 DCHECK_LE(new_end_offset, items.back().EndOffset()); 96 DCHECK_LE(new_end_offset, items.back().EndOffset());
97 97
98 // |new_end_offset| should be in the current item or next. 98 // |new_end_offset| should be in the current item or next.
99 // TODO(kojii): Reconsider this restriction if needed. 99 // TODO(kojii): Reconsider this restriction if needed.
(...skipping 18 matching lines...) Expand all
118 void NGLineBuilder::SetBreakOpportunity() { 118 void NGLineBuilder::SetBreakOpportunity() {
119 last_break_opportunity_index_ = last_index_; 119 last_break_opportunity_index_ = last_index_;
120 last_break_opportunity_offset_ = end_offset_; 120 last_break_opportunity_offset_ = end_offset_;
121 last_break_opportunity_position_ = end_position_; 121 last_break_opportunity_position_ = end_position_;
122 } 122 }
123 123
124 void NGLineBuilder::SetStartOfHangables(unsigned offset) { 124 void NGLineBuilder::SetStartOfHangables(unsigned offset) {
125 // TODO(kojii): Implement. 125 // TODO(kojii): Implement.
126 } 126 }
127 127
128 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item) {
129 if (item.IsAtomicInlineLevel())
130 return InlineSizeFromLayout(item);
131 return item.InlineSize();
132 }
133
134 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item,
135 unsigned start_offset,
136 unsigned end_offset) {
137 if (item.StartOffset() == start_offset && item.EndOffset() == end_offset &&
138 item.IsAtomicInlineLevel())
139 return InlineSizeFromLayout(item);
140 return item.InlineSize(start_offset, end_offset);
141 }
142
143 LayoutUnit NGLineBuilder::InlineSizeFromLayout(const NGLayoutInlineItem& item) {
144 const RefPtr<NGLayoutResult>& layout_result = LayoutItem(item);
145 return IsHorizontalWritingMode()
ikilpatrick 2017/03/16 16:15:40 instead of this can you stack allocate a NGBoxFrag
kojii 2017/03/16 16:48:45 Done. I didn't know I can pass parent's writing-mo
146 ? layout_result->PhysicalFragment()->Width()
147 : layout_result->PhysicalFragment()->Height();
148 }
149
150 RefPtr<NGLayoutResult>& NGLineBuilder::LayoutItem(
151 const NGLayoutInlineItem& item) {
152 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
153 if (layout_results_.isEmpty())
154 layout_results_.resize(items.size());
155 unsigned index = std::distance(items.begin(), &item);
156 RefPtr<NGLayoutResult>& layout_result = layout_results_[index];
157 if (!layout_result)
158 layout_result = item.Layout(ConstraintSpace());
ikilpatrick 2017/03/16 16:15:41 We'll need to fix this constraint space, this migh
ikilpatrick 2017/03/16 16:15:41 on this is not a NGLayoutInputNode, hmmm... i foun
kojii 2017/03/16 16:48:45 Understood, moved the layout code here.
159 return layout_result;
ikilpatrick 2017/03/16 16:15:40 do we need to assign back to the layout_results_ v
kojii 2017/03/16 16:48:45 |layout_result| here is a reference to the vector.
160 }
161
128 void NGLineBuilder::CreateLine() { 162 void NGLineBuilder::CreateLine() {
129 if (HasItemsAfterLastBreakOpportunity()) 163 if (HasItemsAfterLastBreakOpportunity())
130 SetBreakOpportunity(); 164 SetBreakOpportunity();
131 CreateLineUpToLastBreakOpportunity(); 165 CreateLineUpToLastBreakOpportunity();
132 } 166 }
133 167
134 void NGLineBuilder::CreateLineUpToLastBreakOpportunity() { 168 void NGLineBuilder::CreateLineUpToLastBreakOpportunity() {
135 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 169 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
136 170
137 // Create a list of LineItemChunk from |start| and |last_break_opportunity|. 171 // Create a list of LineItemChunk from |start| and |last_break_opportunity|.
138 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public 172 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public
139 // API is more finalized. It does not fit well with the current API. 173 // API is more finalized. It does not fit well with the current API.
140 Vector<LineItemChunk, 32> line_item_chunks; 174 Vector<LineItemChunk, 32> line_item_chunks;
141 unsigned start_offset = start_offset_; 175 unsigned start_offset = start_offset_;
142 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) { 176 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) {
143 const NGLayoutInlineItem& item = items[i]; 177 const NGLayoutInlineItem& item = items[i];
144 unsigned end_offset = 178 unsigned end_offset =
145 std::min(item.EndOffset(), last_break_opportunity_offset_); 179 std::min(item.EndOffset(), last_break_opportunity_offset_);
146 line_item_chunks.push_back( 180 line_item_chunks.push_back(
147 LineItemChunk{i, start_offset, end_offset, 181 LineItemChunk{i, start_offset, end_offset,
148 item.InlineSize(start_offset, end_offset)}); 182 InlineSize(item, start_offset, end_offset)});
149 start_offset = end_offset; 183 start_offset = end_offset;
150 } 184 }
151 185
152 if (inline_box_->IsBidiEnabled()) 186 if (inline_box_->IsBidiEnabled())
153 BidiReorder(&line_item_chunks); 187 BidiReorder(&line_item_chunks);
154 188
155 PlaceItems(line_item_chunks); 189 PlaceItems(line_item_chunks);
156 190
157 // Prepare for the next line. 191 // Prepare for the next line.
158 // Move |start| to |last_break_opportunity|, keeping items after 192 // Move |start| to |last_break_opportunity|, keeping items after
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // estimation turned out to be different. 260 // estimation turned out to be different.
227 LayoutUnit estimated_baseline = 261 LayoutUnit estimated_baseline =
228 content_size_ + LayoutUnit(block_metrics.ascent_and_leading); 262 content_size_ + LayoutUnit(block_metrics.ascent_and_leading);
229 263
230 for (const auto& line_item_chunk : line_item_chunks) { 264 for (const auto& line_item_chunk : line_item_chunks) {
231 const NGLayoutInlineItem& item = items[line_item_chunk.index]; 265 const NGLayoutInlineItem& item = items[line_item_chunk.index];
232 // Skip bidi controls. 266 // Skip bidi controls.
233 if (!item.GetLayoutObject()) 267 if (!item.GetLayoutObject())
234 continue; 268 continue;
235 269
236 LayoutUnit top, height; 270 LayoutUnit top;
237 const ComputedStyle* style = item.Style(); 271 const ComputedStyle* style = item.Style();
238 if (style) { 272 if (style) {
273 DCHECK(item.GetLayoutObject()->isText());
239 // |InlineTextBoxPainter| sets the baseline at |top + 274 // |InlineTextBoxPainter| sets the baseline at |top +
240 // ascent-of-primary-font|. Compute |top| to match. 275 // ascent-of-primary-font|. Compute |top| to match.
241 InlineItemMetrics metrics(*style, baseline_type_); 276 InlineItemMetrics metrics(*style, baseline_type_);
242 top = estimated_baseline - LayoutUnit(metrics.ascent); 277 top = estimated_baseline - LayoutUnit(metrics.ascent);
243 height = LayoutUnit(metrics.ascent + metrics.descent); 278 LayoutUnit height = LayoutUnit(metrics.ascent + metrics.descent);
244 line_box_data.UpdateMaxAscentAndDescent(metrics); 279 line_box_data.UpdateMaxAscentAndDescent(metrics);
245 280
246 // Take all used fonts into account if 'line-height: normal'. 281 // Take all used fonts into account if 'line-height: normal'.
247 if (style->lineHeight().isNegative()) 282 if (style->lineHeight().isNegative())
248 AccumulateUsedFonts(item, line_item_chunk, &line_box_data); 283 AccumulateUsedFonts(item, line_item_chunk, &line_box_data);
284
285 // The direction of a fragment is the CSS direction to resolve logical
286 // properties, not the resolved bidi direction.
287 text_builder.SetDirection(style->direction())
288 .SetInlineSize(line_item_chunk.inline_size)
289 .SetInlineOverflow(line_item_chunk.inline_size)
290 .SetBlockSize(height)
291 .SetBlockOverflow(height);
249 } else { 292 } else {
250 LayoutObject* layout_object = item.GetLayoutObject(); 293 LayoutObject* layout_object = item.GetLayoutObject();
251 if (layout_object->isOutOfFlowPositioned()) { 294 if (layout_object->isOutOfFlowPositioned()) {
252 if (containing_block_builder_) { 295 if (containing_block_builder_) {
253 // Absolute positioning blockifies the box's display type. 296 // Absolute positioning blockifies the box's display type.
254 // https://drafts.csswg.org/css-display/#transformations 297 // https://drafts.csswg.org/css-display/#transformations
255 containing_block_builder_->AddOutOfFlowChildCandidate( 298 containing_block_builder_->AddOutOfFlowChildCandidate(
256 new NGBlockNode(layout_object), 299 new NGBlockNode(layout_object),
257 NGLogicalOffset(line_box_data.inline_size, content_size_)); 300 NGLogicalOffset(line_box_data.inline_size, content_size_));
258 } 301 }
259 continue; 302 continue;
260 } else if (layout_object->isFloating()) { 303 } else if (layout_object->isFloating()) {
261 // TODO(kojii): Implement float. 304 // TODO(kojii): Implement float.
262 DLOG(ERROR) << "Floats in inline not implemented yet."; 305 DLOG(ERROR) << "Floats in inline not implemented yet.";
263 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert. 306 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert.
264 layout_object->clearNeedsLayout(); 307 layout_object->clearNeedsLayout();
265 continue; 308 continue;
266 } 309 }
267 DCHECK(layout_object->isAtomicInlineLevel()); 310 top = PlaceAtomicInline(item, estimated_baseline, &line_box_data,
268 // TODO(kojii): Implement atomic inline. 311 &text_builder);
269 style = layout_object->style();
270 top = content_size_;
271 } 312 }
272 313
273 // The direction of a fragment is the CSS direction to resolve logical
274 // properties, not the resolved bidi direction.
275 text_builder.SetDirection(style->direction())
276 .SetInlineSize(line_item_chunk.inline_size)
277 .SetInlineOverflow(line_item_chunk.inline_size)
278 .SetBlockSize(height)
279 .SetBlockOverflow(height);
280 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 314 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
281 line_item_chunk.index, line_item_chunk.start_offset, 315 line_item_chunk.index, line_item_chunk.start_offset,
282 line_item_chunk.end_offset); 316 line_item_chunk.end_offset);
283 fragments_.push_back(std::move(text_fragment)); 317 fragments_.push_back(std::move(text_fragment));
284 318
285 NGLogicalOffset logical_offset( 319 NGLogicalOffset logical_offset(
286 line_box_data.inline_size + current_opportunity_.InlineStartOffset() - 320 line_box_data.inline_size + current_opportunity_.InlineStartOffset() -
287 ConstraintSpace().BfcOffset().inline_offset, 321 ConstraintSpace().BfcOffset().inline_offset,
288 top); 322 top);
289 offsets_.push_back(logical_offset); 323 offsets_.push_back(logical_offset);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 HashSet<const SimpleFontData*> fallback_fonts; 394 HashSet<const SimpleFontData*> fallback_fonts;
361 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 395 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
362 line_item_chunk.end_offset); 396 line_item_chunk.end_offset);
363 for (const auto& fallback_font : fallback_fonts) { 397 for (const auto& fallback_font : fallback_fonts) {
364 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(), 398 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(),
365 baseline_type_); 399 baseline_type_);
366 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics); 400 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics);
367 } 401 }
368 } 402 }
369 403
404 LayoutUnit NGLineBuilder::PlaceAtomicInline(const NGLayoutInlineItem& item,
405 LayoutUnit estimated_baseline,
406 LineBoxData* line_box_data,
407 NGFragmentBuilder* text_builder) {
408 const RefPtr<NGLayoutResult>& layout_result = LayoutItem(item);
409 RefPtr<NGPhysicalFragment> fragment = layout_result->PhysicalFragment();
410 LayoutUnit height;
411 // TODO(kojii): Try to eliminate the text fragment and use the |fragment|
412 // directly. Currently |CopyFragmentDataToLayoutBlockFlow| requires a text
413 // fragment.
414 // TODO(kojii): Margin and border in block progression not implemented yet.
415 if (IsHorizontalWritingMode()) {
416 height = fragment->Height();
417 text_builder->SetInlineSize(fragment->Width())
418 .SetInlineOverflow(fragment->WidthOverflow())
419 .SetBlockSize(height)
420 .SetBlockOverflow(fragment->HeightOverflow());
421 } else {
422 height = fragment->Width();
423 text_builder->SetInlineSize(fragment->Height())
424 .SetInlineOverflow(fragment->HeightOverflow())
425 .SetBlockSize(height)
426 .SetBlockOverflow(fragment->WidthOverflow());
427 }
428
429 // TODO(kojii): Add baseline position to NGPhysicalFragment.
430 LayoutBox* box = toLayoutBox(item.GetLayoutObject());
431 LineDirectionMode line_direction_mode =
432 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine
433 : LineDirectionMode::VerticalLine;
434 bool is_first_line = line_box_data_list_.size() == 1;
435 int baseline_offset =
436 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode);
437 LayoutUnit top = estimated_baseline - baseline_offset;
438
439 line_box_data->max_ascent_and_leading =
440 std::max<float>(baseline_offset, line_box_data->max_ascent_and_leading);
441 line_box_data->max_descent_and_leading = std::max<float>(
442 height - baseline_offset, line_box_data->max_descent_and_leading);
443
444 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
445 // Floats are ok because atomic inlines are BFC?
446
447 return top;
448 }
449
370 void NGLineBuilder::FindNextLayoutOpportunity() { 450 void NGLineBuilder::FindNextLayoutOpportunity() {
371 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 451 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
372 iter_offset.block_offset += content_size_; 452 iter_offset.block_offset += content_size_;
373 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset); 453 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
374 NGLayoutOpportunity opportunity = iter->Next(); 454 NGLayoutOpportunity opportunity = iter->Next();
375 if (!opportunity.IsEmpty()) 455 if (!opportunity.IsEmpty())
376 current_opportunity_ = opportunity; 456 current_opportunity_ = opportunity;
377 } 457 }
378 458
379 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() { 459 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 if (layout_object->isText()) { 505 if (layout_object->isText()) {
426 unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; 506 unsigned text_offset = text_offsets[text_fragment->ItemIndex()];
427 run = new BidiRun(text_fragment->StartOffset() - text_offset, 507 run = new BidiRun(text_fragment->StartOffset() - text_offset,
428 text_fragment->EndOffset() - text_offset, 508 text_fragment->EndOffset() - text_offset,
429 item.BidiLevel(), LineLayoutItem(layout_object)); 509 item.BidiLevel(), LineLayoutItem(layout_object));
430 layout_object->clearNeedsLayout(); 510 layout_object->clearNeedsLayout();
431 } else { 511 } else {
432 DCHECK(layout_object->isAtomicInlineLevel()); 512 DCHECK(layout_object->isAtomicInlineLevel());
433 run = 513 run =
434 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object)); 514 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object));
435 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert.
436 layout_object->clearNeedsLayout();
437 } 515 }
438 bidi_runs.addRun(run); 516 bidi_runs.addRun(run);
439 fragments_for_bidi_runs.push_back(text_fragment); 517 fragments_for_bidi_runs.push_back(text_fragment);
440 } 518 }
441 // TODO(kojii): bidi needs to find the logical last run. 519 // TODO(kojii): bidi needs to find the logical last run.
442 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun()); 520 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun());
443 521
444 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the 522 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the
445 // RootInlineBox are set to Bidirun::m_box. 523 // RootInlineBox are set to Bidirun::m_box.
446 line_info.setEmpty(false); 524 line_info.setEmpty(false);
447 // TODO(kojii): Implement setFirstLine, LastLine, etc. 525 // TODO(kojii): Implement setFirstLine, LastLine, etc.
448 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info); 526 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info);
449 527
450 // Copy fragments data to InlineBoxes. 528 // Copy fragments data to InlineBoxes.
451 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount()); 529 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount());
452 BidiRun* run = bidi_runs.firstRun(); 530 BidiRun* run = bidi_runs.firstRun();
453 for (auto* physical_fragment : fragments_for_bidi_runs) { 531 for (auto* physical_fragment : fragments_for_bidi_runs) {
454 DCHECK(run); 532 DCHECK(run);
455 NGTextFragment fragment(ConstraintSpace().WritingMode(), 533 NGTextFragment fragment(ConstraintSpace().WritingMode(),
456 toNGPhysicalTextFragment(physical_fragment)); 534 toNGPhysicalTextFragment(physical_fragment));
457 InlineBox* inline_box = run->m_box; 535 InlineBox* inline_box = run->m_box;
458 inline_box->setLogicalWidth(fragment.InlineSize()); 536 inline_box->setLogicalWidth(fragment.InlineSize());
459 inline_box->setLogicalLeft(fragment.InlineOffset()); 537 inline_box->setLogicalLeft(fragment.InlineOffset());
460 inline_box->setLogicalTop(fragment.BlockOffset()); 538 inline_box->setLogicalTop(fragment.BlockOffset());
539 if (inline_box->getLineLayoutItem().isBox()) {
540 LineLayoutBox box(inline_box->getLineLayoutItem());
541 box.setLocation(inline_box->location());
542 }
461 run = run->next(); 543 run = run->next();
462 } 544 }
463 DCHECK(!run); 545 DCHECK(!run);
464 546
465 // Copy LineBoxData to RootInlineBox. 547 // Copy LineBoxData to RootInlineBox.
466 line_box->setLogicalWidth(line_box_data.inline_size); 548 line_box->setLogicalWidth(line_box_data.inline_size);
549 line_box->setLogicalTop(line_box_data.top_with_leading);
467 LayoutUnit baseline_position = 550 LayoutUnit baseline_position =
468 line_box_data.top_with_leading + 551 line_box_data.top_with_leading +
469 LayoutUnit(line_box_data.max_ascent_and_leading); 552 LayoutUnit(line_box_data.max_ascent_and_leading);
470 line_box->setLineTopBottomPositions( 553 line_box->setLineTopBottomPositions(
471 baseline_position - LayoutUnit(line_box_data.max_ascent), 554 baseline_position - LayoutUnit(line_box_data.max_ascent),
472 baseline_position + LayoutUnit(line_box_data.max_descent), 555 baseline_position + LayoutUnit(line_box_data.max_descent),
473 line_box_data.top_with_leading, 556 line_box_data.top_with_leading,
474 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 557 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading));
475 558
476 bidi_runs.deleteRuns(); 559 bidi_runs.deleteRuns();
477 fragments_for_bidi_runs.clear(); 560 fragments_for_bidi_runs.clear();
478 } 561 }
479 } 562 }
480 } // namespace blink 563 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698