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/MultiColumnFragmentainerGroup.h" | 5 #include "core/layout/MultiColumnFragmentainerGroup.h" |
6 | 6 |
7 #include "core/layout/ColumnBalancer.h" | 7 #include "core/layout/ColumnBalancer.h" |
8 #include "core/layout/FragmentationContext.h" | 8 #include "core/layout/FragmentationContext.h" |
9 #include "core/layout/LayoutMultiColumnSet.h" | 9 #include "core/layout/LayoutMultiColumnSet.h" |
10 | 10 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 return startColumnRect; // It all takes place in one column. We're done. | 192 return startColumnRect; // It all takes place in one column. We're done. |
193 | 193 |
194 LayoutRect endColumnFlowThreadOverflowPortion = flowThreadPortionOverflowRec
tAt(endColumn); | 194 LayoutRect endColumnFlowThreadOverflowPortion = flowThreadPortionOverflowRec
tAt(endColumn); |
195 flowThread->flipForWritingMode(endColumnFlowThreadOverflowPortion); | 195 flowThread->flipForWritingMode(endColumnFlowThreadOverflowPortion); |
196 LayoutRect endColumnRect(boundingBoxInFlowThread); | 196 LayoutRect endColumnRect(boundingBoxInFlowThread); |
197 endColumnRect.intersect(endColumnFlowThreadOverflowPortion); | 197 endColumnRect.intersect(endColumnFlowThreadOverflowPortion); |
198 endColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(en
dColumn), CoordinateSpaceConversion::Containing)); | 198 endColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(en
dColumn), CoordinateSpaceConversion::Containing)); |
199 return unionRect(startColumnRect, endColumnRect); | 199 return unionRect(startColumnRect, endColumnRect); |
200 } | 200 } |
201 | 201 |
202 void MultiColumnFragmentainerGroup::collectLayerFragments(PaintLayerFragments& f
ragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) const | |
203 { | |
204 // |layerBoundingBox| is in the flow thread coordinate space, relative to th
e top/left edge of | |
205 // the flow thread, but note that it has been converted with respect to writ
ing mode (so that | |
206 // it's visual/physical in that sense). | |
207 // | |
208 // |dirtyRect| is visual, relative to the multicol container. | |
209 // | |
210 // Then there's the output from this method - the stuff we put into the list
of fragments. The | |
211 // fragment.paginationOffset point is the actual visual translation required
to get from a | |
212 // location in the flow thread to a location in a given column. The fragment
.paginationClip | |
213 // rectangle, on the other hand, is in flow thread coordinates, but otherwis
e completely | |
214 // physical in terms of writing mode. | |
215 | |
216 LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(
); | |
217 bool isHorizontalWritingMode = m_columnSet.isHorizontalWritingMode(); | |
218 | |
219 // Put the layer bounds into flow thread-local coordinates by flipping it fi
rst. Since we're in | |
220 // a layoutObject, most rectangles are represented this way. | |
221 LayoutRect layerBoundsInFlowThread(layerBoundingBox); | |
222 flowThread->flipForWritingMode(layerBoundsInFlowThread); | |
223 | |
224 // Now we can compare with the flow thread portions owned by each column. Fi
rst let's | |
225 // see if the rect intersects our flow thread portion at all. | |
226 LayoutRect clippedRect(layerBoundsInFlowThread); | |
227 clippedRect.intersect(m_columnSet.flowThreadPortionOverflowRect()); | |
228 if (clippedRect.isEmpty()) | |
229 return; | |
230 | |
231 // Now we know we intersect at least one column. Let's figure out the logica
l top and logical | |
232 // bottom of the area we're checking. | |
233 LayoutUnit layerLogicalTop = isHorizontalWritingMode ? layerBoundsInFlowThre
ad.y() : layerBoundsInFlowThread.x(); | |
234 LayoutUnit layerLogicalBottom = (isHorizontalWritingMode ? layerBoundsInFlow
Thread.maxY() : layerBoundsInFlowThread.maxX()); | |
235 | |
236 // Figure out the start and end columns for the layer and only check within
that range so that | |
237 // we don't walk the entire column row. | |
238 unsigned startColumn; | |
239 unsigned endColumn; | |
240 columnIntervalForBlockRangeInFlowThread(layerLogicalTop, layerLogicalBottom,
startColumn, endColumn); | |
241 | |
242 // Now intersect with the columns actually occupied by the dirty rect, to na
rrow it down even further. | |
243 unsigned firstColumnInDirtyRect, lastColumnInDirtyRect; | |
244 columnIntervalForVisualRect(dirtyRect, firstColumnInDirtyRect, lastColumnInD
irtyRect); | |
245 if (firstColumnInDirtyRect > endColumn || lastColumnInDirtyRect < startColum
n) | |
246 return; // The two column intervals are disjoint. There's nothing to col
lect. | |
247 if (startColumn < firstColumnInDirtyRect) | |
248 startColumn = firstColumnInDirtyRect; | |
249 if (endColumn > lastColumnInDirtyRect) | |
250 endColumn = lastColumnInDirtyRect; | |
251 ASSERT(endColumn >= startColumn); | |
252 | |
253 for (unsigned i = startColumn; i <= endColumn; i++) { | |
254 PaintLayerFragment fragment; | |
255 | |
256 // Set the physical translation offset. | |
257 fragment.paginationOffset = toLayoutPoint(flowThreadTranslationAtOffset(
logicalTopInFlowThreadAt(i), CoordinateSpaceConversion::Visual)); | |
258 | |
259 // Set the overflow clip rect that corresponds to the column. | |
260 fragment.paginationClip = flowThreadPortionOverflowRectAt(i); | |
261 // Flip it into more a physical (PaintLayer-style) rectangle. | |
262 flowThread->flipForWritingMode(fragment.paginationClip); | |
263 | |
264 fragments.append(fragment); | |
265 } | |
266 } | |
267 | |
268 LayoutRect MultiColumnFragmentainerGroup::calculateOverflow() const | 202 LayoutRect MultiColumnFragmentainerGroup::calculateOverflow() const |
269 { | 203 { |
270 // Note that we just return the bounding rectangle of the column boxes here.
We currently don't | 204 // Note that we just return the bounding rectangle of the column boxes here.
We currently don't |
271 // examine overflow caused by the actual content that ends up in each column
. | 205 // examine overflow caused by the actual content that ends up in each column
. |
272 LayoutRect overflowRect; | 206 LayoutRect overflowRect; |
273 if (unsigned columnCount = actualColumnCount()) { | 207 if (unsigned columnCount = actualColumnCount()) { |
274 overflowRect = columnRectAt(0); | 208 overflowRect = columnRectAt(0); |
275 if (columnCount > 1) | 209 if (columnCount > 1) |
276 overflowRect.uniteEvenIfEmpty(columnRectAt(columnCount - 1)); | 210 overflowRect.uniteEvenIfEmpty(columnRectAt(columnCount - 1)); |
277 } | 211 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 append(MultiColumnFragmentainerGroup(m_columnSet)); | 474 append(MultiColumnFragmentainerGroup(m_columnSet)); |
541 return last(); | 475 return last(); |
542 } | 476 } |
543 | 477 |
544 void MultiColumnFragmentainerGroupList::deleteExtraGroups() | 478 void MultiColumnFragmentainerGroupList::deleteExtraGroups() |
545 { | 479 { |
546 shrink(1); | 480 shrink(1); |
547 } | 481 } |
548 | 482 |
549 } // namespace blink | 483 } // namespace blink |
OLD | NEW |