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 INTERRUPTION) 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/RenderMultiColumnSet.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BoxPainter.h" 307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/MultiColumnSetPainter.h" 317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/ObjectPainter.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/PaintInfo.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMultiColumnFlowThread.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderMultiColumnSet::RenderMultiColumnSet(RenderFlowThread* flowThread) 39323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) : RenderRegion(0, flowThread) 40d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_columnHeight(0) 4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_maxColumnHeight(RenderFlowThread::maxLogicalHeight()) 4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_minSpaceShortage(RenderFlowThread::maxLogicalHeight()) 43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_minimumColumnHeight(0) 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 47f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuRenderMultiColumnSet* RenderMultiColumnSet::createAnonymous(RenderFlowThread* flowThread, RenderStyle* parentStyle) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) Document& document = flowThread->document(); 50f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RenderMultiColumnSet* renderer = new RenderMultiColumnSet(flowThread); 518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) renderer->setDocumentForAnonymous(&document); 52f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu renderer->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK)); 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return renderer; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 56f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuRenderMultiColumnSet* RenderMultiColumnSet::nextSiblingMultiColumnSet() const 57f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) { 59f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (sibling->isRenderMultiColumnSet()) 60f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return toRenderMultiColumnSet(sibling); 61f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 62f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return 0; 63f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 64f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)RenderMultiColumnSet* RenderMultiColumnSet::previousSiblingMultiColumnSet() const 66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 67d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) { 68d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (sibling->isRenderMultiColumnSet()) 69d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return toRenderMultiColumnSet(sibling); 70d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 71d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return 0; 72d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 73d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 74f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuLayoutSize RenderMultiColumnSet::flowThreadTranslationAtOffset(LayoutUnit blockOffset) const 75f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 76f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu unsigned columnIndex = columnIndexAtOffset(blockOffset); 77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutRect portionRect(flowThreadPortionRectAt(columnIndex)); 78f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu flipForWritingMode(portionRect); 79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutRect columnRect(columnRectAt(columnIndex)); 80f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu flipForWritingMode(columnRect); 81f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return contentBoxRect().location() + columnRect.location() - portionRect.location(); 82f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 83f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 84591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochLayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const 85591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 86d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Adjust for the top offset within the content box of the multicol container (containing 87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // block), unless this is the first set. We know that the top offset for the first set will be 88d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // zero, but if the multicol container has non-zero top border or padding, the set's top offset 89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // (initially being 0 and relative to the border box) will be negative until it has been laid 90d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // out. Had we used this bogus offset, we would calculate the wrong height, and risk performing 91d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // a wasted layout iteration. Of course all other sets (if any) have this problem in the first 92d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // layout pass too, but there's really nothing we can do there until the flow thread has been 93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // laid out anyway. 94d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (previousSiblingMultiColumnSet()) { 95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); 96d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderAndPaddingBefore(); 97d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) height -= contentLogicalTop; 98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 99591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created. 100591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 101591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) const 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 104591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch unsigned columnIndex = columnIndexAtOffset(offset, AssumeNewColumns); 105d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return logicalTopInFlowThread() + columnIndex * pageLogicalHeight(); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 108591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderMultiColumnSet::setAndConstrainColumnHeight(LayoutUnit newHeight) 109591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 110d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_columnHeight = newHeight; 111d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (m_columnHeight > m_maxColumnHeight) 112d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_columnHeight = m_maxColumnHeight; 113591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // FIXME: the height may also be affected by the enclosing pagination context, if any. 114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)unsigned RenderMultiColumnSet::findRunWithTallestColumns() const 117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) unsigned indexWithLargestHeight = 0; 11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutUnit largestHeight; 120d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit previousOffset = logicalTopInFlowThread(); 12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) size_t runCount = m_contentRuns.size(); 12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(runCount); 12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) for (size_t i = 0; i < runCount; i++) { 12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const ContentRun& run = m_contentRuns[i]; 12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutUnit height = run.columnLogicalHeight(previousOffset); 12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (largestHeight < height) { 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) largestHeight = height; 12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) indexWithLargestHeight = i; 12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) previousOffset = run.breakOffset(); 13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return indexWithLargestHeight; 13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RenderMultiColumnSet::distributeImplicitBreaks() 13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // There should be no implicit breaks assumed at this point. 139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) for (unsigned i = 0; i < m_contentRuns.size(); i++) 14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(!m_contentRuns[i].assumedImplicitBreaks()); 141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif // ENABLE(ASSERT) 14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 143323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Insert a final content run to encompass all content. This will include overflow if this is 144323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // the last set. 145d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) addContentRun(logicalBottomInFlowThread()); 146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned columnCount = m_contentRuns.size(); 14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If there is room for more breaks (to reach the used value of column-count), imagine that we 14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // insert implicit breaks at suitable locations. At any given time, the content run with the 15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // currently tallest columns will get another implicit break "inserted", which will increase its 15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // column count by one and shrink its columns' height. Repeat until we have the desired total 15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // number of breaks. The largest column height among the runs will then be the initial column 15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // height for the balancer to use. 154d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) while (columnCount < usedColumnCount()) { 15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) unsigned index = findRunWithTallestColumns(); 15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_contentRuns[index].assumeAnotherImplicitBreak(); 157d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) columnCount++; 15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 160591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 161d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)LayoutUnit RenderMultiColumnSet::calculateColumnHeight(BalancedHeightCalculation calculationMode) const 16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 163d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (calculationMode == GuessFromFlowThreadPortion) { 164d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Initial balancing. Start with the lowest imaginable column height. We use the tallest 165d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // content run (after having "inserted" implicit breaks), and find its start offset (by 166d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // looking at the previous run's end offset, or, if there's no previous run, the set's start 167d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // offset in the flow thread). 16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) unsigned index = findRunWithTallestColumns(); 169d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : logicalTopInFlowThread(); 17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(startOffset), m_minimumColumnHeight); 171591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 172591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 173d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (actualColumnCount() <= usedColumnCount()) { 174591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // With the current column height, the content fits without creating overflowing columns. We're done. 175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_columnHeight; 17609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 178d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (m_contentRuns.size() >= usedColumnCount()) { 17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Too many forced breaks to allow any implicit breaks. Initial balancing should already 18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // have set a good height. There's nothing more we should do. 181d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_columnHeight; 182591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 183591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 184591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest 185591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // amount of space shortage found during layout. 186591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! 18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If this happens, we probably have a bug. 18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) 190d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_columnHeight; // So bail out rather than looping infinitely. 191591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 192d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return m_columnHeight + m_minSpaceShortage; 19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 195d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage) 19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!multiColumnFlowThread()->heightIsAuto()) 19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 199d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last().breakOffset()) 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Append another item as long as we haven't exceeded used column count. What ends up in the 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // overflow area shouldn't affect column balancing. 203d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (m_contentRuns.size() < usedColumnCount()) 204d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_contentRuns.append(ContentRun(endOffsetFromFirstPage)); 20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 207d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation calculationMode) 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(multiColumnFlowThread()->heightIsAuto()); 21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 211d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit oldColumnHeight = m_columnHeight; 212d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (calculationMode == GuessFromFlowThreadPortion) { 213d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Post-process the content runs and find out where the implicit breaks will occur. 21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) distributeImplicitBreaks(); 215d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 216d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode); 21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) setAndConstrainColumnHeight(newColumnHeight); 21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // After having calculated an initial column height, the multicol container typically needs at 22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // least one more layout pass with a new column height, but if a height was specified, we only 22109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // need to do this if we think that we need less space than specified. Conversely, if we 22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // determined that the columns need to be as tall as the specified height of the container, we 22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // have already laid it out correctly, and there's no need for another pass. 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 225d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // We can get rid of the content runs now, if we haven't already done so. They are only needed 226d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // to calculate the initial balanced column height. In fact, we have to get rid of them before 227d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // the next layout pass, since each pass will rebuild this. 228d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_contentRuns.clear(); 229d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 230d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (m_columnHeight == oldColumnHeight) 23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; // No change. We're done. 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return true; // Need another pass. 235591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 236591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 237591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage) 238591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 239591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (spaceShortage >= m_minSpaceShortage) 240591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 241591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 242591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // The space shortage is what we use as our stretch amount. We need a positive number here in 243591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // order to get anywhere. 244591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(spaceShortage > 0); 245591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 246591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_minSpaceShortage = spaceShortage; 247591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 248591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 249d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RenderMultiColumnSet::resetColumnHeight() 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 251d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Nuke previously stored minimum column height. Contents may have changed for all we know. 252d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_minimumColumnHeight = 0; 253591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 254d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_maxColumnHeight = calculateMaxColumnHeight(); 255591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 256d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit oldColumnHeight = pageLogicalHeight(); 257591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (multiColumnFlowThread()->heightIsAuto()) 259d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_columnHeight = 0; 260d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) else 261f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowThread()->columnHeightAvailable())); 262591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 263d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (pageLogicalHeight() != oldColumnHeight) 264d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) setChildNeedsLayout(MarkOnlyThis); 26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 266d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Content runs are only needed in the initial layout pass, in order to find an initial column 267d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // height, and should have been deleted afterwards. We're about to rebuild the content runs, so 268d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // the list needs to be empty. 269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ASSERT(m_contentRuns.isEmpty()); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 272323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded() 273323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles){ 274323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this); 275323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) LayoutRect rect(flowThreadPortionRect()); 276323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 277323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Get the offset within the flow thread in its block progression direction. Then get the 278323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // flow thread's remaining logical height including its overflow and expand our rect 279323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // to encompass that remaining height and overflow. The idea is that we will generate 280323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // additional columns and pages to hold that overflow, since people do write bad 281323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // content like <body style="height:0px"> in multi-column layouts. 282323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) bool isHorizontal = flowThread()->isHorizontalWritingMode(); 283323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) LayoutUnit logicalTopOffset = isHorizontal ? rect.y() : rect.x(); 284323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) LayoutRect layoutRect = flowThread()->layoutOverflowRect(); 285323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) LayoutUnit logicalHeightWithOverflow = (isHorizontal ? layoutRect.maxY() : layoutRect.maxX()) - logicalTopOffset; 286323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) setFlowThreadPortionRect(LayoutRect(rect.x(), rect.y(), isHorizontal ? rect.width() : logicalHeightWithOverflow, isHorizontal ? logicalHeightWithOverflow : rect.height())); 287323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)} 288323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 289591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 291d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) computedValues.m_extent = m_columnHeight; 292591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch computedValues.m_position = logicalTop; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)LayoutUnit RenderMultiColumnSet::calculateMaxColumnHeight() const 296d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 297d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RenderBlockFlow* multicolBlock = multiColumnBlockFlow(); 298d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RenderStyle* multicolStyle = multicolBlock->style(); 299d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit availableHeight = multiColumnFlowThread()->columnHeightAvailable(); 300d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit maxColumnHeight = availableHeight ? availableHeight : RenderFlowThread::maxLogicalHeight(); 3019e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (!multicolStyle->logicalMaxHeight().isMaxSizeNone()) { 302d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalMaxHeight(), -1); 303d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight) 304d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) maxColumnHeight = logicalMaxHeight; 305d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 306d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return heightAdjustedForSetOffset(maxColumnHeight); 307d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 308d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutUnit RenderMultiColumnSet::columnGap() const 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RenderBlockFlow* parentBlock = multiColumnBlockFlow(); 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (parentBlock->style()->hasNormalColumnGap()) 313926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return parentBlock->style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins. 314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return parentBlock->style()->columnGap(); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 317d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)unsigned RenderMultiColumnSet::actualColumnCount() const 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 319591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // We must always return a value of 1 or greater. Column count = 0 is a meaningless situation, 320591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // and will confuse and cause problems in other parts of the code. 321d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!pageLogicalHeight()) 322591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 1; 323591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Our portion rect determines our column count. We have as many columns as needed to fit all the content. 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit logicalHeightInColumns = flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width(); 326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!logicalHeightInColumns) 327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return 1; 328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 329d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned count = ceil(logicalHeightInColumns.toFloat() / pageLogicalHeight().toFloat()); 330591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT(count >= 1); 331591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return count; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 336d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit colLogicalWidth = pageLogicalWidth(); 337d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit colLogicalHeight = pageLogicalHeight(); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit colLogicalTop = borderBefore() + paddingBefore(); 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft(); 340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutUnit colGap = columnGap(); 341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 342197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (multiColumnFlowThread()->progressionIsInline()) { 343197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (style()->isLeftToRightDirection()) 344197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch colLogicalLeft += index * (colLogicalWidth + colGap); 345197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch else 346197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap); 347197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else { 348197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch colLogicalTop += index * (colLogicalHeight + colGap); 349197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontalWritingMode()) 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 356591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochunsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnIndexCalculationMode mode) const 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect portionRect(flowThreadPortionRect()); 359591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Handle the offset being out of range. 361591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch LayoutUnit flowThreadLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (offset < flowThreadLogicalTop) 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 364591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // If we're laying out right now, we cannot constrain against some logical bottom, since it 365591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // isn't known yet. Otherwise, just return the last column if we're past the logical bottom. 366591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (mode == ClampToExistingColumns) { 367591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX(); 368591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (offset >= flowThreadLogicalBottom) 369d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return actualColumnCount() - 1; 370591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 371591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Just divide by the column height to determine the correct column. 373d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return (offset - flowThreadLogicalTop).toFloat() / pageLogicalHeight().toFloat(); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)LayoutRect RenderMultiColumnSet::flowThreadPortionRectAt(unsigned index) const 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect portionRect = flowThreadPortionRect(); 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontalWritingMode()) 380d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) portionRect = LayoutRect(portionRect.x(), portionRect.y() + index * pageLogicalHeight(), portionRect.width(), pageLogicalHeight()); 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 382d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) portionRect = LayoutRect(portionRect.x() + index * pageLogicalHeight(), portionRect.y(), pageLogicalHeight(), portionRect.height()); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return portionRect; 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 386926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)LayoutRect RenderMultiColumnSet::flowThreadPortionOverflowRect(const LayoutRect& portionRect, unsigned index, unsigned colCount, LayoutUnit colGap) const 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This function determines the portion of the flow thread that paints for the column. Along the inline axis, columns are 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // unclipped at outside edges (i.e., the first and last column in the set), and they clip to half the column 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // gap along interior edges. 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // In the block direction, we will not clip overflow out of the top of the first column, or out of the bottom of 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the last column. This applies only to the true first column and last column across all column sets. 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Eventually we will know overflow on a per-column basis, but we can't do this until we have a painting 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // mode that understands not to paint contents from a previous column in the overflow area of a following column. 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This problem applies to regions and pages as well and is not unique to columns. 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isFirstColumn = !index; 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isLastColumn = index == colCount - 1; 400926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool isLeftmostColumn = style()->isLeftToRightDirection() ? isFirstColumn : isLastColumn; 401926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) bool isRightmostColumn = style()->isLeftToRightDirection() ? isLastColumn : isFirstColumn; 4021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 4031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Calculate the overflow rectangle, based on the flow thread's, clipped at column logical 4041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // top/bottom unless it's the first/last column. 4051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) LayoutRect overflowRect = overflowRectForFlowThreadPortion(portionRect, isFirstColumn && isFirstRegion(), isLastColumn && isLastRegion()); 4061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 4071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Avoid overflowing into neighboring columns, by clipping in the middle of adjacent column 4081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // gaps. Also make sure that we avoid rounding errors. 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontalWritingMode()) { 4101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!isLeftmostColumn) 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) overflowRect.shiftXEdgeTo(portionRect.x() - colGap / 2); 4121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!isRightmostColumn) 4131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) overflowRect.shiftMaxXEdgeTo(portionRect.maxX() + colGap - colGap / 2); 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!isLeftmostColumn) 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) overflowRect.shiftYEdgeTo(portionRect.y() - colGap / 2); 4171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!isRightmostColumn) 4181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) overflowRect.shiftMaxYEdgeTo(portionRect.maxY() + colGap - colGap / 2); 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return overflowRect; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderMultiColumnSet::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci MultiColumnSetPainter(*this).paintObject(paintInfo, paintOffset); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4289e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void RenderMultiColumnSet::paintInvalidationForFlowThreadContent(const LayoutRect& paintInvalidationRect) const 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Figure out the start and end columns and only check within that range so that we don't walk the 4319e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // entire column set. Put the paint invalidation rect into flow thread coordinates by flipping it first. 4329e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) LayoutRect flowThreadPaintInvalidationRect(paintInvalidationRect); 4339e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) flowThread()->flipForWritingMode(flowThreadPaintInvalidationRect); 43402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now we can compare this rect with the flow thread portions owned by each column. First let's 4369e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // just see if the paint invalidation rect intersects our flow thread portion at all. 4379e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) LayoutRect clippedRect(flowThreadPaintInvalidationRect); 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) clippedRect.intersect(RenderRegion::flowThreadPortionOverflowRect()); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (clippedRect.isEmpty()) 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 44102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now we know we intersect at least one column. Let's figure out the logical top and logical 4439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // bottom of the area in which we're issuing paint invalidations. 4449e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) LayoutUnit paintInvalidationLogicalTop = isHorizontalWritingMode() ? flowThreadPaintInvalidationRect.y() : flowThreadPaintInvalidationRect.x(); 4459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) LayoutUnit paintInvalidationLogicalBottom = (isHorizontalWritingMode() ? flowThreadPaintInvalidationRect.maxY() : flowThreadPaintInvalidationRect.maxX()) - 1; 44602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) unsigned startColumn = columnIndexAtOffset(paintInvalidationLogicalTop); 4489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) unsigned endColumn = columnIndexAtOffset(paintInvalidationLogicalBottom); 44902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit colGap = columnGap(); 451d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned colCount = actualColumnCount(); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = startColumn; i <= endColumn; i++) { 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect colRect = columnRectAt(i); 45402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Get the portion of the flow thread that corresponds to this column. 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect flowThreadPortion = flowThreadPortionRectAt(i); 45702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now get the overflow rect that corresponds to the column. 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flowThreadPortion, i, colCount, colGap); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) // Do a paint invalidation for this specific column. 4627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci paintInvalidationOfFlowThreadContentRectangle(paintInvalidationRect, flowThreadPortion, flowThreadOverflowPortion, colRect.location()); 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 466926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderMultiColumnSet::collectLayerFragments(LayerFragments& fragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) 467926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 4681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // The two rectangles passed to this method are physical, except that we pretend that there's 4691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // only one long column (that's how a flow thread works). 4701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // 4711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Then there's the output from this method - the stuff we put into the list of fragments. The 4721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // fragment.paginationOffset point is the actual physical translation required to get from a 4731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // location in the flow thread to a location in a given column. The fragment.paginationClip 4741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // rectangle, on the other hand, is in the same coordinate system as the two rectangles passed 4751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // to this method (flow thread coordinates). 4761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // 4771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // All other rectangles in this method are sized physically, and the inline direction coordinate 4781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // is physical too, but the block direction coordinate is "logical top". This is the same as 4791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // e.g. RenderBox::frameRect(). These rectangles also pretend that there's only one long column, 4801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // i.e. they are for the flow thread. 4811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 4821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Put the layer bounds into flow thread-local coordinates by flipping it first. Since we're in 4831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // a renderer, most rectangles are represented this way. 484926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect layerBoundsInFlowThread(layerBoundingBox); 485926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) flowThread()->flipForWritingMode(layerBoundsInFlowThread); 486926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Now we can compare with the flow thread portions owned by each column. First let's 488926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // see if the rect intersects our flow thread portion at all. 489926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect clippedRect(layerBoundsInFlowThread); 490926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) clippedRect.intersect(RenderRegion::flowThreadPortionOverflowRect()); 491926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (clippedRect.isEmpty()) 492926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 49302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 494926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Now we know we intersect at least one column. Let's figure out the logical top and logical 495926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // bottom of the area we're checking. 496926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutUnit layerLogicalTop = isHorizontalWritingMode() ? layerBoundsInFlowThread.y() : layerBoundsInFlowThread.x(); 497926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutUnit layerLogicalBottom = (isHorizontalWritingMode() ? layerBoundsInFlowThread.maxY() : layerBoundsInFlowThread.maxX()) - 1; 49802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 499926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Figure out the start and end columns and only check within that range so that we don't walk the 500926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // entire column set. 501926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned startColumn = columnIndexAtOffset(layerLogicalTop); 502926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned endColumn = columnIndexAtOffset(layerLogicalBottom); 50302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 504d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutUnit colLogicalWidth = pageLogicalWidth(); 505926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutUnit colGap = columnGap(); 506d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned colCount = actualColumnCount(); 50702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 508197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread(); 509197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool progressionIsInline = flowThread->progressionIsInline(); 510197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool leftToRight = style()->isLeftToRightDirection(); 511197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 512197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutUnit initialBlockOffset = logicalTop() - flowThread->logicalTop(); 513197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 514926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = startColumn; i <= endColumn; i++) { 515926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Get the portion of the flow thread that corresponds to this column. 516926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect flowThreadPortion = flowThreadPortionRectAt(i); 51702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 518926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Now get the overflow rect that corresponds to the column. 519926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flowThreadPortion, i, colCount, colGap); 520926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 521926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // In order to create a fragment we must intersect the portion painted by this column. 522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect clippedRect(layerBoundsInFlowThread); 523926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) clippedRect.intersect(flowThreadOverflowPortion); 524926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (clippedRect.isEmpty()) 525926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) continue; 52602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // We also need to intersect the dirty rect. We have to apply a translation and shift based off 528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // our column index. 529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutPoint translationOffset; 530197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutUnit inlineOffset = progressionIsInline ? i * (colLogicalWidth + colGap) : LayoutUnit(); 531197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!leftToRight) 532926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) inlineOffset = -inlineOffset; 533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) translationOffset.setX(inlineOffset); 534197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutUnit blockOffset; 535197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (progressionIsInline) { 536197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch blockOffset = initialBlockOffset + (isHorizontalWritingMode() ? -flowThreadPortion.y() : -flowThreadPortion.x()); 537197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else { 538197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Column gap can apply in the block direction for page fragmentainers. 539197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // There is currently no spec which calls for column-gap to apply 540197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // for page fragmentainers at all, but it's applied here for compatibility 541197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // with the old multicolumn implementation. 542197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch blockOffset = i * colGap; 543197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 544926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (isFlippedBlocksWritingMode(style()->writingMode())) 545926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) blockOffset = -blockOffset; 546926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) translationOffset.setY(blockOffset); 547926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!isHorizontalWritingMode()) 548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) translationOffset = translationOffset.transposedPoint(); 549926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: The translation needs to include the multicolumn set's content offset within the 550926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // multicolumn block as well. This won't be an issue until we start creating multiple multicolumn sets. 551926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 552926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Shift the dirty rect to be in flow thread coordinates with this translation applied. 5531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) LayoutRect translatedDirtyRect(dirtyRect); 554926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) translatedDirtyRect.moveBy(-translationOffset); 55502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 556926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // See if we intersect the dirty rect. 5571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) clippedRect = layerBoundingBox; 558926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) clippedRect.intersect(translatedDirtyRect); 559926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (clippedRect.isEmpty()) 560926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) continue; 56102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 562926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Something does need to paint in this column. Make a fragment now and supply the physical translation 563926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // offset and the clip rect for the column with that offset applied. 564926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayerFragment fragment; 565926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) fragment.paginationOffset = translationOffset; 56602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 567926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LayoutRect flippedFlowThreadOverflowPortion(flowThreadOverflowPortion); 5681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Flip it into more a physical (RenderLayer-style) rectangle. 569197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch flowThread->flipForWritingMode(flippedFlowThreadOverflowPortion); 570926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) fragment.paginationClip = flippedFlowThreadOverflowPortion; 571926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) fragments.append(fragment); 572926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 575d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RenderMultiColumnSet::addOverflowFromChildren() 576d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 577d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) unsigned colCount = actualColumnCount(); 578d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!colCount) 579d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return; 580d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 581d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LayoutRect lastRect = columnRectAt(colCount - 1); 582d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) addLayoutOverflow(lastRect); 583d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (!hasOverflowClip()) 584d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) addVisualOverflow(lastRect); 585d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 586d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char* RenderMultiColumnSet::renderName() const 58802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{ 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return "RenderMultiColumnSet"; 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 592197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderMultiColumnSet::insertedIntoTree() 593197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 594197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderRegion::insertedIntoTree(); 595197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 596197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch attachRegion(); 597197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 598197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 599197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderMultiColumnSet::willBeRemovedFromTree() 600197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 601197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderRegion::willBeRemovedFromTree(); 602197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 603197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch detachRegion(); 604197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 605197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 606197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderMultiColumnSet::attachRegion() 607197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 608197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (documentBeingDestroyed()) 609197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 610197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 611197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // A region starts off invalid. 612197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch setIsValid(false); 613197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 614197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!m_flowThread) 615197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 616197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 617197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Only after adding the region to the thread, the region is marked to be valid. 618197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_flowThread->addRegionToThread(this); 619197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 620197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 621197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderMultiColumnSet::detachRegion() 622197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 623197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_flowThread) { 624197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_flowThread->removeRegionFromThread(this); 625197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_flowThread = 0; 626197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 627197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 628197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 630