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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 { | 77 { |
| 78 RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); | 78 RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); |
| 79 LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore(); | 79 LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore(); |
| 80 | 80 |
| 81 height -= contentLogicalTop; | 81 height -= contentLogicalTop; |
| 82 return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created. | 82 return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created. |
| 83 } | 83 } |
| 84 | 84 |
| 85 LayoutUnit RenderMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) cons t | 85 LayoutUnit RenderMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) cons t |
| 86 { | 86 { |
| 87 LayoutUnit portionLogicalTop = (isHorizontalWritingMode() ? flowThreadPortio nRect().y() : flowThreadPortionRect().x()); | |
| 88 unsigned columnIndex = columnIndexAtOffset(offset, AssumeNewColumns); | 87 unsigned columnIndex = columnIndexAtOffset(offset, AssumeNewColumns); |
| 89 return portionLogicalTop + columnIndex * computedColumnHeight(); | 88 return logicalTopInFlowThread() + columnIndex * computedColumnHeight(); |
| 90 } | 89 } |
| 91 | 90 |
| 92 void RenderMultiColumnSet::setAndConstrainColumnHeight(LayoutUnit newHeight) | 91 void RenderMultiColumnSet::setAndConstrainColumnHeight(LayoutUnit newHeight) |
| 93 { | 92 { |
| 94 m_computedColumnHeight = newHeight; | 93 m_computedColumnHeight = newHeight; |
| 95 if (m_computedColumnHeight > m_maxColumnHeight) | 94 if (m_computedColumnHeight > m_maxColumnHeight) |
| 96 m_computedColumnHeight = m_maxColumnHeight; | 95 m_computedColumnHeight = m_maxColumnHeight; |
| 97 // FIXME: the height may also be affected by the enclosing pagination contex t, if any. | 96 // FIXME: the height may also be affected by the enclosing pagination contex t, if any. |
| 98 } | 97 } |
| 99 | 98 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 } | 198 } |
| 200 LayoutUnit newColumnHeight = calculateColumnHeight(initial); | 199 LayoutUnit newColumnHeight = calculateColumnHeight(initial); |
| 201 setAndConstrainColumnHeight(newColumnHeight); | 200 setAndConstrainColumnHeight(newColumnHeight); |
| 202 | 201 |
| 203 // After having calculated an initial column height, the multicol container typically needs at | 202 // After having calculated an initial column height, the multicol container typically needs at |
| 204 // least one more layout pass with a new column height, but if a height was specified, we only | 203 // least one more layout pass with a new column height, but if a height was specified, we only |
| 205 // need to do this if we think that we need less space than specified. Conve rsely, if we | 204 // need to do this if we think that we need less space than specified. Conve rsely, if we |
| 206 // determined that the columns need to be as tall as the specified height of the container, we | 205 // determined that the columns need to be as tall as the specified height of the container, we |
| 207 // have already laid it out correctly, and there's no need for another pass. | 206 // have already laid it out correctly, and there's no need for another pass. |
| 208 | 207 |
| 208 // We can get rid of the content runs now, if we haven't already done so. Th ey are only needed | |
| 209 // to calculate the initial balanced column height. In fact, we have to get rid of them before | |
| 210 // the next layout pass, since each pass will rebuild this. | |
| 211 m_contentRuns.clear(); | |
| 212 | |
| 209 if (m_computedColumnHeight == oldColumnHeight) | 213 if (m_computedColumnHeight == oldColumnHeight) |
| 210 return false; // No change. We're done. | 214 return false; // No change. We're done. |
| 211 | 215 |
| 212 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); | 216 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); |
| 213 m_contentRuns.clear(); | |
| 214 return true; // Need another pass. | 217 return true; // Need another pass. |
| 215 } | 218 } |
| 216 | 219 |
| 217 void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage) | 220 void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage) |
| 218 { | 221 { |
| 219 if (spaceShortage >= m_minSpaceShortage) | 222 if (spaceShortage >= m_minSpaceShortage) |
| 220 return; | 223 return; |
| 221 | 224 |
| 222 // The space shortage is what we use as our stretch amount. We need a positi ve number here in | 225 // The space shortage is what we use as our stretch amount. We need a positi ve number here in |
| 223 // order to get anywhere. | 226 // order to get anywhere. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 241 LayoutUnit minimumContentLogicalWidth = colCount * computedColumnWidth() + ( colCount - 1) * colGap; | 244 LayoutUnit minimumContentLogicalWidth = colCount * computedColumnWidth() + ( colCount - 1) * colGap; |
| 242 LayoutUnit currentContentLogicalWidth = contentLogicalWidth(); | 245 LayoutUnit currentContentLogicalWidth = contentLogicalWidth(); |
| 243 LayoutUnit delta = max(LayoutUnit(), minimumContentLogicalWidth - currentCon tentLogicalWidth); | 246 LayoutUnit delta = max(LayoutUnit(), minimumContentLogicalWidth - currentCon tentLogicalWidth); |
| 244 if (!delta) | 247 if (!delta) |
| 245 return; | 248 return; |
| 246 | 249 |
| 247 // Increase our logical width by the delta. | 250 // Increase our logical width by the delta. |
| 248 setLogicalWidth(logicalWidth() + delta); | 251 setLogicalWidth(logicalWidth() + delta); |
| 249 } | 252 } |
| 250 | 253 |
| 251 void RenderMultiColumnSet::prepareForLayout() | 254 void RenderMultiColumnSet::prepareForLayout(bool initial) |
|
Julien - ping for review
2014/05/20 17:03:04
We should replace the first-pass boolean logic wit
mstensho (USE GERRIT)
2014/05/22 15:07:18
Done.
I did the second best thing - removed the p
| |
| 252 { | 255 { |
| 253 RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); | 256 RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); |
| 254 RenderStyle* multicolStyle = multicolBlock->style(); | |
| 255 | 257 |
| 256 // Set box logical top. | 258 // Set box logical top. |
| 257 ASSERT(!previousSiblingBox() || !previousSiblingBox()->isRenderMultiColumnSe t()); // FIXME: multiple set not implemented; need to examine previous set to ca lculate the correct logical top. | 259 ASSERT(!previousSiblingBox() || !previousSiblingBox()->isRenderMultiColumnSe t()); // FIXME: multiple set not implemented; need to examine previous set to ca lculate the correct logical top. |
| 258 setLogicalTop(multicolBlock->borderBefore() + multicolBlock->paddingBefore() ); | 260 setLogicalTop(multicolBlock->borderAndPaddingBefore()); |
| 259 | 261 |
| 260 // Set box width. | 262 if (initial) { |
| 261 updateLogicalWidth(); | 263 m_maxColumnHeight = calculateMaxColumnHeight(); |
| 262 | 264 updateLogicalWidth(); |
|
Julien - ping for review
2014/05/20 17:03:04
It's weird that prepareForLayout actually does wha
mstensho (USE GERRIT)
2014/05/22 15:07:18
Done.
All it really needed from updateLogicalWidt
| |
| 265 } | |
| 263 if (multiColumnFlowThread()->requiresBalancing()) { | 266 if (multiColumnFlowThread()->requiresBalancing()) { |
| 264 // Set maximum column height. We will not stretch beyond this. | 267 if (initial) |
| 265 m_maxColumnHeight = RenderFlowThread::maxLogicalHeight(); | 268 m_computedColumnHeight = 0; |
| 266 if (!multicolStyle->logicalHeight().isAuto()) { | |
| 267 m_maxColumnHeight = multicolBlock->computeContentLogicalHeight(multi colStyle->logicalHeight(), -1); | |
| 268 if (m_maxColumnHeight == -1) | |
| 269 m_maxColumnHeight = RenderFlowThread::maxLogicalHeight(); | |
| 270 } | |
| 271 if (!multicolStyle->logicalMaxHeight().isUndefined()) { | |
| 272 LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHe ight(multicolStyle->logicalMaxHeight(), -1); | |
| 273 if (logicalMaxHeight != -1 && m_maxColumnHeight > logicalMaxHeight) | |
| 274 m_maxColumnHeight = logicalMaxHeight; | |
| 275 } | |
| 276 m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight); | |
| 277 m_computedColumnHeight = 0; // Restart balancing. | |
| 278 } else { | 269 } else { |
| 279 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); | 270 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); |
| 280 } | 271 } |
| 281 | 272 |
| 282 m_contentRuns.clear(); | 273 // Content runs are only needed in the initial layout pass, in order to find an initial column |
| 274 // height, and should have been deleted afterwards. We're about to rebuild t he content runs, so | |
| 275 // the list needs to be empty. | |
| 276 ASSERT(m_contentRuns.isEmpty()); | |
| 283 | 277 |
| 284 // Nuke previously stored minimum column height. Contents may have changed f or all we know. | 278 // Nuke previously stored minimum column height. Contents may have changed f or all we know. |
| 285 m_minimumColumnHeight = 0; | 279 m_minimumColumnHeight = 0; |
| 280 | |
| 281 setNeedsLayoutAndFullRepaint(); | |
|
Julien - ping for review
2014/05/20 17:03:04
There is no branch in prepareForLayout, which mean
mstensho (USE GERRIT)
2014/05/21 09:02:33
No, that looks very unnecessary, apart from being
mstensho (USE GERRIT)
2014/05/22 15:07:18
Done.
We now call setChildNeedsLayout(MarkOnlyThi
| |
| 286 } | 282 } |
| 287 | 283 |
| 288 void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded() | 284 void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded() |
| 289 { | 285 { |
| 290 ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this); | 286 ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this); |
| 291 LayoutRect rect(flowThreadPortionRect()); | 287 LayoutRect rect(flowThreadPortionRect()); |
| 292 | 288 |
| 293 // Get the offset within the flow thread in its block progression direction. Then get the | 289 // Get the offset within the flow thread in its block progression direction. Then get the |
| 294 // flow thread's remaining logical height including its overflow and expand our rect | 290 // flow thread's remaining logical height including its overflow and expand our rect |
| 295 // to encompass that remaining height and overflow. The idea is that we will generate | 291 // to encompass that remaining height and overflow. The idea is that we will generate |
| 296 // additional columns and pages to hold that overflow, since people do write bad | 292 // additional columns and pages to hold that overflow, since people do write bad |
| 297 // content like <body style="height:0px"> in multi-column layouts. | 293 // content like <body style="height:0px"> in multi-column layouts. |
| 298 bool isHorizontal = flowThread()->isHorizontalWritingMode(); | 294 bool isHorizontal = flowThread()->isHorizontalWritingMode(); |
| 299 LayoutUnit logicalTopOffset = isHorizontal ? rect.y() : rect.x(); | 295 LayoutUnit logicalTopOffset = isHorizontal ? rect.y() : rect.x(); |
| 300 LayoutRect layoutRect = flowThread()->layoutOverflowRect(); | 296 LayoutRect layoutRect = flowThread()->layoutOverflowRect(); |
| 301 LayoutUnit logicalHeightWithOverflow = (isHorizontal ? layoutRect.maxY() : l ayoutRect.maxX()) - logicalTopOffset; | 297 LayoutUnit logicalHeightWithOverflow = (isHorizontal ? layoutRect.maxY() : l ayoutRect.maxX()) - logicalTopOffset; |
| 302 setFlowThreadPortionRect(LayoutRect(rect.x(), rect.y(), isHorizontal ? rect. width() : logicalHeightWithOverflow, isHorizontal ? logicalHeightWithOverflow : rect.height())); | 298 setFlowThreadPortionRect(LayoutRect(rect.x(), rect.y(), isHorizontal ? rect. width() : logicalHeightWithOverflow, isHorizontal ? logicalHeightWithOverflow : rect.height())); |
| 303 } | 299 } |
| 304 | 300 |
| 305 void RenderMultiColumnSet::layout() | 301 void RenderMultiColumnSet::layout() |
| 306 { | 302 { |
| 307 RenderRegion::layout(); | 303 RenderRegion::layout(); |
| 308 | 304 |
| 309 if (!nextSiblingMultiColumnSet()) { | 305 // At this point the logical top of the column set is known. Update maximum column height |
| 310 // This is the last set, i.e. the last region. Seize the opportunity to validate them. | 306 // (multicol height may be constrained, and in order to calculate it, we nee d to know our top). |
| 311 multiColumnFlowThread()->validateRegions(); | 307 m_maxColumnHeight = calculateMaxColumnHeight(); |
| 312 } | |
| 313 } | 308 } |
| 314 | 309 |
| 315 void RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTo p, LogicalExtentComputedValues& computedValues) const | 310 void RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTo p, LogicalExtentComputedValues& computedValues) const |
| 316 { | 311 { |
| 317 computedValues.m_extent = m_computedColumnHeight; | 312 computedValues.m_extent = m_computedColumnHeight; |
| 318 computedValues.m_position = logicalTop; | 313 computedValues.m_position = logicalTop; |
| 319 } | 314 } |
| 320 | 315 |
| 316 LayoutUnit RenderMultiColumnSet::calculateMaxColumnHeight() const | |
| 317 { | |
| 318 RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); | |
| 319 RenderStyle* multicolStyle = multicolBlock->style(); | |
| 320 LayoutUnit availableHeight = multiColumnFlowThread()->columnHeightAvailable( ); | |
| 321 LayoutUnit maxColumnHeight = availableHeight ? availableHeight : RenderFlowT hread::maxLogicalHeight(); | |
| 322 if (!multicolStyle->logicalMaxHeight().isUndefined()) { | |
| 323 LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight (multicolStyle->logicalMaxHeight(), -1); | |
| 324 if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight) | |
| 325 maxColumnHeight = logicalMaxHeight; | |
| 326 } | |
| 327 return heightAdjustedForSetOffset(maxColumnHeight); | |
| 328 } | |
| 329 | |
| 321 LayoutUnit RenderMultiColumnSet::columnGap() const | 330 LayoutUnit RenderMultiColumnSet::columnGap() const |
| 322 { | 331 { |
| 323 RenderBlockFlow* parentBlock = multiColumnBlockFlow(); | 332 RenderBlockFlow* parentBlock = multiColumnBlockFlow(); |
| 324 if (parentBlock->style()->hasNormalColumnGap()) | 333 if (parentBlock->style()->hasNormalColumnGap()) |
| 325 return parentBlock->style()->fontDescription().computedPixelSize(); // " 1em" is recommended as the normal gap setting. Matches <p> margins. | 334 return parentBlock->style()->fontDescription().computedPixelSize(); // " 1em" is recommended as the normal gap setting. Matches <p> margins. |
| 326 return parentBlock->style()->columnGap(); | 335 return parentBlock->style()->columnGap(); |
| 327 } | 336 } |
| 328 | 337 |
| 329 unsigned RenderMultiColumnSet::columnCount() const | 338 unsigned RenderMultiColumnSet::columnCount() const |
| 330 { | 339 { |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 630 fragments.append(fragment); | 639 fragments.append(fragment); |
| 631 } | 640 } |
| 632 } | 641 } |
| 633 | 642 |
| 634 const char* RenderMultiColumnSet::renderName() const | 643 const char* RenderMultiColumnSet::renderName() const |
| 635 { | 644 { |
| 636 return "RenderMultiColumnSet"; | 645 return "RenderMultiColumnSet"; |
| 637 } | 646 } |
| 638 | 647 |
| 639 } | 648 } |
| OLD | NEW |