| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/ColumnBalancer.h" | 5 #include "core/layout/ColumnBalancer.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutMultiColumnFlowThread.h" | 7 #include "core/layout/LayoutMultiColumnFlowThread.h" |
| 8 #include "core/layout/LayoutMultiColumnSet.h" | 8 #include "core/layout/LayoutMultiColumnSet.h" |
| 9 #include "core/layout/api/LineLayoutBlockFlow.h" | 9 #include "core/layout/api/LineLayoutBlockFlow.h" |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 break; | 45 break; |
| 46 examineLine(*line); | 46 examineLine(*line); |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 void ColumnBalancer::traverseChildren(const LayoutObject& object) { | 50 void ColumnBalancer::traverseChildren(const LayoutObject& object) { |
| 51 // The break-after value from the previous in-flow block-level object to be | 51 // The break-after value from the previous in-flow block-level object to be |
| 52 // joined with the break-before value of the next in-flow block-level sibling. | 52 // joined with the break-before value of the next in-flow block-level sibling. |
| 53 EBreak previousBreakAfterValue = BreakAuto; | 53 EBreak previousBreakAfterValue = BreakAuto; |
| 54 | 54 |
| 55 const LayoutFlowThread* flowThread = columnSet().flowThread(); | |
| 56 bool isHorizontalWritingMode = flowThread->isHorizontalWritingMode(); | |
| 57 | |
| 58 for (const LayoutObject* child = object.slowFirstChild(); child; | 55 for (const LayoutObject* child = object.slowFirstChild(); child; |
| 59 child = child->nextSibling()) { | 56 child = child->nextSibling()) { |
| 60 if (!child->isBox()) { | 57 if (!child->isBox()) { |
| 61 // Keep traversing inside inlines. There may be floats there. | 58 // Keep traversing inside inlines. There may be floats there. |
| 62 if (child->isLayoutInline()) | 59 if (child->isLayoutInline()) |
| 63 traverseChildren(*child); | 60 traverseChildren(*child); |
| 64 continue; | 61 continue; |
| 65 } | 62 } |
| 66 | 63 |
| 67 const LayoutBox& childBox = toLayoutBox(*child); | 64 const LayoutBox& childBox = toLayoutBox(*child); |
| 68 LayoutRect overflowRect = childBox.layoutOverflowRect(); | 65 |
| 69 LayoutUnit childLogicalBottomWithOverflow = | 66 LayoutUnit borderEdgeOffset; |
| 70 childBox.logicalTop() + | 67 LayoutUnit logicalTop = childBox.logicalTop(); |
| 71 (isHorizontalWritingMode ? overflowRect.maxY() : overflowRect.maxX()); | 68 LayoutUnit logicalHeight = childBox.logicalHeightWithVisibleOverflow(); |
| 72 if (m_flowThreadOffset + childLogicalBottomWithOverflow <= | 69 // Floats' margins don't collapse with column boundaries, and we don't want |
| 70 // to break inside them, or separate them from the float's border box. Set |
| 71 // the offset to the margin-before edge (rather than border-before edge), |
| 72 // and include the block direction margins in the child height. |
| 73 if (childBox.isFloating()) { |
| 74 LayoutUnit marginBefore = childBox.marginBefore(object.style()); |
| 75 LayoutUnit marginAfter = childBox.marginAfter(object.style()); |
| 76 logicalHeight = |
| 77 std::max(logicalHeight, childBox.logicalHeight() + marginAfter); |
| 78 logicalTop -= marginBefore; |
| 79 logicalHeight += marginBefore; |
| 80 |
| 81 // As soon as we want to process content inside this child, though, we |
| 82 // need to get to its border-before edge. |
| 83 borderEdgeOffset = marginBefore; |
| 84 } |
| 85 |
| 86 if (m_flowThreadOffset + logicalTop + logicalHeight <= |
| 73 logicalTopInFlowThread()) { | 87 logicalTopInFlowThread()) { |
| 74 // This child is fully above the flow thread portion we're examining. | 88 // This child is fully above the flow thread portion we're examining. |
| 75 continue; | 89 continue; |
| 76 } | 90 } |
| 77 LayoutUnit childLogicalTopWithOverflow = | 91 if (m_flowThreadOffset + logicalTop >= logicalBottomInFlowThread()) { |
| 78 childBox.logicalTop() + | |
| 79 (isHorizontalWritingMode ? overflowRect.y() : overflowRect.x()); | |
| 80 if (m_flowThreadOffset + childLogicalTopWithOverflow >= | |
| 81 logicalBottomInFlowThread()) { | |
| 82 // This child is fully below the flow thread portion we're examining. We | 92 // This child is fully below the flow thread portion we're examining. We |
| 83 // cannot just stop here, though, thanks to negative margins. | 93 // cannot just stop here, though, thanks to negative margins. |
| 84 // So keep looking. | 94 // So keep looking. |
| 85 continue; | 95 continue; |
| 86 } | 96 } |
| 87 if (childBox.isOutOfFlowPositioned() || childBox.isColumnSpanAll()) | 97 if (childBox.isOutOfFlowPositioned() || childBox.isColumnSpanAll()) |
| 88 continue; | 98 continue; |
| 89 | 99 |
| 90 // Tables are wicked. Both table rows and table cells are relative to their | 100 // Tables are wicked. Both table rows and table cells are relative to their |
| 91 // table section. | 101 // table section. |
| 92 LayoutUnit offsetForThisChild = | 102 LayoutUnit offsetForThisChild = |
| 93 childBox.isTableRow() ? LayoutUnit() : childBox.logicalTop(); | 103 childBox.isTableRow() ? LayoutUnit() : logicalTop; |
| 104 |
| 94 m_flowThreadOffset += offsetForThisChild; | 105 m_flowThreadOffset += offsetForThisChild; |
| 95 | 106 |
| 96 examineBoxAfterEntering(childBox, previousBreakAfterValue); | 107 examineBoxAfterEntering(childBox, logicalHeight, previousBreakAfterValue); |
| 97 // Unless the child is unsplittable, or if the child establishes an inner | 108 // Unless the child is unsplittable, or if the child establishes an inner |
| 98 // multicol container, we descend into its subtree for further examination. | 109 // multicol container, we descend into its subtree for further examination. |
| 99 if (childBox.getPaginationBreakability() != LayoutBox::ForbidBreaks && | 110 if (childBox.getPaginationBreakability() != LayoutBox::ForbidBreaks && |
| 100 (!childBox.isLayoutBlockFlow() || | 111 (!childBox.isLayoutBlockFlow() || |
| 101 !toLayoutBlockFlow(childBox).multiColumnFlowThread())) | 112 !toLayoutBlockFlow(childBox).multiColumnFlowThread())) { |
| 113 // We need to get to the border edge before processing content inside |
| 114 // this child. If the child is floated, we're currently at the margin |
| 115 // edge. |
| 116 m_flowThreadOffset += borderEdgeOffset; |
| 102 traverseSubtree(childBox); | 117 traverseSubtree(childBox); |
| 118 m_flowThreadOffset -= borderEdgeOffset; |
| 119 } |
| 103 previousBreakAfterValue = childBox.breakAfter(); | 120 previousBreakAfterValue = childBox.breakAfter(); |
| 104 examineBoxBeforeLeaving(childBox); | 121 examineBoxBeforeLeaving(childBox, logicalHeight); |
| 105 | 122 |
| 106 m_flowThreadOffset -= offsetForThisChild; | 123 m_flowThreadOffset -= offsetForThisChild; |
| 107 } | 124 } |
| 108 } | 125 } |
| 109 | 126 |
| 110 InitialColumnHeightFinder::InitialColumnHeightFinder( | 127 InitialColumnHeightFinder::InitialColumnHeightFinder( |
| 111 const LayoutMultiColumnSet& columnSet, | 128 const LayoutMultiColumnSet& columnSet, |
| 112 LayoutUnit logicalTopInFlowThread, | 129 LayoutUnit logicalTopInFlowThread, |
| 113 LayoutUnit logicalBottomInFlowThread) | 130 LayoutUnit logicalBottomInFlowThread) |
| 114 : ColumnBalancer(columnSet, | 131 : ColumnBalancer(columnSet, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 127 | 144 |
| 128 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const { | 145 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const { |
| 129 unsigned index = contentRunIndexWithTallestColumns(); | 146 unsigned index = contentRunIndexWithTallestColumns(); |
| 130 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() | 147 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() |
| 131 : logicalTopInFlowThread(); | 148 : logicalTopInFlowThread(); |
| 132 return m_contentRuns[index].columnLogicalHeight(startOffset); | 149 return m_contentRuns[index].columnLogicalHeight(startOffset); |
| 133 } | 150 } |
| 134 | 151 |
| 135 void InitialColumnHeightFinder::examineBoxAfterEntering( | 152 void InitialColumnHeightFinder::examineBoxAfterEntering( |
| 136 const LayoutBox& box, | 153 const LayoutBox& box, |
| 154 LayoutUnit childLogicalHeight, |
| 137 EBreak previousBreakAfterValue) { | 155 EBreak previousBreakAfterValue) { |
| 138 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { | 156 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { |
| 139 if (box.needsForcedBreakBefore(previousBreakAfterValue)) { | 157 if (box.needsForcedBreakBefore(previousBreakAfterValue)) { |
| 140 addContentRun(flowThreadOffset()); | 158 addContentRun(flowThreadOffset()); |
| 141 } else { | 159 } else { |
| 142 if (isFirstAfterBreak(flowThreadOffset())) { | 160 if (isFirstAfterBreak(flowThreadOffset())) { |
| 143 // This box is first after a soft break. | 161 // This box is first after a soft break. |
| 144 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); | 162 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); |
| 145 } | 163 } |
| 146 } | 164 } |
| 147 } | 165 } |
| 148 | 166 |
| 149 if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) { | 167 if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) { |
| 150 LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); | |
| 151 if (box.isFloating()) | |
| 152 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); | |
| 153 m_tallestUnbreakableLogicalHeight = | 168 m_tallestUnbreakableLogicalHeight = |
| 154 std::max(m_tallestUnbreakableLogicalHeight, unsplittableLogicalHeight); | 169 std::max(m_tallestUnbreakableLogicalHeight, childLogicalHeight); |
| 155 return; | 170 return; |
| 156 } | 171 } |
| 157 // Need to examine inner multicol containers to find their tallest unbreakable | 172 // Need to examine inner multicol containers to find their tallest unbreakable |
| 158 // piece of content. | 173 // piece of content. |
| 159 if (!box.isLayoutBlockFlow()) | 174 if (!box.isLayoutBlockFlow()) |
| 160 return; | 175 return; |
| 161 LayoutMultiColumnFlowThread* innerFlowThread = | 176 LayoutMultiColumnFlowThread* innerFlowThread = |
| 162 toLayoutBlockFlow(box).multiColumnFlowThread(); | 177 toLayoutBlockFlow(box).multiColumnFlowThread(); |
| 163 if (!innerFlowThread || innerFlowThread->isLayoutPagedFlowThread()) | 178 if (!innerFlowThread || innerFlowThread->isLayoutPagedFlowThread()) |
| 164 return; | 179 return; |
| 165 LayoutUnit offsetInInnerFlowThread = | 180 LayoutUnit offsetInInnerFlowThread = |
| 166 flowThreadOffset() - | 181 flowThreadOffset() - |
| 167 innerFlowThread->blockOffsetInEnclosingFragmentationContext(); | 182 innerFlowThread->blockOffsetInEnclosingFragmentationContext(); |
| 168 LayoutUnit innerUnbreakableHeight = | 183 LayoutUnit innerUnbreakableHeight = |
| 169 innerFlowThread->tallestUnbreakableLogicalHeight(offsetInInnerFlowThread); | 184 innerFlowThread->tallestUnbreakableLogicalHeight(offsetInInnerFlowThread); |
| 170 m_tallestUnbreakableLogicalHeight = | 185 m_tallestUnbreakableLogicalHeight = |
| 171 std::max(m_tallestUnbreakableLogicalHeight, innerUnbreakableHeight); | 186 std::max(m_tallestUnbreakableLogicalHeight, innerUnbreakableHeight); |
| 172 } | 187 } |
| 173 | 188 |
| 174 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) {} | 189 void InitialColumnHeightFinder::examineBoxBeforeLeaving( |
| 190 const LayoutBox& box, |
| 191 LayoutUnit childLogicalHeight) {} |
| 175 | 192 |
| 176 static inline LayoutUnit columnLogicalHeightRequirementForLine( | 193 static inline LayoutUnit columnLogicalHeightRequirementForLine( |
| 177 const ComputedStyle& style, | 194 const ComputedStyle& style, |
| 178 const RootInlineBox& lastLine) { | 195 const RootInlineBox& lastLine) { |
| 179 // We may require a certain minimum number of lines per page in order to | 196 // We may require a certain minimum number of lines per page in order to |
| 180 // satisfy orphans and widows, and that may affect the minimum page height. | 197 // satisfy orphans and widows, and that may affect the minimum page height. |
| 181 unsigned minimumLineCount = | 198 unsigned minimumLineCount = |
| 182 std::max<unsigned>(style.orphans(), style.widows()); | 199 std::max<unsigned>(style.orphans(), style.widows()); |
| 183 const RootInlineBox* firstLine = &lastLine; | 200 const RootInlineBox* firstLine = &lastLine; |
| 184 for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++) | 201 for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++) |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 logicalTopInFlowThread, | 306 logicalTopInFlowThread, |
| 290 logicalBottomInFlowThread), | 307 logicalBottomInFlowThread), |
| 291 m_minimumSpaceShortage(LayoutUnit::max()), | 308 m_minimumSpaceShortage(LayoutUnit::max()), |
| 292 m_pendingStrut(LayoutUnit::min()), | 309 m_pendingStrut(LayoutUnit::min()), |
| 293 m_forcedBreaksCount(0) { | 310 m_forcedBreaksCount(0) { |
| 294 traverse(); | 311 traverse(); |
| 295 } | 312 } |
| 296 | 313 |
| 297 void MinimumSpaceShortageFinder::examineBoxAfterEntering( | 314 void MinimumSpaceShortageFinder::examineBoxAfterEntering( |
| 298 const LayoutBox& box, | 315 const LayoutBox& box, |
| 316 LayoutUnit childLogicalHeight, |
| 299 EBreak previousBreakAfterValue) { | 317 EBreak previousBreakAfterValue) { |
| 300 LayoutBox::PaginationBreakability breakability = | 318 LayoutBox::PaginationBreakability breakability = |
| 301 box.getPaginationBreakability(); | 319 box.getPaginationBreakability(); |
| 302 | 320 |
| 303 // Look for breaks before the child box. | 321 // Look for breaks before the child box. |
| 304 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { | 322 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { |
| 305 if (box.needsForcedBreakBefore(previousBreakAfterValue)) { | 323 if (box.needsForcedBreakBefore(previousBreakAfterValue)) { |
| 306 m_forcedBreaksCount++; | 324 m_forcedBreaksCount++; |
| 307 } else { | 325 } else { |
| 308 if (isFirstAfterBreak(flowThreadOffset())) { | 326 if (isFirstAfterBreak(flowThreadOffset())) { |
| 309 // This box is first after a soft break. | 327 // This box is first after a soft break. |
| 310 LayoutUnit strut = box.paginationStrut(); | 328 LayoutUnit strut = box.paginationStrut(); |
| 311 // Figure out how much more space we would need to prevent it from being | 329 // Figure out how much more space we would need to prevent it from being |
| 312 // pushed to the next column. | 330 // pushed to the next column. |
| 313 recordSpaceShortage(box.logicalHeight() - strut); | 331 recordSpaceShortage(childLogicalHeight - strut); |
| 314 if (breakability != LayoutBox::ForbidBreaks && | 332 if (breakability != LayoutBox::ForbidBreaks && |
| 315 m_pendingStrut == LayoutUnit::min()) { | 333 m_pendingStrut == LayoutUnit::min()) { |
| 316 // We now want to look for the first piece of unbreakable content | 334 // We now want to look for the first piece of unbreakable content |
| 317 // (e.g. a line or a block-displayed image) inside this block. That | 335 // (e.g. a line or a block-displayed image) inside this block. That |
| 318 // ought to be a good candidate for minimum space shortage; a much | 336 // ought to be a good candidate for minimum space shortage; a much |
| 319 // better one than reporting space shortage for the entire block | 337 // better one than reporting space shortage for the entire block |
| 320 // (which we'll also do (further down), in case we couldn't find | 338 // (which we'll also do (further down), in case we couldn't find |
| 321 // anything more suitable). | 339 // anything more suitable). |
| 322 m_pendingStrut = strut; | 340 m_pendingStrut = strut; |
| 323 } | 341 } |
| 324 } | 342 } |
| 325 } | 343 } |
| 326 } | 344 } |
| 327 | 345 |
| 328 if (breakability != LayoutBox::ForbidBreaks) { | 346 if (breakability != LayoutBox::ForbidBreaks) { |
| 329 // See if this breakable box crosses column boundaries. | 347 // See if this breakable box crosses column boundaries. |
| 330 LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight(); | 348 LayoutUnit bottomInFlowThread = flowThreadOffset() + childLogicalHeight; |
| 331 const MultiColumnFragmentainerGroup& group = | 349 const MultiColumnFragmentainerGroup& group = |
| 332 groupAtOffset(flowThreadOffset()); | 350 groupAtOffset(flowThreadOffset()); |
| 333 if (isFirstAfterBreak(flowThreadOffset()) || | 351 if (isFirstAfterBreak(flowThreadOffset()) || |
| 334 group.columnLogicalTopForOffset(flowThreadOffset()) != | 352 group.columnLogicalTopForOffset(flowThreadOffset()) != |
| 335 group.columnLogicalTopForOffset(bottomInFlowThread)) { | 353 group.columnLogicalTopForOffset(bottomInFlowThread)) { |
| 336 // If the child crosses a column boundary, record space shortage, in case | 354 // If the child crosses a column boundary, record space shortage, in case |
| 337 // nothing inside it has already done so. The column balancer needs to | 355 // nothing inside it has already done so. The column balancer needs to |
| 338 // know by how much it has to stretch the columns to make more content | 356 // know by how much it has to stretch the columns to make more content |
| 339 // fit. If no breaks are reported (but do occur), the balancer will have | 357 // fit. If no breaks are reported (but do occur), the balancer will have |
| 340 // no clue. Only measure the space after the last column boundary, in case | 358 // no clue. Only measure the space after the last column boundary, in case |
| (...skipping 19 matching lines...) Expand all Loading... |
| 360 // multicol container. We need to let it walk through all fragmentainer | 378 // multicol container. We need to let it walk through all fragmentainer |
| 361 // groups in one go, or we'd miss the column boundaries between each | 379 // groups in one go, or we'd miss the column boundaries between each |
| 362 // fragmentainer group. We need to record space shortage there too. | 380 // fragmentainer group. We need to record space shortage there too. |
| 363 MinimumSpaceShortageFinder innerFinder( | 381 MinimumSpaceShortageFinder innerFinder( |
| 364 *columnSet, columnSet->logicalTopInFlowThread(), | 382 *columnSet, columnSet->logicalTopInFlowThread(), |
| 365 columnSet->logicalBottomInFlowThread()); | 383 columnSet->logicalBottomInFlowThread()); |
| 366 recordSpaceShortage(innerFinder.minimumSpaceShortage()); | 384 recordSpaceShortage(innerFinder.minimumSpaceShortage()); |
| 367 } | 385 } |
| 368 } | 386 } |
| 369 | 387 |
| 370 void MinimumSpaceShortageFinder::examineBoxBeforeLeaving(const LayoutBox& box) { | 388 void MinimumSpaceShortageFinder::examineBoxBeforeLeaving( |
| 389 const LayoutBox& box, |
| 390 LayoutUnit childLogicalHeight) { |
| 371 if (m_pendingStrut == LayoutUnit::min() || | 391 if (m_pendingStrut == LayoutUnit::min() || |
| 372 box.getPaginationBreakability() != LayoutBox::ForbidBreaks) | 392 box.getPaginationBreakability() != LayoutBox::ForbidBreaks) |
| 373 return; | 393 return; |
| 374 | 394 |
| 375 // The previous break was before a breakable block. Here's the first piece of | 395 // The previous break was before a breakable block. Here's the first piece of |
| 376 // unbreakable content after / inside that block. We want to record the | 396 // unbreakable content after / inside that block. We want to record the |
| 377 // distance from the top of the column to the bottom of this box as space | 397 // distance from the top of the column to the bottom of this box as space |
| 378 // shortage. | 398 // shortage. |
| 379 LayoutUnit logicalOffsetFromCurrentColumn = | 399 LayoutUnit logicalOffsetFromCurrentColumn = |
| 380 offsetFromColumnLogicalTop(flowThreadOffset()); | 400 offsetFromColumnLogicalTop(flowThreadOffset()); |
| 381 recordSpaceShortage(logicalOffsetFromCurrentColumn + box.logicalHeight() - | 401 recordSpaceShortage(logicalOffsetFromCurrentColumn + childLogicalHeight - |
| 382 m_pendingStrut); | 402 m_pendingStrut); |
| 383 m_pendingStrut = LayoutUnit::min(); | 403 m_pendingStrut = LayoutUnit::min(); |
| 384 } | 404 } |
| 385 | 405 |
| 386 void MinimumSpaceShortageFinder::examineLine(const RootInlineBox& line) { | 406 void MinimumSpaceShortageFinder::examineLine(const RootInlineBox& line) { |
| 387 LayoutUnit lineTop = line.lineTopWithLeading(); | 407 LayoutUnit lineTop = line.lineTopWithLeading(); |
| 388 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; | 408 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; |
| 389 LayoutUnit lineHeight = line.lineBottomWithLeading() - lineTop; | 409 LayoutUnit lineHeight = line.lineBottomWithLeading() - lineTop; |
| 390 if (m_pendingStrut != LayoutUnit::min()) { | 410 if (m_pendingStrut != LayoutUnit::min()) { |
| 391 // The previous break was before a breakable block. Here's the first line | 411 // The previous break was before a breakable block. Here's the first line |
| (...skipping 23 matching lines...) Expand all Loading... |
| 415 if (group.columnLogicalTopForOffset(lineTopInFlowThread) != | 435 if (group.columnLogicalTopForOffset(lineTopInFlowThread) != |
| 416 group.columnLogicalTopForOffset(lineBottomWithOverflow)) { | 436 group.columnLogicalTopForOffset(lineBottomWithOverflow)) { |
| 417 LayoutUnit shortage = | 437 LayoutUnit shortage = |
| 418 lineBottomWithOverflow - | 438 lineBottomWithOverflow - |
| 419 group.columnLogicalTopForOffset(lineBottomWithOverflow); | 439 group.columnLogicalTopForOffset(lineBottomWithOverflow); |
| 420 recordSpaceShortage(shortage); | 440 recordSpaceShortage(shortage); |
| 421 } | 441 } |
| 422 } | 442 } |
| 423 | 443 |
| 424 } // namespace blink | 444 } // namespace blink |
| OLD | NEW |