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

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

Issue 1856373002: Only allow forced fragmentainer breaks at class A break points. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Woho! LayoutTests/printing/css2.1/page-break-after-003.html now passes. Created 4 years, 8 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/layout/ColumnBalancer.h" 5 #include "core/layout/ColumnBalancer.h"
6 6
7 #include "core/layout/LayoutMultiColumnFlowThread.h" 7 #include "core/layout/LayoutMultiColumnFlowThread.h"
8 #include "core/layout/LayoutMultiColumnSet.h" 8 #include "core/layout/LayoutMultiColumnSet.h"
9 #include "core/layout/api/LineLayoutBlockFlow.h" 9 #include "core/layout/api/LineLayoutBlockFlow.h"
10 10
11 namespace blink { 11 namespace blink {
12 12
13 ColumnBalancer::ColumnBalancer(const MultiColumnFragmentainerGroup& group) 13 ColumnBalancer::ColumnBalancer(const MultiColumnFragmentainerGroup& group)
14 : m_group(group) 14 : m_group(group)
15 , m_previousBreakAfterValue(BreakAuto)
15 { 16 {
16 } 17 }
17 18
18 void ColumnBalancer::traverse() 19 void ColumnBalancer::traverse()
19 { 20 {
20 traverseSubtree(*m_group.columnSet().flowThread()); 21 traverseSubtree(*m_group.columnSet().flowThread());
21 ASSERT(!flowThreadOffset()); 22 ASSERT(!flowThreadOffset());
22 } 23 }
23 24
24 void ColumnBalancer::traverseSubtree(const LayoutBox& box) 25 void ColumnBalancer::traverseSubtree(const LayoutBox& box)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 // Tables are wicked. Both table rows and table cells are relative to th eir table section. 63 // Tables are wicked. Both table rows and table cells are relative to th eir table section.
63 LayoutUnit offsetForThisChild = childBox.isTableRow() ? LayoutUnit() : c hildBox.logicalTop(); 64 LayoutUnit offsetForThisChild = childBox.isTableRow() ? LayoutUnit() : c hildBox.logicalTop();
64 m_flowThreadOffset += offsetForThisChild; 65 m_flowThreadOffset += offsetForThisChild;
65 66
66 examineBoxAfterEntering(childBox); 67 examineBoxAfterEntering(childBox);
67 // Unless the child is unsplittable, or if the child establishes an inne r multicol 68 // Unless the child is unsplittable, or if the child establishes an inne r multicol
68 // container, we descend into its subtree for further examination. 69 // container, we descend into its subtree for further examination.
69 if (childBox.getPaginationBreakability() != LayoutBox::ForbidBreaks 70 if (childBox.getPaginationBreakability() != LayoutBox::ForbidBreaks
70 && (!childBox.isLayoutBlockFlow() || !toLayoutBlockFlow(childBox).mu ltiColumnFlowThread())) 71 && (!childBox.isLayoutBlockFlow() || !toLayoutBlockFlow(childBox).mu ltiColumnFlowThread()))
71 traverseSubtree(childBox); 72 traverseSubtree(childBox);
73 m_previousBreakAfterValue = childBox.breakAfter();
72 examineBoxBeforeLeaving(childBox); 74 examineBoxBeforeLeaving(childBox);
73 75
74 m_flowThreadOffset -= offsetForThisChild; 76 m_flowThreadOffset -= offsetForThisChild;
75 } 77 }
76 } 78 }
77 79
78 InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentai nerGroup& group) 80 InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentai nerGroup& group)
79 : ColumnBalancer(group) 81 : ColumnBalancer(group)
80 { 82 {
81 m_shortestStruts.resize(group.columnSet().usedColumnCount()); 83 m_shortestStruts.resize(group.columnSet().usedColumnCount());
82 for (auto& strut : m_shortestStruts) 84 for (auto& strut : m_shortestStruts)
83 strut = LayoutUnit::max(); 85 strut = LayoutUnit::max();
84 traverse(); 86 traverse();
85 // We have now found each explicit / forced break, and their location. Now w e need to figure out 87 // We have now found each explicit / forced break, and their location. Now w e need to figure out
86 // how many additional implicit / soft breaks we need and guess where they w ill occur, in order 88 // how many additional implicit / soft breaks we need and guess where they w ill occur, in order
87 // to provide an initial column height. 89 // to provide an initial column height.
88 distributeImplicitBreaks(); 90 distributeImplicitBreaks();
89 } 91 }
90 92
91 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const 93 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const
92 { 94 {
93 unsigned index = contentRunIndexWithTallestColumns(); 95 unsigned index = contentRunIndexWithTallestColumns();
94 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread(); 96 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread();
95 return m_contentRuns[index].columnLogicalHeight(startOffset); 97 return m_contentRuns[index].columnLogicalHeight(startOffset);
96 } 98 }
97 99
98 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) 100 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box)
99 { 101 {
100 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { 102 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) {
101 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); 103 if (box.needsForcedBreakBefore(previousBreakAfterValue())) {
102 if (box.hasForcedBreakBefore()) {
103 addContentRun(flowThreadOffset()); 104 addContentRun(flowThreadOffset());
104 } else if (isFirstAfterBreak(flowThreadOffset())) { 105 } else if (isFirstAfterBreak(flowThreadOffset())) {
105 // This box is first after a soft break. 106 // This box is first after a soft break.
107 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut ());
106 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); 108 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut());
107 } 109 }
108 } 110 }
109 111
110 if (box.hasForcedBreakAfter()) {
111 LayoutUnit logicalBottomInFlowThread = flowThreadOffset() + box.logicalH eight();
112 if (isLogicalBottomWithinBounds(logicalBottomInFlowThread))
113 addContentRun(logicalBottomInFlowThread);
114 }
115
116 if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) { 112 if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) {
117 LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); 113 LayoutUnit unsplittableLogicalHeight = box.logicalHeight();
118 if (box.isFloating()) 114 if (box.isFloating())
119 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); 115 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter();
120 m_tallestUnbreakableLogicalHeight = std::max(m_tallestUnbreakableLogical Height, unsplittableLogicalHeight); 116 m_tallestUnbreakableLogicalHeight = std::max(m_tallestUnbreakableLogical Height, unsplittableLogicalHeight);
121 return; 117 return;
122 } 118 }
123 // Need to examine inner multicol containers to find their tallest unbreakab le piece of content. 119 // Need to examine inner multicol containers to find their tallest unbreakab le piece of content.
124 if (!box.isLayoutBlockFlow()) 120 if (!box.isLayoutBlockFlow())
125 return; 121 return;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 { 236 {
241 traverse(); 237 traverse();
242 } 238 }
243 239
244 void MinimumSpaceShortageFinder::examineBoxAfterEntering(const LayoutBox& box) 240 void MinimumSpaceShortageFinder::examineBoxAfterEntering(const LayoutBox& box)
245 { 241 {
246 LayoutBox::PaginationBreakability breakability = box.getPaginationBreakabili ty(); 242 LayoutBox::PaginationBreakability breakability = box.getPaginationBreakabili ty();
247 243
248 // Look for breaks before the child box. 244 // Look for breaks before the child box.
249 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { 245 if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) {
250 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); 246 if (box.needsForcedBreakBefore(previousBreakAfterValue())) {
251 if (box.hasForcedBreakBefore()) {
252 m_forcedBreaksCount++; 247 m_forcedBreaksCount++;
253 } else if (isFirstAfterBreak(flowThreadOffset())) { 248 } else if (isFirstAfterBreak(flowThreadOffset())) {
254 // This box is first after a soft break. 249 // This box is first after a soft break.
250 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut ());
255 LayoutUnit strut = box.paginationStrut(); 251 LayoutUnit strut = box.paginationStrut();
256 // Figure out how much more space we would need to prevent it from b eing pushed to the next column. 252 // Figure out how much more space we would need to prevent it from b eing pushed to the next column.
257 recordSpaceShortage(box.logicalHeight() - strut); 253 recordSpaceShortage(box.logicalHeight() - strut);
258 if (breakability != LayoutBox::ForbidBreaks && m_pendingStrut == Lay outUnit::min()) { 254 if (breakability != LayoutBox::ForbidBreaks && m_pendingStrut == Lay outUnit::min()) {
259 // We now want to look for the first piece of unbreakable conten t (e.g. a line or a 255 // We now want to look for the first piece of unbreakable conten t (e.g. a line or a
260 // block-displayed image) inside this block. That ought to be a good candidate for 256 // block-displayed image) inside this block. That ought to be a good candidate for
261 // minimum space shortage; a much better one than reporting spac e shortage for the 257 // minimum space shortage; a much better one than reporting spac e shortage for the
262 // entire block (which we'll also do (further down), in case we couldn't find anything 258 // entire block (which we'll also do (further down), in case we couldn't find anything
263 // more suitable). 259 // more suitable).
264 m_pendingStrut = strut; 260 m_pendingStrut = strut;
265 } 261 }
266 } 262 }
267 } 263 }
268 264
269 if (box.hasForcedBreakAfter() && isLogicalBottomWithinBounds(flowThreadOffse t() + box.logicalHeight()))
270 m_forcedBreaksCount++;
271
272 if (breakability != LayoutBox::ForbidBreaks) { 265 if (breakability != LayoutBox::ForbidBreaks) {
273 // See if this breakable box crosses column boundaries. 266 // See if this breakable box crosses column boundaries.
274 LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight() ; 267 LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight() ;
275 if (isFirstAfterBreak(flowThreadOffset()) 268 if (isFirstAfterBreak(flowThreadOffset())
276 || group().columnLogicalTopForOffset(flowThreadOffset()) != group(). columnLogicalTopForOffset(bottomInFlowThread)) { 269 || group().columnLogicalTopForOffset(flowThreadOffset()) != group(). columnLogicalTopForOffset(bottomInFlowThread)) {
277 // If the child crosses a column boundary, record space shortage, in case nothing 270 // If the child crosses a column boundary, record space shortage, in case nothing
278 // inside it has already done so. The column balancer needs to know by how much it 271 // inside it has already done so. The column balancer needs to know by how much it
279 // has to stretch the columns to make more content fit. If no breaks are reported 272 // has to stretch the columns to make more content fit. If no breaks are reported
280 // (but do occur), the balancer will have no clue. Only measure the space after the 273 // (but do occur), the balancer will have no clue. Only measure the space after the
281 // last column boundary, in case it crosses more than one. 274 // last column boundary, in case it crosses more than one.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend ingStrut); 317 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend ingStrut);
325 m_pendingStrut = LayoutUnit::min(); 318 m_pendingStrut = LayoutUnit::min();
326 return; 319 return;
327 } 320 }
328 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut() || !isLogicalTopWithinBounds(lineTopInFlowThread - line.paginationStrut())); 321 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut() || !isLogicalTopWithinBounds(lineTopInFlowThread - line.paginationStrut()));
329 if (isFirstAfterBreak(lineTopInFlowThread)) 322 if (isFirstAfterBreak(lineTopInFlowThread))
330 recordSpaceShortage(lineHeight - line.paginationStrut()); 323 recordSpaceShortage(lineHeight - line.paginationStrut());
331 } 324 }
332 325
333 } // namespace blink 326 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/ColumnBalancer.h ('k') | third_party/WebKit/Source/core/layout/LayoutBlockFlow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698