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

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

Issue 2753743003: Make NGFragmentBuilder to keep track on text children. (Closed)
Patch Set: get a raw ptr of NGPhysicalFragment instead of RefPtr 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"
(...skipping 10 matching lines...) Expand all
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 baseline_type_(constraint_space->WritingMode() ==
29 NGWritingMode::kHorizontalTopBottom 29 NGWritingMode::kHorizontalTopBottom
30 ? FontBaseline::AlphabeticBaseline 30 ? FontBaseline::AlphabeticBaseline
31 : FontBaseline::IdeographicBaseline) 31 : FontBaseline::IdeographicBaseline),
32 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_),
33 container_layout_result_(nullptr)
32 #if DCHECK_IS_ON() 34 #if DCHECK_IS_ON()
33 , 35 ,
34 is_bidi_reordered_(false) 36 is_bidi_reordered_(false)
35 #endif 37 #endif
36 { 38 {
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)
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 unsigned logical_index = indices_in_visual_order[visual_index]; 201 unsigned logical_index = indices_in_visual_order[visual_index];
200 line_item_chunks_in_visual_order[visual_index] = 202 line_item_chunks_in_visual_order[visual_index] =
201 (*line_item_chunks)[logical_index]; 203 (*line_item_chunks)[logical_index];
202 } 204 }
203 line_item_chunks->swap(line_item_chunks_in_visual_order); 205 line_item_chunks->swap(line_item_chunks_in_visual_order);
204 } 206 }
205 207
206 void NGLineBuilder::PlaceItems( 208 void NGLineBuilder::PlaceItems(
207 const Vector<LineItemChunk, 32>& line_item_chunks) { 209 const Vector<LineItemChunk, 32>& line_item_chunks) {
208 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 210 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
209 const unsigned fragment_start_index = fragments_.size(); 211 const unsigned fragment_start_index = container_builder_.Children().size();
210 212
211 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText, 213 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText,
212 inline_box_); 214 inline_box_);
213 text_builder.SetWritingMode(ConstraintSpace().WritingMode()); 215 text_builder.SetWritingMode(ConstraintSpace().WritingMode());
214 line_box_data_list_.grow(line_box_data_list_.size() + 1); 216 line_box_data_list_.grow(line_box_data_list_.size() + 1);
215 LineBoxData& line_box_data = line_box_data_list_.back(); 217 LineBoxData& line_box_data = line_box_data_list_.back();
216 218
217 // Accumulate a "strut"; a zero-width inline box with the element's font and 219 // Accumulate a "strut"; a zero-width inline box with the element's font and
218 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut 220 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut
219 const ComputedStyle* block_style = inline_box_->BlockStyle(); 221 const ComputedStyle* block_style = inline_box_->BlockStyle();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 // The direction of a fragment is the CSS direction to resolve logical 275 // The direction of a fragment is the CSS direction to resolve logical
274 // properties, not the resolved bidi direction. 276 // properties, not the resolved bidi direction.
275 text_builder.SetDirection(style->direction()) 277 text_builder.SetDirection(style->direction())
276 .SetInlineSize(line_item_chunk.inline_size) 278 .SetInlineSize(line_item_chunk.inline_size)
277 .SetInlineOverflow(line_item_chunk.inline_size) 279 .SetInlineOverflow(line_item_chunk.inline_size)
278 .SetBlockSize(height) 280 .SetBlockSize(height)
279 .SetBlockOverflow(height); 281 .SetBlockOverflow(height);
280 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 282 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
281 line_item_chunk.index, line_item_chunk.start_offset, 283 line_item_chunk.index, line_item_chunk.start_offset,
282 line_item_chunk.end_offset); 284 line_item_chunk.end_offset);
283 fragments_.push_back(std::move(text_fragment));
284 285
285 NGLogicalOffset logical_offset( 286 NGLogicalOffset logical_offset(
286 line_box_data.inline_size + current_opportunity_.InlineStartOffset() - 287 line_box_data.inline_size + current_opportunity_.InlineStartOffset() -
287 ConstraintSpace().BfcOffset().inline_offset, 288 ConstraintSpace().BfcOffset().inline_offset,
288 top); 289 top);
289 offsets_.push_back(logical_offset); 290 container_builder_.AddChild(std::move(text_fragment), logical_offset);
290 line_box_data.inline_size += line_item_chunk.inline_size; 291 line_box_data.inline_size += line_item_chunk.inline_size;
291 } 292 }
292 DCHECK_EQ(fragments_.size(), offsets_.size());
293 293
294 if (fragment_start_index == fragments_.size()) { 294 if (fragment_start_index == container_builder_.Children().size()) {
295 // The line was empty. Remove the LineBoxData. 295 // The line was empty. Remove the LineBoxData.
296 line_box_data_list_.shrink(line_box_data_list_.size() - 1); 296 line_box_data_list_.shrink(line_box_data_list_.size() - 1);
297 return; 297 return;
298 } 298 }
299 299
300 // If the estimated baseline position was not the actual position, move all 300 // If the estimated baseline position was not the actual position, move all
301 // fragments in the block direction. 301 // fragments in the block direction.
302 if (block_metrics.ascent_and_leading != 302 if (block_metrics.ascent_and_leading !=
303 line_box_data.max_ascent_and_leading) { 303 line_box_data.max_ascent_and_leading) {
304 LayoutUnit adjust_top(line_box_data.max_ascent_and_leading - 304 LayoutUnit adjust_top(line_box_data.max_ascent_and_leading -
305 block_metrics.ascent_and_leading); 305 block_metrics.ascent_and_leading);
306 for (unsigned i = fragment_start_index; i < offsets_.size(); i++) 306 auto& offsets = container_builder_.MutableOffsets();
307 offsets_[i].block_offset += adjust_top; 307 for (unsigned i = fragment_start_index; i < offsets.size(); i++)
308 offsets[i].block_offset += adjust_top;
308 } 309 }
309 310
310 line_box_data.fragment_end = fragments_.size(); 311 line_box_data.fragment_end = container_builder_.Children().size();
311 line_box_data.top_with_leading = content_size_; 312 line_box_data.top_with_leading = content_size_;
312 max_inline_size_ = std::max(max_inline_size_, line_box_data.inline_size); 313 max_inline_size_ = std::max(max_inline_size_, line_box_data.inline_size);
313 content_size_ += LayoutUnit(line_box_data.max_ascent_and_leading + 314 content_size_ += LayoutUnit(line_box_data.max_ascent_and_leading +
314 line_box_data.max_descent_and_leading); 315 line_box_data.max_descent_and_leading);
315 } 316 }
316 317
317 NGLineBuilder::InlineItemMetrics::InlineItemMetrics( 318 NGLineBuilder::InlineItemMetrics::InlineItemMetrics(
318 const ComputedStyle& style, 319 const ComputedStyle& style,
319 FontBaseline baseline_type) { 320 FontBaseline baseline_type) {
320 const SimpleFontData* font_data = style.font().primaryFont(); 321 const SimpleFontData* font_data = style.font().primaryFont();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 372 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
372 iter_offset.block_offset += content_size_; 373 iter_offset.block_offset += content_size_;
373 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset); 374 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
374 NGLayoutOpportunity opportunity = iter->Next(); 375 NGLayoutOpportunity opportunity = iter->Next();
375 if (!opportunity.IsEmpty()) 376 if (!opportunity.IsEmpty())
376 current_opportunity_ = opportunity; 377 current_opportunity_ = opportunity;
377 } 378 }
378 379
379 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() { 380 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() {
380 DCHECK(!HasItems()) << "Must call CreateLine()"; 381 DCHECK(!HasItems()) << "Must call CreateLine()";
381 DCHECK_EQ(fragments_.size(), offsets_.size());
382
383 NGFragmentBuilder container_builder(NGPhysicalFragment::kFragmentBox,
384 inline_box_);
385
386 for (unsigned i = 0; i < fragments_.size(); i++) {
387 // TODO(layout-dev): This should really be a std::move but
388 // CopyFragmentDataToLayoutBlockFlow also uses the fragments.
389 container_builder.AddChild(fragments_[i].get(), offsets_[i]);
390 }
391 382
392 // TODO(kojii): Check if the line box width should be content or available. 383 // TODO(kojii): Check if the line box width should be content or available.
393 // TODO(kojii): Need to take constraint_space into account. 384 // TODO(kojii): Need to take constraint_space into account.
394 container_builder.SetInlineSize(max_inline_size_) 385 container_builder_.SetInlineSize(max_inline_size_)
395 .SetInlineOverflow(max_inline_size_) 386 .SetInlineOverflow(max_inline_size_)
396 .SetBlockSize(content_size_) 387 .SetBlockSize(content_size_)
397 .SetBlockOverflow(content_size_); 388 .SetBlockOverflow(content_size_);
398 389
399 return container_builder.ToBoxFragment(); 390 container_layout_result_ = container_builder_.ToBoxFragment();
391 return container_layout_result_;
400 } 392 }
401 393
402 void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() { 394 void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() {
403 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow(); 395 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow();
404 block->deleteLineBoxTree(); 396 block->deleteLineBoxTree();
405 397
406 Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 398 Vector<NGLayoutInlineItem>& items = inline_box_->Items();
407 Vector<unsigned, 32> text_offsets(items.size()); 399 Vector<unsigned, 32> text_offsets(items.size());
408 inline_box_->GetLayoutTextOffsets(&text_offsets); 400 inline_box_->GetLayoutTextOffsets(&text_offsets);
409 401
410 Vector<NGPhysicalFragment*, 32> fragments_for_bidi_runs; 402 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs;
411 fragments_for_bidi_runs.reserveInitialCapacity(items.size()); 403 fragments_for_bidi_runs.reserveInitialCapacity(items.size());
412 BidiRunList<BidiRun> bidi_runs; 404 BidiRunList<BidiRun> bidi_runs;
413 LineInfo line_info; 405 LineInfo line_info;
414 unsigned fragment_index = 0; 406 unsigned fragment_index = 0;
407 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment(
408 container_layout_result_->PhysicalFragment().get());
415 for (const auto& line_box_data : line_box_data_list_) { 409 for (const auto& line_box_data : line_box_data_list_) {
416 // Create a BidiRunList for this line. 410 // Create a BidiRunList for this line.
417 for (; fragment_index < line_box_data.fragment_end; fragment_index++) { 411 for (; fragment_index < line_box_data.fragment_end; fragment_index++) {
418 NGPhysicalTextFragment* text_fragment = 412 const NGPhysicalFragment* fragment =
419 toNGPhysicalTextFragment(fragments_[fragment_index].get()); 413 box_fragment->Children()[fragment_index].get();
414 if (!fragment->IsText())
415 continue;
416 const auto* text_fragment = toNGPhysicalTextFragment(fragment);
420 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()]; 417 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()];
421 LayoutObject* layout_object = item.GetLayoutObject(); 418 LayoutObject* layout_object = item.GetLayoutObject();
422 if (!layout_object) // Skip bidi controls. 419 if (!layout_object) // Skip bidi controls.
423 continue; 420 continue;
424 BidiRun* run; 421 BidiRun* run;
425 if (layout_object->isText()) { 422 if (layout_object->isText()) {
426 unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; 423 unsigned text_offset = text_offsets[text_fragment->ItemIndex()];
427 run = new BidiRun(text_fragment->StartOffset() - text_offset, 424 run = new BidiRun(text_fragment->StartOffset() - text_offset,
428 text_fragment->EndOffset() - text_offset, 425 text_fragment->EndOffset() - text_offset,
429 item.BidiLevel(), LineLayoutItem(layout_object)); 426 item.BidiLevel(), LineLayoutItem(layout_object));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 baseline_position - LayoutUnit(line_box_data.max_ascent), 468 baseline_position - LayoutUnit(line_box_data.max_ascent),
472 baseline_position + LayoutUnit(line_box_data.max_descent), 469 baseline_position + LayoutUnit(line_box_data.max_descent),
473 line_box_data.top_with_leading, 470 line_box_data.top_with_leading,
474 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 471 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading));
475 472
476 bidi_runs.deleteRuns(); 473 bidi_runs.deleteRuns();
477 fragments_for_bidi_runs.clear(); 474 fragments_for_bidi_runs.clear();
478 } 475 }
479 } 476 }
480 } // namespace blink 477 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698