| 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 |