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 |