Chromium Code Reviews| 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 "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "core/layout/MultiColumnFragmentainerGroup.h" | 7 #include "core/layout/MultiColumnFragmentainerGroup.h" |
| 8 | 8 |
| 9 #include "core/layout/LayoutMultiColumnSet.h" | 9 #include "core/layout/LayoutMultiColumnSet.h" |
| 10 | 10 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 // the flow thread, but note that it has been converted with respect to writ ing mode (so that | 181 // the flow thread, but note that it has been converted with respect to writ ing mode (so that |
| 182 // it's visual/physical in that sense). | 182 // it's visual/physical in that sense). |
| 183 // | 183 // |
| 184 // |dirtyRect| is visual, relative to the multicol container. | 184 // |dirtyRect| is visual, relative to the multicol container. |
| 185 // | 185 // |
| 186 // Then there's the output from this method - the stuff we put into the list of fragments. The | 186 // Then there's the output from this method - the stuff we put into the list of fragments. The |
| 187 // fragment.paginationOffset point is the actual visual translation required to get from a | 187 // fragment.paginationOffset point is the actual visual translation required to get from a |
| 188 // location in the flow thread to a location in a given column. The fragment .paginationClip | 188 // location in the flow thread to a location in a given column. The fragment .paginationClip |
| 189 // rectangle, on the other hand, is in flow thread coordinates, but otherwis e completely | 189 // rectangle, on the other hand, is in flow thread coordinates, but otherwis e completely |
| 190 // physical in terms of writing mode. | 190 // physical in terms of writing mode. |
| 191 // | |
| 192 // All other rectangles in this method are sized physically, and the inline direction coordinate | |
| 193 // is physical too, but the block direction coordinate is "logical top". Thi s is the same as | |
| 194 // e.g. LayoutBox::frameRect(). These rectangles also pretend that there's o nly one long column, | |
| 195 // i.e. they are for the flow thread. | |
| 196 | 191 |
| 197 LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread( ); | 192 LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread( ); |
| 198 bool isHorizontalWritingMode = m_columnSet.isHorizontalWritingMode(); | 193 bool isHorizontalWritingMode = m_columnSet.isHorizontalWritingMode(); |
| 199 | 194 |
| 200 // Put the layer bounds into flow thread-local coordinates by flipping it fi rst. Since we're in | 195 // Put the layer bounds into flow thread-local coordinates by flipping it fi rst. Since we're in |
| 201 // a layoutObject, most rectangles are represented this way. | 196 // a layoutObject, most rectangles are represented this way. |
| 202 LayoutRect layerBoundsInFlowThread(layerBoundingBox); | 197 LayoutRect layerBoundsInFlowThread(layerBoundingBox); |
| 203 flowThread->flipForWritingMode(layerBoundsInFlowThread); | 198 flowThread->flipForWritingMode(layerBoundsInFlowThread); |
| 204 | 199 |
| 205 // Now we can compare with the flow thread portions owned by each column. Fi rst let's | 200 // Now we can compare with the flow thread portions owned by each column. Fi rst let's |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 223 unsigned firstColumnInDirtyRect, lastColumnInDirtyRect; | 218 unsigned firstColumnInDirtyRect, lastColumnInDirtyRect; |
| 224 columnIntervalForVisualRect(dirtyRect, firstColumnInDirtyRect, lastColumnInD irtyRect); | 219 columnIntervalForVisualRect(dirtyRect, firstColumnInDirtyRect, lastColumnInD irtyRect); |
| 225 if (firstColumnInDirtyRect > endColumn || lastColumnInDirtyRect < startColum n) | 220 if (firstColumnInDirtyRect > endColumn || lastColumnInDirtyRect < startColum n) |
| 226 return; // The two column intervals are disjoint. There's nothing to col lect. | 221 return; // The two column intervals are disjoint. There's nothing to col lect. |
| 227 if (startColumn < firstColumnInDirtyRect) | 222 if (startColumn < firstColumnInDirtyRect) |
| 228 startColumn = firstColumnInDirtyRect; | 223 startColumn = firstColumnInDirtyRect; |
| 229 if (endColumn > lastColumnInDirtyRect) | 224 if (endColumn > lastColumnInDirtyRect) |
| 230 endColumn = lastColumnInDirtyRect; | 225 endColumn = lastColumnInDirtyRect; |
| 231 ASSERT(endColumn >= startColumn); | 226 ASSERT(endColumn >= startColumn); |
| 232 | 227 |
| 233 LayoutUnit colLogicalWidth = m_columnSet.pageLogicalWidth(); | 228 for (unsigned i = startColumn; i <= endColumn; i++) { |
| 234 LayoutUnit colGap = m_columnSet.columnGap(); | 229 DeprecatedPaintLayerFragment fragment; |
| 235 unsigned colCount = actualColumnCount(); | |
| 236 | 230 |
| 237 bool progressionIsInline = flowThread->progressionIsInline(); | 231 // Set the physical translation offset. |
| 238 bool leftToRight = m_columnSet.style()->isLeftToRightDirection(); | 232 fragment.paginationOffset = toLayoutPoint(flowThreadTranslationAtOffset( logicalTopInFlowThreadAt(i))); |
| 239 | 233 |
| 240 LayoutUnit initialBlockOffset = m_columnSet.logicalTop() + logicalTop() - fl owThread->logicalTop(); | 234 // Set the overflow clip rect that corresponds to the column. |
| 235 fragment.paginationClip = flowThreadPortionOverflowRectAt(i); | |
| 236 // Flip it into more a physical (DeprecatedPaintLayer-style) rectangle. | |
| 237 flowThread->flipForWritingMode(fragment.paginationClip); | |
| 241 | 238 |
| 242 for (unsigned i = startColumn; i <= endColumn; i++) { | |
| 243 // Get the portion of the flow thread that corresponds to this column. | |
|
leviw_travelin_and_unemployed
2015/07/28 18:48:38
Wow. That's a lot of code to remove.
| |
| 244 LayoutRect flowThreadPortion = flowThreadPortionRectAt(i); | |
| 245 | |
| 246 // Now get the overflow rect that corresponds to the column. | |
| 247 LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flo wThreadPortion, i, colCount, colGap); | |
| 248 | |
| 249 LayoutPoint translationOffset; | |
| 250 LayoutUnit inlineOffset = progressionIsInline ? i * (colLogicalWidth + c olGap) : LayoutUnit(); | |
| 251 if (!leftToRight) | |
| 252 inlineOffset = -inlineOffset; | |
| 253 translationOffset.setX(inlineOffset); | |
| 254 LayoutUnit blockOffset; | |
| 255 if (progressionIsInline) { | |
| 256 blockOffset = initialBlockOffset + (isHorizontalWritingMode ? -flowT hreadPortion.y() : -flowThreadPortion.x()); | |
| 257 } else { | |
| 258 // Column gap can apply in the block direction for page fragmentaine rs. | |
| 259 // There is currently no spec which calls for column-gap to apply | |
| 260 // for page fragmentainers at all, but it's applied here for compati bility | |
| 261 // with the old multicolumn implementation. | |
| 262 blockOffset = i * colGap; | |
| 263 } | |
| 264 if (isFlippedBlocksWritingMode(m_columnSet.style()->writingMode())) | |
| 265 blockOffset = -blockOffset; | |
| 266 translationOffset.setY(blockOffset); | |
| 267 if (!isHorizontalWritingMode) | |
| 268 translationOffset = translationOffset.transposedPoint(); | |
| 269 | |
| 270 // Make a fragment now and supply the physical translation offset and th e clip rect for the | |
| 271 // column with that offset applied. | |
| 272 DeprecatedPaintLayerFragment fragment; | |
| 273 fragment.paginationOffset = translationOffset; | |
| 274 | |
| 275 LayoutRect flippedFlowThreadOverflowPortion(flowThreadOverflowPortion); | |
| 276 // Flip it into more a physical (DeprecatedPaintLayer-style) rectangle. | |
| 277 flowThread->flipForWritingMode(flippedFlowThreadOverflowPortion); | |
| 278 fragment.paginationClip = flippedFlowThreadOverflowPortion; | |
| 279 fragments.append(fragment); | 239 fragments.append(fragment); |
| 280 } | 240 } |
| 281 } | 241 } |
| 282 | 242 |
| 283 LayoutRect MultiColumnFragmentainerGroup::calculateOverflow() const | 243 LayoutRect MultiColumnFragmentainerGroup::calculateOverflow() const |
| 284 { | 244 { |
| 285 unsigned columnCount = actualColumnCount(); | 245 unsigned columnCount = actualColumnCount(); |
| 286 if (!columnCount) | 246 if (!columnCount) |
| 287 return LayoutRect(); | 247 return LayoutRect(); |
| 288 return columnRectAt(columnCount - 1); | 248 return columnRectAt(columnCount - 1); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 ASSERT(columnIndex + 1 == actualColumnCount()); | 432 ASSERT(columnIndex + 1 == actualColumnCount()); |
| 473 logicalBottom = logicalBottomInFlowThread(); | 433 logicalBottom = logicalBottomInFlowThread(); |
| 474 ASSERT(logicalBottom >= logicalTop); | 434 ASSERT(logicalBottom >= logicalTop); |
| 475 } | 435 } |
| 476 LayoutUnit portionLogicalHeight = logicalBottom - logicalTop; | 436 LayoutUnit portionLogicalHeight = logicalBottom - logicalTop; |
| 477 if (m_columnSet.isHorizontalWritingMode()) | 437 if (m_columnSet.isHorizontalWritingMode()) |
| 478 return LayoutRect(LayoutUnit(), logicalTop, m_columnSet.pageLogicalWidth (), portionLogicalHeight); | 438 return LayoutRect(LayoutUnit(), logicalTop, m_columnSet.pageLogicalWidth (), portionLogicalHeight); |
| 479 return LayoutRect(logicalTop, LayoutUnit(), portionLogicalHeight, m_columnSe t.pageLogicalWidth()); | 439 return LayoutRect(logicalTop, LayoutUnit(), portionLogicalHeight, m_columnSe t.pageLogicalWidth()); |
| 480 } | 440 } |
| 481 | 441 |
| 482 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRect(const La youtRect& portionRect, unsigned columnIndex, unsigned columnCount, LayoutUnit co lumnGap) const | 442 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRectAt(unsign ed columnIndex) const |
|
leviw_travelin_and_unemployed
2015/07/28 18:48:38
That's way nicer :)
| |
| 483 { | 443 { |
| 484 // This function determines the portion of the flow thread that paints for t he column. Along the inline axis, columns are | 444 // This function determines the portion of the flow thread that paints for t he column. Along the inline axis, columns are |
| 485 // unclipped at outside edges (i.e., the first and last column in the set), and they clip to half the column | 445 // unclipped at outside edges (i.e., the first and last column in the set), and they clip to half the column |
| 486 // gap along interior edges. | 446 // gap along interior edges. |
| 487 // | 447 // |
| 488 // In the block direction, we will not clip overflow out of the top of the f irst column, or out of the bottom of | 448 // In the block direction, we will not clip overflow out of the top of the f irst column, or out of the bottom of |
| 489 // the last column. This applies only to the true first column and last colu mn across all column sets. | 449 // the last column. This applies only to the true first column and last colu mn across all column sets. |
| 490 // | 450 // |
| 491 // FIXME: Eventually we will know overflow on a per-column basis, but we can 't do this until we have a painting | 451 // FIXME: Eventually we will know overflow on a per-column basis, but we can 't do this until we have a painting |
| 492 // mode that understands not to paint contents from a previous column in the overflow area of a following column. | 452 // mode that understands not to paint contents from a previous column in the overflow area of a following column. |
| 493 bool isFirstColumn = !columnIndex; | 453 bool isFirstColumn = !columnIndex; |
| 494 bool isLastColumn = columnIndex == columnCount - 1; | 454 bool isLastColumn = columnIndex == actualColumnCount() - 1; |
| 495 bool isLTR = m_columnSet.style()->isLeftToRightDirection(); | 455 bool isLTR = m_columnSet.style()->isLeftToRightDirection(); |
| 496 bool isLeftmostColumn = isLTR ? isFirstColumn : isLastColumn; | 456 bool isLeftmostColumn = isLTR ? isFirstColumn : isLastColumn; |
| 497 bool isRightmostColumn = isLTR ? isLastColumn : isFirstColumn; | 457 bool isRightmostColumn = isLTR ? isLastColumn : isFirstColumn; |
| 498 | 458 |
| 459 LayoutRect portionRect = flowThreadPortionRectAt(columnIndex); | |
| 499 // Calculate the overflow rectangle, based on the flow thread's, clipped at column logical | 460 // Calculate the overflow rectangle, based on the flow thread's, clipped at column logical |
| 500 // top/bottom unless it's the first/last column. | 461 // top/bottom unless it's the first/last column. |
| 501 LayoutRect overflowRect = m_columnSet.overflowRectForFlowThreadPortion(porti onRect, isFirstColumn && !m_columnSet.previousSiblingMultiColumnSet(), isLastCol umn && !m_columnSet.nextSiblingMultiColumnSet()); | 462 LayoutRect overflowRect = m_columnSet.overflowRectForFlowThreadPortion(porti onRect, isFirstColumn && !m_columnSet.previousSiblingMultiColumnSet(), isLastCol umn && !m_columnSet.nextSiblingMultiColumnSet()); |
| 502 | 463 |
| 503 // Avoid overflowing into neighboring columns, by clipping in the middle of adjacent column | 464 // Avoid overflowing into neighboring columns, by clipping in the middle of adjacent column |
| 504 // gaps. Also make sure that we avoid rounding errors. | 465 // gaps. Also make sure that we avoid rounding errors. |
| 466 LayoutUnit columnGap = m_columnSet.columnGap(); | |
| 505 if (m_columnSet.isHorizontalWritingMode()) { | 467 if (m_columnSet.isHorizontalWritingMode()) { |
| 506 if (!isLeftmostColumn) | 468 if (!isLeftmostColumn) |
| 507 overflowRect.shiftXEdgeTo(portionRect.x() - columnGap / 2); | 469 overflowRect.shiftXEdgeTo(portionRect.x() - columnGap / 2); |
| 508 if (!isRightmostColumn) | 470 if (!isRightmostColumn) |
| 509 overflowRect.shiftMaxXEdgeTo(portionRect.maxX() + columnGap - column Gap / 2); | 471 overflowRect.shiftMaxXEdgeTo(portionRect.maxX() + columnGap - column Gap / 2); |
| 510 } else { | 472 } else { |
| 511 if (!isLeftmostColumn) | 473 if (!isLeftmostColumn) |
| 512 overflowRect.shiftYEdgeTo(portionRect.y() - columnGap / 2); | 474 overflowRect.shiftYEdgeTo(portionRect.y() - columnGap / 2); |
| 513 if (!isRightmostColumn) | 475 if (!isRightmostColumn) |
| 514 overflowRect.shiftMaxYEdgeTo(portionRect.maxY() + columnGap - column Gap / 2); | 476 overflowRect.shiftMaxYEdgeTo(portionRect.maxY() + columnGap - column Gap / 2); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 append(MultiColumnFragmentainerGroup(m_columnSet)); | 557 append(MultiColumnFragmentainerGroup(m_columnSet)); |
| 596 return last(); | 558 return last(); |
| 597 } | 559 } |
| 598 | 560 |
| 599 void MultiColumnFragmentainerGroupList::deleteExtraGroups() | 561 void MultiColumnFragmentainerGroupList::deleteExtraGroups() |
| 600 { | 562 { |
| 601 shrink(1); | 563 shrink(1); |
| 602 } | 564 } |
| 603 | 565 |
| 604 } // namespace blink | 566 } // namespace blink |
| OLD | NEW |