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

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

Issue 2764753007: [LayoutNG] Add NGLineBoxFragment (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/layout/ng/ng_line_builder.h" 5 #include "core/layout/ng/ng_line_builder.h"
6 6
7 #include "core/layout/BidiRun.h" 7 #include "core/layout/BidiRun.h"
8 #include "core/layout/LayoutBlockFlow.h" 8 #include "core/layout/LayoutBlockFlow.h"
9 #include "core/layout/line/LineInfo.h" 9 #include "core/layout/line/LineInfo.h"
10 #include "core/layout/line/RootInlineBox.h" 10 #include "core/layout/line/RootInlineBox.h"
11 #include "core/layout/ng/ng_bidi_paragraph.h" 11 #include "core/layout/ng/ng_bidi_paragraph.h"
12 #include "core/layout/ng/ng_box_fragment.h" 12 #include "core/layout/ng/ng_box_fragment.h"
13 #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" 14 #include "core/layout/ng/ng_constraint_space_builder.h"
15 #include "core/layout/ng/ng_fragment_builder.h" 15 #include "core/layout/ng/ng_fragment_builder.h"
16 #include "core/layout/ng/ng_inline_node.h" 16 #include "core/layout/ng/ng_inline_node.h"
17 #include "core/layout/ng/ng_length_utils.h" 17 #include "core/layout/ng/ng_length_utils.h"
18 #include "core/layout/ng/ng_linebox_fragment.h"
19 #include "core/layout/ng/ng_linebox_fragment_builder.h"
18 #include "core/layout/ng/ng_text_fragment.h" 20 #include "core/layout/ng/ng_text_fragment.h"
21 #include "core/layout/ng/ng_text_fragment_builder.h"
19 #include "core/style/ComputedStyle.h" 22 #include "core/style/ComputedStyle.h"
20 #include "platform/text/BidiRunList.h" 23 #include "platform/text/BidiRunList.h"
21 24
22 namespace blink { 25 namespace blink {
23 26
24 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box, 27 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
25 NGConstraintSpace* constraint_space) 28 NGConstraintSpace* constraint_space)
26 : inline_box_(inline_box), 29 : inline_box_(inline_box),
27 constraint_space_(constraint_space), 30 constraint_space_(constraint_space),
28 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_), 31 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_),
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 unsigned logical_index = indices_in_visual_order[visual_index]; 257 unsigned logical_index = indices_in_visual_order[visual_index];
255 line_item_chunks_in_visual_order[visual_index] = 258 line_item_chunks_in_visual_order[visual_index] =
256 (*line_item_chunks)[logical_index]; 259 (*line_item_chunks)[logical_index];
257 } 260 }
258 line_item_chunks->swap(line_item_chunks_in_visual_order); 261 line_item_chunks->swap(line_item_chunks_in_visual_order);
259 } 262 }
260 263
261 void NGLineBuilder::PlaceItems( 264 void NGLineBuilder::PlaceItems(
262 const Vector<LineItemChunk, 32>& line_item_chunks) { 265 const Vector<LineItemChunk, 32>& line_item_chunks) {
263 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 266 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
264 const unsigned fragment_start_index = container_builder_.Children().size();
265 267
266 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText, 268 NGLineboxFragmentBuilder linebox(inline_box_);
ikilpatrick 2017/03/23 16:47:26 This is going to be incredibly annoying but should
267 inline_box_); 269 NGTextFragmentBuilder text_builder(inline_box_);
268 text_builder.SetWritingMode(ConstraintSpace().WritingMode());
269 line_box_data_list_.grow(line_box_data_list_.size() + 1);
270 LineBoxData& line_box_data = line_box_data_list_.back();
271 270
272 // Accumulate a "strut"; a zero-width inline box with the element's font and 271 // Accumulate a "strut"; a zero-width inline box with the element's font and
273 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut 272 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut
274 const ComputedStyle* block_style = inline_box_->BlockStyle(); 273 const ComputedStyle* block_style = inline_box_->BlockStyle();
275 InlineItemMetrics block_metrics(*block_style, baseline_type_); 274 NGLineHeightMetrics block_metrics(*block_style, baseline_type_);
276 line_box_data.UpdateMaxAscentAndDescent(block_metrics); 275 linebox.UniteMetrics(block_metrics);
277 276
278 // Use the block style to compute the estimated baseline position because the 277 // Use the block style to compute the estimated baseline position because the
279 // baseline position is not known until we know the maximum ascent and leading 278 // baseline position is not known until we know the maximum ascent and leading
280 // of the line. Items are placed on this baseline, then adjusted later if the 279 // of the line. Items are placed on this baseline, then adjusted later if the
281 // estimation turned out to be different. 280 // estimation turned out to be different.
282 LayoutUnit estimated_baseline = 281 LayoutUnit estimated_baseline =
283 content_size_ + LayoutUnit(block_metrics.ascent_and_leading); 282 content_size_ + LayoutUnit(block_metrics.ascent_and_leading);
284 283
284 LayoutUnit inline_size;
285 for (const auto& line_item_chunk : line_item_chunks) { 285 for (const auto& line_item_chunk : line_item_chunks) {
286 const NGLayoutInlineItem& item = items[line_item_chunk.index]; 286 const NGLayoutInlineItem& item = items[line_item_chunk.index];
287 // Skip bidi controls. 287 // Skip bidi controls.
288 if (!item.GetLayoutObject()) 288 if (!item.GetLayoutObject())
289 continue; 289 continue;
290 290
291 LayoutUnit block_start; 291 LayoutUnit block_start;
292 if (item.Type() == NGLayoutInlineItem::kText) { 292 if (item.Type() == NGLayoutInlineItem::kText) {
293 DCHECK(item.GetLayoutObject()->isText()); 293 DCHECK(item.GetLayoutObject()->isText());
294 const ComputedStyle* style = item.Style(); 294 const ComputedStyle* style = item.Style();
295 // The direction of a fragment is the CSS direction to resolve logical
296 // properties, not the resolved bidi direction.
297 text_builder.SetDirection(style->direction())
298 .SetInlineSize(line_item_chunk.inline_size);
299
295 // |InlineTextBoxPainter| sets the baseline at |top + 300 // |InlineTextBoxPainter| sets the baseline at |top +
296 // ascent-of-primary-font|. Compute |top| to match. 301 // ascent-of-primary-font|. Compute |top| to match.
297 InlineItemMetrics metrics(*style, baseline_type_); 302 NGLineHeightMetrics metrics(*style, baseline_type_);
298 block_start = estimated_baseline - LayoutUnit(metrics.ascent); 303 block_start = estimated_baseline - LayoutUnit(metrics.ascent);
299 LayoutUnit line_height = LayoutUnit(metrics.ascent + metrics.descent); 304 text_builder.SetBlockSize(metrics.LineHeight());
300 line_box_data.UpdateMaxAscentAndDescent(metrics); 305 linebox.UniteMetrics(metrics);
301 306
302 // Take all used fonts into account if 'line-height: normal'. 307 // Take all used fonts into account if 'line-height: normal'.
303 if (style->lineHeight().isNegative()) 308 if (style->lineHeight().isNegative())
304 AccumulateUsedFonts(item, line_item_chunk, &line_box_data); 309 AccumulateUsedFonts(item, line_item_chunk, &linebox);
305
306 // The direction of a fragment is the CSS direction to resolve logical
307 // properties, not the resolved bidi direction.
308 text_builder.SetDirection(style->direction())
309 .SetInlineSize(line_item_chunk.inline_size)
310 .SetInlineOverflow(line_item_chunk.inline_size)
311 .SetBlockSize(line_height)
312 .SetBlockOverflow(line_height);
313 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) { 310 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) {
314 block_start = PlaceAtomicInline(item, estimated_baseline, &line_box_data, 311 block_start =
315 &text_builder); 312 PlaceAtomicInline(item, estimated_baseline, &linebox, &text_builder);
316 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) { 313 } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) {
317 // TODO(layout-dev): Report the correct static position for the out of 314 // TODO(layout-dev): Report the correct static position for the out of
318 // flow descendant. We can't do this here yet as it doesn't know the 315 // flow descendant. We can't do this here yet as it doesn't know the
319 // size of the line box. 316 // size of the line box.
320 container_builder_.AddOutOfFlowDescendant( 317 container_builder_.AddOutOfFlowDescendant(
321 // Absolute positioning blockifies the box's display type. 318 // Absolute positioning blockifies the box's display type.
322 // https://drafts.csswg.org/css-display/#transformations 319 // https://drafts.csswg.org/css-display/#transformations
323 new NGBlockNode(item.GetLayoutObject()), 320 new NGBlockNode(item.GetLayoutObject()),
324 NGStaticPosition::Create(ConstraintSpace().WritingMode(), 321 NGStaticPosition::Create(ConstraintSpace().WritingMode(),
325 ConstraintSpace().Direction(), 322 ConstraintSpace().Direction(),
326 NGPhysicalOffset())); 323 NGPhysicalOffset()));
327 continue; 324 continue;
328 } else if (item.Type() == NGLayoutInlineItem::kFloating) { 325 } else if (item.Type() == NGLayoutInlineItem::kFloating) {
329 // TODO(kojii): Implement float. 326 // TODO(kojii): Implement float.
330 DLOG(ERROR) << "Floats in inline not implemented yet."; 327 DLOG(ERROR) << "Floats in inline not implemented yet.";
331 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert. 328 // TODO(kojii): Temporarily clearNeedsLayout() for not to assert.
332 item.GetLayoutObject()->clearNeedsLayout(); 329 item.GetLayoutObject()->clearNeedsLayout();
333 continue; 330 continue;
334 } else { 331 } else {
335 continue; 332 continue;
336 } 333 }
337 334
338 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 335 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
339 line_item_chunk.index, line_item_chunk.start_offset, 336 line_item_chunk.index, line_item_chunk.start_offset,
340 line_item_chunk.end_offset); 337 line_item_chunk.end_offset);
341 338
342 NGLogicalOffset logical_offset( 339 NGLogicalOffset logical_offset(
343 line_box_data.inline_size + current_opportunity_.InlineStartOffset() - 340 inline_size + current_opportunity_.InlineStartOffset() -
344 ConstraintSpace().BfcOffset().inline_offset, 341 ConstraintSpace().BfcOffset().inline_offset,
345 block_start); 342 block_start);
346 container_builder_.AddChild(std::move(text_fragment), logical_offset); 343 linebox.AddChild(std::move(text_fragment), logical_offset);
347 line_box_data.inline_size += line_item_chunk.inline_size; 344 inline_size += line_item_chunk.inline_size;
348 } 345 }
349 346
350 if (fragment_start_index == container_builder_.Children().size()) { 347 if (linebox.Children().isEmpty()) {
351 // The line was empty. Remove the LineBoxData. 348 // The line was empty.
352 line_box_data_list_.shrink(line_box_data_list_.size() - 1);
353 return; 349 return;
354 } 350 }
355 351
356 // If the estimated baseline position was not the actual position, move all 352 // If the estimated baseline position was not the actual position, move all
357 // fragments in the block direction. 353 // fragments in the block direction.
358 if (block_metrics.ascent_and_leading != 354 LayoutUnit adjust_baseline(linebox.Metrics().ascent_and_leading -
359 line_box_data.max_ascent_and_leading) { 355 block_metrics.ascent_and_leading);
360 LayoutUnit adjust_top(line_box_data.max_ascent_and_leading - 356 if (adjust_baseline)
361 block_metrics.ascent_and_leading); 357 linebox.MoveChildrenInBlockDirection(adjust_baseline);
362 auto& offsets = container_builder_.MutableOffsets();
363 for (unsigned i = fragment_start_index; i < offsets.size(); i++)
364 offsets[i].block_offset += adjust_top;
365 }
366 358
367 line_box_data.fragment_end = container_builder_.Children().size(); 359 linebox.SetInlineSize(inline_size);
368 line_box_data.top_with_leading = content_size_; 360 NGLogicalOffset offset(LayoutUnit(), content_size_);
369 max_inline_size_ = std::max(max_inline_size_, line_box_data.inline_size); 361 container_builder_.AddChild(linebox.ToLineboxFragment(), offset);
370 content_size_ += LayoutUnit(line_box_data.max_ascent_and_leading + 362 max_inline_size_ = std::max(max_inline_size_, inline_size);
371 line_box_data.max_descent_and_leading); 363 content_size_ += linebox.Metrics().LineHeight();
372 }
373
374 NGLineBuilder::InlineItemMetrics::InlineItemMetrics(
375 const ComputedStyle& style,
376 FontBaseline baseline_type) {
377 const SimpleFontData* font_data = style.font().primaryFont();
378 DCHECK(font_data);
379 Initialize(font_data->getFontMetrics(), baseline_type,
380 style.computedLineHeightInFloat());
381 }
382
383 NGLineBuilder::InlineItemMetrics::InlineItemMetrics(
384 const FontMetrics& font_metrics,
385 FontBaseline baseline_type) {
386 Initialize(font_metrics, baseline_type, font_metrics.floatLineSpacing());
387 }
388
389 void NGLineBuilder::InlineItemMetrics::Initialize(
390 const FontMetrics& font_metrics,
391 FontBaseline baseline_type,
392 float line_height) {
393 ascent = font_metrics.floatAscent(baseline_type);
394 descent = font_metrics.floatDescent(baseline_type);
395 float half_leading = (line_height - (ascent + descent)) / 2;
396 // Ensure the top and the baseline is snapped to CSS pixel.
397 // TODO(kojii): How to handle fractional ascent isn't determined yet. Should
398 // we snap top or baseline? If baseline, top needs fractional. If top,
399 // baseline may not align across fonts.
400 ascent_and_leading = ascent + floor(half_leading);
401 descent_and_leading = line_height - ascent_and_leading;
402 }
403
404 void NGLineBuilder::LineBoxData::UpdateMaxAscentAndDescent(
405 const NGLineBuilder::InlineItemMetrics& metrics) {
406 max_ascent = std::max(max_ascent, metrics.ascent);
407 max_descent = std::max(max_descent, metrics.descent);
408 max_ascent_and_leading =
409 std::max(max_ascent_and_leading, metrics.ascent_and_leading);
410 max_descent_and_leading =
411 std::max(max_descent_and_leading, metrics.descent_and_leading);
412 } 364 }
413 365
414 void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item, 366 void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item,
415 const LineItemChunk& line_item_chunk, 367 const LineItemChunk& line_item_chunk,
416 LineBoxData* line_box_data) { 368 NGLineboxFragmentBuilder* linebox) {
417 HashSet<const SimpleFontData*> fallback_fonts; 369 HashSet<const SimpleFontData*> fallback_fonts;
418 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 370 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
419 line_item_chunk.end_offset); 371 line_item_chunk.end_offset);
420 for (const auto& fallback_font : fallback_fonts) { 372 for (const auto& fallback_font : fallback_fonts) {
421 InlineItemMetrics fallback_font_metrics(fallback_font->getFontMetrics(), 373 NGLineHeightMetrics metrics(fallback_font->getFontMetrics(),
422 baseline_type_); 374 baseline_type_);
423 line_box_data->UpdateMaxAscentAndDescent(fallback_font_metrics); 375 linebox->UniteMetrics(metrics);
424 } 376 }
425 } 377 }
426 378
427 LayoutUnit NGLineBuilder::PlaceAtomicInline(const NGLayoutInlineItem& item, 379 LayoutUnit NGLineBuilder::PlaceAtomicInline(
428 LayoutUnit estimated_baseline, 380 const NGLayoutInlineItem& item,
429 LineBoxData* line_box_data, 381 LayoutUnit estimated_baseline,
430 NGFragmentBuilder* text_builder) { 382 NGLineboxFragmentBuilder* linebox,
383 NGTextFragmentBuilder* text_builder) {
431 NGBoxFragment fragment( 384 NGBoxFragment fragment(
432 ConstraintSpace().WritingMode(), 385 ConstraintSpace().WritingMode(),
433 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get())); 386 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get()));
434 // TODO(kojii): Margin and border in block progression not implemented yet. 387 // TODO(kojii): Margin and border in block progression not implemented yet.
435 LayoutUnit block_size = fragment.BlockSize(); 388 LayoutUnit block_size = fragment.BlockSize();
436 389
437 // TODO(kojii): Try to eliminate the wrapping text fragment and use the 390 // TODO(kojii): Try to eliminate the wrapping text fragment and use the
438 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow| 391 // |fragment| directly. Currently |CopyFragmentDataToLayoutBlockFlow|
439 // requires a text fragment. 392 // requires a text fragment.
440 text_builder->SetInlineSize(fragment.InlineSize()) 393 text_builder->SetInlineSize(fragment.InlineSize()).SetBlockSize(block_size);
441 .SetInlineOverflow(fragment.InlineOverflow())
442 .SetBlockSize(block_size)
443 .SetBlockOverflow(fragment.BlockOverflow());
444 394
445 // TODO(kojii): Add baseline position to NGPhysicalFragment. 395 // TODO(kojii): Add baseline position to NGPhysicalFragment.
446 LayoutBox* box = toLayoutBox(item.GetLayoutObject()); 396 LayoutBox* box = toLayoutBox(item.GetLayoutObject());
447 LineDirectionMode line_direction_mode = 397 LineDirectionMode line_direction_mode =
448 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine 398 IsHorizontalWritingMode() ? LineDirectionMode::HorizontalLine
449 : LineDirectionMode::VerticalLine; 399 : LineDirectionMode::VerticalLine;
450 bool is_first_line = line_box_data_list_.size() == 1; 400 bool is_first_line = container_builder_.Children().isEmpty();
451 int baseline_offset = 401 int baseline_offset =
452 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode); 402 box->baselinePosition(baseline_type_, is_first_line, line_direction_mode);
453 LayoutUnit block_start = estimated_baseline - baseline_offset; 403 LayoutUnit block_start = estimated_baseline - baseline_offset;
454 404
455 line_box_data->max_ascent_and_leading = 405 NGLineHeightMetrics metrics;
456 std::max<float>(baseline_offset, line_box_data->max_ascent_and_leading); 406 metrics.ascent_and_leading = baseline_offset;
457 line_box_data->max_descent_and_leading = std::max<float>( 407 metrics.descent_and_leading = block_size - baseline_offset;
458 block_size - baseline_offset, line_box_data->max_descent_and_leading); 408 linebox->UniteMetrics(metrics);
459 409
460 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. 410 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
461 // Floats are ok because atomic inlines are BFC? 411 // Floats are ok because atomic inlines are BFC?
462 412
463 return block_start; 413 return block_start;
464 } 414 }
465 415
466 void NGLineBuilder::FindNextLayoutOpportunity() { 416 void NGLineBuilder::FindNextLayoutOpportunity() {
467 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 417 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
468 iter_offset.block_offset += content_size_; 418 iter_offset.block_offset += content_size_;
(...skipping 22 matching lines...) Expand all
491 block->deleteLineBoxTree(); 441 block->deleteLineBoxTree();
492 442
493 Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 443 Vector<NGLayoutInlineItem>& items = inline_box_->Items();
494 Vector<unsigned, 32> text_offsets(items.size()); 444 Vector<unsigned, 32> text_offsets(items.size());
495 inline_box_->GetLayoutTextOffsets(&text_offsets); 445 inline_box_->GetLayoutTextOffsets(&text_offsets);
496 446
497 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs; 447 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs;
498 fragments_for_bidi_runs.reserveInitialCapacity(items.size()); 448 fragments_for_bidi_runs.reserveInitialCapacity(items.size());
499 BidiRunList<BidiRun> bidi_runs; 449 BidiRunList<BidiRun> bidi_runs;
500 LineInfo line_info; 450 LineInfo line_info;
501 unsigned fragment_index = 0;
502 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment( 451 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment(
503 container_layout_result_->PhysicalFragment().get()); 452 container_layout_result_->PhysicalFragment().get());
504 for (const auto& line_box_data : line_box_data_list_) { 453 for (const auto& container_child : box_fragment->Children()) {
454 NGPhysicalLineboxFragment* physical_linebox =
455 toNGPhysicalLineboxFragment(container_child.get());
505 // Create a BidiRunList for this line. 456 // Create a BidiRunList for this line.
506 for (; fragment_index < line_box_data.fragment_end; fragment_index++) { 457 for (const auto& line_child : physical_linebox->Children()) {
507 const NGPhysicalFragment* fragment = 458 const auto* text_fragment = toNGPhysicalTextFragment(line_child.get());
508 box_fragment->Children()[fragment_index].get();
509 if (!fragment->IsText())
510 continue;
511 const auto* text_fragment = toNGPhysicalTextFragment(fragment);
512 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()]; 459 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()];
513 LayoutObject* layout_object = item.GetLayoutObject();
514 if (!layout_object) // Skip bidi controls.
515 continue;
516 BidiRun* run; 460 BidiRun* run;
517 if (layout_object->isText()) { 461 if (item.Type() == NGLayoutInlineItem::kText) {
462 LayoutObject* layout_object = item.GetLayoutObject();
463 DCHECK(layout_object->isText());
518 unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; 464 unsigned text_offset = text_offsets[text_fragment->ItemIndex()];
519 run = new BidiRun(text_fragment->StartOffset() - text_offset, 465 run = new BidiRun(text_fragment->StartOffset() - text_offset,
520 text_fragment->EndOffset() - text_offset, 466 text_fragment->EndOffset() - text_offset,
521 item.BidiLevel(), LineLayoutItem(layout_object)); 467 item.BidiLevel(), LineLayoutItem(layout_object));
522 layout_object->clearNeedsLayout(); 468 layout_object->clearNeedsLayout();
523 } else { 469 } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) {
470 LayoutObject* layout_object = item.GetLayoutObject();
524 DCHECK(layout_object->isAtomicInlineLevel()); 471 DCHECK(layout_object->isAtomicInlineLevel());
525 run = 472 run =
526 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object)); 473 new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object));
474 } else {
475 continue;
527 } 476 }
528 bidi_runs.addRun(run); 477 bidi_runs.addRun(run);
529 fragments_for_bidi_runs.push_back(text_fragment); 478 fragments_for_bidi_runs.push_back(text_fragment);
530 } 479 }
531 // TODO(kojii): bidi needs to find the logical last run. 480 // TODO(kojii): bidi needs to find the logical last run.
532 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun()); 481 bidi_runs.setLogicallyLastRun(bidi_runs.lastRun());
533 482
534 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the 483 // Create a RootInlineBox from BidiRunList. InlineBoxes created for the
535 // RootInlineBox are set to Bidirun::m_box. 484 // RootInlineBox are set to Bidirun::m_box.
536 line_info.setEmpty(false); 485 line_info.setEmpty(false);
537 // TODO(kojii): Implement setFirstLine, LastLine, etc. 486 // TODO(kojii): Implement setFirstLine, LastLine, etc.
538 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info); 487 RootInlineBox* root_line_box = block->constructLine(bidi_runs, line_info);
539 488
540 // Copy fragments data to InlineBoxes. 489 // Copy fragments data to InlineBoxes.
541 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount()); 490 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount());
542 BidiRun* run = bidi_runs.firstRun(); 491 BidiRun* run = bidi_runs.firstRun();
543 for (auto* physical_fragment : fragments_for_bidi_runs) { 492 for (auto* physical_fragment : fragments_for_bidi_runs) {
544 DCHECK(run); 493 DCHECK(run);
545 NGTextFragment fragment(ConstraintSpace().WritingMode(), 494 NGTextFragment fragment(ConstraintSpace().WritingMode(),
546 toNGPhysicalTextFragment(physical_fragment)); 495 toNGPhysicalTextFragment(physical_fragment));
547 InlineBox* inline_box = run->m_box; 496 InlineBox* inline_box = run->m_box;
548 inline_box->setLogicalWidth(fragment.InlineSize()); 497 inline_box->setLogicalWidth(fragment.InlineSize());
549 inline_box->setLogicalLeft(fragment.InlineOffset()); 498 inline_box->setLogicalLeft(fragment.InlineOffset());
550 inline_box->setLogicalTop(fragment.BlockOffset()); 499 inline_box->setLogicalTop(fragment.BlockOffset());
551 if (inline_box->getLineLayoutItem().isBox()) { 500 if (inline_box->getLineLayoutItem().isBox()) {
552 LineLayoutBox box(inline_box->getLineLayoutItem()); 501 LineLayoutBox box(inline_box->getLineLayoutItem());
553 box.setLocation(inline_box->location()); 502 box.setLocation(inline_box->location());
554 } 503 }
555 run = run->next(); 504 run = run->next();
556 } 505 }
557 DCHECK(!run); 506 DCHECK(!run);
558 507
559 // Copy LineBoxData to RootInlineBox. 508 // Copy to RootInlineBox.
560 line_box->setLogicalWidth(line_box_data.inline_size); 509 NGLineboxFragment linebox(ConstraintSpace().WritingMode(),
561 line_box->setLogicalTop(line_box_data.top_with_leading); 510 physical_linebox);
562 LayoutUnit baseline_position = 511 root_line_box->setLogicalWidth(linebox.InlineSize());
563 line_box_data.top_with_leading + 512 LayoutUnit line_top_with_leading = linebox.BlockOffset();
564 LayoutUnit(line_box_data.max_ascent_and_leading); 513 root_line_box->setLogicalTop(line_top_with_leading);
565 line_box->setLineTopBottomPositions( 514 const NGLineHeightMetrics& metrics = physical_linebox->Metrics();
566 baseline_position - LayoutUnit(line_box_data.max_ascent), 515 LayoutUnit baseline =
567 baseline_position + LayoutUnit(line_box_data.max_descent), 516 line_top_with_leading + LayoutUnit(metrics.ascent_and_leading);
568 line_box_data.top_with_leading, 517 root_line_box->setLineTopBottomPositions(
569 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 518 baseline - LayoutUnit(metrics.ascent),
519 baseline + LayoutUnit(metrics.descent), line_top_with_leading,
520 baseline + LayoutUnit(metrics.descent_and_leading));
570 521
571 bidi_runs.deleteRuns(); 522 bidi_runs.deleteRuns();
572 fragments_for_bidi_runs.clear(); 523 fragments_for_bidi_runs.clear();
573 } 524 }
574 } 525 }
575 } // namespace blink 526 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698