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

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

Powered by Google App Engine
This is Rietveld 408576698