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

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

Issue 2314763002: Replace collectLayerFragments() with FragmentainerIterator. (Closed)
Patch Set: rebase master for https://codereview.chromium.org/2310233002/ 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 m_currentFragmentainerIndex++;
56
57 if (m_currentFragmentainerIndex > m_endFragmentainerIndex) {
eae 2016/09/08 08:15:03 How about reversing this logic instead of increasi
mstensho (USE GERRIT) 2016/09/08 08:59:51 Done. Very nice! I like!
58 // That was the last fragmentainer to visit in this fragmentainer group. Advance to the
59 // next group.
60 moveToNextFragmentainerGroup();
61 if (atEnd())
62 return;
63 }
64 updateOutput();
65 }
66
67 const MultiColumnFragmentainerGroup& FragmentainerIterator::currentGroup() const
68 {
69 DCHECK(!atEnd());
70 return m_currentColumnSet->fragmentainerGroups()[m_currentFragmentainerGroup Index];
71 }
72
73 void FragmentainerIterator::moveToNextFragmentainerGroup()
74 {
75 do {
76 m_currentFragmentainerGroupIndex++;
77 if (m_currentFragmentainerGroupIndex >= m_currentColumnSet->fragmentaine rGroups().size()) {
78 // That was the last fragmentainer group in this set. Advance to the next set.
79 m_currentColumnSet = m_currentColumnSet->nextSiblingMultiColumnSet() ;
80 m_currentFragmentainerGroupIndex = 0;
81 if (!m_currentColumnSet || m_currentColumnSet->logicalTopInFlowThrea d() >= m_logicalBottomInFlowThread) {
82 setAtEnd();
83 return; // No more sets or next set out of range. We're done.
84 }
85 }
86 if (currentGroup().logicalTopInFlowThread() >= m_logicalBottomInFlowThre ad) {
87 setAtEnd(); // This fragmentainer group doesn't intersect with the r ange we're interested in. We're done.
88 return;
89 }
90 } while (!setFragmentainersOfInterest());
91 }
92
93 bool FragmentainerIterator::setFragmentainersOfInterest()
94 {
95 const MultiColumnFragmentainerGroup& group = currentGroup();
96
97 // Figure out the start and end fragmentainers for the block range we're int erested in. We
98 // might not have to walk the entire fragmentainer group.
99 group.columnIntervalForBlockRangeInFlowThread(m_logicalTopInFlowThread, m_lo gicalBottomInFlowThread, m_currentFragmentainerIndex, m_endFragmentainerIndex);
100
101 // Now intersect with the fragmentainers that actually intersect with the cl ip rect, to narrow
102 // it down even further.
103 unsigned firstFragmentainerInClipRect, lastFragmentainerInClipRect;
104 group.columnIntervalForVisualRect(m_clipRectInMulticolContainer, firstFragme ntainerInClipRect, lastFragmentainerInClipRect);
105 // If the two fragmentainer intervals are disjoint, there's nothing of inter est in this
106 // fragmentainer group.
107 if (firstFragmentainerInClipRect > m_endFragmentainerIndex || lastFragmentai nerInClipRect < m_currentFragmentainerIndex)
108 return false;
109 if (m_currentFragmentainerIndex < firstFragmentainerInClipRect)
110 m_currentFragmentainerIndex = firstFragmentainerInClipRect;
111 if (m_endFragmentainerIndex > lastFragmentainerInClipRect)
112 m_endFragmentainerIndex = lastFragmentainerInClipRect;
113 DCHECK(m_endFragmentainerIndex >= m_currentFragmentainerIndex);
114 return true;
115 }
116
117 void FragmentainerIterator::updateOutput()
118 {
119 const MultiColumnFragmentainerGroup& group = currentGroup();
120
121 // Set the physical translation offset.
122 LayoutUnit fragmentainerLogicalTopInFlowThread = group.logicalTopInFlowThrea d() + m_currentFragmentainerIndex * group.logicalHeight();
123 m_paginationOffset = group.flowThreadTranslationAtOffset(fragmentainerLogica lTopInFlowThread, CoordinateSpaceConversion::Visual);
124
125 // Set the overflow clip rect that corresponds to the fragmentainer.
126 m_clipRectInFlowThread = group.flowThreadPortionOverflowRectAt(m_currentFrag mentainerIndex);
127
128 // Flip it into a physical rectangle.
129 m_flowThread.flipForWritingMode(m_clipRectInFlowThread);
130 }
131
132 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698