Chromium Code Reviews| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 64 |
| 65 RenderMultiColumnSet* RenderMultiColumnSet::previousSiblingMultiColumnSet() cons t | 65 RenderMultiColumnSet* RenderMultiColumnSet::previousSiblingMultiColumnSet() cons t |
| 66 { | 66 { |
| 67 for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling-> previousSibling()) { | 67 for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling-> previousSibling()) { |
| 68 if (sibling->isRenderMultiColumnSet()) | 68 if (sibling->isRenderMultiColumnSet()) |
| 69 return toRenderMultiColumnSet(sibling); | 69 return toRenderMultiColumnSet(sibling); |
| 70 } | 70 } |
| 71 return 0; | 71 return 0; |
| 72 } | 72 } |
| 73 | 73 |
| 74 void RenderMultiColumnSet::setLogicalTopInFlowThread(LayoutUnit logicalTop) | |
| 75 { | |
| 76 LayoutRect rect = flowThreadPortionRect(); | |
| 77 if (isHorizontalWritingMode()) | |
| 78 rect.setY(logicalTop); | |
| 79 else | |
| 80 rect.setX(logicalTop); | |
| 81 setFlowThreadPortionRect(rect); | |
| 82 } | |
| 83 | |
| 84 void RenderMultiColumnSet::setLogicalBottomInFlowThread(LayoutUnit logicalBottom ) | |
| 85 { | |
| 86 LayoutRect rect = flowThreadPortionRect(); | |
| 87 if (isHorizontalWritingMode()) | |
| 88 rect.shiftMaxYEdgeTo(logicalBottom); | |
| 89 else | |
| 90 rect.shiftMaxXEdgeTo(logicalBottom); | |
| 91 setFlowThreadPortionRect(rect); | |
|
Julien - ping for review
2014/11/26 21:09:01
I assume we have testing for that?
mstensho (USE GERRIT)
2014/11/27 21:20:29
I just wrote unit tests for it. :)
| |
| 92 } | |
| 93 | |
| 94 bool RenderMultiColumnSet::heightIsAuto() const | |
| 95 { | |
| 96 RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread(); | |
| 97 if (!flowThread->isRenderPagedFlowThread()) { | |
| 98 if (multiColumnBlockFlow()->style()->columnFill() == ColumnFillBalance) | |
| 99 return true; | |
| 100 if (RenderMultiColumnSet* next = nextSiblingMultiColumnSet()) { | |
| 101 if (next->isRenderMultiColumnSpannerSet()) { | |
| 102 // If we're followed by a spanner, we need to balance. | |
| 103 return true; | |
| 104 } | |
| 105 } | |
| 106 } | |
| 107 return !flowThread->columnHeightAvailable(); | |
| 108 } | |
| 109 | |
| 74 LayoutSize RenderMultiColumnSet::flowThreadTranslationAtOffset(LayoutUnit blockO ffset) const | 110 LayoutSize RenderMultiColumnSet::flowThreadTranslationAtOffset(LayoutUnit blockO ffset) const |
| 75 { | 111 { |
| 76 unsigned columnIndex = columnIndexAtOffset(blockOffset); | 112 unsigned columnIndex = columnIndexAtOffset(blockOffset); |
| 77 LayoutRect portionRect(flowThreadPortionRectAt(columnIndex)); | 113 LayoutRect portionRect(flowThreadPortionRectAt(columnIndex)); |
| 78 flipForWritingMode(portionRect); | 114 flipForWritingMode(portionRect); |
| 79 LayoutRect columnRect(columnRectAt(columnIndex)); | 115 LayoutRect columnRect(columnRectAt(columnIndex)); |
| 80 flipForWritingMode(columnRect); | 116 flipForWritingMode(columnRect); |
| 81 return contentBoxRect().location() + columnRect.location() - portionRect.loc ation(); | 117 return contentBoxRect().location() + columnRect.location() - portionRect.loc ation(); |
| 82 } | 118 } |
| 83 | 119 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! | 223 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! |
| 188 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug. | 224 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug. |
| 189 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) | 225 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) |
| 190 return m_columnHeight; // So bail out rather than looping infinitely. | 226 return m_columnHeight; // So bail out rather than looping infinitely. |
| 191 | 227 |
| 192 return m_columnHeight + m_minSpaceShortage; | 228 return m_columnHeight + m_minSpaceShortage; |
| 193 } | 229 } |
| 194 | 230 |
| 195 void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage) | 231 void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage) |
| 196 { | 232 { |
| 197 if (!multiColumnFlowThread()->heightIsAuto()) | 233 if (!requiresBalancing()) |
| 198 return; | 234 return; |
| 199 if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last ().breakOffset()) | 235 if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last ().breakOffset()) |
| 200 return; | 236 return; |
| 201 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the | 237 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the |
| 202 // overflow area shouldn't affect column balancing. | 238 // overflow area shouldn't affect column balancing. |
| 203 if (m_contentRuns.size() < usedColumnCount()) | 239 if (m_contentRuns.size() < usedColumnCount()) |
| 204 m_contentRuns.append(ContentRun(endOffsetFromFirstPage)); | 240 m_contentRuns.append(ContentRun(endOffsetFromFirstPage)); |
| 205 } | 241 } |
| 206 | 242 |
| 207 bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation cal culationMode) | 243 bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation cal culationMode) |
| 208 { | 244 { |
| 209 if (previousSiblingMultiColumnSet()) { | 245 LayoutUnit oldColumnHeight = m_columnHeight; |
| 210 // FIXME: column spanner layout is not yet implemented. Until it's in pl ace, we only operate | 246 |
| 211 // on the first set during layout. We need to ignore the others here, or assertions will | 247 m_maxColumnHeight = calculateMaxColumnHeight(); |
| 212 // fail. | 248 |
| 213 return false; | 249 if (requiresBalancing()) { |
| 250 if (calculationMode == GuessFromFlowThreadPortion) { | |
| 251 // Post-process the content runs and find out where the implicit bre aks will occur. | |
| 252 distributeImplicitBreaks(); | |
| 253 } | |
| 254 LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode); | |
| 255 setAndConstrainColumnHeight(newColumnHeight); | |
| 256 // After having calculated an initial column height, the multicol contai ner typically needs at | |
| 257 // least one more layout pass with a new column height, but if a height was specified, we only | |
| 258 // need to do this if we think that we need less space than specified. C onversely, if we | |
| 259 // determined that the columns need to be as tall as the specified heigh t of the container, we | |
| 260 // have already laid it out correctly, and there's no need for another p ass. | |
| 261 } else { | |
| 262 // The position of the column set may have changed, in which case height available for | |
| 263 // columns may have changed as well. | |
| 264 setAndConstrainColumnHeight(m_columnHeight); | |
| 214 } | 265 } |
| 215 ASSERT(multiColumnFlowThread()->heightIsAuto()); | |
| 216 | |
| 217 LayoutUnit oldColumnHeight = m_columnHeight; | |
| 218 if (calculationMode == GuessFromFlowThreadPortion) { | |
| 219 // Post-process the content runs and find out where the implicit breaks will occur. | |
| 220 distributeImplicitBreaks(); | |
| 221 } | |
| 222 LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode); | |
| 223 setAndConstrainColumnHeight(newColumnHeight); | |
| 224 | |
| 225 // After having calculated an initial column height, the multicol container typically needs at | |
| 226 // least one more layout pass with a new column height, but if a height was specified, we only | |
| 227 // need to do this if we think that we need less space than specified. Conve rsely, if we | |
| 228 // determined that the columns need to be as tall as the specified height of the container, we | |
| 229 // have already laid it out correctly, and there's no need for another pass. | |
| 230 | 266 |
| 231 // We can get rid of the content runs now, if we haven't already done so. Th ey are only needed | 267 // We can get rid of the content runs now, if we haven't already done so. Th ey are only needed |
| 232 // to calculate the initial balanced column height. In fact, we have to get rid of them before | 268 // to calculate the initial balanced column height. In fact, we have to get rid of them before |
| 233 // the next layout pass, since each pass will rebuild this. | 269 // the next layout pass, since each pass will rebuild this. |
| 234 m_contentRuns.clear(); | 270 m_contentRuns.clear(); |
| 235 | 271 |
| 236 if (m_columnHeight == oldColumnHeight) | 272 if (m_columnHeight == oldColumnHeight) |
| 237 return false; // No change. We're done. | 273 return false; // No change. We're done. |
| 238 | 274 |
| 239 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); | 275 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 254 | 290 |
| 255 void RenderMultiColumnSet::resetColumnHeight() | 291 void RenderMultiColumnSet::resetColumnHeight() |
| 256 { | 292 { |
| 257 // Nuke previously stored minimum column height. Contents may have changed f or all we know. | 293 // Nuke previously stored minimum column height. Contents may have changed f or all we know. |
| 258 m_minimumColumnHeight = 0; | 294 m_minimumColumnHeight = 0; |
| 259 | 295 |
| 260 m_maxColumnHeight = calculateMaxColumnHeight(); | 296 m_maxColumnHeight = calculateMaxColumnHeight(); |
| 261 | 297 |
| 262 LayoutUnit oldColumnHeight = pageLogicalHeight(); | 298 LayoutUnit oldColumnHeight = pageLogicalHeight(); |
| 263 | 299 |
| 264 if (multiColumnFlowThread()->heightIsAuto()) | 300 if (heightIsAuto()) |
| 265 m_columnHeight = 0; | 301 m_columnHeight = 0; |
| 266 else | 302 else |
| 267 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); | 303 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); |
| 268 | 304 |
| 269 if (pageLogicalHeight() != oldColumnHeight) | 305 if (pageLogicalHeight() != oldColumnHeight) |
| 270 setChildNeedsLayout(MarkOnlyThis); | 306 setChildNeedsLayout(MarkOnlyThis); |
| 271 | 307 |
| 272 // Content runs are only needed in the initial layout pass, in order to find an initial column | 308 // Content runs are only needed in the initial layout pass, in order to find an initial column |
| 273 // height, and should have been deleted afterwards. We're about to rebuild t he content runs, so | 309 // height, and should have been deleted afterwards. We're about to rebuild t he content runs, so |
| 274 // the list needs to be empty. | 310 // the list needs to be empty. |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 | 664 |
| 629 void RenderMultiColumnSet::detachRegion() | 665 void RenderMultiColumnSet::detachRegion() |
| 630 { | 666 { |
| 631 if (m_flowThread) { | 667 if (m_flowThread) { |
| 632 m_flowThread->removeRegionFromThread(this); | 668 m_flowThread->removeRegionFromThread(this); |
| 633 m_flowThread = 0; | 669 m_flowThread = 0; |
| 634 } | 670 } |
| 635 } | 671 } |
| 636 | 672 |
| 637 } | 673 } |
| OLD | NEW |