OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above | 8 * 1. Redistributions of source code must retain the above |
9 * copyright notice, this list of conditions and the following | 9 * copyright notice, this list of conditions and the following |
10 * disclaimer. | 10 * disclaimer. |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #include "core/layout/LayoutFlowThread.h" | 32 #include "core/layout/LayoutFlowThread.h" |
33 | 33 |
34 #include "core/layout/LayoutMultiColumnSet.h" | 34 #include "core/layout/LayoutMultiColumnSet.h" |
35 #include "core/layout/LayoutView.h" | 35 #include "core/layout/LayoutView.h" |
36 | 36 |
37 namespace blink { | 37 namespace blink { |
38 | 38 |
39 LayoutFlowThread::LayoutFlowThread() | 39 LayoutFlowThread::LayoutFlowThread() |
40 : LayoutBlockFlow(0) | 40 : LayoutBlockFlow(0) |
41 , m_regionsInvalidated(false) | 41 , m_columnSetsInvalidated(false) |
42 , m_regionsHaveUniformLogicalHeight(true) | 42 , m_columnSetsHaveUniformLogicalHeight(true) |
43 , m_pageLogicalSizeChanged(false) | 43 , m_pageLogicalSizeChanged(false) |
44 { | 44 { |
45 } | 45 } |
46 | 46 |
47 void LayoutFlowThread::removeRegionFromThread(LayoutMultiColumnSet* columnSet) | 47 void LayoutFlowThread::removeColumnSetFromThread(LayoutMultiColumnSet* columnSet
) |
48 { | 48 { |
49 ASSERT(columnSet); | 49 ASSERT(columnSet); |
50 m_multiColumnSetList.remove(columnSet); | 50 m_multiColumnSetList.remove(columnSet); |
51 } | 51 } |
52 | 52 |
53 void LayoutFlowThread::invalidateRegions() | 53 void LayoutFlowThread::invalidateColumnSets() |
54 { | 54 { |
55 if (m_regionsInvalidated) { | 55 if (m_columnSetsInvalidated) { |
56 ASSERT(selfNeedsLayout()); | 56 ASSERT(selfNeedsLayout()); |
57 return; | 57 return; |
58 } | 58 } |
59 | 59 |
60 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::ColumnsChan
ged); | 60 setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::ColumnsChan
ged); |
61 | 61 |
62 m_regionsInvalidated = true; | 62 m_columnSetsInvalidated = true; |
63 } | 63 } |
64 | 64 |
65 void LayoutFlowThread::validateRegions() | 65 void LayoutFlowThread::validateColumnSets() |
66 { | 66 { |
67 if (m_regionsInvalidated) { | 67 if (m_columnSetsInvalidated) { |
68 m_regionsInvalidated = false; | 68 m_columnSetsInvalidated = false; |
69 m_regionsHaveUniformLogicalHeight = true; | 69 m_columnSetsHaveUniformLogicalHeight = true; |
70 | 70 |
71 if (hasRegions()) { | 71 if (hasColumnSets()) { |
72 LayoutUnit previousRegionLogicalHeight = 0; | 72 LayoutUnit previousLogicalHeight = 0; |
73 bool firstRegionVisited = false; | 73 bool firstVisited = false; |
74 | 74 |
75 for (auto* columnSet : m_multiColumnSetList) { | 75 for (auto* columnSet : m_multiColumnSetList) { |
76 LayoutUnit regionLogicalHeight = columnSet->pageLogicalHeight(); | 76 LayoutUnit currentLogicalHeight = columnSet->pageLogicalHeight()
; |
77 | 77 |
78 if (!firstRegionVisited) { | 78 if (!firstVisited) { |
79 firstRegionVisited = true; | 79 firstVisited = true; |
80 } else { | 80 } else { |
81 if (m_regionsHaveUniformLogicalHeight && previousRegionLogic
alHeight != regionLogicalHeight) | 81 if (m_columnSetsHaveUniformLogicalHeight && previousLogicalH
eight != currentLogicalHeight) |
82 m_regionsHaveUniformLogicalHeight = false; | 82 m_columnSetsHaveUniformLogicalHeight = false; |
83 } | 83 } |
84 | 84 |
85 previousRegionLogicalHeight = regionLogicalHeight; | 85 previousLogicalHeight = currentLogicalHeight; |
86 } | 86 } |
87 } | 87 } |
88 } | 88 } |
89 | 89 |
90 updateLogicalWidth(); // Called to get the maximum logical width for the col
umnSet. | 90 updateLogicalWidth(); // Called to get the maximum logical width for the col
umnSet. |
91 generateColumnSetIntervalTree(); | 91 generateColumnSetIntervalTree(); |
92 } | 92 } |
93 | 93 |
94 void LayoutFlowThread::mapRectToPaintInvalidationBacking(const LayoutBoxModelObj
ect* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState*
paintInvalidationState) const | 94 void LayoutFlowThread::mapRectToPaintInvalidationBacking(const LayoutBoxModelObj
ect* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState*
paintInvalidationState) const |
95 { | 95 { |
96 ASSERT(paintInvalidationContainer != this); // A flow thread should never be
an invalidation container. | 96 ASSERT(paintInvalidationContainer != this); // A flow thread should never be
an invalidation container. |
97 // |rect| is a layout rectangle, where the block direction coordinate is fli
pped for writing | 97 // |rect| is a layout rectangle, where the block direction coordinate is fli
pped for writing |
98 // mode. fragmentsBoundingBox(), on the other hand, works on physical rectan
gles, so we need to | 98 // mode. fragmentsBoundingBox(), on the other hand, works on physical rectan
gles, so we need to |
99 // flip the rectangle before and after calling it. | 99 // flip the rectangle before and after calling it. |
100 flipForWritingMode(rect); | 100 flipForWritingMode(rect); |
101 rect = fragmentsBoundingBox(rect); | 101 rect = fragmentsBoundingBox(rect); |
102 flipForWritingMode(rect); | 102 flipForWritingMode(rect); |
103 LayoutBlockFlow::mapRectToPaintInvalidationBacking(paintInvalidationContaine
r, rect, paintInvalidationState); | 103 LayoutBlockFlow::mapRectToPaintInvalidationBacking(paintInvalidationContaine
r, rect, paintInvalidationState); |
104 } | 104 } |
105 | 105 |
106 void LayoutFlowThread::layout() | 106 void LayoutFlowThread::layout() |
107 { | 107 { |
108 m_pageLogicalSizeChanged = m_regionsInvalidated && everHadLayout(); | 108 m_pageLogicalSizeChanged = m_columnSetsInvalidated && everHadLayout(); |
109 LayoutBlockFlow::layout(); | 109 LayoutBlockFlow::layout(); |
110 m_pageLogicalSizeChanged = false; | 110 m_pageLogicalSizeChanged = false; |
111 } | 111 } |
112 | 112 |
113 void LayoutFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, L
ogicalExtentComputedValues& computedValues) const | 113 void LayoutFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, L
ogicalExtentComputedValues& computedValues) const |
114 { | 114 { |
115 computedValues.m_position = logicalTop; | 115 computedValues.m_position = logicalTop; |
116 computedValues.m_extent = 0; | 116 computedValues.m_extent = 0; |
117 | 117 |
118 for (LayoutMultiColumnSetList::const_iterator iter = m_multiColumnSetList.be
gin(); iter != m_multiColumnSetList.end(); ++iter) { | 118 for (LayoutMultiColumnSetList::const_iterator iter = m_multiColumnSetList.be
gin(); iter != m_multiColumnSetList.end(); ++iter) { |
(...skipping 29 matching lines...) Expand all Loading... |
148 LayoutUnit pageLogicalBottom = pageLogicalTop + pageLogicalHeight; | 148 LayoutUnit pageLogicalBottom = pageLogicalTop + pageLogicalHeight; |
149 LayoutUnit remainingHeight = pageLogicalBottom - offset; | 149 LayoutUnit remainingHeight = pageLogicalBottom - offset; |
150 if (pageBoundaryRule == IncludePageBoundary) { | 150 if (pageBoundaryRule == IncludePageBoundary) { |
151 // If IncludePageBoundary is set, the line exactly on the top edge of a | 151 // If IncludePageBoundary is set, the line exactly on the top edge of a |
152 // columnSet will act as being part of the previous columnSet. | 152 // columnSet will act as being part of the previous columnSet. |
153 remainingHeight = intMod(remainingHeight, pageLogicalHeight); | 153 remainingHeight = intMod(remainingHeight, pageLogicalHeight); |
154 } | 154 } |
155 return remainingHeight; | 155 return remainingHeight; |
156 } | 156 } |
157 | 157 |
158 LayoutRegion* LayoutFlowThread::firstRegion() const | |
159 { | |
160 if (!hasValidRegionInfo()) | |
161 return 0; | |
162 return m_multiColumnSetList.first(); | |
163 } | |
164 | |
165 LayoutRegion* LayoutFlowThread::lastRegion() const | |
166 { | |
167 if (!hasValidRegionInfo()) | |
168 return 0; | |
169 return m_multiColumnSetList.last(); | |
170 } | |
171 | |
172 void LayoutFlowThread::generateColumnSetIntervalTree() | 158 void LayoutFlowThread::generateColumnSetIntervalTree() |
173 { | 159 { |
174 // FIXME: Optimize not to clear the interval all the time. This implies manu
ally managing the tree nodes lifecycle. | 160 // FIXME: Optimize not to clear the interval all the time. This implies manu
ally managing the tree nodes lifecycle. |
175 m_multiColumnSetIntervalTree.clear(); | 161 m_multiColumnSetIntervalTree.clear(); |
176 m_multiColumnSetIntervalTree.initIfNeeded(); | 162 m_multiColumnSetIntervalTree.initIfNeeded(); |
177 for (auto columnSet : m_multiColumnSetList) | 163 for (auto columnSet : m_multiColumnSetList) |
178 m_multiColumnSetIntervalTree.add(MultiColumnSetIntervalTree::createInter
val(columnSet->logicalTopInFlowThread(), columnSet->logicalBottomInFlowThread(),
columnSet)); | 164 m_multiColumnSetIntervalTree.add(MultiColumnSetIntervalTree::createInter
val(columnSet->logicalTopInFlowThread(), columnSet->logicalBottomInFlowThread(),
columnSet)); |
179 } | 165 } |
180 | 166 |
181 void LayoutFlowThread::collectLayerFragments(DeprecatedPaintLayerFragments& laye
rFragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) | 167 void LayoutFlowThread::collectLayerFragments(DeprecatedPaintLayerFragments& laye
rFragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) |
182 { | 168 { |
183 ASSERT(!m_regionsInvalidated); | 169 ASSERT(!m_columnSetsInvalidated); |
184 | 170 |
185 for (LayoutMultiColumnSetList::const_iterator iter = m_multiColumnSetList.be
gin(); iter != m_multiColumnSetList.end(); ++iter) { | 171 for (LayoutMultiColumnSetList::const_iterator iter = m_multiColumnSetList.be
gin(); iter != m_multiColumnSetList.end(); ++iter) { |
186 LayoutMultiColumnSet* columnSet = *iter; | 172 LayoutMultiColumnSet* columnSet = *iter; |
187 columnSet->collectLayerFragments(layerFragments, layerBoundingBox, dirty
Rect); | 173 columnSet->collectLayerFragments(layerFragments, layerBoundingBox, dirty
Rect); |
188 } | 174 } |
189 } | 175 } |
190 | 176 |
191 LayoutRect LayoutFlowThread::fragmentsBoundingBox(const LayoutRect& layerBoundin
gBox) const | 177 LayoutRect LayoutFlowThread::fragmentsBoundingBox(const LayoutRect& layerBoundin
gBox) const |
192 { | 178 { |
193 ASSERT(!m_regionsInvalidated); | 179 ASSERT(!m_columnSetsInvalidated); |
194 | 180 |
195 LayoutRect result; | 181 LayoutRect result; |
196 for (auto* columnSet : m_multiColumnSetList) { | 182 for (auto* columnSet : m_multiColumnSetList) { |
197 DeprecatedPaintLayerFragments fragments; | 183 DeprecatedPaintLayerFragments fragments; |
198 columnSet->collectLayerFragments(fragments, layerBoundingBox, LayoutRect
(LayoutRect::infiniteIntRect())); | 184 columnSet->collectLayerFragments(fragments, layerBoundingBox, LayoutRect
(LayoutRect::infiniteIntRect())); |
199 for (const auto& fragment : fragments) { | 185 for (const auto& fragment : fragments) { |
200 LayoutRect fragmentRect(layerBoundingBox); | 186 LayoutRect fragmentRect(layerBoundingBox); |
201 fragmentRect.intersect(fragment.paginationClip); | 187 fragmentRect.intersect(fragment.paginationClip); |
202 fragmentRect.moveBy(fragment.paginationOffset); | 188 fragmentRect.moveBy(fragment.paginationOffset); |
203 result.unite(fragmentRect); | 189 result.unite(fragmentRect); |
204 } | 190 } |
205 } | 191 } |
206 | 192 |
207 return result; | 193 return result; |
208 } | 194 } |
209 | 195 |
210 void LayoutFlowThread::MultiColumnSetSearchAdapter::collectIfNeeded(const MultiC
olumnSetInterval& interval) | 196 void LayoutFlowThread::MultiColumnSetSearchAdapter::collectIfNeeded(const MultiC
olumnSetInterval& interval) |
211 { | 197 { |
212 if (m_result) | 198 if (m_result) |
213 return; | 199 return; |
214 if (interval.low() <= m_offset && interval.high() > m_offset) | 200 if (interval.low() <= m_offset && interval.high() > m_offset) |
215 m_result = interval.data(); | 201 m_result = interval.data(); |
216 } | 202 } |
217 | 203 |
218 } // namespace blink | 204 } // namespace blink |
OLD | NEW |