OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 356 } |
357 | 357 |
358 bool LayoutMultiColumnFlowThread::NeedsNewWidth() const { | 358 bool LayoutMultiColumnFlowThread::NeedsNewWidth() const { |
359 LayoutUnit new_width; | 359 LayoutUnit new_width; |
360 unsigned dummy_column_count; // We only care if used column-width changes. | 360 unsigned dummy_column_count; // We only care if used column-width changes. |
361 CalculateColumnCountAndWidth(new_width, dummy_column_count); | 361 CalculateColumnCountAndWidth(new_width, dummy_column_count); |
362 return new_width != LogicalWidth(); | 362 return new_width != LogicalWidth(); |
363 } | 363 } |
364 | 364 |
365 bool LayoutMultiColumnFlowThread::IsPageLogicalHeightKnown() const { | 365 bool LayoutMultiColumnFlowThread::IsPageLogicalHeightKnown() const { |
366 if (LayoutMultiColumnSet* column_set = LastMultiColumnSet()) | 366 return all_columns_have_known_height_; |
367 return column_set->IsPageLogicalHeightKnown(); | |
368 return false; | |
369 } | 367 } |
370 | 368 |
371 bool LayoutMultiColumnFlowThread::MayHaveNonUniformPageLogicalHeight() const { | 369 bool LayoutMultiColumnFlowThread::MayHaveNonUniformPageLogicalHeight() const { |
372 const LayoutMultiColumnSet* column_set = FirstMultiColumnSet(); | 370 const LayoutMultiColumnSet* column_set = FirstMultiColumnSet(); |
373 if (!column_set) | 371 if (!column_set) |
374 return false; | 372 return false; |
375 if (column_set->NextSiblingMultiColumnSet()) | 373 if (column_set->NextSiblingMultiColumnSet()) |
376 return true; | 374 return true; |
377 return EnclosingFragmentationContext(); | 375 return EnclosingFragmentationContext(); |
378 } | 376 } |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 // new outer row). Without sufficient rows in all ancestor multicol | 534 // new outer row). Without sufficient rows in all ancestor multicol |
537 // containers, we may use the wrong column height. | 535 // containers, we may use the wrong column height. |
538 LayoutUnit offset = block_offset_in_enclosing_fragmentation_context_ + | 536 LayoutUnit offset = block_offset_in_enclosing_fragmentation_context_ + |
539 first_set->LogicalTopFromMulticolContentEdge(); | 537 first_set->LogicalTopFromMulticolContentEdge(); |
540 enclosing_flow_thread->AppendNewFragmentainerGroupIfNeeded( | 538 enclosing_flow_thread->AppendNewFragmentainerGroupIfNeeded( |
541 offset, kAssociateWithLatterPage); | 539 offset, kAssociateWithLatterPage); |
542 } | 540 } |
543 } | 541 } |
544 } | 542 } |
545 | 543 |
| 544 // We'll start by assuming that all columns have some known height, and flip |
| 545 // it to false if we discover that this isn't the case. |
| 546 all_columns_have_known_height_ = true; |
| 547 |
546 for (LayoutBox* column_box = FirstMultiColumnBox(); column_box; | 548 for (LayoutBox* column_box = FirstMultiColumnBox(); column_box; |
547 column_box = column_box->NextSiblingMultiColumnBox()) { | 549 column_box = column_box->NextSiblingMultiColumnBox()) { |
548 if (!column_box->IsLayoutMultiColumnSet()) { | 550 if (!column_box->IsLayoutMultiColumnSet()) { |
549 // No other type is expected. | 551 // No other type is expected. |
550 DCHECK(column_box->IsLayoutMultiColumnSpannerPlaceholder()); | 552 DCHECK(column_box->IsLayoutMultiColumnSpannerPlaceholder()); |
551 continue; | 553 continue; |
552 } | 554 } |
553 LayoutMultiColumnSet* column_set = ToLayoutMultiColumnSet(column_box); | 555 LayoutMultiColumnSet* column_set = ToLayoutMultiColumnSet(column_box); |
554 layout_scope.SetChildNeedsLayout(column_set); | 556 layout_scope.SetChildNeedsLayout(column_set); |
555 if (!column_heights_changed_) { | 557 if (!column_heights_changed_) { |
556 // This is the initial layout pass. We need to reset the column height, | 558 // This is the initial layout pass. We need to reset the column height, |
557 // because contents typically have changed. | 559 // because contents typically have changed. |
558 column_set->ResetColumnHeight(); | 560 column_set->ResetColumnHeight(); |
559 } | 561 } |
| 562 if (all_columns_have_known_height_ && |
| 563 !column_set->IsPageLogicalHeightKnown()) { |
| 564 // If any of the column sets requires a layout pass before it has any |
| 565 // clue about its height, we cannot fragment in this pass, just measure |
| 566 // the block sizes. |
| 567 all_columns_have_known_height_ = false; |
| 568 } |
560 // Since column sets are regular block flow objects, and their position is | 569 // Since column sets are regular block flow objects, and their position is |
561 // changed in regular block layout code (with no means for the multicol code | 570 // changed in regular block layout code (with no means for the multicol code |
562 // to notice unless we add hooks there), store the previous position now. If | 571 // to notice unless we add hooks there), store the previous position now. If |
563 // it changes in the imminent layout pass, we may have to rebalance its | 572 // it changes in the imminent layout pass, we may have to rebalance its |
564 // columns. | 573 // columns. |
565 column_set->StoreOldPosition(); | 574 column_set->StoreOldPosition(); |
566 } | 575 } |
567 | 576 |
568 column_heights_changed_ = false; | 577 column_heights_changed_ = false; |
569 InvalidateColumnSets(); | 578 InvalidateColumnSets(); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 // and where such out-of-flow objects might be, just go through the whole | 947 // and where such out-of-flow objects might be, just go through the whole |
939 // subtree. | 948 // subtree. |
940 for (LayoutObject* descendant = layout_object->SlowFirstChild(); descendant; | 949 for (LayoutObject* descendant = layout_object->SlowFirstChild(); descendant; |
941 descendant = descendant->NextInPreOrder()) { | 950 descendant = descendant->NextInPreOrder()) { |
942 if (descendant->IsBox() && descendant->IsOutOfFlowPositioned()) | 951 if (descendant->IsBox() && descendant->IsOutOfFlowPositioned()) |
943 descendant->ContainingBlock()->InsertPositionedObject( | 952 descendant->ContainingBlock()->InsertPositionedObject( |
944 ToLayoutBox(descendant)); | 953 ToLayoutBox(descendant)); |
945 } | 954 } |
946 } | 955 } |
947 | 956 |
| 957 bool LayoutMultiColumnFlowThread::FinishLayout() { |
| 958 all_columns_have_known_height_ = true; |
| 959 for (const auto* column_set = FirstMultiColumnSet(); column_set; |
| 960 column_set = column_set->NextSiblingMultiColumnSet()) { |
| 961 if (!column_set->IsPageLogicalHeightKnown()) { |
| 962 all_columns_have_known_height_ = false; |
| 963 break; |
| 964 } |
| 965 } |
| 966 return !ColumnHeightsChanged(); |
| 967 } |
| 968 |
948 // When processing layout objects to remove or when processing layout objects | 969 // When processing layout objects to remove or when processing layout objects |
949 // that have just been inserted, certain types of objects should be skipped. | 970 // that have just been inserted, certain types of objects should be skipped. |
950 static bool ShouldSkipInsertedOrRemovedChild( | 971 static bool ShouldSkipInsertedOrRemovedChild( |
951 LayoutMultiColumnFlowThread* flow_thread, | 972 LayoutMultiColumnFlowThread* flow_thread, |
952 const LayoutObject& child) { | 973 const LayoutObject& child) { |
953 if (child.IsSVGChild()) { | 974 if (child.IsSVGChild()) { |
954 // Don't descend into SVG objects. What's in there is of no interest, and | 975 // Don't descend into SVG objects. What's in there is of no interest, and |
955 // there might even be a foreignObject there with column-span:all, which | 976 // there might even be a foreignObject there with column-span:all, which |
956 // doesn't apply to us. | 977 // doesn't apply to us. |
957 return true; | 978 return true; |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 const { | 1411 const { |
1391 return MultiColumnLayoutState(last_set_worked_on_); | 1412 return MultiColumnLayoutState(last_set_worked_on_); |
1392 } | 1413 } |
1393 | 1414 |
1394 void LayoutMultiColumnFlowThread::RestoreMultiColumnLayoutState( | 1415 void LayoutMultiColumnFlowThread::RestoreMultiColumnLayoutState( |
1395 const MultiColumnLayoutState& state) { | 1416 const MultiColumnLayoutState& state) { |
1396 last_set_worked_on_ = state.ColumnSet(); | 1417 last_set_worked_on_ = state.ColumnSet(); |
1397 } | 1418 } |
1398 | 1419 |
1399 } // namespace blink | 1420 } // namespace blink |
OLD | NEW |