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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } | 72 } |
73 | 73 |
74 const MultiColumnFragmentainerGroup& | 74 const MultiColumnFragmentainerGroup& |
75 LayoutMultiColumnSet::FragmentainerGroupAtVisualPoint( | 75 LayoutMultiColumnSet::FragmentainerGroupAtVisualPoint( |
76 const LayoutPoint& visual_point) const { | 76 const LayoutPoint& visual_point) const { |
77 DCHECK_GT(fragmentainer_groups_.size(), 0u); | 77 DCHECK_GT(fragmentainer_groups_.size(), 0u); |
78 LayoutUnit block_offset = | 78 LayoutUnit block_offset = |
79 IsHorizontalWritingMode() ? visual_point.Y() : visual_point.X(); | 79 IsHorizontalWritingMode() ? visual_point.Y() : visual_point.X(); |
80 for (unsigned index = 0; index < fragmentainer_groups_.size(); index++) { | 80 for (unsigned index = 0; index < fragmentainer_groups_.size(); index++) { |
81 const auto& row = fragmentainer_groups_[index]; | 81 const auto& row = fragmentainer_groups_[index]; |
82 if (row.LogicalTop() + row.LogicalHeight() > block_offset) | 82 if (row.LogicalTop() + row.GroupLogicalHeight() > block_offset) |
83 return row; | 83 return row; |
84 } | 84 } |
85 return fragmentainer_groups_.Last(); | 85 return fragmentainer_groups_.Last(); |
86 } | 86 } |
87 | 87 |
88 LayoutUnit LayoutMultiColumnSet::PageLogicalHeightForOffset( | 88 LayoutUnit LayoutMultiColumnSet::PageLogicalHeightForOffset( |
89 LayoutUnit offset_in_flow_thread) const { | 89 LayoutUnit offset_in_flow_thread) const { |
90 const MultiColumnFragmentainerGroup& last_row = LastFragmentainerGroup(); | 90 const MultiColumnFragmentainerGroup& last_row = LastFragmentainerGroup(); |
91 if (!last_row.LogicalHeight() && fragmentainer_groups_.size() == 1) { | 91 if (!last_row.GroupLogicalHeight() && fragmentainer_groups_.size() == 1) { |
92 // In the first layout pass of an auto-height multicol container, height | 92 // In the first layout pass of an auto-height multicol container, height |
93 // isn't set. No need to perform the series of complicated dance steps below | 93 // isn't set. No need to perform the series of complicated dance steps below |
94 // to figure out that we should simply return 0. Bail now. | 94 // to figure out that we should simply return 0. Bail now. |
95 return LayoutUnit(); | 95 return LayoutUnit(); |
96 } | 96 } |
97 if (offset_in_flow_thread >= last_row.LogicalTopInFlowThread() + | 97 if (offset_in_flow_thread >= last_row.LogicalTopInFlowThread() + |
98 FragmentainerGroupCapacity(last_row)) { | 98 FragmentainerGroupCapacity(last_row)) { |
99 // The offset is outside the bounds of the fragmentainer groups that we have | 99 // The offset is outside the bounds of the fragmentainer groups that we have |
100 // established at this point. If we're nested inside another fragmentation | 100 // established at this point. If we're nested inside another fragmentation |
101 // context, we need to calculate the height on our own. | 101 // context, we need to calculate the height on our own. |
102 const LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread(); | 102 const LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread(); |
103 if (FragmentationContext* enclosing_fragmentation_context = | 103 if (FragmentationContext* enclosing_fragmentation_context = |
104 flow_thread->EnclosingFragmentationContext()) { | 104 flow_thread->EnclosingFragmentationContext()) { |
105 // We'd ideally like to translate |offsetInFlowThread| to an offset in the | 105 // We'd ideally like to translate |offsetInFlowThread| to an offset in the |
106 // coordinate space of the enclosing fragmentation context here, but | 106 // coordinate space of the enclosing fragmentation context here, but |
107 // that's hard, since the offset is out of bounds. So just use the bottom | 107 // that's hard, since the offset is out of bounds. So just use the bottom |
108 // we have found so far. | 108 // we have found so far. |
109 LayoutUnit enclosing_context_bottom = | 109 LayoutUnit enclosing_context_bottom = |
110 last_row.BlockOffsetInEnclosingFragmentationContext() + | 110 last_row.BlockOffsetInEnclosingFragmentationContext() + |
111 last_row.LogicalHeight(); | 111 last_row.GroupLogicalHeight(); |
112 LayoutUnit enclosing_fragmentainer_height = | 112 LayoutUnit enclosing_fragmentainer_height = |
113 enclosing_fragmentation_context->FragmentainerLogicalHeightAt( | 113 enclosing_fragmentation_context->FragmentainerLogicalHeightAt( |
114 enclosing_context_bottom); | 114 enclosing_context_bottom); |
115 // Constrain against specified height / max-height. | 115 // Constrain against specified height / max-height. |
116 LayoutUnit current_multicol_height = LogicalTopFromMulticolContentEdge() + | 116 LayoutUnit current_multicol_height = LogicalTopFromMulticolContentEdge() + |
117 last_row.LogicalTop() + | 117 last_row.LogicalTop() + |
118 last_row.LogicalHeight(); | 118 last_row.GroupLogicalHeight(); |
119 LayoutUnit multicol_height_with_extra_row = | 119 LayoutUnit multicol_height_with_extra_row = |
120 current_multicol_height + enclosing_fragmentainer_height; | 120 current_multicol_height + enclosing_fragmentainer_height; |
121 multicol_height_with_extra_row = | 121 multicol_height_with_extra_row = |
122 std::min(multicol_height_with_extra_row, | 122 std::min(multicol_height_with_extra_row, |
123 flow_thread->MaxColumnLogicalHeight()); | 123 flow_thread->MaxColumnLogicalHeight()); |
124 return std::max(LayoutUnit(1), | 124 return std::max(LayoutUnit(1), |
125 multicol_height_with_extra_row - current_multicol_height); | 125 multicol_height_with_extra_row - current_multicol_height); |
126 } | 126 } |
127 } | 127 } |
128 return FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread, | 128 return FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread, |
129 kAssociateWithLatterPage) | 129 kAssociateWithLatterPage) |
130 .LogicalHeight(); | 130 .ColumnLogicalHeight(); |
131 } | 131 } |
132 | 132 |
133 LayoutUnit LayoutMultiColumnSet::PageRemainingLogicalHeightForOffset( | 133 LayoutUnit LayoutMultiColumnSet::PageRemainingLogicalHeightForOffset( |
134 LayoutUnit offset_in_flow_thread, | 134 LayoutUnit offset_in_flow_thread, |
135 PageBoundaryRule page_boundary_rule) const { | 135 PageBoundaryRule page_boundary_rule) const { |
136 const MultiColumnFragmentainerGroup& row = | 136 const MultiColumnFragmentainerGroup& row = |
137 FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread, | 137 FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread, |
138 page_boundary_rule); | 138 page_boundary_rule); |
139 LayoutUnit page_logical_height = row.LogicalHeight(); | 139 LayoutUnit page_logical_height = row.ColumnLogicalHeight(); |
140 LayoutUnit page_logical_bottom = | 140 LayoutUnit page_logical_bottom = |
141 row.ColumnLogicalTopForOffset(offset_in_flow_thread) + | 141 row.ColumnLogicalTopForOffset(offset_in_flow_thread) + |
142 page_logical_height; | 142 page_logical_height; |
143 LayoutUnit remaining_logical_height = | 143 LayoutUnit remaining_logical_height = |
144 page_logical_bottom - offset_in_flow_thread; | 144 page_logical_bottom - offset_in_flow_thread; |
145 | 145 |
146 if (page_boundary_rule == kAssociateWithFormerPage) { | 146 if (page_boundary_rule == kAssociateWithFormerPage) { |
147 // An offset exactly at a column boundary will act as being part of the | 147 // An offset exactly at a column boundary will act as being part of the |
148 // former column in question (i.e. no remaining space), rather than being | 148 // former column in question (i.e. no remaining space), rather than being |
149 // part of the latter (i.e. one whole column length of remaining space). | 149 // part of the latter (i.e. one whole column length of remaining space). |
150 remaining_logical_height = | 150 remaining_logical_height = |
151 IntMod(remaining_logical_height, page_logical_height); | 151 IntMod(remaining_logical_height, page_logical_height); |
152 } else if (!remaining_logical_height) { | 152 } else if (!remaining_logical_height) { |
153 // When pageBoundaryRule is AssociateWithLatterPage, we shouldn't just | 153 // When pageBoundaryRule is AssociateWithLatterPage, we shouldn't just |
154 // return 0 if there's no space left, because in that case we're at a | 154 // return 0 if there's no space left, because in that case we're at a |
155 // column boundary, in which case we should return the amount of space | 155 // column boundary, in which case we should return the amount of space |
156 // remaining in the *next* column. Note that the page height itself may be | 156 // remaining in the *next* column. Note that the page height itself may be |
157 // 0, though. | 157 // 0, though. |
158 remaining_logical_height = page_logical_height; | 158 remaining_logical_height = page_logical_height; |
159 } | 159 } |
160 return remaining_logical_height; | 160 return remaining_logical_height; |
161 } | 161 } |
162 | 162 |
163 bool LayoutMultiColumnSet::IsPageLogicalHeightKnown() const { | 163 bool LayoutMultiColumnSet::IsPageLogicalHeightKnown() const { |
164 return FirstFragmentainerGroup().LogicalHeight(); | 164 return FirstFragmentainerGroup().ColumnLogicalHeight(); |
165 } | 165 } |
166 | 166 |
167 bool LayoutMultiColumnSet::NewFragmentainerGroupsAllowed() const { | 167 bool LayoutMultiColumnSet::NewFragmentainerGroupsAllowed() const { |
168 if (!IsPageLogicalHeightKnown()) { | 168 if (!IsPageLogicalHeightKnown()) { |
169 // If we have no clue about the height of the multicol container, bail. This | 169 // If we have no clue about the height of the multicol container, bail. This |
170 // situation occurs initially when an auto-height multicol container is | 170 // situation occurs initially when an auto-height multicol container is |
171 // nested inside another auto-height multicol container. We need at least an | 171 // nested inside another auto-height multicol container. We need at least an |
172 // estimated height of the outer multicol container before we can check what | 172 // estimated height of the outer multicol container before we can check what |
173 // an inner fragmentainer group has room for. | 173 // an inner fragmentainer group has room for. |
174 // Its height is indefinite for now. | 174 // Its height is indefinite for now. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 // multicol), we need to look beyond the first row here. | 207 // multicol), we need to look beyond the first row here. |
208 const MultiColumnFragmentainerGroup& first_row = FirstFragmentainerGroup(); | 208 const MultiColumnFragmentainerGroup& first_row = FirstFragmentainerGroup(); |
209 LayoutUnit first_row_logical_bottom_in_flow_thread = | 209 LayoutUnit first_row_logical_bottom_in_flow_thread = |
210 first_row.LogicalTopInFlowThread() + | 210 first_row.LogicalTopInFlowThread() + |
211 FragmentainerGroupCapacity(first_row); | 211 FragmentainerGroupCapacity(first_row); |
212 if (flow_thread_offset >= first_row_logical_bottom_in_flow_thread) | 212 if (flow_thread_offset >= first_row_logical_bottom_in_flow_thread) |
213 return flow_thread_offset; // We're not in the first row. Give up. | 213 return flow_thread_offset; // We're not in the first row. Give up. |
214 LayoutUnit new_logical_height = | 214 LayoutUnit new_logical_height = |
215 enclosing_fragmentation_context->FragmentainerLogicalHeightAt( | 215 enclosing_fragmentation_context->FragmentainerLogicalHeightAt( |
216 first_row.BlockOffsetInEnclosingFragmentationContext() + | 216 first_row.BlockOffsetInEnclosingFragmentationContext() + |
217 first_row.LogicalHeight()); | 217 first_row.GroupLogicalHeight()); |
218 if (content_logical_height > new_logical_height) { | 218 if (content_logical_height > new_logical_height) { |
219 // The next outer column or page doesn't have enough space either. Give up | 219 // The next outer column or page doesn't have enough space either. Give up |
220 // and stay where we are. | 220 // and stay where we are. |
221 return flow_thread_offset; | 221 return flow_thread_offset; |
222 } | 222 } |
223 return first_row_logical_bottom_in_flow_thread; | 223 return first_row_logical_bottom_in_flow_thread; |
224 } | 224 } |
225 | 225 |
226 LayoutMultiColumnSet* LayoutMultiColumnSet::NextSiblingMultiColumnSet() const { | 226 LayoutMultiColumnSet* LayoutMultiColumnSet::NextSiblingMultiColumnSet() const { |
227 for (LayoutObject* sibling = NextSibling(); sibling; | 227 for (LayoutObject* sibling = NextSibling(); sibling; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 // multicol container. When setting up a new fragmentainer group, we always | 276 // multicol container. When setting up a new fragmentainer group, we always |
277 // constrain against the remaining portion of any specified | 277 // constrain against the remaining portion of any specified |
278 // height/max-height. This means that we shouldn't allow creation of | 278 // height/max-height. This means that we shouldn't allow creation of |
279 // fragmentainer groups below the bottom of the multicol container, or we'd | 279 // fragmentainer groups below the bottom of the multicol container, or we'd |
280 // end up with zero-height fragmentainer groups (or actually 1px; see | 280 // end up with zero-height fragmentainer groups (or actually 1px; see |
281 // heightAdjustedForRowOffset() in MultiColumnFragmentainerGroup, which | 281 // heightAdjustedForRowOffset() in MultiColumnFragmentainerGroup, which |
282 // guards against zero-height groups), i.e. potentially a lot of pretty | 282 // guards against zero-height groups), i.e. potentially a lot of pretty |
283 // useless fragmentainer groups, and possibly broken layout too. Instead, | 283 // useless fragmentainer groups, and possibly broken layout too. Instead, |
284 // we'll just allow additional (overflowing) columns to be created in the | 284 // we'll just allow additional (overflowing) columns to be created in the |
285 // last fragmentainer group, similar to what we do when we're not nested. | 285 // last fragmentainer group, similar to what we do when we're not nested. |
286 LayoutUnit logical_bottom = last_row.LogicalTop() + last_row.LogicalHeight(); | 286 LayoutUnit logical_bottom = |
| 287 last_row.LogicalTop() + last_row.GroupLogicalHeight(); |
287 LayoutUnit space_used = logical_bottom + LogicalTopFromMulticolContentEdge(); | 288 LayoutUnit space_used = logical_bottom + LogicalTopFromMulticolContentEdge(); |
288 LayoutUnit max_column_height = | 289 LayoutUnit max_column_height = |
289 MultiColumnFlowThread()->MaxColumnLogicalHeight(); | 290 MultiColumnFlowThread()->MaxColumnLogicalHeight(); |
290 return max_column_height - space_used > LayoutUnit(); | 291 return max_column_height - space_used > LayoutUnit(); |
291 } | 292 } |
292 | 293 |
293 MultiColumnFragmentainerGroup& | 294 MultiColumnFragmentainerGroup& |
294 LayoutMultiColumnSet::AppendNewFragmentainerGroup() { | 295 LayoutMultiColumnSet::AppendNewFragmentainerGroup() { |
295 MultiColumnFragmentainerGroup new_group(*this); | 296 MultiColumnFragmentainerGroup new_group(*this); |
296 { // Extra scope here for previousGroup; it's potentially invalid once we | 297 { // Extra scope here for previousGroup; it's potentially invalid once we |
297 // modify the m_fragmentainerGroups Vector. | 298 // modify the m_fragmentainerGroups Vector. |
298 MultiColumnFragmentainerGroup& previous_group = | 299 MultiColumnFragmentainerGroup& previous_group = |
299 fragmentainer_groups_.Last(); | 300 fragmentainer_groups_.Last(); |
300 | 301 |
301 // This is the flow thread block offset where |previousGroup| ends and | 302 // This is the flow thread block offset where |previousGroup| ends and |
302 // |newGroup| takes over. | 303 // |newGroup| takes over. |
303 LayoutUnit block_offset_in_flow_thread = | 304 LayoutUnit block_offset_in_flow_thread = |
304 previous_group.LogicalTopInFlowThread() + | 305 previous_group.LogicalTopInFlowThread() + |
305 FragmentainerGroupCapacity(previous_group); | 306 FragmentainerGroupCapacity(previous_group); |
306 previous_group.SetLogicalBottomInFlowThread(block_offset_in_flow_thread); | 307 previous_group.SetLogicalBottomInFlowThread(block_offset_in_flow_thread); |
307 new_group.SetLogicalTopInFlowThread(block_offset_in_flow_thread); | 308 new_group.SetLogicalTopInFlowThread(block_offset_in_flow_thread); |
308 new_group.SetLogicalTop(previous_group.LogicalTop() + | 309 new_group.SetLogicalTop(previous_group.LogicalTop() + |
309 previous_group.LogicalHeight()); | 310 previous_group.GroupLogicalHeight()); |
310 new_group.ResetColumnHeight(); | 311 new_group.ResetColumnHeight(); |
311 } | 312 } |
312 fragmentainer_groups_.Append(new_group); | 313 fragmentainer_groups_.Append(new_group); |
313 return fragmentainer_groups_.Last(); | 314 return fragmentainer_groups_.Last(); |
314 } | 315 } |
315 | 316 |
316 LayoutUnit LayoutMultiColumnSet::LogicalTopFromMulticolContentEdge() const { | 317 LayoutUnit LayoutMultiColumnSet::LogicalTopFromMulticolContentEdge() const { |
317 // We subtract the position of the first column set or spanner placeholder, | 318 // We subtract the position of the first column set or spanner placeholder, |
318 // rather than the "before" border+padding of the multicol container. This | 319 // rather than the "before" border+padding of the multicol container. This |
319 // distinction doesn't matter after layout, but during layout it does: | 320 // distinction doesn't matter after layout, but during layout it does: |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 min_logical_width = flow_thread_->MinPreferredLogicalWidth(); | 456 min_logical_width = flow_thread_->MinPreferredLogicalWidth(); |
456 max_logical_width = flow_thread_->MaxPreferredLogicalWidth(); | 457 max_logical_width = flow_thread_->MaxPreferredLogicalWidth(); |
457 } | 458 } |
458 | 459 |
459 void LayoutMultiColumnSet::ComputeLogicalHeight( | 460 void LayoutMultiColumnSet::ComputeLogicalHeight( |
460 LayoutUnit, | 461 LayoutUnit, |
461 LayoutUnit logical_top, | 462 LayoutUnit logical_top, |
462 LogicalExtentComputedValues& computed_values) const { | 463 LogicalExtentComputedValues& computed_values) const { |
463 LayoutUnit logical_height; | 464 LayoutUnit logical_height; |
464 for (const auto& group : fragmentainer_groups_) | 465 for (const auto& group : fragmentainer_groups_) |
465 logical_height += group.LogicalHeight(); | 466 logical_height += group.GroupLogicalHeight(); |
466 computed_values.extent_ = logical_height; | 467 computed_values.extent_ = logical_height; |
467 computed_values.position_ = logical_top; | 468 computed_values.position_ = logical_top; |
468 } | 469 } |
469 | 470 |
470 PositionWithAffinity LayoutMultiColumnSet::PositionForPoint( | 471 PositionWithAffinity LayoutMultiColumnSet::PositionForPoint( |
471 const LayoutPoint& point) { | 472 const LayoutPoint& point) { |
472 // Convert the visual point to a flow thread point. | 473 // Convert the visual point to a flow thread point. |
473 const MultiColumnFragmentainerGroup& row = | 474 const MultiColumnFragmentainerGroup& row = |
474 FragmentainerGroupAtVisualPoint(point); | 475 FragmentainerGroupAtVisualPoint(point); |
475 LayoutPoint flow_thread_point = row.VisualPointToFlowThreadPoint( | 476 LayoutPoint flow_thread_point = row.VisualPointToFlowThreadPoint( |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 // Now add in column rule bounds, if present. | 626 // Now add in column rule bounds, if present. |
626 Vector<LayoutRect> column_rule_bounds; | 627 Vector<LayoutRect> column_rule_bounds; |
627 if (ComputeColumnRuleBounds(LayoutPoint(), column_rule_bounds)) { | 628 if (ComputeColumnRuleBounds(LayoutPoint(), column_rule_bounds)) { |
628 for (auto& bound : column_rule_bounds) | 629 for (auto& bound : column_rule_bounds) |
629 block_flow_bounds.Unite(bound); | 630 block_flow_bounds.Unite(bound); |
630 } | 631 } |
631 return block_flow_bounds; | 632 return block_flow_bounds; |
632 } | 633 } |
633 | 634 |
634 } // namespace blink | 635 } // namespace blink |
OLD | NEW |