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

Side by Side Diff: Source/core/rendering/RenderMultiColumnBlock.cpp

Issue 179993006: [New multicol] Eliminate the need for RenderMultiColumnBlock. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Code review Created 6 years, 9 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
(Empty)
1 /*
2 * Copyright (C) 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "core/rendering/RenderMultiColumnBlock.h"
28
29 #include "core/rendering/RenderMultiColumnFlowThread.h"
30 #include "core/rendering/RenderMultiColumnSet.h"
31 #include "core/rendering/RenderView.h"
32
33 using namespace std;
34
35 namespace WebCore {
36
37 RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element)
38 : RenderBlockFlow(element)
39 , m_flowThread(0)
40 , m_columnCount(1)
41 , m_columnWidth(0)
42 , m_columnHeightAvailable(0)
43 , m_inBalancingPass(false)
44 , m_needsRebalancing(false)
45 {
46 }
47
48 void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderSt yle* oldStyle)
49 {
50 RenderBlockFlow::styleDidChange(diff, oldStyle);
51 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo x())
52 child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BL OCK));
53 }
54
55 void RenderMultiColumnBlock::computeColumnCountAndWidth()
56 {
57 // Calculate our column width and column count.
58 // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibli ng4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
59 m_columnCount = 1;
60 m_columnWidth = contentLogicalWidth();
61
62 ASSERT(!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth());
63
64 LayoutUnit availWidth = m_columnWidth;
65 LayoutUnit colGap = columnGap();
66 LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth())) ;
67 int colCount = max<int>(1, style()->columnCount());
68
69 if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
70 m_columnCount = colCount;
71 m_columnWidth = max<LayoutUnit>(0, (availWidth - ((m_columnCount - 1) * colGap)) / m_columnCount);
72 } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
73 m_columnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + c olGap));
74 m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
75 } else {
76 m_columnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
77 m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
78 }
79 }
80
81 bool RenderMultiColumnBlock::updateLogicalWidthAndColumnWidth()
82 {
83 bool relayoutChildren = RenderBlockFlow::updateLogicalWidthAndColumnWidth();
84 LayoutUnit oldColumnWidth = m_columnWidth;
85 computeColumnCountAndWidth();
86 if (m_columnWidth != oldColumnWidth)
87 relayoutChildren = true;
88 return relayoutChildren;
89 }
90
91 void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& / *pageLogicalHeight*/, bool& /*pageLogicalHeightChanged*/, bool& /*hasSpecifiedPa geLogicalHeight*/)
92 {
93 // We don't actually update any of the variables. We just subclassed to adju st our column height.
94 updateLogicalHeight();
95 m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0);
96 setLogicalHeight(0);
97 }
98
99 bool RenderMultiColumnBlock::shouldRelayoutMultiColumnBlock()
100 {
101 if (!m_needsRebalancing)
102 return false;
103
104 // Column heights may change here because of balancing. We may have to do mu ltiple layout
105 // passes, depending on how the contents is fitted to the changed column hei ghts. In most
106 // cases, laying out again twice or even just once will suffice. Sometimes w e need more
107 // passes than that, though, but the number of retries should not exceed the number of
108 // columns, unless we have a bug.
109 bool needsRelayout = false;
110 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->n extSiblingBox()) {
111 if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
112 RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox) ;
113 if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) {
114 multicolSet->setChildNeedsLayout(MarkOnlyThis);
115 needsRelayout = true;
116 }
117 }
118 }
119
120 if (needsRelayout)
121 m_flowThread->setChildNeedsLayout(MarkOnlyThis);
122
123 m_inBalancingPass = needsRelayout;
124 return needsRelayout;
125 }
126
127 void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* befo reChild)
128 {
129 if (!m_flowThread) {
130 m_flowThread = RenderMultiColumnFlowThread::createAnonymous(&document()) ;
131 m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(styl e(), BLOCK));
132 RenderBlockFlow::addChild(m_flowThread);
133 }
134 m_flowThread->addChild(newChild, beforeChild);
135 }
136
137 RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutCh ildren, SubtreeLayoutScope& layoutScope)
138 {
139 if (!m_flowThread)
140 return 0;
141
142 // Update the dimensions of our regions before we lay out the flow thread.
143 // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
144 // instead of trying to keep them around.
145 bool shouldInvalidateRegions = false;
146 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->n extSiblingBox()) {
147 if (childBox == m_flowThread)
148 continue;
149
150 if (relayoutChildren || childBox->needsLayout()) {
151 if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
152 toRenderMultiColumnSet(childBox)->prepareForLayout();
153 shouldInvalidateRegions = true;
154 }
155 }
156
157 if (shouldInvalidateRegions)
158 m_flowThread->invalidateRegions();
159
160 if (relayoutChildren)
161 layoutScope.setChildNeedsLayout(m_flowThread);
162
163 if (requiresBalancing()) {
164 // At the end of multicol layout, relayoutForPagination() is called unco nditionally, but if
165 // no children are to be laid out (e.g. fixed width with layout already being up-to-date),
166 // we want to prevent it from doing any work, so that the column balanci ng machinery doesn't
167 // kick in and trigger additional unnecessary layout passes. Actually, i t's not just a good
168 // idea in general to not waste time on balancing content that hasn't be en re-laid out; we
169 // are actually required to guarantee this. The calculation of implicit breaks needs to be
170 // preceded by a proper layout pass, since it's layout that sets up cont ent runs, and the
171 // runs get deleted right after every pass.
172 m_needsRebalancing = shouldInvalidateRegions || m_flowThread->needsLayou t();
173 }
174
175 setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore());
176 m_flowThread->layoutIfNeeded();
177 determineLogicalLeftPositionForChild(m_flowThread);
178
179 return m_flowThread;
180 }
181
182 const char* RenderMultiColumnBlock::renderName() const
183 {
184 if (isFloating())
185 return "RenderMultiColumnBlock (floating)";
186 if (isOutOfFlowPositioned())
187 return "RenderMultiColumnBlock (positioned)";
188 if (isAnonymousBlock())
189 return "RenderMultiColumnBlock (anonymous)";
190 // FIXME: Temporary hack while the new generated content system is being imp lemented.
191 if (isPseudoElement())
192 return "RenderMultiColumnBlock (generated)";
193 if (isAnonymous())
194 return "RenderMultiColumnBlock (generated)";
195 if (isRelPositioned())
196 return "RenderMultiColumnBlock (relative positioned)";
197 return "RenderMultiColumnBlock";
198 }
199
200 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698