OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 66 |
67 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::lastMultiColumnSet() const | 67 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::lastMultiColumnSet() const |
68 { | 68 { |
69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { | 69 for (LayoutObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s
ibling = sibling->previousSibling()) { |
70 if (sibling->isLayoutMultiColumnSet()) | 70 if (sibling->isLayoutMultiColumnSet()) |
71 return toLayoutMultiColumnSet(sibling); | 71 return toLayoutMultiColumnSet(sibling); |
72 } | 72 } |
73 return nullptr; | 73 return nullptr; |
74 } | 74 } |
75 | 75 |
| 76 static inline bool isMultiColumnContainer(const LayoutObject& object) |
| 77 { |
| 78 if (!object.isLayoutBlockFlow()) |
| 79 return false; |
| 80 return toLayoutBlockFlow(object).multiColumnFlowThread(); |
| 81 } |
| 82 |
76 // Find the next layout object that has the multicol container in its containing
block chain, skipping nested multicol containers. | 83 // Find the next layout object that has the multicol container in its containing
block chain, skipping nested multicol containers. |
77 static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow(LayoutMultiCol
umnFlowThread* flowThread, LayoutObject* descendant) | 84 static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow(LayoutMultiCol
umnFlowThread* flowThread, LayoutObject* descendant) |
78 { | 85 { |
79 ASSERT(descendant->isDescendantOf(flowThread)); | 86 ASSERT(descendant->isDescendantOf(flowThread)); |
80 LayoutObject* object = descendant->nextInPreOrderAfterChildren(flowThread); | 87 LayoutObject* object = descendant->nextInPreOrderAfterChildren(flowThread); |
81 while (object) { | 88 while (object) { |
82 // Walk through the siblings and find the first one which is either in-f
low or has this | 89 // Walk through the siblings and find the first one which is either in-f
low or has this |
83 // flow thread as its containing block flow thread. | 90 // flow thread as its containing block flow thread. |
84 if (!object->isOutOfFlowPositioned()) | 91 if (!object->isOutOfFlowPositioned()) |
85 break; | 92 break; |
86 if (object->containingBlock()->flowThreadContainingBlock() == flowThread
) { | 93 if (object->containingBlock()->flowThreadContainingBlock() == flowThread
) { |
87 // This out-of-flow object is still part of the flow thread, because
its containing | 94 // This out-of-flow object is still part of the flow thread, because
its containing |
88 // block (probably relatively positioned) is part of the flow thread
. | 95 // block (probably relatively positioned) is part of the flow thread
. |
89 break; | 96 break; |
90 } | 97 } |
91 object = object->nextInPreOrderAfterChildren(flowThread); | 98 object = object->nextInPreOrderAfterChildren(flowThread); |
92 } | 99 } |
93 if (!object) | 100 if (!object) |
94 return nullptr; | 101 return nullptr; |
95 #if ENABLE(ASSERT) | 102 #if ENABLE(ASSERT) |
96 // Make sure that we didn't stumble into an inner multicol container. | 103 // Make sure that we didn't stumble into an inner multicol container. |
97 for (LayoutObject* walker = object->parent(); walker && walker != flowThread
; walker = walker->parent()) | 104 for (LayoutObject* walker = object->parent(); walker && walker != flowThread
; walker = walker->parent()) |
98 ASSERT(!walker->isLayoutBlockFlow() || !toLayoutBlockFlow(walker)->multi
ColumnFlowThread()); | 105 ASSERT(!isMultiColumnContainer(*walker)); |
99 #endif | 106 #endif |
100 return object; | 107 return object; |
101 } | 108 } |
102 | 109 |
103 // Find the previous layout object that has the multicol container in its contai
ning block chain, skipping nested multicol containers. | 110 // Find the previous layout object that has the multicol container in its contai
ning block chain, skipping nested multicol containers. |
104 static LayoutObject* previousInPreOrderSkippingOutOfFlow(LayoutMultiColumnFlowTh
read* flowThread, LayoutObject* descendant) | 111 static LayoutObject* previousInPreOrderSkippingOutOfFlow(LayoutMultiColumnFlowTh
read* flowThread, LayoutObject* descendant) |
105 { | 112 { |
106 ASSERT(descendant->isDescendantOf(flowThread)); | 113 ASSERT(descendant->isDescendantOf(flowThread)); |
107 LayoutObject* object = descendant->previousInPreOrder(flowThread); | 114 LayoutObject* object = descendant->previousInPreOrder(flowThread); |
108 while (object && object != flowThread) { | 115 while (object && object != flowThread) { |
109 if (object->isColumnSpanAll()) { | 116 if (object->isColumnSpanAll()) { |
110 LayoutMultiColumnFlowThread* placeholderFlowThread = toLayoutBox(obj
ect)->spannerPlaceholder()->flowThread(); | 117 LayoutMultiColumnFlowThread* placeholderFlowThread = toLayoutBox(obj
ect)->spannerPlaceholder()->flowThread(); |
111 if (placeholderFlowThread == flowThread) | 118 if (placeholderFlowThread == flowThread) |
112 break; | 119 break; |
113 // We're inside an inner multicol container. We have no business the
re. Continue on the outside. | 120 // We're inside an inner multicol container. We have no business the
re. Continue on the outside. |
114 object = placeholderFlowThread->parent(); | 121 object = placeholderFlowThread->parent(); |
115 ASSERT(object->isDescendantOf(flowThread)); | 122 ASSERT(object->isDescendantOf(flowThread)); |
116 continue; | 123 continue; |
117 } | 124 } |
118 if (object->flowThreadContainingBlock() == flowThread) { | 125 if (object->flowThreadContainingBlock() == flowThread) { |
119 LayoutObject* ancestor; | 126 LayoutObject* ancestor; |
120 for (ancestor = object->parent(); ; ancestor = ancestor->parent()) { | 127 for (ancestor = object->parent(); ; ancestor = ancestor->parent()) { |
121 if (ancestor == flowThread) | 128 if (ancestor == flowThread) |
122 return object; | 129 return object; |
123 if (ancestor->isLayoutBlockFlow() && toLayoutBlockFlow(ancestor)
->multiColumnFlowThread()) { | 130 if (isMultiColumnContainer(*ancestor)) { |
124 // We're inside an inner multicol container. We have no busi
ness there. | 131 // We're inside an inner multicol container. We have no busi
ness there. |
125 break; | 132 break; |
126 } | 133 } |
127 } | 134 } |
128 object = ancestor; | 135 object = ancestor; |
129 ASSERT(ancestor->isDescendantOf(flowThread)); | 136 ASSERT(ancestor->isDescendantOf(flowThread)); |
130 continue; // Continue on the outside of the inner flow thread. | 137 continue; // Continue on the outside of the inner flow thread. |
131 } | 138 } |
132 // We're inside something that's out-of-flow. Keep looking upwards and b
ackwards in the tree. | 139 // We're inside something that's out-of-flow. Keep looking upwards and b
ackwards in the tree. |
133 object = object->previousInPreOrder(flowThread); | 140 object = object->previousInPreOrder(flowThread); |
134 } | 141 } |
135 if (!object || object == flowThread) | 142 if (!object || object == flowThread) |
136 return nullptr; | 143 return nullptr; |
137 #if ENABLE(ASSERT) | 144 #if ENABLE(ASSERT) |
138 // Make sure that we didn't stumble into an inner multicol container. | 145 // Make sure that we didn't stumble into an inner multicol container. |
139 for (LayoutObject* walker = object->parent(); walker && walker != flowThread
; walker = walker->parent()) | 146 for (LayoutObject* walker = object->parent(); walker && walker != flowThread
; walker = walker->parent()) |
140 ASSERT(!walker->isLayoutBlockFlow() || !toLayoutBlockFlow(walker)->multi
ColumnFlowThread()); | 147 ASSERT(!isMultiColumnContainer(*walker)); |
141 #endif | 148 #endif |
142 return object; | 149 return object; |
143 } | 150 } |
144 | 151 |
145 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) | 152 static LayoutObject* firstLayoutObjectInSet(LayoutMultiColumnSet* multicolSet) |
146 { | 153 { |
147 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); | 154 LayoutBox* sibling = multicolSet->previousSiblingMultiColumnBox(); |
148 if (!sibling) | 155 if (!sibling) |
149 return multicolSet->flowThread()->firstChild(); | 156 return multicolSet->flowThread()->firstChild(); |
150 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each | 157 // Adjacent column content sets should not occur. We would have no way of fi
guring out what each |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 } | 889 } |
883 | 890 |
884 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const | 891 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
885 { | 892 { |
886 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) | 893 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
887 return columnSet->pageLogicalHeight(); | 894 return columnSet->pageLogicalHeight(); |
888 return false; | 895 return false; |
889 } | 896 } |
890 | 897 |
891 } | 898 } |
OLD | NEW |