Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp

Issue 2314763002: Replace collectLayerFragments() with FragmentainerIterator. (Closed)
Patch Set: code review. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/layout/FragmentainerIterator.h"
6
7 #include "core/layout/LayoutMultiColumnSet.h"
8
9 namespace blink {
10
11 FragmentainerIterator::FragmentainerIterator(const LayoutFlowThread& flowThread, const LayoutRect& physicalBoundingBoxInFlowThread, const LayoutRect& clipRectIn MulticolContainer)
12 : m_flowThread(flowThread)
13 , m_clipRectInMulticolContainer(clipRectInMulticolContainer)
14 , m_currentFragmentainerGroupIndex(0)
15 {
16 // Put the bounds into flow thread-local coordinates by flipping it first. T his is how
17 // rectangles typically are represented in layout, i.e. with the block direc tion coordinate
18 // flipped, if writing mode is vertical-rl.
19 LayoutRect boundsInFlowThread = physicalBoundingBoxInFlowThread;
20 m_flowThread.flipForWritingMode(boundsInFlowThread);
21
22 if (m_flowThread.isHorizontalWritingMode()) {
23 m_logicalTopInFlowThread = boundsInFlowThread.y();
24 m_logicalBottomInFlowThread = boundsInFlowThread.maxY();
25 } else {
26 m_logicalTopInFlowThread = boundsInFlowThread.x();
27 m_logicalBottomInFlowThread = boundsInFlowThread.maxX();
28 }
29
30 // Jump to the first interesting column set.
31 m_currentColumnSet = flowThread.columnSetAtBlockOffset(m_logicalTopInFlowThr ead);
32 if (!m_currentColumnSet || m_currentColumnSet->logicalTopInFlowThread() >= m _logicalBottomInFlowThread) {
33 setAtEnd();
34 return;
35 }
36 // Then find the first interesting fragmentainer group.
37 m_currentFragmentainerGroupIndex = m_currentColumnSet->fragmentainerGroupInd exAtFlowThreadOffset(m_logicalTopInFlowThread);
38
39 // Now find the first and last fragmentainer we're interested in. We'll also clip against
40 // the clip rect here. In case the clip rect doesn't intersect with any of t he
41 // fragmentainers, we have to move on to the next fragmentainer group, and s ee if we find
42 // something there.
43 if (!setFragmentainersOfInterest()) {
44 moveToNextFragmentainerGroup();
45 if (atEnd())
46 return;
47 }
48
49 updateOutput();
50 }
51
52 void FragmentainerIterator::advance()
53 {
54 DCHECK(!atEnd());
55
56 if (m_currentFragmentainerIndex < m_endFragmentainerIndex) {
57 m_currentFragmentainerIndex++;
58 } else {
59 // That was the last fragmentainer to visit in this fragmentainer group. Advance to the
60 // next group.
61 moveToNextFragmentainerGroup();
62 if (atEnd())
63 return;
64 }
65 updateOutput();
66 }
67
68 const MultiColumnFragmentainerGroup& FragmentainerIterator::currentGroup() const
69 {
70 DCHECK(!atEnd());
71 return m_currentColumnSet->fragmentainerGroups()[m_currentFragmentainerGroup Index];
72 }
73
74 void FragmentainerIterator::moveToNextFragmentainerGroup()
75 {
76 do {
77 m_currentFragmentainerGroupIndex++;
78 if (m_currentFragmentainerGroupIndex >= m_currentColumnSet->fragmentaine rGroups().size()) {
79 // That was the last fragmentainer group in this set. Advance to the next set.
80 m_currentColumnSet = m_currentColumnSet->nextSiblingMultiColumnSet() ;
81 m_currentFragmentainerGroupIndex = 0;
82 if (!m_currentColumnSet || m_currentColumnSet->logicalTopInFlowThrea d() >= m_logicalBottomInFlowThread) {
83 setAtEnd();
84 return; // No more sets or next set out of range. We're done.
85 }
86 }
87 if (currentGroup().logicalTopInFlowThread() >= m_logicalBottomInFlowThre ad) {
88 setAtEnd(); // This fragmentainer group doesn't intersect with the r ange we're interested in. We're done.
89 return;
90 }
91 } while (!setFragmentainersOfInterest());
92 }
93
94 bool FragmentainerIterator::setFragmentainersOfInterest()
95 {
96 const MultiColumnFragmentainerGroup& group = currentGroup();
97
98 // Figure out the start and end fragmentainers for the block range we're int erested in. We
99 // might not have to walk the entire fragmentainer group.
100 group.columnIntervalForBlockRangeInFlowThread(m_logicalTopInFlowThread, m_lo gicalBottomInFlowThread, m_currentFragmentainerIndex, m_endFragmentainerIndex);
101
102 // Now intersect with the fragmentainers that actually intersect with the cl ip rect, to narrow
103 // it down even further.
104 unsigned firstFragmentainerInClipRect, lastFragmentainerInClipRect;
105 group.columnIntervalForVisualRect(m_clipRectInMulticolContainer, firstFragme ntainerInClipRect, lastFragmentainerInClipRect);
106 // If the two fragmentainer intervals are disjoint, there's nothing of inter est in this
107 // fragmentainer group.
108 if (firstFragmentainerInClipRect > m_endFragmentainerIndex || lastFragmentai nerInClipRect < m_currentFragmentainerIndex)
109 return false;
110 if (m_currentFragmentainerIndex < firstFragmentainerInClipRect)
111 m_currentFragmentainerIndex = firstFragmentainerInClipRect;
112 if (m_endFragmentainerIndex > lastFragmentainerInClipRect)
113 m_endFragmentainerIndex = lastFragmentainerInClipRect;
114 DCHECK(m_endFragmentainerIndex >= m_currentFragmentainerIndex);
115 return true;
116 }
117
118 void FragmentainerIterator::updateOutput()
119 {
120 const MultiColumnFragmentainerGroup& group = currentGroup();
121
122 // Set the physical translation offset.
123 LayoutUnit fragmentainerLogicalTopInFlowThread = group.logicalTopInFlowThrea d() + m_currentFragmentainerIndex * group.logicalHeight();
124 m_paginationOffset = group.flowThreadTranslationAtOffset(fragmentainerLogica lTopInFlowThread, CoordinateSpaceConversion::Visual);
125
126 // Set the overflow clip rect that corresponds to the fragmentainer.
127 m_clipRectInFlowThread = group.flowThreadPortionOverflowRectAt(m_currentFrag mentainerIndex);
128
129 // Flip it into a physical rectangle.
130 m_flowThread.flipForWritingMode(m_clipRectInFlowThread);
131 }
132
133 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698