15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS IN..0TERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMultiColumnFlowThread.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMultiColumnSet.h" 30926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)RenderMultiColumnFlowThread::RenderMultiColumnFlowThread() 34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) : m_columnCount(1) 35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_columnHeightAvailable(0) 36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_inBalancingPass(false) 37323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) , m_needsColumnHeightsRecalculation(false) 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch , m_progressionIsInline(true) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setFlowThreadState(InsideInFlowThread); 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread() 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document& document, RenderStyle* parentStyle) 4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 49f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RenderMultiColumnFlowThread* renderer = new RenderMultiColumnFlowThread(); 50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) renderer->setDocumentForAnonymous(&document); 51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) renderer->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK)); 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return renderer; 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 55f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuRenderMultiColumnSet* RenderMultiColumnFlowThread::firstMultiColumnSet() const 56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 57f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) { 58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (sibling->isRenderMultiColumnSet()) 59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return toRenderMultiColumnSet(sibling); 60f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 61f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return 0; 62f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 63f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuRenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const 65f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 66f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; sibling = sibling->previousSibling()) { 67f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (sibling->isRenderMultiColumnSet()) 68f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return toRenderMultiColumnSet(sibling); 69f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 70f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return 0; 71f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 72f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 73f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid RenderMultiColumnFlowThread::addChild(RenderObject* newChild, RenderObject* beforeChild) 74f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 75f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu RenderBlockFlow::addChild(newChild, beforeChild); 76f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (firstMultiColumnSet()) 77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return; 78f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // For now we only create one column set. It's created as soon as the multicol container gets 80f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // any content at all. 81f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, multiColumnBlockFlow()->style()); 82f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 83f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // Need to skip RenderBlockFlow's implementation of addChild(), or we'd get redirected right 84f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // back here. 85f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu multiColumnBlockFlow()->RenderBlock::addChild(newSet); 86f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 87f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu invalidateRegions(); 88f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 89f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 906f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid RenderMultiColumnFlowThread::populate() 916f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 926f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 936f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!nextSibling()); 946f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // Reparent children preceding the flow thread into the flow thread. It's multicol content 956f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // now. At this point there's obviously nothing after the flow thread, but renderers (column 966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // sets and spanners) will be inserted there as we insert elements into the flow thread. 976f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, true); 986f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 996f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid RenderMultiColumnFlowThread::evacuateAndDestroy() 1016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 1026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 1036f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1046f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // Remove all sets. 105f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu while (RenderMultiColumnSet* columnSet = firstMultiColumnSet()) 106f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu columnSet->destroy(); 1076f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1086f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!previousSibling()); 1096f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch ASSERT(!nextSibling()); 1106f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1116f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // Finally we can promote all flow thread's children. Before we move them to the flow thread's 1126f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // container, we need to unregister the flow thread, so that they aren't just re-added again to 1136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch // the flow thread that we're trying to empty. 1146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch multicolContainer->resetMultiColumnFlowThread(); 1156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch moveAllChildrenTo(multicolContainer, true); 1166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 11710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch // FIXME: it's scary that neither destroy() nor the move*Children* methods take care of this, 11810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch // and instead leave you with dangling root line box pointers. But since this is how it is done 11910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch // in other parts of the code that deal with reparenting renderers, let's do the cleanup on our 12010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch // own here as well. 12110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch deleteLineBoxTree(); 12210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch 1236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch destroy(); 1246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 1256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 126f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuLayoutSize RenderMultiColumnFlowThread::columnOffset(const LayoutPoint& point) const 127f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 128f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (!hasValidRegionInfo()) 129f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return LayoutSize(0, 0); 130f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 131f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutPoint flowThreadPoint(point); 132f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu flipForWritingMode(flowThreadPoint); 133f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : flowThreadPoint.x(); 134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderMultiColumnSet* columnSet = columnSetAtBlockOffset(blockOffset); 135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!columnSet) 136f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return LayoutSize(0, 0); 137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return columnSet->flowThreadTranslationAtOffset(blockOffset); 138f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 139f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 140d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)bool RenderMultiColumnFlowThread::needsNewWidth() const 141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit newWidth; 143d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned dummyColumnCount; // We only care if used column-width changes. 144d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) calculateColumnCountAndWidth(newWidth, dummyColumnCount); 145d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return newWidth != logicalWidth(); 146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLayoutScope& layoutScope) 149d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (relayoutChildren) 151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) layoutScope.setChildNeedsLayout(this); 152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 153d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!needsLayout()) { 154d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Just before the multicol container (our parent RenderBlockFlow) finishes laying out, it 155d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // will call recalculateColumnHeights() on us unconditionally, but we only want that method 156d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // to do any work if we actually laid out the flow thread. Otherwise, the balancing 157d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // machinery would kick in needlessly, and trigger additional layout passes. Furthermore, we 158d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // actually depend on a proper flowthread layout pass in order to do balancing, since it's 159d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // flowthread layout that sets up content runs. 160d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_needsColumnHeightsRecalculation = false; 161d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return; 162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 164d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) { 165d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!m_inBalancingPass) { 166d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // This is the initial layout pass. We need to reset the column height, because contents 167d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // typically have changed. 168d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) columnSet->resetColumnHeight(); 169d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 172d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) invalidateRegions(); 173197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_needsColumnHeightsRecalculation = heightIsAuto(); 174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) layout(); 175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool RenderMultiColumnFlowThread::recalculateColumnHeights() 178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 179d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // All column sets that needed layout have now been laid out, so we can finally validate them. 180d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) validateRegions(); 181d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 182323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (!m_needsColumnHeightsRecalculation) 183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Column heights may change here because of balancing. We may have to do multiple layout 186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // passes, depending on how the contents is fitted to the changed column heights. In most 187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // cases, laying out again twice or even just once will suffice. Sometimes we need more 188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // passes than that, though, but the number of retries should not exceed the number of 189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // columns, unless we have a bug. 190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool needsRelayout = false; 191f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { 192d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) needsRelayout |= multicolSet->recalculateColumnHeight(m_inBalancingPass ? RenderMultiColumnSet::StretchBySpaceShortage : RenderMultiColumnSet::GuessFromFlowThreadPortion); 193d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (needsRelayout) { 194d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Once a column set gets a new column height, that column set and all successive column 195d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // sets need to be laid out over again, since their logical top will be affected by 196d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // this, and therefore their column heights may change as well, at least if the multicol 197d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // height is constrained. 198f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu multicolSet->setChildNeedsLayout(MarkOnlyThis); 199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (needsRelayout) 203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) setChildNeedsLayout(MarkOnlyThis); 204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_inBalancingPass = needsRelayout; 206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return needsRelayout; 207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 209d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RenderMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const 210d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 211d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RenderBlock* columnBlock = multiColumnBlockFlow(); 212d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const RenderStyle* columnStyle = columnBlock->style(); 213d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); 214d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit columnGap = columnBlock->columnGap(); 215d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->columnWidth())); 216d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); 217d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 218d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidth()); 219d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (columnStyle->hasAutoColumnWidth() && !columnStyle->hasAutoColumnCount()) { 220d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) count = computedColumnCount; 221d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) width = std::max<LayoutUnit>(0, (availableWidth - ((count - 1) * columnGap)) / count); 222d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else if (!columnStyle->hasAutoColumnWidth() && columnStyle->hasAutoColumnCount()) { 223d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) count = std::max<LayoutUnit>(1, (availableWidth + columnGap) / (computedColumnWidth + columnGap)); 224d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) width = ((availableWidth + columnGap) / count) - columnGap; 225d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else { 226d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) count = std::max<LayoutUnit>(std::min<LayoutUnit>(computedColumnCount, (availableWidth + columnGap) / (computedColumnWidth + columnGap)), 1); 227d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) width = ((availableWidth + columnGap) / count) - columnGap; 228d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 229d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 230d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RenderMultiColumnFlowThread::renderName() const 23202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return "RenderMultiColumnFlowThread"; 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 236197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderMultiColumnFlowThread::addRegionToThread(RenderMultiColumnSet* columnSet) 237f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 238f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (RenderMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) { 239197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderMultiColumnSetList::iterator it = m_multiColumnSetList.find(nextSet); 240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(it != m_multiColumnSetList.end()); 241197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_multiColumnSetList.insertBefore(it, columnSet); 242f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } else { 243197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_multiColumnSetList.add(columnSet); 244f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 245197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch columnSet->setIsValid(true); 246f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 247f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 248f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid RenderMultiColumnFlowThread::willBeRemovedFromTree() 249f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 250f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // Detach all column sets from the flow thread. Cannot destroy them at this point, since they 251f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // are siblings of this object, and there may be pointers to this object's sibling somewhere 252f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // further up on the call stack. 253f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) 254f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu columnSet->detachRegion(); 255f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu multiColumnBlockFlow()->resetMultiColumnFlowThread(); 256f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu RenderFlowThread::willBeRemovedFromTree(); 257f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 258f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We simply remain at our intrinsic height. 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computedValues.m_extent = logicalHeight; 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computedValues.m_position = logicalTop; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 266323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void RenderMultiColumnFlowThread::updateLogicalWidth() 267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 268d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit columnWidth; 269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) calculateColumnCountAndWidth(columnWidth, m_columnCount); 270d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) setLogicalWidth(columnWidth); 271323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)} 272323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 273323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void RenderMultiColumnFlowThread::layout() 274323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){ 275323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) RenderFlowThread::layout(); 276323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) 277323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) lastSet->expandToEncompassFlowThreadContentsIfNeeded(); 278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 279926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 280591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) 281591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 282d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Only positive values are interesting (and allowed) here. Zero space shortage may be reported 283d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // when we're at the top of a column and the element has zero height. Ignore this, and also 284d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // ignore any negative values, which may occur when we set an early break in order to honor 285d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // widows in the next column. 286d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (spaceShortage <= 0) 287d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return; 288d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 289197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) 290591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch multicolSet->recordSpaceShortage(spaceShortage); 291591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 292591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 293591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) 294591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 295197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) 296591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch multicolSet->updateMinimumColumnHeight(minHeight); 297591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 298591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 299197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRenderMultiColumnSet* RenderMultiColumnFlowThread::columnSetAtBlockOffset(LayoutUnit /*offset*/) const 300f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 301f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu // For now there's only one column set, so this is easy: 302f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return firstMultiColumnSet(); 303f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 304f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 30509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, RenderObject* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment) 30609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 307197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) { 308d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) multicolSet->addContentRun(offset); 30909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (offsetBreakAdjustment) 31009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRemainingLogicalHeightForOffset(offset, IncludePageBoundary) : LayoutUnit(); 31109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return true; 31209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 31309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; 31409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 31509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 31607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochbool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const 31707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 318f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) 319d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return columnSet->pageLogicalHeight(); 320f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return false; 32107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 32207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 324