| 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 |