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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp

Issue 2770123003: Replace ASSERT with DCHECK in core/layout/ excluding subdirs (Closed)
Patch Set: Check if DCHECK is ON in TextAutosizer 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 /* 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 LayoutBox* firstBox = flowThread.firstMultiColumnBox(); 115 LayoutBox* firstBox = flowThread.firstMultiColumnBox();
116 return firstBox && (firstBox != flowThread.lastMultiColumnBox() || 116 return firstBox && (firstBox != flowThread.lastMultiColumnBox() ||
117 firstBox->isLayoutMultiColumnSpannerPlaceholder()); 117 firstBox->isLayoutMultiColumnSpannerPlaceholder());
118 } 118 }
119 119
120 // Find the next layout object that has the multicol container in its containing 120 // Find the next layout object that has the multicol container in its containing
121 // block chain, skipping nested multicol containers. 121 // block chain, skipping nested multicol containers.
122 static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow( 122 static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow(
123 LayoutMultiColumnFlowThread* flowThread, 123 LayoutMultiColumnFlowThread* flowThread,
124 LayoutObject* descendant) { 124 LayoutObject* descendant) {
125 ASSERT(descendant->isDescendantOf(flowThread)); 125 DCHECK(descendant->isDescendantOf(flowThread));
126 LayoutObject* object = descendant->nextInPreOrderAfterChildren(flowThread); 126 LayoutObject* object = descendant->nextInPreOrderAfterChildren(flowThread);
127 while (object) { 127 while (object) {
128 // Walk through the siblings and find the first one which is either in-flow 128 // Walk through the siblings and find the first one which is either in-flow
129 // or has this flow thread as its containing block flow thread. 129 // or has this flow thread as its containing block flow thread.
130 if (!object->isOutOfFlowPositioned()) 130 if (!object->isOutOfFlowPositioned())
131 break; 131 break;
132 if (object->containingBlock()->flowThreadContainingBlock() == flowThread) { 132 if (object->containingBlock()->flowThreadContainingBlock() == flowThread) {
133 // This out-of-flow object is still part of the flow thread, because its 133 // This out-of-flow object is still part of the flow thread, because its
134 // containing block (probably relatively positioned) is part of the flow 134 // containing block (probably relatively positioned) is part of the flow
135 // thread. 135 // thread.
136 break; 136 break;
137 } 137 }
138 object = object->nextInPreOrderAfterChildren(flowThread); 138 object = object->nextInPreOrderAfterChildren(flowThread);
139 } 139 }
140 if (!object) 140 if (!object)
141 return nullptr; 141 return nullptr;
142 #if DCHECK_IS_ON() 142 #if DCHECK_IS_ON()
143 // Make sure that we didn't stumble into an inner multicol container. 143 // Make sure that we didn't stumble into an inner multicol container.
144 for (LayoutObject* walker = object->parent(); walker && walker != flowThread; 144 for (LayoutObject* walker = object->parent(); walker && walker != flowThread;
145 walker = walker->parent()) 145 walker = walker->parent())
146 ASSERT(!isMultiColumnContainer(*walker)); 146 DCHECK(!isMultiColumnContainer(*walker));
147 #endif 147 #endif
148 return object; 148 return object;
149 } 149 }
150 150
151 // Find the previous layout object that has the multicol container in its 151 // Find the previous layout object that has the multicol container in its
152 // containing block chain, skipping nested multicol containers. 152 // containing block chain, skipping nested multicol containers.
153 static LayoutObject* previousInPreOrderSkippingOutOfFlow( 153 static LayoutObject* previousInPreOrderSkippingOutOfFlow(
154 LayoutMultiColumnFlowThread* flowThread, 154 LayoutMultiColumnFlowThread* flowThread,
155 LayoutObject* descendant) { 155 LayoutObject* descendant) {
156 ASSERT(descendant->isDescendantOf(flowThread)); 156 DCHECK(descendant->isDescendantOf(flowThread));
157 LayoutObject* object = descendant->previousInPreOrder(flowThread); 157 LayoutObject* object = descendant->previousInPreOrder(flowThread);
158 while (object && object != flowThread) { 158 while (object && object != flowThread) {
159 if (object->isColumnSpanAll()) { 159 if (object->isColumnSpanAll()) {
160 LayoutMultiColumnFlowThread* placeholderFlowThread = 160 LayoutMultiColumnFlowThread* placeholderFlowThread =
161 toLayoutBox(object)->spannerPlaceholder()->flowThread(); 161 toLayoutBox(object)->spannerPlaceholder()->flowThread();
162 if (placeholderFlowThread == flowThread) 162 if (placeholderFlowThread == flowThread)
163 break; 163 break;
164 // We're inside an inner multicol container. We have no business there. 164 // We're inside an inner multicol container. We have no business there.
165 // Continue on the outside. 165 // Continue on the outside.
166 object = placeholderFlowThread->parent(); 166 object = placeholderFlowThread->parent();
167 ASSERT(object->isDescendantOf(flowThread)); 167 DCHECK(object->isDescendantOf(flowThread));
168 continue; 168 continue;
169 } 169 }
170 if (object->flowThreadContainingBlock() == flowThread) { 170 if (object->flowThreadContainingBlock() == flowThread) {
171 LayoutObject* ancestor; 171 LayoutObject* ancestor;
172 for (ancestor = object->parent();; ancestor = ancestor->parent()) { 172 for (ancestor = object->parent();; ancestor = ancestor->parent()) {
173 if (ancestor == flowThread) 173 if (ancestor == flowThread)
174 return object; 174 return object;
175 if (isMultiColumnContainer(*ancestor)) { 175 if (isMultiColumnContainer(*ancestor)) {
176 // We're inside an inner multicol container. We have no business 176 // We're inside an inner multicol container. We have no business
177 // there. 177 // there.
178 break; 178 break;
179 } 179 }
180 } 180 }
181 object = ancestor; 181 object = ancestor;
182 ASSERT(ancestor->isDescendantOf(flowThread)); 182 DCHECK(ancestor->isDescendantOf(flowThread));
183 continue; // Continue on the outside of the inner flow thread. 183 continue; // Continue on the outside of the inner flow thread.
184 } 184 }
185 // We're inside something that's out-of-flow. Keep looking upwards and 185 // We're inside something that's out-of-flow. Keep looking upwards and
186 // backwards in the tree. 186 // backwards in the tree.
187 object = object->previousInPreOrder(flowThread); 187 object = object->previousInPreOrder(flowThread);
188 } 188 }
189 if (!object || object == flowThread) 189 if (!object || object == flowThread)
190 return nullptr; 190 return nullptr;
191 #if DCHECK_IS_ON() 191 #if DCHECK_IS_ON()
192 // Make sure that we didn't stumble into an inner multicol container. 192 // Make sure that we didn't stumble into an inner multicol container.
193 for (LayoutObject* walker = object->parent(); walker && walker != flowThread; 193 for (LayoutObject* walker = object->parent(); walker && walker != flowThread;
194 walker = walker->parent()) 194 walker = walker->parent())
195 ASSERT(!isMultiColumnContainer(*walker)); 195 DCHECK(!isMultiColumnContainer(*walker));
196 #endif 196 #endif
197 return object; 197 return object;
198 } 198 }
199 199
200 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) { 200 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) {
201 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); 201 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox();
202 if (!sibling) 202 if (!sibling)
203 return multicolSet->flowThread()->firstChild(); 203 return multicolSet->flowThread()->firstChild();
204 // Adjacent column content sets should not occur. We would have no way of 204 // Adjacent column content sets should not occur. We would have no way of
205 // figuring out what each of them contains then. 205 // figuring out what each of them contains then.
206 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); 206 DCHECK(sibling->isLayoutMultiColumnSpannerPlaceholder());
207 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling) 207 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling)
208 ->layoutObjectInFlowThread(); 208 ->layoutObjectInFlowThread();
209 return nextInPreOrderAfterChildrenSkippingOutOfFlow( 209 return nextInPreOrderAfterChildrenSkippingOutOfFlow(
210 multicolSet->multiColumnFlowThread(), spanner); 210 multicolSet->multiColumnFlowThread(), spanner);
211 } 211 }
212 212
213 static LayoutObject* lastLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) { 213 static LayoutObject* lastLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) {
214 LayoutBox* sibling = multicolSet->nextSiblingMultiColumnBox(); 214 LayoutBox* sibling = multicolSet->nextSiblingMultiColumnBox();
215 // By right we should return lastLeafChild() here, but the caller doesn't 215 // By right we should return lastLeafChild() here, but the caller doesn't
216 // care, so just return nullptr. 216 // care, so just return nullptr.
217 if (!sibling) 217 if (!sibling)
218 return nullptr; 218 return nullptr;
219 // Adjacent column content sets should not occur. We would have no way of 219 // Adjacent column content sets should not occur. We would have no way of
220 // figuring out what each of them contains then. 220 // figuring out what each of them contains then.
221 ASSERT(sibling->isLayoutMultiColumnSpannerPlaceholder()); 221 DCHECK(sibling->isLayoutMultiColumnSpannerPlaceholder());
222 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling) 222 LayoutBox* spanner = toLayoutMultiColumnSpannerPlaceholder(sibling)
223 ->layoutObjectInFlowThread(); 223 ->layoutObjectInFlowThread();
224 return previousInPreOrderSkippingOutOfFlow( 224 return previousInPreOrderSkippingOutOfFlow(
225 multicolSet->multiColumnFlowThread(), spanner); 225 multicolSet->multiColumnFlowThread(), spanner);
226 } 226 }
227 227
228 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::mapDescendantToColumnSet( 228 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::mapDescendantToColumnSet(
229 LayoutObject* layoutObject) const { 229 LayoutObject* layoutObject) const {
230 // Should not be used for spanners or content inside them. 230 // Should not be used for spanners or content inside them.
231 DCHECK(!containingColumnSpannerPlaceholder(layoutObject)); 231 DCHECK(!containingColumnSpannerPlaceholder(layoutObject));
232 DCHECK(layoutObject != this); 232 DCHECK_NE(layoutObject, this);
233 DCHECK(layoutObject->isDescendantOf(this)); 233 DCHECK(layoutObject->isDescendantOf(this));
234 // Out-of-flow objects don't belong in column sets. 234 // Out-of-flow objects don't belong in column sets.
235 DCHECK(layoutObject->containingBlock()->isDescendantOf(this)); 235 DCHECK(layoutObject->containingBlock()->isDescendantOf(this));
236 DCHECK(layoutObject->flowThreadContainingBlock() == this); 236 DCHECK_EQ(layoutObject->flowThreadContainingBlock(), this);
237 DCHECK(!layoutObject->isLayoutMultiColumnSet()); 237 DCHECK(!layoutObject->isLayoutMultiColumnSet());
238 DCHECK(!layoutObject->isLayoutMultiColumnSpannerPlaceholder()); 238 DCHECK(!layoutObject->isLayoutMultiColumnSpannerPlaceholder());
239 LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); 239 LayoutMultiColumnSet* multicolSet = firstMultiColumnSet();
240 if (!multicolSet) 240 if (!multicolSet)
241 return nullptr; 241 return nullptr;
242 if (!multicolSet->nextSiblingMultiColumnSet()) 242 if (!multicolSet->nextSiblingMultiColumnSet())
243 return multicolSet; 243 return multicolSet;
244 244
245 // This is potentially SLOW! But luckily very uncommon. You would have to 245 // This is potentially SLOW! But luckily very uncommon. You would have to
246 // dynamically insert a spanner into the middle of column contents to need 246 // dynamically insert a spanner into the middle of column contents to need
247 // this. 247 // this.
248 for (; multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { 248 for (; multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) {
249 LayoutObject* firstLayoutObject = firstLayoutObjectInSet(multicolSet); 249 LayoutObject* firstLayoutObject = firstLayoutObjectInSet(multicolSet);
250 LayoutObject* lastLayoutObject = lastLayoutObjectInSet(multicolSet); 250 LayoutObject* lastLayoutObject = lastLayoutObjectInSet(multicolSet);
251 ASSERT(firstLayoutObject); 251 DCHECK(firstLayoutObject);
252 252
253 for (LayoutObject* walker = firstLayoutObject; walker; 253 for (LayoutObject* walker = firstLayoutObject; walker;
254 walker = walker->nextInPreOrder(this)) { 254 walker = walker->nextInPreOrder(this)) {
255 if (walker == layoutObject) 255 if (walker == layoutObject)
256 return multicolSet; 256 return multicolSet;
257 if (walker == lastLayoutObject) 257 if (walker == lastLayoutObject)
258 break; 258 break;
259 } 259 }
260 } 260 }
261 261
262 return nullptr; 262 return nullptr;
263 } 263 }
264 264
265 LayoutMultiColumnSpannerPlaceholder* 265 LayoutMultiColumnSpannerPlaceholder*
266 LayoutMultiColumnFlowThread::containingColumnSpannerPlaceholder( 266 LayoutMultiColumnFlowThread::containingColumnSpannerPlaceholder(
267 const LayoutObject* descendant) const { 267 const LayoutObject* descendant) const {
268 ASSERT(descendant->isDescendantOf(this)); 268 DCHECK(descendant->isDescendantOf(this));
269 269
270 if (!hasAnyColumnSpanners(*this)) 270 if (!hasAnyColumnSpanners(*this))
271 return nullptr; 271 return nullptr;
272 272
273 // We have spanners. See if the layoutObject in question is one or inside of 273 // We have spanners. See if the layoutObject in question is one or inside of
274 // one then. 274 // one then.
275 for (const LayoutObject* ancestor = descendant; ancestor && ancestor != this; 275 for (const LayoutObject* ancestor = descendant; ancestor && ancestor != this;
276 ancestor = ancestor->parent()) { 276 ancestor = ancestor->parent()) {
277 if (LayoutMultiColumnSpannerPlaceholder* placeholder = 277 if (LayoutMultiColumnSpannerPlaceholder* placeholder =
278 ancestor->spannerPlaceholder()) 278 ancestor->spannerPlaceholder())
279 return placeholder; 279 return placeholder;
280 } 280 }
281 return nullptr; 281 return nullptr;
282 } 282 }
283 283
284 void LayoutMultiColumnFlowThread::populate() { 284 void LayoutMultiColumnFlowThread::populate() {
285 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); 285 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow();
286 ASSERT(!nextSibling()); 286 DCHECK(!nextSibling());
287 // Reparent children preceding the flow thread into the flow thread. It's 287 // Reparent children preceding the flow thread into the flow thread. It's
288 // multicol content now. At this point there's obviously nothing after the 288 // multicol content now. At this point there's obviously nothing after the
289 // flow thread, but layoutObjects (column sets and spanners) will be inserted 289 // flow thread, but layoutObjects (column sets and spanners) will be inserted
290 // there as we insert elements into the flow thread. 290 // there as we insert elements into the flow thread.
291 multicolContainer->removeFloatingObjectsFromDescendants(); 291 multicolContainer->removeFloatingObjectsFromDescendants();
292 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, 292 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this,
293 true); 293 true);
294 } 294 }
295 295
296 void LayoutMultiColumnFlowThread::evacuateAndDestroy() { 296 void LayoutMultiColumnFlowThread::evacuateAndDestroy() {
297 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); 297 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow();
298 m_isBeingEvacuated = true; 298 m_isBeingEvacuated = true;
299 299
300 // Remove all sets and spanners. 300 // Remove all sets and spanners.
301 while (LayoutBox* columnBox = firstMultiColumnBox()) { 301 while (LayoutBox* columnBox = firstMultiColumnBox()) {
302 ASSERT(columnBox->isAnonymous()); 302 DCHECK(columnBox->isAnonymous());
303 columnBox->destroy(); 303 columnBox->destroy();
304 } 304 }
305 305
306 ASSERT(!previousSibling()); 306 DCHECK(!previousSibling());
307 ASSERT(!nextSibling()); 307 DCHECK(!nextSibling());
308 308
309 // Finally we can promote all flow thread's children. Before we move them to 309 // Finally we can promote all flow thread's children. Before we move them to
310 // the flow thread's container, we need to unregister the flow thread, so that 310 // the flow thread's container, we need to unregister the flow thread, so that
311 // they aren't just re-added again to the flow thread that we're trying to 311 // they aren't just re-added again to the flow thread that we're trying to
312 // empty. 312 // empty.
313 multicolContainer->resetMultiColumnFlowThread(); 313 multicolContainer->resetMultiColumnFlowThread();
314 moveAllChildrenTo(multicolContainer, true); 314 moveAllChildrenTo(multicolContainer, true);
315 315
316 // We used to manually nuke the line box tree here, but that should happen 316 // We used to manually nuke the line box tree here, but that should happen
317 // automatically when moving children around (the code above). 317 // automatically when moving children around (the code above).
318 ASSERT(!firstLineBox()); 318 DCHECK(!firstLineBox());
319 319
320 destroy(); 320 destroy();
321 } 321 }
322 322
323 LayoutUnit LayoutMultiColumnFlowThread::maxColumnLogicalHeight() const { 323 LayoutUnit LayoutMultiColumnFlowThread::maxColumnLogicalHeight() const {
324 if (m_columnHeightAvailable) { 324 if (m_columnHeightAvailable) {
325 // If height is non-auto, it's already constrained against max-height as 325 // If height is non-auto, it's already constrained against max-height as
326 // well. Just return it. 326 // well. Just return it.
327 return m_columnHeightAvailable; 327 return m_columnHeightAvailable;
328 } 328 }
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 } 570 }
571 571
572 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() { 572 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() {
573 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; 573 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet;
574 columnSet = columnSet->nextSiblingMultiColumnSet()) 574 columnSet = columnSet->nextSiblingMultiColumnSet())
575 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange); 575 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange);
576 } 576 }
577 577
578 bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid( 578 bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(
579 LayoutBox* spannerObjectInFlowThread) { 579 LayoutBox* spannerObjectInFlowThread) {
580 ASSERT(spannerObjectInFlowThread->spannerPlaceholder()); 580 DCHECK(spannerObjectInFlowThread->spannerPlaceholder());
581 if (descendantIsValidColumnSpanner(spannerObjectInFlowThread)) 581 if (descendantIsValidColumnSpanner(spannerObjectInFlowThread))
582 return false; // Still a valid spanner. 582 return false; // Still a valid spanner.
583 583
584 // No longer a valid spanner. Get rid of the placeholder. 584 // No longer a valid spanner. Get rid of the placeholder.
585 destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder()); 585 destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder());
586 ASSERT(!spannerObjectInFlowThread->spannerPlaceholder()); 586 DCHECK(!spannerObjectInFlowThread->spannerPlaceholder());
587 587
588 // We may have a new containing block, since we're no longer a spanner. Mark 588 // We may have a new containing block, since we're no longer a spanner. Mark
589 // it for relayout. 589 // it for relayout.
590 spannerObjectInFlowThread->containingBlock() 590 spannerObjectInFlowThread->containingBlock()
591 ->setNeedsLayoutAndPrefWidthsRecalc( 591 ->setNeedsLayoutAndPrefWidthsRecalc(
592 LayoutInvalidationReason::ColumnsChanged); 592 LayoutInvalidationReason::ColumnsChanged);
593 593
594 // Now generate a column set for this ex-spanner, if needed and none is there 594 // Now generate a column set for this ex-spanner, if needed and none is there
595 // for us already. 595 // for us already.
596 flowThreadDescendantWasInserted(spannerObjectInFlowThread); 596 flowThreadDescendantWasInserted(spannerObjectInFlowThread);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 lastRow.blockOffsetInEnclosingFragmentationContext() + 663 lastRow.blockOffsetInEnclosingFragmentationContext() +
664 lastRow.logicalHeight(); 664 lastRow.logicalHeight();
665 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded( 665 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(
666 logicalOffsetInOuter, AssociateWithLatterPage); 666 logicalOffsetInOuter, AssociateWithLatterPage);
667 } 667 }
668 668
669 const MultiColumnFragmentainerGroup& newRow = 669 const MultiColumnFragmentainerGroup& newRow =
670 columnSet->appendNewFragmentainerGroup(); 670 columnSet->appendNewFragmentainerGroup();
671 // Zero-height rows should really not occur here, but if it does anyway, 671 // Zero-height rows should really not occur here, but if it does anyway,
672 // break, so that we don't get stuck in an infinite loop. 672 // break, so that we don't get stuck in an infinite loop.
673 ASSERT(newRow.logicalHeight() > 0); 673 DCHECK_GT(newRow.logicalHeight(), 0);
674 if (newRow.logicalHeight() <= 0) 674 if (newRow.logicalHeight() <= 0)
675 break; 675 break;
676 } while (columnSet->needsNewFragmentainerGroupAt(offsetInFlowThread, 676 } while (columnSet->needsNewFragmentainerGroupAt(offsetInFlowThread,
677 pageBoundaryRule)); 677 pageBoundaryRule));
678 } 678 }
679 } 679 }
680 680
681 bool LayoutMultiColumnFlowThread::isFragmentainerLogicalHeightKnown() { 681 bool LayoutMultiColumnFlowThread::isFragmentainerLogicalHeightKnown() {
682 return isPageLogicalHeightKnown(); 682 return isPageLogicalHeightKnown();
683 } 683 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 LayoutUnit& width, 721 LayoutUnit& width,
722 unsigned& count) const { 722 unsigned& count) const {
723 LayoutBlock* columnBlock = multiColumnBlockFlow(); 723 LayoutBlock* columnBlock = multiColumnBlockFlow();
724 const ComputedStyle* columnStyle = columnBlock->style(); 724 const ComputedStyle* columnStyle = columnBlock->style();
725 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); 725 LayoutUnit availableWidth = columnBlock->contentLogicalWidth();
726 LayoutUnit columnGap = LayoutUnit(columnBlock->columnGap()); 726 LayoutUnit columnGap = LayoutUnit(columnBlock->columnGap());
727 LayoutUnit computedColumnWidth = 727 LayoutUnit computedColumnWidth =
728 max(LayoutUnit(1), LayoutUnit(columnStyle->columnWidth())); 728 max(LayoutUnit(1), LayoutUnit(columnStyle->columnWidth()));
729 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); 729 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount());
730 730
731 ASSERT(!columnStyle->hasAutoColumnCount() || 731 DCHECK(!columnStyle->hasAutoColumnCount() ||
732 !columnStyle->hasAutoColumnWidth()); 732 !columnStyle->hasAutoColumnWidth());
733 if (columnStyle->hasAutoColumnWidth() && !columnStyle->hasAutoColumnCount()) { 733 if (columnStyle->hasAutoColumnWidth() && !columnStyle->hasAutoColumnCount()) {
734 count = computedColumnCount; 734 count = computedColumnCount;
735 width = ((availableWidth - ((count - 1) * columnGap)) / count) 735 width = ((availableWidth - ((count - 1) * columnGap)) / count)
736 .clampNegativeToZero(); 736 .clampNegativeToZero();
737 } else if (!columnStyle->hasAutoColumnWidth() && 737 } else if (!columnStyle->hasAutoColumnWidth() &&
738 columnStyle->hasAutoColumnCount()) { 738 columnStyle->hasAutoColumnCount()) {
739 count = std::max(LayoutUnit(1), (availableWidth + columnGap) / 739 count = std::max(LayoutUnit(1), (availableWidth + columnGap) /
740 (computedColumnWidth + columnGap)) 740 (computedColumnWidth + columnGap))
741 .toUnsigned(); 741 .toUnsigned();
(...skipping 11 matching lines...) Expand all
753 void LayoutMultiColumnFlowThread::createAndInsertMultiColumnSet( 753 void LayoutMultiColumnFlowThread::createAndInsertMultiColumnSet(
754 LayoutBox* insertBefore) { 754 LayoutBox* insertBefore) {
755 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); 755 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow();
756 LayoutMultiColumnSet* newSet = LayoutMultiColumnSet::createAnonymous( 756 LayoutMultiColumnSet* newSet = LayoutMultiColumnSet::createAnonymous(
757 *this, multicolContainer->styleRef()); 757 *this, multicolContainer->styleRef());
758 multicolContainer->LayoutBlock::addChild(newSet, insertBefore); 758 multicolContainer->LayoutBlock::addChild(newSet, insertBefore);
759 invalidateColumnSets(); 759 invalidateColumnSets();
760 760
761 // We cannot handle immediate column set siblings (and there's no need for it, 761 // We cannot handle immediate column set siblings (and there's no need for it,
762 // either). There has to be at least one spanner separating them. 762 // either). There has to be at least one spanner separating them.
763 ASSERT(!newSet->previousSiblingMultiColumnBox() || 763 DCHECK(!newSet->previousSiblingMultiColumnBox() ||
764 !newSet->previousSiblingMultiColumnBox()->isLayoutMultiColumnSet()); 764 !newSet->previousSiblingMultiColumnBox()->isLayoutMultiColumnSet());
765 ASSERT(!newSet->nextSiblingMultiColumnBox() || 765 DCHECK(!newSet->nextSiblingMultiColumnBox() ||
766 !newSet->nextSiblingMultiColumnBox()->isLayoutMultiColumnSet()); 766 !newSet->nextSiblingMultiColumnBox()->isLayoutMultiColumnSet());
767 } 767 }
768 768
769 void LayoutMultiColumnFlowThread::createAndInsertSpannerPlaceholder( 769 void LayoutMultiColumnFlowThread::createAndInsertSpannerPlaceholder(
770 LayoutBox* spannerObjectInFlowThread, 770 LayoutBox* spannerObjectInFlowThread,
771 LayoutObject* insertedBeforeInFlowThread) { 771 LayoutObject* insertedBeforeInFlowThread) {
772 LayoutBox* insertBeforeColumnBox = nullptr; 772 LayoutBox* insertBeforeColumnBox = nullptr;
773 LayoutMultiColumnSet* setToSplit = nullptr; 773 LayoutMultiColumnSet* setToSplit = nullptr;
774 if (insertedBeforeInFlowThread) { 774 if (insertedBeforeInFlowThread) {
775 // The spanner is inserted before something. Figure out what this entails. 775 // The spanner is inserted before something. Figure out what this entails.
(...skipping 13 matching lines...) Expand all
789 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlaceholder = 789 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlaceholder =
790 containingColumnSpannerPlaceholder(previousLayoutObject)) { 790 containingColumnSpannerPlaceholder(previousLayoutObject)) {
791 // Before us is another spanner. We belong right after it then. 791 // Before us is another spanner. We belong right after it then.
792 insertBeforeColumnBox = 792 insertBeforeColumnBox =
793 previousPlaceholder->nextSiblingMultiColumnBox(); 793 previousPlaceholder->nextSiblingMultiColumnBox();
794 } else { 794 } else {
795 // We're inside regular column content with both feet. Find out which 795 // We're inside regular column content with both feet. Find out which
796 // column set this is. It needs to be split it into two sets, so that we 796 // column set this is. It needs to be split it into two sets, so that we
797 // can insert a new spanner placeholder between them. 797 // can insert a new spanner placeholder between them.
798 setToSplit = mapDescendantToColumnSet(previousLayoutObject); 798 setToSplit = mapDescendantToColumnSet(previousLayoutObject);
799 ASSERT(setToSplit == 799 DCHECK_EQ(setToSplit,
800 mapDescendantToColumnSet(insertedBeforeInFlowThread)); 800 mapDescendantToColumnSet(insertedBeforeInFlowThread));
801 insertBeforeColumnBox = setToSplit->nextSiblingMultiColumnBox(); 801 insertBeforeColumnBox = setToSplit->nextSiblingMultiColumnBox();
802 // We've found out which set that needs to be split. Now proceed to 802 // We've found out which set that needs to be split. Now proceed to
803 // inserting the spanner placeholder, and then insert a second column 803 // inserting the spanner placeholder, and then insert a second column
804 // set. 804 // set.
805 } 805 }
806 } 806 }
807 ASSERT(setToSplit || insertBeforeColumnBox); 807 DCHECK(setToSplit || insertBeforeColumnBox);
808 } 808 }
809 809
810 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); 810 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow();
811 LayoutMultiColumnSpannerPlaceholder* newPlaceholder = 811 LayoutMultiColumnSpannerPlaceholder* newPlaceholder =
812 LayoutMultiColumnSpannerPlaceholder::createAnonymous( 812 LayoutMultiColumnSpannerPlaceholder::createAnonymous(
813 multicolContainer->styleRef(), *spannerObjectInFlowThread); 813 multicolContainer->styleRef(), *spannerObjectInFlowThread);
814 ASSERT(!insertBeforeColumnBox || 814 DCHECK(!insertBeforeColumnBox ||
815 insertBeforeColumnBox->parent() == multicolContainer); 815 insertBeforeColumnBox->parent() == multicolContainer);
816 multicolContainer->LayoutBlock::addChild(newPlaceholder, 816 multicolContainer->LayoutBlock::addChild(newPlaceholder,
817 insertBeforeColumnBox); 817 insertBeforeColumnBox);
818 spannerObjectInFlowThread->setSpannerPlaceholder(*newPlaceholder); 818 spannerObjectInFlowThread->setSpannerPlaceholder(*newPlaceholder);
819 819
820 if (setToSplit) 820 if (setToSplit)
821 createAndInsertMultiColumnSet(insertBeforeColumnBox); 821 createAndInsertMultiColumnSet(insertBeforeColumnBox);
822 } 822 }
823 823
824 void LayoutMultiColumnFlowThread::destroySpannerPlaceholder( 824 void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(
(...skipping 17 matching lines...) Expand all
842 // one (return true). 842 // one (return true).
843 // - When the descendant doesn't have a spanner placeholder and still should 843 // - When the descendant doesn't have a spanner placeholder and still should
844 // not have one (return false). 844 // not have one (return false).
845 // - When the descendant has a spanner placeholder but should no longer have 845 // - When the descendant has a spanner placeholder but should no longer have
846 // one (return false). 846 // one (return false).
847 // - When the descendant has a spanner placeholder and should still have one 847 // - When the descendant has a spanner placeholder and should still have one
848 // (return true). 848 // (return true).
849 849
850 // We assume that we're inside the flow thread. This function is not to be 850 // We assume that we're inside the flow thread. This function is not to be
851 // called otherwise. 851 // called otherwise.
852 ASSERT(descendant->isDescendantOf(this)); 852 DCHECK(descendant->isDescendantOf(this));
853 853
854 // The spec says that column-span only applies to in-flow block-level 854 // The spec says that column-span only applies to in-flow block-level
855 // elements. 855 // elements.
856 if (descendant->style()->getColumnSpan() != ColumnSpanAll || 856 if (descendant->style()->getColumnSpan() != ColumnSpanAll ||
857 !descendant->isBox() || descendant->isInline() || 857 !descendant->isBox() || descendant->isInline() ||
858 descendant->isFloatingOrOutOfFlowPositioned()) 858 descendant->isFloatingOrOutOfFlowPositioned())
859 return false; 859 return false;
860 860
861 if (!descendant->containingBlock()->isLayoutBlockFlow()) { 861 if (!descendant->containingBlock()->isLayoutBlockFlow()) {
862 // Needs to be in a block-flow container, and not e.g. a table. 862 // Needs to be in a block-flow container, and not e.g. a table.
863 return false; 863 return false;
864 } 864 }
865 865
866 // This looks like a spanner, but if we're inside something unbreakable or 866 // This looks like a spanner, but if we're inside something unbreakable or
867 // something that establishes a new formatting context, it's not to be treated 867 // something that establishes a new formatting context, it's not to be treated
868 // as one. 868 // as one.
869 for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor; 869 for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor;
870 ancestor = ancestor->containingBlock()) { 870 ancestor = ancestor->containingBlock()) {
871 if (ancestor->isLayoutFlowThread()) { 871 if (ancestor->isLayoutFlowThread()) {
872 ASSERT(ancestor == this); 872 DCHECK_EQ(ancestor, this);
873 return true; 873 return true;
874 } 874 }
875 if (!canContainSpannerInParentFragmentationContext(*ancestor)) 875 if (!canContainSpannerInParentFragmentationContext(*ancestor))
876 return false; 876 return false;
877 } 877 }
878 NOTREACHED(); 878 NOTREACHED();
879 return false; 879 return false;
880 } 880 }
881 881
882 void LayoutMultiColumnFlowThread::addColumnSetToThread( 882 void LayoutMultiColumnFlowThread::addColumnSetToThread(
883 LayoutMultiColumnSet* columnSet) { 883 LayoutMultiColumnSet* columnSet) {
884 if (LayoutMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) { 884 if (LayoutMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) {
885 LayoutMultiColumnSetList::iterator it = m_multiColumnSetList.find(nextSet); 885 LayoutMultiColumnSetList::iterator it = m_multiColumnSetList.find(nextSet);
886 ASSERT(it != m_multiColumnSetList.end()); 886 DCHECK(it != m_multiColumnSetList.end());
tkent 2017/04/04 01:36:17 Use DCHECK_NE if it doesn't cause a compile failur
mrunal 2017/04/05 00:39:14 Not possible because of compile failure.
887 m_multiColumnSetList.insertBefore(it, columnSet); 887 m_multiColumnSetList.insertBefore(it, columnSet);
888 } else { 888 } else {
889 m_multiColumnSetList.insert(columnSet); 889 m_multiColumnSetList.insert(columnSet);
890 } 890 }
891 } 891 }
892 892
893 void LayoutMultiColumnFlowThread::willBeRemovedFromTree() { 893 void LayoutMultiColumnFlowThread::willBeRemovedFromTree() {
894 // Detach all column sets from the flow thread. Cannot destroy them at this 894 // Detach all column sets from the flow thread. Cannot destroy them at this
895 // point, since they are siblings of this object, and there may be pointers to 895 // point, since they are siblings of this object, and there may be pointers to
896 // this object's sibling somewhere further up on the call stack. 896 // this object's sibling somewhere further up on the call stack.
897 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; 897 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet;
898 columnSet = columnSet->nextSiblingMultiColumnSet()) 898 columnSet = columnSet->nextSiblingMultiColumnSet())
899 columnSet->detachFromFlowThread(); 899 columnSet->detachFromFlowThread();
900 multiColumnBlockFlow()->resetMultiColumnFlowThread(); 900 multiColumnBlockFlow()->resetMultiColumnFlowThread();
901 LayoutFlowThread::willBeRemovedFromTree(); 901 LayoutFlowThread::willBeRemovedFromTree();
902 } 902 }
903 903
904 void LayoutMultiColumnFlowThread::skipColumnSpanner( 904 void LayoutMultiColumnFlowThread::skipColumnSpanner(
905 LayoutBox* layoutObject, 905 LayoutBox* layoutObject,
906 LayoutUnit logicalTopInFlowThread) { 906 LayoutUnit logicalTopInFlowThread) {
907 ASSERT(layoutObject->isColumnSpanAll()); 907 DCHECK(layoutObject->isColumnSpanAll());
908 LayoutMultiColumnSpannerPlaceholder* placeholder = 908 LayoutMultiColumnSpannerPlaceholder* placeholder =
909 layoutObject->spannerPlaceholder(); 909 layoutObject->spannerPlaceholder();
910 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox(); 910 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox();
911 if (previousColumnBox && previousColumnBox->isLayoutMultiColumnSet()) 911 if (previousColumnBox && previousColumnBox->isLayoutMultiColumnSet())
912 toLayoutMultiColumnSet(previousColumnBox)->endFlow(logicalTopInFlowThread); 912 toLayoutMultiColumnSet(previousColumnBox)->endFlow(logicalTopInFlowThread);
913 LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox(); 913 LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox();
914 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) { 914 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet()) {
915 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox); 915 LayoutMultiColumnSet* nextSet = toLayoutMultiColumnSet(nextColumnBox);
916 m_lastSetWorkedOn = nextSet; 916 m_lastSetWorkedOn = nextSet;
917 nextSet->beginFlow(logicalTopInFlowThread); 917 nextSet->beginFlow(logicalTopInFlowThread);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 child.containingBlock()->flowThreadContainingBlock() != flowThread) { 959 child.containingBlock()->flowThreadContainingBlock() != flowThread) {
960 // Out-of-flow with its containing block on the outside of the multicol 960 // Out-of-flow with its containing block on the outside of the multicol
961 // container. 961 // container.
962 return true; 962 return true;
963 } 963 }
964 return false; 964 return false;
965 } 965 }
966 966
967 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted( 967 void LayoutMultiColumnFlowThread::flowThreadDescendantWasInserted(
968 LayoutObject* descendant) { 968 LayoutObject* descendant) {
969 ASSERT(!m_isBeingEvacuated); 969 DCHECK(!m_isBeingEvacuated);
970 // This method ensures that the list of column sets and spanner placeholders 970 // This method ensures that the list of column sets and spanner placeholders
971 // reflects the multicol content after having inserted a descendant (or 971 // reflects the multicol content after having inserted a descendant (or
972 // descendant subtree). See the header file for more information. Go through 972 // descendant subtree). See the header file for more information. Go through
973 // the subtree that was just inserted and create column sets (needed by 973 // the subtree that was just inserted and create column sets (needed by
974 // regular column content) and spanner placeholders (one needed by each 974 // regular column content) and spanner placeholders (one needed by each
975 // spanner) where needed. 975 // spanner) where needed.
976 if (shouldSkipInsertedOrRemovedChild(this, *descendant)) 976 if (shouldSkipInsertedOrRemovedChild(this, *descendant))
977 return; 977 return;
978 LayoutObject* objectAfterSubtree = 978 LayoutObject* objectAfterSubtree =
979 nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant); 979 nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant);
(...skipping 22 matching lines...) Expand all
1002 objectAfterSubtree->spannerPlaceholder()) { 1002 objectAfterSubtree->spannerPlaceholder()) {
1003 // If inserted right before a spanner, we need to make sure that there's 1003 // If inserted right before a spanner, we need to make sure that there's
1004 // a set for us there. 1004 // a set for us there.
1005 LayoutBox* previous = placeholder->previousSiblingMultiColumnBox(); 1005 LayoutBox* previous = placeholder->previousSiblingMultiColumnBox();
1006 if (!previous || !previous->isLayoutMultiColumnSet()) 1006 if (!previous || !previous->isLayoutMultiColumnSet())
1007 createAndInsertMultiColumnSet(placeholder); 1007 createAndInsertMultiColumnSet(placeholder);
1008 } else { 1008 } else {
1009 // Otherwise, since |objectAfterSubtree| isn't a spanner, it has to mean 1009 // Otherwise, since |objectAfterSubtree| isn't a spanner, it has to mean
1010 // that there's already a set for that content. We can use it for this 1010 // that there's already a set for that content. We can use it for this
1011 // layoutObject too. 1011 // layoutObject too.
1012 ASSERT(mapDescendantToColumnSet(objectAfterSubtree)); 1012 DCHECK(mapDescendantToColumnSet(objectAfterSubtree));
1013 ASSERT(mapDescendantToColumnSet(layoutObject) == 1013 DCHECK_EQ(mapDescendantToColumnSet(layoutObject),
1014 mapDescendantToColumnSet(objectAfterSubtree)); 1014 mapDescendantToColumnSet(objectAfterSubtree));
1015 } 1015 }
1016 } else { 1016 } else {
1017 // Inserting at the end. Then we just need to make sure that there's a 1017 // Inserting at the end. Then we just need to make sure that there's a
1018 // column set at the end. 1018 // column set at the end.
1019 LayoutBox* lastColumnBox = lastMultiColumnBox(); 1019 LayoutBox* lastColumnBox = lastMultiColumnBox();
1020 if (!lastColumnBox || !lastColumnBox->isLayoutMultiColumnSet()) 1020 if (!lastColumnBox || !lastColumnBox->isLayoutMultiColumnSet())
1021 createAndInsertMultiColumnSet(); 1021 createAndInsertMultiColumnSet();
1022 } 1022 }
1023 } 1023 }
1024 } 1024 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 return; // Followed by column content. Set still needed. 1083 return; // Followed by column content. Set still needed.
1084 } 1084 }
1085 // We have now determined that, with the removal of |descendant|, we should 1085 // We have now determined that, with the removal of |descendant|, we should
1086 // remove a column set. Locate it and remove it. Do it without involving 1086 // remove a column set. Locate it and remove it. Do it without involving
1087 // mapDescendantToColumnSet(), as that might be very slow. Deduce the right 1087 // mapDescendantToColumnSet(), as that might be very slow. Deduce the right
1088 // set from the spanner placeholders that we've already found. 1088 // set from the spanner placeholders that we've already found.
1089 LayoutMultiColumnSet* columnSetToRemove; 1089 LayoutMultiColumnSet* columnSetToRemove;
1090 if (adjacentNextSpannerPlaceholder) { 1090 if (adjacentNextSpannerPlaceholder) {
1091 columnSetToRemove = toLayoutMultiColumnSet( 1091 columnSetToRemove = toLayoutMultiColumnSet(
1092 adjacentNextSpannerPlaceholder->previousSiblingMultiColumnBox()); 1092 adjacentNextSpannerPlaceholder->previousSiblingMultiColumnBox());
1093 ASSERT(!adjacentPreviousSpannerPlaceholder || 1093 DCHECK(!adjacentPreviousSpannerPlaceholder ||
1094 columnSetToRemove == 1094 columnSetToRemove ==
1095 adjacentPreviousSpannerPlaceholder->nextSiblingMultiColumnBox()); 1095 adjacentPreviousSpannerPlaceholder->nextSiblingMultiColumnBox());
1096 } else if (adjacentPreviousSpannerPlaceholder) { 1096 } else if (adjacentPreviousSpannerPlaceholder) {
1097 columnSetToRemove = toLayoutMultiColumnSet( 1097 columnSetToRemove = toLayoutMultiColumnSet(
1098 adjacentPreviousSpannerPlaceholder->nextSiblingMultiColumnBox()); 1098 adjacentPreviousSpannerPlaceholder->nextSiblingMultiColumnBox());
1099 } else { 1099 } else {
1100 // If there were no adjacent spanners, it has to mean that there's only one 1100 // If there were no adjacent spanners, it has to mean that there's only one
1101 // column set, since it's only spanners that may cause creation of 1101 // column set, since it's only spanners that may cause creation of
1102 // multiple sets. 1102 // multiple sets.
1103 columnSetToRemove = firstMultiColumnSet(); 1103 columnSetToRemove = firstMultiColumnSet();
1104 ASSERT(columnSetToRemove); 1104 DCHECK(columnSetToRemove);
1105 ASSERT(!columnSetToRemove->nextSiblingMultiColumnSet()); 1105 DCHECK(!columnSetToRemove->nextSiblingMultiColumnSet());
1106 } 1106 }
1107 ASSERT(columnSetToRemove); 1107 DCHECK(columnSetToRemove);
1108 columnSetToRemove->destroy(); 1108 columnSetToRemove->destroy();
1109 } 1109 }
1110 1110
1111 static inline bool needsToReinsertIntoFlowThread( 1111 static inline bool needsToReinsertIntoFlowThread(
1112 const ComputedStyle& oldStyle, 1112 const ComputedStyle& oldStyle,
1113 const ComputedStyle& newStyle) { 1113 const ComputedStyle& newStyle) {
1114 // If we've become (or are about to become) a container for absolutely 1114 // If we've become (or are about to become) a container for absolutely
1115 // positioned descendants, or if we're no longer going to be one, we need to 1115 // positioned descendants, or if we're no longer going to be one, we need to
1116 // re-evaluate the need for column sets. There may be out-of-flow descendants 1116 // re-evaluate the need for column sets. There may be out-of-flow descendants
1117 // further down that become part of the flow thread, or cease to be part of 1117 // further down that become part of the flow thread, or cease to be part of
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 const ComputedStyle& oldStyle) { 1170 const ComputedStyle& oldStyle) {
1171 bool toggleSpannersIfNeeded = s_toggleSpannersIfNeeded; 1171 bool toggleSpannersIfNeeded = s_toggleSpannersIfNeeded;
1172 s_toggleSpannersIfNeeded = false; 1172 s_toggleSpannersIfNeeded = false;
1173 1173
1174 if (needsToInsertIntoFlowThread(oldStyle, descendant->styleRef())) { 1174 if (needsToInsertIntoFlowThread(oldStyle, descendant->styleRef())) {
1175 flowThreadDescendantWasInserted(descendant); 1175 flowThreadDescendantWasInserted(descendant);
1176 return; 1176 return;
1177 } 1177 }
1178 if (descendantIsValidColumnSpanner(descendant)) { 1178 if (descendantIsValidColumnSpanner(descendant)) {
1179 // We went from being regular column content to becoming a spanner. 1179 // We went from being regular column content to becoming a spanner.
1180 ASSERT(!descendant->spannerPlaceholder()); 1180 DCHECK(!descendant->spannerPlaceholder());
1181 1181
1182 // First remove this as regular column content. Note that this will walk the 1182 // First remove this as regular column content. Note that this will walk the
1183 // entire subtree of |descendant|. There might be spanners there (which 1183 // entire subtree of |descendant|. There might be spanners there (which
1184 // won't be spanners anymore, since we're not allowed to nest spanners), 1184 // won't be spanners anymore, since we're not allowed to nest spanners),
1185 // whose placeholders must die. 1185 // whose placeholders must die.
1186 flowThreadDescendantWillBeRemoved(descendant); 1186 flowThreadDescendantWillBeRemoved(descendant);
1187 1187
1188 createAndInsertSpannerPlaceholder( 1188 createAndInsertSpannerPlaceholder(
1189 descendant, 1189 descendant,
1190 nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant)); 1190 nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant));
1191 return; 1191 return;
1192 } 1192 }
1193 1193
1194 if (!toggleSpannersIfNeeded) 1194 if (!toggleSpannersIfNeeded)
1195 return; 1195 return;
1196 #if DCHECK_IS_ON() 1196 #if DCHECK_IS_ON()
1197 // Make sure that we were preceded by a call to 1197 // Make sure that we were preceded by a call to
1198 // flowThreadDescendantStyleWillChange() with the same descendant as we have 1198 // flowThreadDescendantStyleWillChange() with the same descendant as we have
1199 // now. 1199 // now.
1200 DCHECK(s_styleChangedBox == descendant); 1200 DCHECK_EQ(s_styleChangedBox, descendant);
1201 #endif 1201 #endif
1202 1202
1203 if (s_couldContainSpanners != 1203 if (s_couldContainSpanners !=
1204 canContainSpannerInParentFragmentationContext(*descendant)) 1204 canContainSpannerInParentFragmentationContext(*descendant))
1205 toggleSpannersInSubtree(descendant); 1205 toggleSpannersInSubtree(descendant);
1206 } 1206 }
1207 1207
1208 void LayoutMultiColumnFlowThread::toggleSpannersInSubtree( 1208 void LayoutMultiColumnFlowThread::toggleSpannersInSubtree(
1209 LayoutBox* descendant) { 1209 LayoutBox* descendant) {
1210 DCHECK(s_couldContainSpanners != 1210 DCHECK_NE(s_couldContainSpanners,
1211 canContainSpannerInParentFragmentationContext(*descendant)); 1211 canContainSpannerInParentFragmentationContext(*descendant));
1212 1212
1213 // If there are no spanners at all in this multicol container, there's no 1213 // If there are no spanners at all in this multicol container, there's no
1214 // need to look for any to remove. 1214 // need to look for any to remove.
1215 if (s_couldContainSpanners && !hasAnyColumnSpanners(*this)) 1215 if (s_couldContainSpanners && !hasAnyColumnSpanners(*this))
1216 return; 1216 return;
1217 1217
1218 bool walkChildren; 1218 bool walkChildren;
1219 for (LayoutObject* object = descendant->nextInPreOrder(descendant); object; 1219 for (LayoutObject* object = descendant->nextInPreOrder(descendant); object;
1220 object = walkChildren 1220 object = walkChildren
1221 ? object->nextInPreOrder(descendant) 1221 ? object->nextInPreOrder(descendant)
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 computedValues.m_position = logicalTop; 1294 computedValues.m_position = logicalTop;
1295 } 1295 }
1296 1296
1297 void LayoutMultiColumnFlowThread::updateLogicalWidth() { 1297 void LayoutMultiColumnFlowThread::updateLogicalWidth() {
1298 LayoutUnit columnWidth; 1298 LayoutUnit columnWidth;
1299 calculateColumnCountAndWidth(columnWidth, m_columnCount); 1299 calculateColumnCountAndWidth(columnWidth, m_columnCount);
1300 setLogicalWidth(columnWidth); 1300 setLogicalWidth(columnWidth);
1301 } 1301 }
1302 1302
1303 void LayoutMultiColumnFlowThread::layout() { 1303 void LayoutMultiColumnFlowThread::layout() {
1304 ASSERT(!m_lastSetWorkedOn); 1304 DCHECK(!m_lastSetWorkedOn);
1305 m_lastSetWorkedOn = firstMultiColumnSet(); 1305 m_lastSetWorkedOn = firstMultiColumnSet();
1306 if (m_lastSetWorkedOn) 1306 if (m_lastSetWorkedOn)
1307 m_lastSetWorkedOn->beginFlow(LayoutUnit()); 1307 m_lastSetWorkedOn->beginFlow(LayoutUnit());
1308 LayoutFlowThread::layout(); 1308 LayoutFlowThread::layout();
1309 if (LayoutMultiColumnSet* lastSet = lastMultiColumnSet()) { 1309 if (LayoutMultiColumnSet* lastSet = lastMultiColumnSet()) {
1310 ASSERT(lastSet == m_lastSetWorkedOn); 1310 DCHECK_EQ(lastSet, m_lastSetWorkedOn);
1311 if (!lastSet->nextSiblingMultiColumnSet()) { 1311 if (!lastSet->nextSiblingMultiColumnSet()) {
1312 // Include trailing overflow in the last column set (also if the last set 1312 // Include trailing overflow in the last column set (also if the last set
1313 // is followed by one or more spanner placeholders). The idea is that we 1313 // is followed by one or more spanner placeholders). The idea is that we
1314 // will generate additional columns and pages to hold that overflow, 1314 // will generate additional columns and pages to hold that overflow,
1315 // since people do write bad content like <body style="height:0px"> in 1315 // since people do write bad content like <body style="height:0px"> in
1316 // multi-column layouts. 1316 // multi-column layouts.
1317 // TODO(mstensho): Once we support nested multicol, adding in overflow 1317 // TODO(mstensho): Once we support nested multicol, adding in overflow
1318 // here may result in the need for creating additional rows, since there 1318 // here may result in the need for creating additional rows, since there
1319 // may not be enough space remaining in the currently last row. 1319 // may not be enough space remaining in the currently last row.
1320 LayoutRect layoutRect = layoutOverflowRect(); 1320 LayoutRect layoutRect = layoutOverflowRect();
1321 LayoutUnit logicalBottomInFlowThread = 1321 LayoutUnit logicalBottomInFlowThread =
1322 isHorizontalWritingMode() ? layoutRect.maxY() : layoutRect.maxX(); 1322 isHorizontalWritingMode() ? layoutRect.maxY() : layoutRect.maxX();
1323 ASSERT(logicalBottomInFlowThread >= logicalHeight()); 1323 DCHECK_GE(logicalBottomInFlowThread, logicalHeight());
1324 lastSet->endFlow(logicalBottomInFlowThread); 1324 lastSet->endFlow(logicalBottomInFlowThread);
1325 } 1325 }
1326 } 1326 }
1327 m_lastSetWorkedOn = nullptr; 1327 m_lastSetWorkedOn = nullptr;
1328 } 1328 }
1329 1329
1330 void LayoutMultiColumnFlowThread::contentWasLaidOut( 1330 void LayoutMultiColumnFlowThread::contentWasLaidOut(
1331 LayoutUnit logicalBottomInFlowThreadAfterPagination) { 1331 LayoutUnit logicalBottomInFlowThreadAfterPagination) {
1332 // Check if we need another fragmentainer group. If we've run out of columns 1332 // Check if we need another fragmentainer group. If we've run out of columns
1333 // in the last fragmentainer group (column row), we need to insert another 1333 // in the last fragmentainer group (column row), we need to insert another
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 const { 1377 const {
1378 return MultiColumnLayoutState(m_lastSetWorkedOn); 1378 return MultiColumnLayoutState(m_lastSetWorkedOn);
1379 } 1379 }
1380 1380
1381 void LayoutMultiColumnFlowThread::restoreMultiColumnLayoutState( 1381 void LayoutMultiColumnFlowThread::restoreMultiColumnLayoutState(
1382 const MultiColumnLayoutState& state) { 1382 const MultiColumnLayoutState& state) {
1383 m_lastSetWorkedOn = state.columnSet(); 1383 m_lastSetWorkedOn = state.columnSet();
1384 } 1384 }
1385 1385
1386 } // namespace blink 1386 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698