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

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

Issue 2803433002: [LayoutNG] Initial support for the 'vertical-align' property (Closed)
Patch Set: Move NGInlineBoxState to its own file 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/inline/ng_inline_layout_algorithm.h" 5 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h"
6 6
7 #include "core/layout/ng/inline/ng_bidi_paragraph.h" 7 #include "core/layout/ng/inline/ng_bidi_paragraph.h"
8 #include "core/layout/ng/inline/ng_inline_break_token.h" 8 #include "core/layout/ng/inline/ng_inline_break_token.h"
9 #include "core/layout/ng/inline/ng_inline_node.h" 9 #include "core/layout/ng/inline/ng_inline_node.h"
10 #include "core/layout/ng/inline/ng_line_box_fragment.h" 10 #include "core/layout/ng/inline/ng_line_box_fragment.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 BidiReorder(&line_item_chunks); 264 BidiReorder(&line_item_chunks);
265 265
266 if (!PlaceItems(line_item_chunks)) 266 if (!PlaceItems(line_item_chunks))
267 return false; 267 return false;
268 268
269 // Prepare for the next line. 269 // Prepare for the next line.
270 // Move |start| to |last_break_opportunity|, keeping items after 270 // Move |start| to |last_break_opportunity|, keeping items after
271 // |last_break_opportunity|. 271 // |last_break_opportunity|.
272 start_index_ = last_break_opportunity_index_; 272 start_index_ = last_break_opportunity_index_;
273 start_offset_ = last_break_opportunity_offset_; 273 start_offset_ = last_break_opportunity_offset_;
274 // If the offset is at the end of the item, move to the next item.
275 if (start_offset_ == items[start_index_].EndOffset() &&
276 start_index_ < items.size() - 1) {
277 start_index_++;
278 }
274 DCHECK_GE(end_position_, last_break_opportunity_position_); 279 DCHECK_GE(end_position_, last_break_opportunity_position_);
275 end_position_ -= last_break_opportunity_position_; 280 end_position_ -= last_break_opportunity_position_;
276 last_break_opportunity_position_ = LayoutUnit(); 281 last_break_opportunity_position_ = LayoutUnit();
277 #if DCHECK_IS_ON() 282 #if DCHECK_IS_ON()
278 is_bidi_reordered_ = false; 283 is_bidi_reordered_ = false;
279 #endif 284 #endif
280 285
281 NGLogicalOffset origin_point = 286 NGLogicalOffset origin_point =
282 GetOriginPointForFloats(ConstraintSpace(), content_size_); 287 GetOriginPointForFloats(ConstraintSpace(), content_size_);
283 PositionPendingFloats(origin_point.block_offset, MutableConstraintSpace(), 288 PositionPendingFloats(origin_point.block_offset, MutableConstraintSpace(),
(...skipping 13 matching lines...) Expand all
297 // embedding levels of parts of runs, which requires to split items. 302 // embedding levels of parts of runs, which requires to split items.
298 // http://unicode.org/reports/tr9/#L1 303 // http://unicode.org/reports/tr9/#L1
299 // BidiResolver does not support L1 crbug.com/316409. 304 // BidiResolver does not support L1 crbug.com/316409.
300 305
301 // Create a list of chunk indices in the visual order. 306 // Create a list of chunk indices in the visual order.
302 // ICU |ubidi_getVisualMap()| works for a run of characters. Since we can 307 // ICU |ubidi_getVisualMap()| works for a run of characters. Since we can
303 // handle the direction of each run, we use |ubidi_reorderVisual()| to reorder 308 // handle the direction of each run, we use |ubidi_reorderVisual()| to reorder
304 // runs instead of characters. 309 // runs instead of characters.
305 Vector<UBiDiLevel, 32> levels; 310 Vector<UBiDiLevel, 32> levels;
306 levels.ReserveInitialCapacity(line_item_chunks->size()); 311 levels.ReserveInitialCapacity(line_item_chunks->size());
312 const Vector<NGLayoutInlineItem>& items = Node()->Items();
307 for (const auto& chunk : *line_item_chunks) 313 for (const auto& chunk : *line_item_chunks)
308 levels.push_back(Node()->Items()[chunk.index].BidiLevel()); 314 levels.push_back(items[chunk.index].BidiLevel());
309 Vector<int32_t, 32> indices_in_visual_order(line_item_chunks->size()); 315 Vector<int32_t, 32> indices_in_visual_order(line_item_chunks->size());
310 NGBidiParagraph::IndicesInVisualOrder(levels, &indices_in_visual_order); 316 NGBidiParagraph::IndicesInVisualOrder(levels, &indices_in_visual_order);
311 317
312 // Reorder |line_item_chunks| in visual order. 318 // Reorder |line_item_chunks| in visual order.
313 Vector<LineItemChunk, 32> line_item_chunks_in_visual_order( 319 Vector<LineItemChunk, 32> line_item_chunks_in_visual_order(
314 line_item_chunks->size()); 320 line_item_chunks->size());
315 for (unsigned visual_index = 0; visual_index < indices_in_visual_order.size(); 321 for (unsigned visual_index = 0; visual_index < indices_in_visual_order.size();
316 visual_index++) { 322 visual_index++) {
317 unsigned logical_index = indices_in_visual_order[visual_index]; 323 unsigned logical_index = indices_in_visual_order[visual_index];
318 line_item_chunks_in_visual_order[visual_index] = 324 line_item_chunks_in_visual_order[visual_index] =
319 (*line_item_chunks)[logical_index]; 325 (*line_item_chunks)[logical_index];
320 } 326 }
327
328 // Keep Open before Close in the visual order.
329 HashMap<LayoutObject*, unsigned> first_index;
330 for (unsigned i = 0; i < line_item_chunks_in_visual_order.size(); i++) {
331 LineItemChunk& chunk = line_item_chunks_in_visual_order[i];
332 const NGLayoutInlineItem& item = items[chunk.index];
333 if (item.Type() != NGLayoutInlineItem::kOpenTag &&
334 item.Type() != NGLayoutInlineItem::kCloseTag) {
335 continue;
336 }
337 auto result = first_index.insert(item.GetLayoutObject(), i);
338 if (!result.is_new_entry && item.Type() == NGLayoutInlineItem::kOpenTag) {
339 std::swap(line_item_chunks_in_visual_order[i],
340 line_item_chunks_in_visual_order[result.stored_value->value]);
341 }
342 }
343
321 line_item_chunks->Swap(line_item_chunks_in_visual_order); 344 line_item_chunks->Swap(line_item_chunks_in_visual_order);
322 } 345 }
323 346
324 // TODO(glebl): Add the support of clearance for inline floats. 347 // TODO(glebl): Add the support of clearance for inline floats.
325 void NGInlineLayoutAlgorithm::LayoutAndPositionFloat( 348 void NGInlineLayoutAlgorithm::LayoutAndPositionFloat(
326 LayoutUnit end_position, 349 LayoutUnit end_position,
327 LayoutObject* layout_object) { 350 LayoutObject* layout_object) {
328 NGBlockNode* node = new NGBlockNode(layout_object); 351 NGBlockNode* node = new NGBlockNode(layout_object);
329 352
330 RefPtr<NGConstraintSpace> float_space = 353 RefPtr<NGConstraintSpace> float_space =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 // https://drafts.csswg.org/css2/visudet.html#strut 399 // https://drafts.csswg.org/css2/visudet.html#strut
377 const ComputedStyle& line_style = LineStyle(); 400 const ComputedStyle& line_style = LineStyle();
378 NGLineHeightMetrics line_metrics(line_style, baseline_type_); 401 NGLineHeightMetrics line_metrics(line_style, baseline_type_);
379 NGLineHeightMetrics line_metrics_with_leading = line_metrics; 402 NGLineHeightMetrics line_metrics_with_leading = line_metrics;
380 line_metrics_with_leading.AddLeading(line_style.ComputedLineHeightAsFixed()); 403 line_metrics_with_leading.AddLeading(line_style.ComputedLineHeightAsFixed());
381 NGLineBoxFragmentBuilder line_box(Node(), line_metrics_with_leading); 404 NGLineBoxFragmentBuilder line_box(Node(), line_metrics_with_leading);
382 405
383 // Compute heights of all inline items by placing the dominant baseline at 0. 406 // Compute heights of all inline items by placing the dominant baseline at 0.
384 // The baseline is adjusted after the height of the line box is computed. 407 // The baseline is adjusted after the height of the line box is computed.
385 NGTextFragmentBuilder text_builder(Node()); 408 NGTextFragmentBuilder text_builder(Node());
409 NGInlineBoxState* box = OnBeginPlaceItems();
386 LayoutUnit inline_size; 410 LayoutUnit inline_size;
387 for (const auto& line_item_chunk : line_item_chunks) { 411 for (const auto& line_item_chunk : line_item_chunks) {
388 const NGLayoutInlineItem& item = items[line_item_chunk.index]; 412 const NGLayoutInlineItem& item = items[line_item_chunk.index];
389 // Skip bidi controls. 413 LayoutUnit line_top;
390 if (!item.GetLayoutObject())
391 continue;
392
393 LayoutUnit block_start;
394 if (item.Type() == NGLayoutInlineItem::kText) { 414 if (item.Type() == NGLayoutInlineItem::kText) {
395 DCHECK(item.GetLayoutObject()->IsText()); 415 DCHECK(item.GetLayoutObject()->IsText());
396 const ComputedStyle* style = item.Style(); 416 if (box->text_metrics.IsEmpty())
397 // The direction of a fragment is the CSS direction to resolve logical 417 box->ComputeTextMetrics(item, baseline_type_);
398 // properties, not the resolved bidi direction. 418 line_top = box->text_top;
399 text_builder.SetDirection(style->Direction()) 419 text_builder.SetSize(
400 .SetInlineSize(line_item_chunk.inline_size); 420 {line_item_chunk.inline_size, box->text_metrics.LineHeight()});
401
402 // |InlineTextBoxPainter| sets the baseline at |top +
403 // ascent-of-primary-font|. Compute |top| to match.
404 NGLineHeightMetrics metrics(*style, baseline_type_);
405 block_start = -metrics.ascent;
406 metrics.AddLeading(style->ComputedLineHeightAsFixed());
407 text_builder.SetBlockSize(metrics.LineHeight());
408 line_box.UniteMetrics(metrics);
409
410 // Take all used fonts into account if 'line-height: normal'. 421 // Take all used fonts into account if 'line-height: normal'.
411 if (style->LineHeight().IsNegative()) 422 if (box->include_used_fonts)
412 AccumulateUsedFonts(item, line_item_chunk, &line_box); 423 AccumulateUsedFonts(item, line_item_chunk, &line_box);
424 } else if (item.Type() == NGLayoutInlineItem::kOpenTag) {
425 box = OnOpenTag(item, &line_box, &text_builder);
426 continue;
427 } else if (item.Type() == NGLayoutInlineItem::kCloseTag) {
428 box = OnCloseTag(item, &line_box, box);
429 continue;
413 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) { 430 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) {
414 block_start = PlaceAtomicInline(item, &line_box, &text_builder); 431 line_top = PlaceAtomicInline(item, &line_box, &text_builder);
415 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) { 432 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) {
416 // TODO(layout-dev): Report the correct static position for the out of 433 // TODO(layout-dev): Report the correct static position for the out of
417 // flow descendant. We can't do this here yet as it doesn't know the 434 // flow descendant. We can't do this here yet as it doesn't know the
418 // size of the line box. 435 // size of the line box.
419 container_builder_.AddOutOfFlowDescendant( 436 container_builder_.AddOutOfFlowDescendant(
420 // Absolute positioning blockifies the box's display type. 437 // Absolute positioning blockifies the box's display type.
421 // https://drafts.csswg.org/css-display/#transformations 438 // https://drafts.csswg.org/css-display/#transformations
422 new NGBlockNode(item.GetLayoutObject()), 439 new NGBlockNode(item.GetLayoutObject()),
423 NGStaticPosition::Create(ConstraintSpace().WritingMode(), 440 NGStaticPosition::Create(ConstraintSpace().WritingMode(),
424 ConstraintSpace().Direction(), 441 ConstraintSpace().Direction(),
425 NGPhysicalOffset())); 442 NGPhysicalOffset()));
426 continue; 443 continue;
427 } else { 444 } else {
428 continue; 445 continue;
429 } 446 }
430 447
431 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 448 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
432 line_item_chunk.index, line_item_chunk.start_offset, 449 line_item_chunk.index, line_item_chunk.start_offset,
433 line_item_chunk.end_offset); 450 line_item_chunk.end_offset);
434 451
435 NGLogicalOffset logical_offset( 452 NGLogicalOffset logical_offset(
436 inline_size + current_opportunity_.InlineStartOffset() - 453 inline_size + current_opportunity_.InlineStartOffset() -
437 ConstraintSpace().BfcOffset().inline_offset, 454 ConstraintSpace().BfcOffset().inline_offset,
438 block_start); 455 line_top);
439 line_box.AddChild(std::move(text_fragment), logical_offset); 456 line_box.AddChild(std::move(text_fragment), logical_offset);
440 inline_size += line_item_chunk.inline_size; 457 inline_size += line_item_chunk.inline_size;
441 } 458 }
442 459
443 if (line_box.Children().IsEmpty()) { 460 if (line_box.Children().IsEmpty()) {
444 return true; // The line was empty. 461 return true; // The line was empty.
445 } 462 }
446 463
464 OnEndPlaceItems(&line_box);
465
447 // The baselines are always placed at pixel boundaries. Not doing so results 466 // The baselines are always placed at pixel boundaries. Not doing so results
448 // in incorrect layout of text decorations, most notably underlines. 467 // in incorrect layout of text decorations, most notably underlines.
449 LayoutUnit baseline = content_size_ + line_box.Metrics().ascent; 468 LayoutUnit baseline = content_size_ + line_box.Metrics().ascent;
450 baseline = LayoutUnit(baseline.Round()); 469 baseline = LayoutUnit(baseline.Round());
451 470
452 // Check if the line fits into the constraint space in block direction. 471 // Check if the line fits into the constraint space in block direction.
453 LayoutUnit line_bottom = baseline + line_box.Metrics().descent; 472 LayoutUnit line_bottom = baseline + line_box.Metrics().descent;
454 if (!container_builder_.Children().IsEmpty() && 473 if (!container_builder_.Children().IsEmpty() &&
455 ConstraintSpace().AvailableSize().block_size != NGSizeIndefinite && 474 ConstraintSpace().AvailableSize().block_size != NGSizeIndefinite &&
456 line_bottom > ConstraintSpace().AvailableSize().block_size) { 475 line_bottom > ConstraintSpace().AvailableSize().block_size) {
(...skipping 16 matching lines...) Expand all
473 line_box.MoveChildrenInBlockDirection(baseline); 492 line_box.MoveChildrenInBlockDirection(baseline);
474 line_box.SetInlineSize(inline_size); 493 line_box.SetInlineSize(inline_size);
475 container_builder_.AddChild(line_box.ToLineBoxFragment(), 494 container_builder_.AddChild(line_box.ToLineBoxFragment(),
476 {LayoutUnit(), baseline - line_metrics.ascent}); 495 {LayoutUnit(), baseline - line_metrics.ascent});
477 496
478 max_inline_size_ = std::max(max_inline_size_, inline_size); 497 max_inline_size_ = std::max(max_inline_size_, inline_size);
479 content_size_ = line_bottom; 498 content_size_ = line_bottom;
480 return true; 499 return true;
481 } 500 }
482 501
502 // Initialize the box state stack for a new line.
503 // @return The initial box state for the line.
504 NGInlineBoxState* NGInlineLayoutAlgorithm::OnBeginPlaceItems() {
505 if (box_states_.IsEmpty()) {
506 // For the first line, push a box state for the line itself.
507 box_states_.Resize(1);
508 NGInlineBoxState* box = &box_states_.back();
509 box->fragment_start = 0;
510 box->style = &LineStyle();
511 return box;
512 }
513
514 // For the following lines, clear states that are not shared across lines.
515 for (auto& box : box_states_) {
516 box.fragment_start = 0;
517 box.metrics = NGLineHeightMetrics();
518 DCHECK(box.pending_descendants.IsEmpty());
519 }
520 return &box_states_.back();
521 }
522
523 // Push a box state stack.
524 NGInlineBoxState* NGInlineLayoutAlgorithm::OnOpenTag(
525 const NGLayoutInlineItem& item,
526 NGLineBoxFragmentBuilder* line_box,
527 NGTextFragmentBuilder* text_builder) {
528 box_states_.Resize(box_states_.size() + 1);
529 NGInlineBoxState* box = &box_states_.back();
530 box->fragment_start = line_box->Children().size();
531 box->style = item.Style();
532 text_builder->SetDirection(box->style->Direction());
533 return box;
534 }
535
536 // Pop a box state stack.
537 NGInlineBoxState* NGInlineLayoutAlgorithm::OnCloseTag(
538 const NGLayoutInlineItem& item,
539 NGLineBoxFragmentBuilder* line_box,
540 NGInlineBoxState* box) {
541 EndBoxState(box, line_box);
542 // TODO(kojii): When the algorithm restarts from a break token, the stack may
543 // underflow. We need either synthesize a missing box state, or push all
544 // parents on initialize.
545 box_states_.pop_back();
546 return &box_states_.back();
547 }
548
549 // Compute all the pending positioning at the end of a line.
550 void NGInlineLayoutAlgorithm::OnEndPlaceItems(
551 NGLineBoxFragmentBuilder* line_box) {
552 for (auto it = box_states_.rbegin(); it != box_states_.rend(); ++it) {
553 NGInlineBoxState* box = &(*it);
554 EndBoxState(box, line_box);
555 }
556 line_box->UniteMetrics(box_states_.front().metrics);
557 }
558
559 // End of a box state, either explicitly by close tag, or implicitly at the end
560 // of a line.
561 void NGInlineLayoutAlgorithm::EndBoxState(NGInlineBoxState* box,
562 NGLineBoxFragmentBuilder* line_box) {
563 ApplyBaselineShift(box, line_box);
564
565 // Unite the metrics to the parent box.
566 if (box != box_states_.begin()) {
567 box[-1].metrics.Unite(box->metrics);
568 }
569 }
570
571 // Compute vertical position for the 'vertical-align' property.
572 // The timing to apply varies by values; some values apply at the layout of
573 // the box was computed. Other values apply when the layout of the parent or
574 // the line box was computed.
575 // https://www.w3.org/TR/CSS22/visudet.html#propdef-vertical-align
576 // https://www.w3.org/TR/css-inline-3/#propdef-vertical-align
577 void NGInlineLayoutAlgorithm::ApplyBaselineShift(
578 NGInlineBoxState* box,
579 NGLineBoxFragmentBuilder* line_box) {
580 // Compute descendants that depend on the layout size of this box if any.
581 LayoutUnit baseline_shift;
582 if (!box->pending_descendants.IsEmpty()) {
583 for (const auto& child : box->pending_descendants) {
584 switch (child.vertical_align) {
585 case EVerticalAlign::kTextTop:
586 case EVerticalAlign::kTop:
587 baseline_shift = child.metrics.ascent - box->metrics.ascent;
588 break;
589 case EVerticalAlign::kTextBottom:
590 case EVerticalAlign::kBottom:
591 baseline_shift = box->metrics.descent - child.metrics.descent;
592 break;
593 default:
594 NOTREACHED();
595 continue;
596 }
597 line_box->MoveChildrenInBlockDirection(
598 baseline_shift, child.fragment_start, child.fragment_end);
599 }
600 box->pending_descendants.Clear();
601 }
602
603 const ComputedStyle& style = *box->style;
604 EVerticalAlign vertical_align = style.VerticalAlign();
605 if (vertical_align == EVerticalAlign::kBaseline)
606 return;
607
608 // 'vertical-align' aplies only to inline-level elements.
609 if (box == box_states_.begin())
610 return;
611
612 // Check if there are any fragments to move.
613 unsigned fragment_end = line_box->Children().size();
614 if (box->fragment_start == fragment_end)
615 return;
616
617 switch (vertical_align) {
618 case EVerticalAlign::kSub:
619 baseline_shift = style.ComputedFontSizeAsFixed() / 5 + 1;
620 break;
621 case EVerticalAlign::kSuper:
622 baseline_shift = -(style.ComputedFontSizeAsFixed() / 3 + 1);
623 break;
624 case EVerticalAlign::kLength: {
625 // 'Percentages: refer to the 'line-height' of the element itself'.
626 // https://www.w3.org/TR/CSS22/visudet.html#propdef-vertical-align
627 const Length& length = style.GetVerticalAlignLength();
628 LayoutUnit line_height = length.IsPercentOrCalc()
629 ? style.ComputedLineHeightAsFixed()
630 : box->text_metrics.LineHeight();
631 baseline_shift = -ValueForLength(length, line_height);
632 break;
633 }
634 case EVerticalAlign::kMiddle:
635 baseline_shift = (box->metrics.ascent - box->metrics.descent) / 2;
636 if (const SimpleFontData* font_data = style.GetFont().PrimaryFont()) {
637 baseline_shift -= LayoutUnit::FromFloatRound(
638 font_data->GetFontMetrics().XHeight() / 2);
639 }
640 break;
641 case EVerticalAlign::kBaselineMiddle:
642 baseline_shift = (box->metrics.ascent - box->metrics.descent) / 2;
643 break;
644 case EVerticalAlign::kTop:
645 case EVerticalAlign::kBottom:
646 // 'top' and 'bottom' require the layout size of the line box.
647 box_states_.front().pending_descendants.push_back(NGPendingPositions{
648 box->fragment_start, fragment_end, box->metrics, vertical_align});
649 return;
650 default:
651 // Other values require the layout size of the parent box.
652 SECURITY_CHECK(box != box_states_.begin());
653 box[-1].pending_descendants.push_back(NGPendingPositions{
654 box->fragment_start, fragment_end, box->metrics, vertical_align});
655 return;
656 }
657 box->metrics.Move(baseline_shift);
658 line_box->MoveChildrenInBlockDirection(baseline_shift, box->fragment_start,
659 fragment_end);
660 }
661
483 void NGInlineLayoutAlgorithm::AccumulateUsedFonts( 662 void NGInlineLayoutAlgorithm::AccumulateUsedFonts(
484 const NGLayoutInlineItem& item, 663 const NGLayoutInlineItem& item,
485 const LineItemChunk& line_item_chunk, 664 const LineItemChunk& line_item_chunk,
486 NGLineBoxFragmentBuilder* line_box) { 665 NGLineBoxFragmentBuilder* line_box) {
487 HashSet<const SimpleFontData*> fallback_fonts; 666 HashSet<const SimpleFontData*> fallback_fonts;
488 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 667 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
489 line_item_chunk.end_offset); 668 line_item_chunk.end_offset);
490 for (const auto& fallback_font : fallback_fonts) { 669 for (const auto& fallback_font : fallback_fonts) {
491 NGLineHeightMetrics metrics(fallback_font->GetFontMetrics(), 670 NGLineHeightMetrics metrics(fallback_font->GetFontMetrics(),
492 baseline_type_); 671 baseline_type_);
493 metrics.AddLeading(fallback_font->GetFontMetrics().FixedLineSpacing()); 672 metrics.AddLeading(fallback_font->GetFontMetrics().FixedLineSpacing());
494 line_box->UniteMetrics(metrics); 673 line_box->UniteMetrics(metrics);
495 } 674 }
496 } 675 }
497 676
498 LayoutUnit NGInlineLayoutAlgorithm::PlaceAtomicInline( 677 LayoutUnit NGInlineLayoutAlgorithm::PlaceAtomicInline(
499 const NGLayoutInlineItem& item, 678 const NGLayoutInlineItem& item,
500 NGLineBoxFragmentBuilder* line_box, 679 NGLineBoxFragmentBuilder* line_box,
501 NGTextFragmentBuilder* text_builder) { 680 NGTextFragmentBuilder* text_builder) {
502 NGBoxFragment fragment( 681 NGBoxFragment fragment(
503 ConstraintSpace().WritingMode(), 682 ConstraintSpace().WritingMode(),
504 ToNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().Get())); 683 ToNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().Get()));
505 // TODO(kojii): Margin and border in block progression not implemented yet. 684 // TODO(kojii): Margin and border in block progression not implemented yet.
506 LayoutUnit block_size = fragment.BlockSize(); 685 LayoutUnit block_size = fragment.BlockSize();
507 686
508 // TODO(kojii): Try to eliminate the wrapping text fragment and use the 687 // TODO(kojii): Try to eliminate the wrapping text fragment and use the
509 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow| 688 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow|
510 // requires a text fragment. 689 // requires a text fragment.
511 text_builder->SetInlineSize(fragment.InlineSize()).SetBlockSize(block_size); 690 text_builder->SetSize({fragment.InlineSize(), block_size});
512 691
513 // TODO(kojii): Add baseline position to NGPhysicalFragment. 692 // TODO(kojii): Add baseline position to NGPhysicalFragment.
514 LayoutBox* box = ToLayoutBox(item.GetLayoutObject()); 693 LayoutBox* layout_box = ToLayoutBox(item.GetLayoutObject());
515 LineDirectionMode line_direction_mode = 694 LineDirectionMode line_direction_mode =
516 IsHorizontalWritingMode() ? LineDirectionMode::kHorizontalLine 695 IsHorizontalWritingMode() ? LineDirectionMode::kHorizontalLine
517 : LineDirectionMode::kVerticalLine; 696 : LineDirectionMode::kVerticalLine;
518 LayoutUnit baseline_offset(box->BaselinePosition( 697 LayoutUnit baseline_offset(layout_box->BaselinePosition(
519 baseline_type_, IsFirstLine(), line_direction_mode)); 698 baseline_type_, IsFirstLine(), line_direction_mode));
520 line_box->UniteMetrics({baseline_offset, block_size - baseline_offset}); 699
700 NGLineHeightMetrics metrics(baseline_offset, block_size - baseline_offset);
701 box_states_.back().metrics.Unite(metrics);
521 702
522 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. 703 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
523 // Floats are ok because atomic inlines are BFC? 704 // Floats are ok because atomic inlines are BFC?
524 705
525 return -baseline_offset; 706 return -metrics.ascent;
526 } 707 }
527 708
528 void NGInlineLayoutAlgorithm::FindNextLayoutOpportunity() { 709 void NGInlineLayoutAlgorithm::FindNextLayoutOpportunity() {
529 NGLogicalOffset iter_offset = ConstraintSpace().BfcOffset(); 710 NGLogicalOffset iter_offset = ConstraintSpace().BfcOffset();
530 iter_offset.block_offset += content_size_; 711 iter_offset.block_offset += content_size_;
531 auto* iter = MutableConstraintSpace()->LayoutOpportunityIterator(iter_offset); 712 auto* iter = MutableConstraintSpace()->LayoutOpportunityIterator(iter_offset);
532 NGLayoutOpportunity opportunity = iter->Next(); 713 NGLayoutOpportunity opportunity = iter->Next();
533 if (!opportunity.IsEmpty()) 714 if (!opportunity.IsEmpty())
534 current_opportunity_ = opportunity; 715 current_opportunity_ = opportunity;
535 } 716 }
(...skipping 27 matching lines...) Expand all
563 744
564 // max-content is the width without any line wrapping. 745 // max-content is the width without any line wrapping.
565 // TODO(kojii): Implement hard breaks (<br> etc.) to break. 746 // TODO(kojii): Implement hard breaks (<br> etc.) to break.
566 for (const auto& item : Node()->Items()) 747 for (const auto& item : Node()->Items())
567 sizes.max_content += InlineSize(item); 748 sizes.max_content += InlineSize(item);
568 749
569 return sizes; 750 return sizes;
570 } 751 }
571 752
572 } // namespace blink 753 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698