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

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

Issue 2764753007: [LayoutNG] Add NGLineBoxFragment (Closed)
Patch Set: Rebase again as other CLs landed faster Created 3 years, 8 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/layout_ng_block_flow.h" 11 #include "core/layout/ng/layout_ng_block_flow.h"
12 #include "core/layout/ng/ng_bidi_paragraph.h" 12 #include "core/layout/ng/ng_bidi_paragraph.h"
13 #include "core/layout/ng/ng_block_layout_algorithm.h" 13 #include "core/layout/ng/ng_block_layout_algorithm.h"
14 #include "core/layout/ng/ng_box_fragment.h" 14 #include "core/layout/ng/ng_box_fragment.h"
15 #include "core/layout/ng/ng_constraint_space.h" 15 #include "core/layout/ng/ng_constraint_space.h"
16 #include "core/layout/ng/ng_constraint_space_builder.h" 16 #include "core/layout/ng/ng_constraint_space_builder.h"
17 #include "core/layout/ng/ng_floating_object.h" 17 #include "core/layout/ng/ng_floating_object.h"
18 #include "core/layout/ng/ng_floats_utils.h" 18 #include "core/layout/ng/ng_floats_utils.h"
19 #include "core/layout/ng/ng_fragment_builder.h" 19 #include "core/layout/ng/ng_fragment_builder.h"
20 #include "core/layout/ng/ng_inline_node.h" 20 #include "core/layout/ng/ng_inline_node.h"
21 #include "core/layout/ng/ng_length_utils.h" 21 #include "core/layout/ng/ng_length_utils.h"
22 #include "core/layout/ng/ng_line_box_fragment.h"
23 #include "core/layout/ng/ng_line_box_fragment_builder.h"
22 #include "core/layout/ng/ng_space_utils.h" 24 #include "core/layout/ng/ng_space_utils.h"
23 #include "core/layout/ng/ng_text_fragment.h" 25 #include "core/layout/ng/ng_text_fragment.h"
26 #include "core/layout/ng/ng_text_fragment_builder.h"
24 #include "core/style/ComputedStyle.h" 27 #include "core/style/ComputedStyle.h"
25 #include "platform/text/BidiRunList.h" 28 #include "platform/text/BidiRunList.h"
26 29
27 namespace blink { 30 namespace blink {
28 namespace { 31 namespace {
29 32
30 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( 33 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat(
31 const ComputedStyle& style, 34 const ComputedStyle& style,
32 const NGConstraintSpace& parent_space, 35 const NGConstraintSpace& parent_space,
33 NGConstraintSpaceBuilder* space_builder) { 36 NGConstraintSpaceBuilder* space_builder) {
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 PositionFloat(origin_point, constraint_space_->BfcOffset(), 343 PositionFloat(origin_point, constraint_space_->BfcOffset(),
341 floating_object.get(), constraint_space_); 344 floating_object.get(), constraint_space_);
342 container_builder_.AddFloatingObject(floating_object, offset); 345 container_builder_.AddFloatingObject(floating_object, offset);
343 FindNextLayoutOpportunity(); 346 FindNextLayoutOpportunity();
344 } 347 }
345 } 348 }
346 349
347 void NGLineBuilder::PlaceItems( 350 void NGLineBuilder::PlaceItems(
348 const Vector<LineItemChunk, 32>& line_item_chunks) { 351 const Vector<LineItemChunk, 32>& line_item_chunks) {
349 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 352 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
350 const unsigned fragment_start_index = container_builder_.Children().size();
351 353
352 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText, 354 NGLineBoxFragmentBuilder line_box(inline_box_);
353 inline_box_); 355 NGTextFragmentBuilder text_builder(inline_box_);
354 text_builder.SetWritingMode(ConstraintSpace().WritingMode());
355 line_box_data_list_.grow(line_box_data_list_.size() + 1);
356 LineBoxData& line_box_data = line_box_data_list_.back();
357 356
358 // Accumulate a "strut"; a zero-width inline box with the element's font and 357 // Accumulate a "strut"; a zero-width inline box with the element's font and
359 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut 358 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut
360 const ComputedStyle* block_style = inline_box_->BlockStyle(); 359 const ComputedStyle* block_style = inline_box_->BlockStyle();
361 InlineItemMetrics block_metrics(*block_style, baseline_type_); 360 NGLineHeightMetrics block_metrics(*block_style, baseline_type_);
362 line_box_data.UpdateMaxAscentAndDescent(block_metrics); 361 line_box.UniteMetrics(block_metrics);
363 362
364 // Use the block style to compute the estimated baseline position because the 363 // Use the block style to compute the estimated baseline position because the
365 // baseline position is not known until we know the maximum ascent and leading 364 // baseline position is not known until we know the maximum ascent and leading
366 // of the line. Items are placed on this baseline, then adjusted later if the 365 // of the line. Items are placed on this baseline, then adjusted later if the
367 // estimation turned out to be different. 366 // estimation turned out to be different.
368 LayoutUnit estimated_baseline = 367 LayoutUnit estimated_baseline =
369 content_size_ + LayoutUnit(block_metrics.ascent_and_leading); 368 content_size_ + LayoutUnit(block_metrics.ascent_and_leading);
370 369
370 LayoutUnit inline_size;
371 for (const auto& line_item_chunk : line_item_chunks) { 371 for (const auto& line_item_chunk : line_item_chunks) {
372 const NGLayoutInlineItem& item = items[line_item_chunk.index]; 372 const NGLayoutInlineItem& item = items[line_item_chunk.index];
373 // Skip bidi controls. 373 // Skip bidi controls.
374 if (!item.GetLayoutObject()) 374 if (!item.GetLayoutObject())
375 continue; 375 continue;
376 376
377 LayoutUnit block_start; 377 LayoutUnit block_start;
378 if (item.Type() == NGLayoutInlineItem::kText) { 378 if (item.Type() == NGLayoutInlineItem::kText) {
379 DCHECK(item.GetLayoutObject()->isText()); 379 DCHECK(item.GetLayoutObject()->isText());
380 const ComputedStyle* style = item.Style(); 380 const ComputedStyle* style = item.Style();
381 // The direction of a fragment is the CSS direction to resolve logical
382 // properties, not the resolved bidi direction.
383 text_builder.SetDirection(style->direction())
384 .SetInlineSize(line_item_chunk.inline_size);
385
381 // |InlineTextBoxPainter| sets the baseline at |top + 386 // |InlineTextBoxPainter| sets the baseline at |top +
382 // ascent-of-primary-font|. Compute |top| to match. 387 // ascent-of-primary-font|. Compute |top| to match.
383 InlineItemMetrics metrics(*style, baseline_type_); 388 NGLineHeightMetrics metrics(*style, baseline_type_);
384 block_start = estimated_baseline - LayoutUnit(metrics.ascent); 389 block_start = estimated_baseline - LayoutUnit(metrics.ascent);
385 LayoutUnit line_height = LayoutUnit(metrics.ascent + metrics.descent); 390 text_builder.SetBlockSize(metrics.LineHeight());
386 line_box_data.UpdateMaxAscentAndDescent(metrics); 391 line_box.UniteMetrics(metrics);
387 392
388 // Take all used fonts into account if 'line-height: normal'. 393 // Take all used fonts into account if 'line-height: normal'.
389 if (style->lineHeight().isNegative()) 394 if (style->lineHeight().isNegative())
390 AccumulateUsedFonts(item, line_item_chunk, &line_box_data); 395 AccumulateUsedFonts(item, line_item_chunk, &line_box);
391
392 // The direction of a fragment is the CSS direction to resolve logical
393 // properties, not the resolved bidi direction.
394 text_builder.SetDirection(style->direction())
395 .SetInlineSize(line_item_chunk.inline_size)
396 .SetInlineOverflow(line_item_chunk.inline_size)
397 .SetBlockSize(line_height)
398 .SetBlockOverflow(line_height);
399 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) { 396 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) {
400 block_start = PlaceAtomicInline(item, estimated_baseline, &line_box_data, 397 block_start =
401 &text_builder); 398 PlaceAtomicInline(item, estimated_baseline, &line_box, &text_builder);
402 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) { 399 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) {
403 // TODO(layout-dev): Report the correct static position for the out of 400 // TODO(layout-dev): Report the correct static position for the out of
404 // flow descendant. We can't do this here yet as it doesn't know the 401 // flow descendant. We can't do this here yet as it doesn't know the
405 // size of the line box. 402 // size of the line box.
406 container_builder_.AddOutOfFlowDescendant( 403 container_builder_.AddOutOfFlowDescendant(
407 // Absolute positioning blockifies the box's display type. 404 // Absolute positioning blockifies the box's display type.
408 // https://drafts.csswg.org/css-display/#transformations 405 // https://drafts.csswg.org/css-display/#transformations
409 new NGBlockNode(item.GetLayoutObject()), 406 new NGBlockNode(item.GetLayoutObject()),
410 NGStaticPosition::Create(ConstraintSpace().WritingMode(), 407 NGStaticPosition::Create(ConstraintSpace().WritingMode(),
411 ConstraintSpace().Direction(), 408 ConstraintSpace().Direction(),
412 NGPhysicalOffset())); 409 NGPhysicalOffset()));
413 continue; 410 continue;
414 } else { 411 } else {
415 continue; 412 continue;
416 } 413 }
417 414
418 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 415 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
419 line_item_chunk.index, line_item_chunk.start_offset, 416 line_item_chunk.index, line_item_chunk.start_offset,
420 line_item_chunk.end_offset); 417 line_item_chunk.end_offset);
421 418
422 NGLogicalOffset logical_offset( 419 NGLogicalOffset logical_offset(
423 line_box_data.inline_size + current_opportunity_.InlineStartOffset() - 420 inline_size + current_opportunity_.InlineStartOffset() -
424 ConstraintSpace().BfcOffset().inline_offset, 421 ConstraintSpace().BfcOffset().inline_offset,
425 block_start); 422 block_start);
426 container_builder_.AddChild(std::move(text_fragment), logical_offset); 423 line_box.AddChild(std::move(text_fragment), logical_offset);
427 line_box_data.inline_size += line_item_chunk.inline_size; 424 inline_size += line_item_chunk.inline_size;
428 } 425 }
429 426
430 if (fragment_start_index == container_builder_.Children().size()) { 427 if (line_box.Children().isEmpty()) {
431 // The line was empty. Remove the LineBoxData. 428 // The line was empty.
432 line_box_data_list_.shrink(line_box_data_list_.size() - 1);
433 return; 429 return;
434 } 430 }
435 431
436 // If the estimated baseline position was not the actual position, move all 432 // If the estimated baseline position was not the actual position, move all
437 // fragments in the block direction. 433 // fragments in the block direction.
438 if (block_metrics.ascent_and_leading != 434 LayoutUnit adjust_baseline(line_box.Metrics().ascent_and_leading -
439 line_box_data.max_ascent_and_leading) { 435 block_metrics.ascent_and_leading);
440 LayoutUnit adjust_top(line_box_data.max_ascent_and_leading - 436 if (adjust_baseline)
441 block_metrics.ascent_and_leading); 437 line_box.MoveChildrenInBlockDirection(adjust_baseline);
442 auto& offsets = container_builder_.MutableOffsets();
443 for (unsigned i = fragment_start_index; i < offsets.size(); i++)
444 offsets[i].block_offset += adjust_top;
445 }
446 438
447 line_box_data.fragment_end = container_builder_.Children().size(); 439 line_box.SetInlineSize(inline_size);
448 line_box_data.top_with_leading = content_size_; 440 NGLogicalOffset offset(LayoutUnit(), content_size_);
449 max_inline_size_ = std::max(max_inline_size_, line_box_data.inline_size); 441 container_builder_.AddChild(line_box.ToLineBoxFragment(), offset);
450 content_size_ += LayoutUnit(line_box_data.max_ascent_and_leading + 442 max_inline_size_ = std::max(max_inline_size_, inline_size);
451 line_box_data.max_descent_and_leading); 443 content_size_ += line_box.Metrics().LineHeight();
452 }
453
454 NGLineBuilder::InlineItemMetrics::InlineItemMetrics(
455 const ComputedStyle& style,
456 FontBaseline baseline_type) {
457 const SimpleFontData* font_data = style.font().primaryFont();
458 DCHECK(font_data);
459 Initialize(font_data->getFontMetrics(), baseline_type,
460 style.computedLineHeightInFloat());
461 }
462
463 NGLineBuilder::InlineItemMetrics::InlineItemMetrics(
464 const FontMetrics& font_metrics,
465 FontBaseline baseline_type) {
466 Initialize(font_metrics, baseline_type, font_metrics.floatLineSpacing());
467 }
468
469 void NGLineBuilder::InlineItemMetrics::Initialize(
470 const FontMetrics& font_metrics,
471 FontBaseline baseline_type,
472 float line_height) {
473 ascent = font_metrics.floatAscent(baseline_type);
474 descent = font_metrics.floatDescent(baseline_type);
475 float half_leading = (line_height - (ascent + descent)) / 2;
476 // Ensure the top and the baseline is snapped to CSS pixel.
477 // TODO(kojii): How to handle fractional ascent isn't determined yet. Should
478 // we snap top or baseline? If baseline, top needs fractional. If top,
479 // baseline may not align across fonts.
480 ascent_and_leading = ascent + floor(half_leading);
481 descent_and_leading = line_height - ascent_and_leading;
482 }
483
484 void NGLineBuilder::LineBoxData::UpdateMaxAscentAndDescent(
485 const NGLineBuilder::InlineItemMetrics& metrics) {
486 max_ascent = std::max(max_ascent, metrics.ascent);
487 max_descent = std::max(max_descent, metrics.descent);
488 max_ascent_and_leading =
489 std::max(max_ascent_and_leading, metrics.ascent_and_leading);
490 max_descent_and_leading =
491 std::max(max_descent_and_leading, metrics.descent_and_leading);
492 } 444 }
493 445
494 void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item, 446 void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item,
495 const LineItemChunk& line_item_chunk, 447 const LineItemChunk& line_item_chunk,
496 LineBoxData* line_box_data) { 448 NGLineBoxFragmentBuilder* line_box) {
497 HashSet<const SimpleFontData*> fallback_fonts; 449 HashSet<const SimpleFontData*> fallback_fonts;
498 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 450 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
499 line_item_chunk.end_offset); 451 line_item_chunk.end_offset);
500 for (const auto& fallback_font : fallback_fonts) { 452 for (const auto& fallback_font : fallback_fonts) {
501 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(), 453 NGLineHeightMetrics metrics(fallback_font->getFontMetrics(),
502 baseline_type_); 454 baseline_type_);
503 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics); 455 line_box->UniteMetrics(metrics);
504 } 456 }
505 } 457 }
506 458
507 LayoutUnit NGLineBuilder::PlaceAtomicInline(const NGLayoutInlineItem& item, 459 LayoutUnit NGLineBuilder::PlaceAtomicInline(
508 LayoutUnit estimated_baseline, 460 const NGLayoutInlineItem& item,
509 LineBoxData* line_box_data, 461 LayoutUnit estimated_baseline,
510 NGFragmentBuilder* text_builder) { 462 NGLineBoxFragmentBuilder* line_box,
463 NGTextFragmentBuilder* text_builder) {
511 NGBoxFragment fragment( 464 NGBoxFragment fragment(
512 ConstraintSpace().WritingMode(), 465 ConstraintSpace().WritingMode(),
513 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get())); 466 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get()));
514 // TODO(kojii): Margin and border in block progression not implemented yet. 467 // TODO(kojii): Margin and border in block progression not implemented yet.
515 LayoutUnit block_size = fragment.BlockSize(); 468 LayoutUnit block_size = fragment.BlockSize();
516 469
517 // TODO(kojii): Try to eliminate the wrapping text fragment and use the 470 // TODO(kojii): Try to eliminate the wrapping text fragment and use the
518 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow| 471 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow|
519 // requires a text fragment. 472 // requires a text fragment.
520 text_builder->SetInlineSize(fragment.InlineSize()) 473 text_builder->SetInlineSize(fragment.InlineSize()).SetBlockSize(block_size);
521 .SetInlineOverflow(fragment.InlineOverflow())
522 .SetBlockSize(block_size)
523 .SetBlockOverflow(fragment.BlockOverflow());
524 474
525 // TODO(kojii): Add baseline position to NGPhysicalFragment. 475 // TODO(kojii): Add baseline position to NGPhysicalFragment.
526 LayoutBox* box = toLayoutBox(item.GetLayoutObject()); 476 LayoutBox* box = toLayoutBox(item.GetLayoutObject());
527 LineDirectionMode line_direction_mode = 477 LineDirectionMode line_direction_mode =
528 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine 478 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine
529 : LineDirectionMode::VerticalLine; 479 : LineDirectionMode::VerticalLine;
530 bool is_first_line = line_box_data_list_.size() == 1; 480 bool is_first_line = container_builder_.Children().isEmpty();
531 int baseline_offset = 481 int baseline_offset =
532 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode); 482 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode);
533 LayoutUnit block_start = estimated_baseline - baseline_offset; 483 LayoutUnit block_start = estimated_baseline - baseline_offset;
534 484
535 line_box_data->max_ascent_and_leading = 485 NGLineHeightMetrics metrics;
536 std::max<float>(baseline_offset, line_box_data->max_ascent_and_leading); 486 metrics.ascent_and_leading = baseline_offset;
537 line_box_data->max_descent_and_leading = std::max<float>( 487 metrics.descent_and_leading = block_size - baseline_offset;
538 block_size - baseline_offset, line_box_data->max_descent_and_leading); 488 line_box->UniteMetrics(metrics);
539 489
540 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. 490 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
541 // Floats are ok because atomic inlines are BFC? 491 // Floats are ok because atomic inlines are BFC?
542 492
543 return block_start; 493 return block_start;
544 } 494 }
545 495
546 void NGLineBuilder::FindNextLayoutOpportunity() { 496 void NGLineBuilder::FindNextLayoutOpportunity() {
547 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 497 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
548 iter_offset.block_offset += content_size_; 498 iter_offset.block_offset += content_size_;
(...skipping 22 matching lines...) Expand all
571 block->deleteLineBoxTree(); 521 block->deleteLineBoxTree();
572 522
573 Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 523 Vector<NGLayoutInlineItem>& items = inline_box_->Items();
574 Vector<unsigned, 32> text_offsets(items.size()); 524 Vector<unsigned, 32> text_offsets(items.size());
575 inline_box_->GetLayoutTextOffsets(&text_offsets); 525 inline_box_->GetLayoutTextOffsets(&text_offsets);
576 526
577 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs; 527 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs;
578 fragments_for_bidi_runs.reserveInitialCapacity(items.size()); 528 fragments_for_bidi_runs.reserveInitialCapacity(items.size());
579 BidiRunList<BidiRun> bidi_runs; 529 BidiRunList<BidiRun> bidi_runs;
580 LineInfo line_info; 530 LineInfo line_info;
581 unsigned fragment_index = 0;
582 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment( 531 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment(
583 container_layout_result_->PhysicalFragment().get()); 532 container_layout_result_->PhysicalFragment().get());
584 for (const auto& line_box_data : line_box_data_list_) { 533 for (const auto& container_child : box_fragment->Children()) {
534 NGPhysicalLineBoxFragment* physical_line_box =
535 toNGPhysicalLineBoxFragment(container_child.get());
585 // Create a BidiRunList for this line. 536 // Create a BidiRunList for this line.
586 for (; fragment_index < line_box_data.fragment_end; fragment_index++) { 537 for (const auto& line_child : physical_line_box->Children()) {
587 const NGPhysicalFragment* fragment = 538 const auto* text_fragment = toNGPhysicalTextFragment(line_child.get());
588 box_fragment->Children()[fragment_index].get();
589 if (!fragment->IsText())
590 continue;
591 const auto* text_fragment = toNGPhysicalTextFragment(fragment);
592 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()]; 539 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()];
593 LayoutObject* layout_object = item.GetLayoutObject();
594 if (!layout_object) // Skip bidi controls.
595 continue;
596 BidiRun* run; 540 BidiRun* run;
597 if (layout_object->isText()) { 541 if (item.Type() == NGLayoutInlineItem::kText) {
542 LayoutObject* layout_object = item.GetLayoutObject();
543 DCHECK(layout_object->isText());
598 unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; 544 unsigned text_offset = text_offsets[text_fragment->ItemIndex()];
599 run = new BidiRun(text_fragment->StartOffset() - text_offset, 545 run = new BidiRun(text_fragment->StartOffset() - text_offset,
600 text_fragment->EndOffset() - text_offset, 546 text_fragment->EndOffset() - text_offset,
601 item.BidiLevel(), LineLayoutItem(layout_object)); 547 item.BidiLevel(), LineLayoutItem(layout_object));
602 layout_object->clearNeedsLayout(); 548 layout_object->clearNeedsLayout();
603 } else { 549 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) {
550 LayoutObject* layout_object = item.GetLayoutObject();
604 DCHECK(layout_object->isAtomicInlineLevel()); 551 DCHECK(layout_object->isAtomicInlineLevel());
605 run = 552 run =
606 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object)); 553 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object));
554 } else {
555 continue;
607 } 556 }
608 bidi_runs.addRun(run); 557 bidi_runs.addRun(run);
609 fragments_for_bidi_runs.push_back(text_fragment); 558 fragments_for_bidi_runs.push_back(text_fragment);
610 } 559 }
611 // TODO(kojii): bidi needs to find the logical last run. 560 // TODO(kojii): bidi needs to find the logical last run.
612 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun()); 561 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun());
613 562
614 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the 563 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the
615 // RootInlineBox are set to Bidirun::m_box. 564 // RootInlineBox are set to Bidirun::m_box.
616 line_info.setEmpty(false); 565 line_info.setEmpty(false);
617 // TODO(kojii): Implement setFirstLine, LastLine, etc. 566 // TODO(kojii): Implement setFirstLine, LastLine, etc.
618 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info); 567 RootInlineBox* root_line_box = block->constructLine(bidi_runs, line_info);
619 568
620 // Copy fragments data to InlineBoxes. 569 // Copy fragments data to InlineBoxes.
621 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount()); 570 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount());
622 BidiRun* run = bidi_runs.firstRun(); 571 BidiRun* run = bidi_runs.firstRun();
623 for (auto* physical_fragment : fragments_for_bidi_runs) { 572 for (auto* physical_fragment : fragments_for_bidi_runs) {
624 DCHECK(run); 573 DCHECK(run);
625 NGTextFragment fragment(ConstraintSpace().WritingMode(), 574 NGTextFragment fragment(ConstraintSpace().WritingMode(),
626 toNGPhysicalTextFragment(physical_fragment)); 575 toNGPhysicalTextFragment(physical_fragment));
627 InlineBox* inline_box = run->m_box; 576 InlineBox* inline_box = run->m_box;
628 inline_box->setLogicalWidth(fragment.InlineSize()); 577 inline_box->setLogicalWidth(fragment.InlineSize());
629 inline_box->setLogicalLeft(fragment.InlineOffset()); 578 inline_box->setLogicalLeft(fragment.InlineOffset());
630 inline_box->setLogicalTop(fragment.BlockOffset()); 579 inline_box->setLogicalTop(fragment.BlockOffset());
631 if (inline_box->getLineLayoutItem().isBox()) { 580 if (inline_box->getLineLayoutItem().isBox()) {
632 LineLayoutBox box(inline_box->getLineLayoutItem()); 581 LineLayoutBox box(inline_box->getLineLayoutItem());
633 box.setLocation(inline_box->location()); 582 box.setLocation(inline_box->location());
634 } 583 }
635 run = run->next(); 584 run = run->next();
636 } 585 }
637 DCHECK(!run); 586 DCHECK(!run);
638 587
639 // Copy LineBoxData to RootInlineBox. 588 // Copy to RootInlineBox.
640 line_box->setLogicalWidth(line_box_data.inline_size); 589 NGLineBoxFragment line_box(ConstraintSpace().WritingMode(),
641 line_box->setLogicalTop(line_box_data.top_with_leading); 590 physical_line_box);
642 LayoutUnit baseline_position = 591 root_line_box->setLogicalWidth(line_box.InlineSize());
643 line_box_data.top_with_leading + 592 LayoutUnit line_top_with_leading = line_box.BlockOffset();
644 LayoutUnit(line_box_data.max_ascent_and_leading); 593 root_line_box->setLogicalTop(line_top_with_leading);
645 line_box->setLineTopBottomPositions( 594 const NGLineHeightMetrics& metrics = physical_line_box->Metrics();
646 baseline_position - LayoutUnit(line_box_data.max_ascent), 595 LayoutUnit baseline =
647 baseline_position + LayoutUnit(line_box_data.max_descent), 596 line_top_with_leading + LayoutUnit(metrics.ascent_and_leading);
648 line_box_data.top_with_leading, 597 root_line_box->setLineTopBottomPositions(
649 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 598 baseline - LayoutUnit(metrics.ascent),
599 baseline + LayoutUnit(metrics.descent), line_top_with_leading,
600 baseline + LayoutUnit(metrics.descent_and_leading));
650 601
651 bidi_runs.deleteRuns(); 602 bidi_runs.deleteRuns();
652 fragments_for_bidi_runs.clear(); 603 fragments_for_bidi_runs.clear();
653 } 604 }
654 } 605 }
655 } // namespace blink 606 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698