summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderBlock.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/rendering/RenderBlock.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/rendering/RenderBlock.cpp')
-rwxr-xr-xSource/WebCore/rendering/RenderBlock.cpp999
1 files changed, 451 insertions, 548 deletions
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index d87d77226..d03463b51 100755
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -45,11 +45,11 @@
#include "RenderBoxRegionInfo.h"
#include "RenderCombineText.h"
#include "RenderDeprecatedFlexibleBox.h"
-#include "RenderFlowThread.h"
#include "RenderImage.h"
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderMarquee.h"
+#include "RenderNamedFlowThread.h"
#include "RenderRegion.h"
#include "RenderReplica.h"
#include "RenderTableCell.h"
@@ -69,6 +69,29 @@ namespace WebCore {
using namespace HTMLNames;
+struct SameSizeAsRenderBlock : public RenderBox {
+ void* pointers[3];
+ RenderObjectChildList children;
+ RenderLineBoxList lineBoxes;
+ uint32_t bitfields;
+};
+
+COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
+
+struct SameSizeAsFloatingObject {
+ void* pointers[2];
+ LayoutRect rect;
+ int paginationStrut;
+ uint32_t bitfields : 8;
+};
+
+COMPILE_ASSERT(sizeof(RenderBlock::MarginValues) == sizeof(LayoutUnit[4]), MarginValues_should_stay_small);
+
+struct SameSizeAsMarginInfo {
+ uint32_t bitfields : 16;
+ LayoutUnit margins[2];
+};
+
typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
static ColumnInfoMap* gColumnInfoMap = 0;
@@ -167,8 +190,8 @@ RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, LayoutUnit beforeBorderP
m_quirkContainer = block->isTableCell() || block->isBody() || blockStyle->marginBeforeCollapse() == MDISCARD
|| blockStyle->marginAfterCollapse() == MDISCARD;
- m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : zeroLayoutUnit;
- m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : zeroLayoutUnit;
+ m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : ZERO_LAYOUT_UNIT;
+ m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : ZERO_LAYOUT_UNIT;
}
// -------------------------------------------------------------------------------------------------------
@@ -177,10 +200,11 @@ RenderBlock::RenderBlock(Node* node)
: RenderBox(node)
, m_lineHeight(-1)
, m_beingDestroyed(false)
- , m_hasPositionedFloats(false)
, m_hasMarkupTruncation(false)
{
setChildrenInline(true);
+ COMPILE_ASSERT(sizeof(RenderBlock::FloatingObject) == sizeof(SameSizeAsFloatingObject), FloatingObject_should_stay_small);
+ COMPILE_ASSERT(sizeof(RenderBlock::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small);
}
RenderBlock::~RenderBlock()
@@ -481,7 +505,8 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
}
// Split our anonymous blocks.
- RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
+ RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
+
// Create a new anonymous box of the appropriate type.
RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
@@ -681,94 +706,6 @@ void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
post->setNeedsLayoutAndPrefWidthsRecalc();
}
-RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
-{
- if (beforeChild->isTablePart())
- beforeChild = splitTablePartsAroundChild(beforeChild);
-
- while (beforeChild->parent() != this) {
- RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
- if (blockToSplit->firstChild() != beforeChild) {
- // We have to split the parentBlock into two blocks.
- RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
- post->setChildrenInline(blockToSplit->childrenInline());
- RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
- parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
- blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
- post->setNeedsLayoutAndPrefWidthsRecalc();
- blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
- beforeChild = post;
- } else
- beforeChild = blockToSplit;
- }
- return beforeChild;
-}
-
-static void markTableForSectionAndCellRecalculation(RenderObject* child)
-{
- RenderObject* curr = child;
- while (!curr->isTable()) {
- if (curr->isTableSection())
- toRenderTableSection(curr)->setNeedsCellRecalc();
- curr = curr->parent();
- }
-
- RenderTable* table = toRenderTable(curr);
- table->setNeedsSectionRecalc();
- table->setNeedsLayoutAndPrefWidthsRecalc();
-}
-
-static void moveAllTableChildrenTo(RenderObject* fromTablePart, RenderTable* toTable, RenderObject* startChild)
-{
- for (RenderObject* curr = startChild; curr;) {
- // Need to store next sibling as we won't have access to it
- // after we are removed from table.
- RenderObject* next = curr->nextSibling();
- fromTablePart->removeChild(curr);
- toTable->addChild(curr);
- if (curr->isTableSection())
- toRenderTableSection(curr)->setNeedsCellRecalc();
- curr->setNeedsLayoutAndPrefWidthsRecalc();
- curr = next;
- }
-
- // This marks fromTable for section and cell recalculation.
- markTableForSectionAndCellRecalculation(fromTablePart);
-
- // startChild is now part of toTable. This marks toTable for section and cell recalculation.
- markTableForSectionAndCellRecalculation(startChild);
-}
-
-RenderObject* RenderBlock::splitTablePartsAroundChild(RenderObject* beforeChild)
-{
- ASSERT(beforeChild->isTablePart());
-
- while (beforeChild->parent() != this) {
- RenderObject* tablePartToSplit = beforeChild->parent();
- if (!tablePartToSplit->isTablePart() && !tablePartToSplit->isTable())
- break;
- if (tablePartToSplit->firstChild() != beforeChild) {
- // Get our table container.
- RenderObject* curr = tablePartToSplit;
- while (!curr->isTable())
- curr = curr->parent();
- RenderTable* table = toRenderTable(curr);
-
- // Create an anonymous table container next to our table container.
- RenderBlock* parentBlock = toRenderBlock(table->parent());
- RenderTable* postTable = parentBlock->createAnonymousTable();
- parentBlock->children()->insertChildNode(parentBlock, postTable, table->nextSibling());
-
- // Move all the children from beforeChild to the newly created anonymous table container.
- moveAllTableChildrenTo(tablePartToSplit, postTable, beforeChild);
-
- beforeChild = postTable;
- } else
- beforeChild = tablePartToSplit;
- }
- return beforeChild;
-}
-
void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
{
RenderBlock* pre = 0;
@@ -780,7 +717,7 @@ void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
block->deleteLineBoxTree();
if (beforeChild && beforeChild->parent() != this)
- beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
+ beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
if (beforeChild != firstChild()) {
pre = block->createAnonymousColumnsBlock();
@@ -868,7 +805,13 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
// If the requested beforeChild is not one of our children, then this is because
// there is an anonymous container within this object that contains the beforeChild.
RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
- if (beforeChildAnonymousContainer->isAnonymousBlock()) {
+ if (beforeChildAnonymousContainer->isAnonymousBlock()
+#if ENABLE(FULLSCREEN_API)
+ // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
+ || beforeChildAnonymousContainer->isRenderFullScreen()
+ || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
+#endif
+ ) {
// Insert the child into the anonymous block box instead of here.
if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
beforeChild->parent()->addChild(newChild, beforeChild);
@@ -884,7 +827,7 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
return;
}
- beforeChild = splitTablePartsAroundChild(beforeChild);
+ beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
ASSERT(beforeChild->parent() == this);
if (beforeChild->parent() != this) {
@@ -921,12 +864,19 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
// Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after
// content gets properly destroyed.
+ bool isFirstChild = (beforeChild == firstChild());
bool isLastChild = (beforeChild == lastChild());
if (document()->usesBeforeAfterRules())
children()->updateBeforeAfterContent(this, AFTER);
- if (isLastChild && beforeChild != lastChild())
- beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
- // point to be 0. It's just a straight append now.
+ if (isLastChild && beforeChild != lastChild()) {
+ // We destroyed the last child, so now we need to update our insertion
+ // point to be 0. It's just a straight append now.
+ beforeChild = 0;
+ } else if (isFirstChild && beforeChild != firstChild()) {
+ // If beforeChild was the last anonymous block that collapsed,
+ // then we need to update its value.
+ beforeChild = firstChild();
+ }
splitFlow(beforeChild, newBox, newChild, oldContinuation);
return;
@@ -1063,30 +1013,6 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
return rootBox;
}
-void RenderBlock::moveChildTo(RenderBlock* toBlock, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
-{
- ASSERT(this == child->parent());
- ASSERT(!beforeChild || toBlock == beforeChild->parent());
- if (fullRemoveInsert) {
- // Takes care of adding the new child correctly if toBlock and fromBlock
- // have different kind of children (block vs inline).
- toBlock->addChildIgnoringContinuation(children()->removeChildNode(this, child), beforeChild);
- } else
- toBlock->children()->insertChildNode(toBlock, children()->removeChildNode(this, child, false), beforeChild, false);
-}
-
-void RenderBlock::moveChildrenTo(RenderBlock* toBlock, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
-{
- ASSERT(!beforeChild || toBlock == beforeChild->parent());
-
- for (RenderObject* child = startChild; child && child != endChild; ) {
- // Save our next sibling as moveChildTo will clear it.
- RenderObject* nextSibling = child->nextSibling();
- moveChildTo(toBlock, child, beforeChild, fullRemoveInsert);
- child = nextSibling;
- }
-}
-
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
// makeChildrenNonInline takes a block whose children are *all* inline and it
@@ -1214,8 +1140,8 @@ void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* c
// Delete the now-empty block's lines and nuke it.
if (!parent->documentBeingDestroyed())
anonBlock->deleteLineBoxTree();
- if (childFlowThread && !parent->documentBeingDestroyed())
- childFlowThread->removeFlowChildInfo(anonBlock);
+ if (!parent->documentBeingDestroyed() && childFlowThread && childFlowThread->isRenderNamedFlowThread())
+ toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(anonBlock);
anonBlock->destroy();
}
@@ -1241,7 +1167,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// to clear out inherited column properties by just making a new style, and to also clear the
// column span flag if it is set.
ASSERT(!inlineChildrenBlock->continuation());
- RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
inlineChildrenBlock->setStyle(newStyle);
@@ -1371,18 +1297,12 @@ void RenderBlock::finishDelayUpdateScrollInfo()
void RenderBlock::updateScrollInfoAfterLayout()
{
- if (!hasOverflowClip())
- return;
-
- if (!hasLayer()) {
- updateCachedSizeForOverflowClip();
- return;
+ if (hasOverflowClip()) {
+ if (gDelayUpdateScrollInfo)
+ gDelayedUpdateScrollInfoSet->add(this);
+ else
+ layer()->updateScrollInfoAfterLayout();
}
-
- if (gDelayUpdateScrollInfo)
- gDelayedUpdateScrollInfoSet->add(this);
- else
- layer()->updateScrollInfoAfterLayout();
}
void RenderBlock::layout()
@@ -1409,7 +1329,7 @@ void RenderBlock::computeInitialRegionRangeForBlock()
// effectively clamped to our region range.
LayoutUnit oldHeight = logicalHeight();
LayoutUnit oldLogicalTop = logicalTop();
- setLogicalHeight(numeric_limits<LayoutUnit>::max() / 2);
+ setLogicalHeight(MAX_LAYOUT_UNIT / 2);
computeLogicalHeight();
enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
setLogicalHeight(oldHeight);
@@ -1423,7 +1343,18 @@ void RenderBlock::computeRegionRangeForBlock()
enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
}
-void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight, BlockLayoutPass layoutPass)
+bool RenderBlock::recomputeLogicalWidth()
+{
+ LayoutUnit oldWidth = logicalWidth();
+ LayoutUnit oldColumnWidth = desiredColumnWidth();
+
+ computeLogicalWidth();
+ calcColumnWidth();
+
+ return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth();
+}
+
+void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
{
ASSERT(needsLayout());
@@ -1435,23 +1366,12 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
LayoutRepainter repainter(*this, everHadLayout() && checkForRepaintDuringLayout());
- LayoutUnit oldWidth = logicalWidth();
- LayoutUnit oldColumnWidth = desiredColumnWidth();
-
- computeLogicalWidth();
- calcColumnWidth();
+ if (recomputeLogicalWidth())
+ relayoutChildren = true;
m_overflow.clear();
- if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
- relayoutChildren = true;
-
- // If nothing changed about our floating positioned objects, let's go ahead and try to place them as
- // floats to avoid doing two passes.
- BlockLayoutPass floatsLayoutPass = layoutPass;
- if (floatsLayoutPass == NormalLayoutPass && !relayoutChildren && !positionedFloatsNeedRelayout())
- floatsLayoutPass = PositionedFloatLayoutPass;
- clearFloats(floatsLayoutPass);
+ clearFloats();
LayoutUnit previousHeight = logicalHeight();
setLogicalHeight(0);
@@ -1556,7 +1476,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
RenderBlock* block = toRenderBlock(child);
- if (block->lowestFloatLogicalBottomIncludingPositionedFloats() + block->logicalTop() > newHeight)
+ if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
addOverhangingFloats(block, false);
}
}
@@ -1566,7 +1486,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
if (previousHeight != newHeight)
relayoutChildren = true;
- bool needAnotherLayoutPass = layoutPositionedObjects(relayoutChildren || isRoot());
+ layoutPositionedObjects(relayoutChildren || isRoot());
computeRegionRangeForBlock();
@@ -1611,7 +1531,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
- if (hasOverflowClipWithLayer()) {
+ if (hasOverflowClip()) {
// Adjust repaint rect for scroll offset
repaintRect.move(-scrolledContentOffset());
@@ -1627,11 +1547,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
}
}
- if (needAnotherLayoutPass && layoutPass == NormalLayoutPass) {
- setChildNeedsLayout(true, false);
- layoutBlock(false, pageLogicalHeight, PositionedFloatLayoutPass);
- } else
- setNeedsLayout(false);
+ setNeedsLayout(false);
}
void RenderBlock::addOverflowFromChildren()
@@ -1703,7 +1619,7 @@ void RenderBlock::addOverflowFromFloats()
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
FloatingObject* r = *it;
- if (r->m_isDescendant && !r->m_renderer->isPositioned())
+ if (r->isDescendant())
addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
}
return;
@@ -1734,7 +1650,7 @@ void RenderBlock::addVisualOverflowFromTheme()
if (!style()->hasAppearance())
return;
- IntRect inflatedRect = borderBoxRect();
+ IntRect inflatedRect = pixelSnappedBorderBoxRect();
theme()->adjustRepaintRect(this, inflatedRect);
addVisualOverflow(inflatedRect);
}
@@ -1772,7 +1688,7 @@ void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marg
if (childLayer->staticBlockPosition() != logicalTop) {
childLayer->setStaticBlockPosition(logicalTop);
if (hasStaticBlockPosition)
- child->setChildNeedsLayout(true, false);
+ child->setChildNeedsLayout(true, MarkOnlyThis);
}
}
@@ -1791,7 +1707,7 @@ void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
// for by simply calling canCollapseWithMarginBefore. See
// http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
// an example of this scenario.
- LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? zeroLayoutUnit : marginInfo.margin();
+ LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? ZERO_LAYOUT_UNIT : marginInfo.margin();
setLogicalHeight(logicalHeight() + marginOffset);
positionNewFloats();
setLogicalHeight(logicalHeight() - marginOffset);
@@ -1833,14 +1749,22 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
// block.
if (!child->isRunIn() || !child->childrenInline())
return false;
+
// FIXME: We don't handle non-block elements with run-in for now.
if (!child->isRenderBlock())
- return false;
+ return false;
+
// Run-in child shouldn't intrude into the sibling block if it is part of a
// continuation chain. In that case, treat it as a normal block.
if (child->isElementContinuation() || child->virtualContinuation())
return false;
+ // Check if this node is allowed to run-in. E.g. <select> expects its renderer to
+ // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline run-in.
+ Node* runInNode = child->node();
+ if (runInNode && runInNode->hasTagName(selectTag))
+ return false;
+
RenderBlock* blockRunIn = toRenderBlock(child);
RenderObject* curr = blockRunIn->nextSibling();
if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
@@ -1862,14 +1786,13 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
children()->removeChildNode(this, blockRunIn);
// Create an inline.
- Node* runInNode = blockRunIn->node();
RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
inlineRunIn->setStyle(blockRunIn->style());
// Move the nodes from the old child to the new child
for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
RenderObject* nextSibling = runInChild->nextSibling();
- blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
+ blockRunIn->children()->removeChildNode(blockRunIn, runInChild);
inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
runInChild = nextSibling;
}
@@ -2080,7 +2003,7 @@ LayoutUnit RenderBlock::estimateLogicalTopPosition(RenderBox* child, const Margi
}
LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart,
- LayoutUnit childLogicalWidth, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+ RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
{
LayoutUnit startPosition = startOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
@@ -2097,24 +2020,9 @@ LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const Re
if (childMarginStart < 0)
startOff += childMarginStart;
newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
- } else if (startOff != startPosition) {
- // The object is shifting to the "end" side of the block. The object might be centered, so we need to
- // recalculate our inline direction margins. Note that the containing block content
- // width computation will take into account the delta between |startOff| and |startPosition|
- // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
- // function.
- LayoutUnit oldMarginStart = marginStartForChild(child);
- LayoutUnit oldMarginEnd = marginEndForChild(child);
- RenderBox* mutableChild = const_cast<RenderBox*>(child);
- mutableChild->computeInlineDirectionMargins(this,
- availableLogicalWidthForLine(blockOffset, false, region, offsetFromLogicalTopOfFirstPage), childLogicalWidth);
- newPosition = startOff + marginStartForChild(child);
- if (inRenderFlowThread()) {
- setMarginStartForChild(mutableChild, oldMarginStart);
- setMarginEndForChild(mutableChild, oldMarginEnd);
- }
- }
-
+ } else if (startOff != startPosition)
+ newPosition = startOff + childMarginStart;
+
return newPosition - oldPosition;
}
@@ -2132,7 +2040,7 @@ void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
// Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
// to shift over as necessary to dodge any floats that might get in the way.
if (child->avoidsFloats() && containsFloats() && !inRenderFlowThread())
- newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child), logicalWidthForChild(child));
+ newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
}
@@ -2211,7 +2119,7 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloa
while (box != this) {
if (box->normalChildNeedsLayout())
break;
- box->setChildNeedsLayout(true, false);
+ box->setChildNeedsLayout(true, MarkOnlyThis);
box = box->containingBlock();
ASSERT(box);
if (!box)
@@ -2253,13 +2161,12 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloa
// Make sure we layout children if they need it.
// FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
// an auto value. Add a method to determine this, so that we can avoid the relayout.
- RenderStyle* childStyle = child->style();
- if (relayoutChildren || ((childStyle->logicalHeight().isPercent() || childStyle->logicalMinHeight().isPercent() || childStyle->logicalMaxHeight().isPercent()) && !isRenderView()))
- child->setChildNeedsLayout(true, false);
+ if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()))
+ child->setChildNeedsLayout(true, MarkOnlyThis);
// If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
if (relayoutChildren && child->needsPreferredWidthsRecalculation())
- child->setPreferredLogicalWidthsDirty(true, false);
+ child->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
// Handle the four types of special elements first. These include positioned content, floating content, compacts and
// run-ins. When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
@@ -2313,7 +2220,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, Lay
else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
// If an element might be affected by the presence of floats, then always mark it for
// layout.
- LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottomIncludingPositionedFloats());
+ LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
if (fb > logicalTopEstimate)
markDescendantsWithFloats = true;
}
@@ -2322,7 +2229,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, Lay
if (markDescendantsWithFloats)
childRenderBlock->markAllDescendantsWithFloatsForLayout();
if (!child->isWritingModeRoot())
- previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottomIncludingPositionedFloats());
+ previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
}
if (!child->needsLayout())
@@ -2357,7 +2264,7 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, Lay
// When the child shifts to clear an item, its width can
// change (because it has more available line width).
// So go ahead and mark the item as dirty.
- child->setChildNeedsLayout(true, false);
+ child->setChildNeedsLayout(true, MarkOnlyThis);
}
if (childRenderBlock) {
@@ -2461,8 +2368,8 @@ bool RenderBlock::simplifiedLayout()
simplifiedNormalFlowLayout();
// Lay out our positioned objects if our positioned child bit is set.
- if (posChildNeedsLayout() && layoutPositionedObjects(false))
- return false; // If a positioned float is causing our normal flow to change, then we have to bail and do a full layout.
+ if (posChildNeedsLayout())
+ layoutPositionedObjects(false);
// Recompute our overflow information.
// FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
@@ -2482,41 +2389,14 @@ bool RenderBlock::simplifiedLayout()
return true;
}
-bool RenderBlock::positionedFloatsNeedRelayout()
-{
- if (!hasPositionedFloats())
- return false;
-
- RenderBox* positionedObject;
- Iterator end = m_positionedObjects->end();
- for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
- positionedObject = *it;
- if (!positionedObject->isFloating())
- continue;
-
- if (positionedObject->needsLayout())
- return true;
-
- if (positionedObject->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && positionedObject->parent() != this && positionedObject->parent()->isBlockFlow())
- return true;
-
- if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
- return true;
- }
-
- return false;
-}
-
-bool RenderBlock::layoutPositionedObjects(bool relayoutChildren)
+void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
{
if (!m_positionedObjects)
- return false;
+ return;
if (hasColumns())
view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
- bool didFloatingBoxRelayout = false;
-
RenderBox* r;
Iterator end = m_positionedObjects->end();
for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
@@ -2526,20 +2406,15 @@ bool RenderBlock::layoutPositionedObjects(bool relayoutChildren)
// objects that are positioned implicitly like this. Such objects are rare, and so in typical DHTML menu usage (where everything is
// positioned explicitly) this should not incur a performance penalty.
if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
- r->setChildNeedsLayout(true, false);
+ r->setChildNeedsLayout(true, MarkOnlyThis);
// If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
if (relayoutChildren && r->needsPreferredWidthsRecalculation())
- r->setPreferredLogicalWidthsDirty(true, false);
+ r->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
if (!r->needsLayout())
r->markForPaginationRelayoutIfNeeded();
- // FIXME: Technically we could check the old placement and the new placement of the box and only invalidate if
- // the margin box of the object actually changed.
- if (r->needsLayout() && r->isFloating())
- didFloatingBoxRelayout = true;
-
// We don't have to do a full layout. We just have to update our position. Try that first. If we have shrink-to-fit width
// and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
@@ -2556,20 +2431,26 @@ bool RenderBlock::layoutPositionedObjects(bool relayoutChildren)
r->computeLogicalWidth();
oldLogicalTop = logicalTopForChild(r);
}
-
- r->layoutIfNeeded();
+ r->layoutIfNeeded();
+
+ // Adjust the static position of a center-aligned inline positioned object with a block child now that the child's width has been computed.
+ if (!r->parent()->isRenderView() && r->parent()->isRenderBlock() && r->firstChild() && r->style()->position() == AbsolutePosition
+ && r->style()->isOriginalDisplayInlineType() && (r->style()->textAlign() == CENTER || r->style()->textAlign() == WEBKIT_CENTER)) {
+ RenderBlock* block = toRenderBlock(r->parent());
+ LayoutUnit blockHeight = block->logicalHeight();
+ block->setStaticInlinePositionForChild(r, blockHeight, block->startAlignedOffsetForLine(r, blockHeight, false));
+ }
+
// Lay out again if our estimate was wrong.
if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
- r->setChildNeedsLayout(true, false);
+ r->setChildNeedsLayout(true, MarkOnlyThis);
r->layoutIfNeeded();
}
}
if (hasColumns())
view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
-
- return didFloatingBoxRelayout;
}
void RenderBlock::markPositionedObjectsForLayout()
@@ -2591,7 +2472,7 @@ void RenderBlock::markForPaginationRelayoutIfNeeded()
return;
if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
- setChildNeedsLayout(true, false);
+ setChildNeedsLayout(true, MarkOnlyThis);
}
void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
@@ -2611,7 +2492,7 @@ void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
// Only repaint the object if it is overhanging, is not in its own layer, and
// is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
// condition is replaced with being a descendant of us.
- if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
+ if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->shouldPaint()) && !r->m_renderer->hasSelfPaintingLayer()) {
r->m_renderer->repaint();
r->m_renderer->repaintOverhangingFloats();
}
@@ -2644,7 +2525,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
// Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
- if (hasOverflowClipWithLayer() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
+ if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
}
@@ -2668,9 +2549,9 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
bool antialias = shouldAntialiasLines(paintInfo.context);
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? zeroLayoutUnit : contentLogicalWidth();
+ LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
LayoutUnit ruleAdd = logicalLeftOffsetForContent();
- LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? zeroLayoutUnit : contentLogicalWidth();
+ LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? ZERO_LAYOUT_UNIT : contentLogicalWidth();
LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
BoxSide boxSide = isHorizontalWritingMode()
? style()->isLeftToRightDirection() ? BSLeft : BSRight
@@ -2780,13 +2661,10 @@ void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOf
if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
return;
- // We don't want to hand off painting in the line box tree with the accumulated error of the render tree, as this will cause
- // us to mess up painting aligned things (such as underlines in text) with both the render tree and line box tree's error.
- LayoutPoint roundedPaintOffset = roundedIntPoint(paintOffset);
if (childrenInline())
- m_lineBoxes.paint(this, paintInfo, roundedPaintOffset);
+ m_lineBoxes.paint(this, paintInfo, paintOffset);
else
- paintChildren(paintInfo, roundedPaintOffset);
+ paintChildren(paintInfo, paintOffset);
}
void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -2918,7 +2796,10 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
// 6. paint continuation outlines.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
RenderInline* inlineCont = inlineElementContinuation();
- if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
+ // FIXME: For now, do not add continuations for outline painting by our containing block if we are a relative positioned
+ // anonymous block (i.e. have our own layer). This is because a block depends on renderers in its continuation table being
+ // in the same layer.
+ if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE && !hasLayer()) {
RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
RenderBlock* cb = containingBlock();
@@ -2970,7 +2851,7 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paintOffs
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
FloatingObject* r = *it;
// Only paint the object if our m_shouldPaint flag is set.
- if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
+ if (r->shouldPaint() && !r->m_renderer->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
LayoutPoint childPoint = flipFloatForWritingModeForChild(r, LayoutPoint(paintOffset.x() + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), paintOffset.y() + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
@@ -3282,8 +3163,8 @@ GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPo
// Now paint the gaps for the lines.
for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
- LayoutUnit selTop = curr->selectionTop();
- LayoutUnit selHeight = curr->selectionHeight();
+ LayoutUnit selTop = curr->selectionTopAdjustedForPrecedingBlock();
+ LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
if (!containsStart && !lastSelectedLine &&
selectionState() != SelectionStart && selectionState() != SelectionBoth)
@@ -3475,6 +3356,38 @@ LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, Layo
return logicalRight;
}
+RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
+{
+ if (isSelectionRoot())
+ return 0;
+
+ const RenderBox* object = this;
+ RenderObject* sibling;
+ do {
+ sibling = object->previousSibling();
+ while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
+ sibling = sibling->previousSibling();
+
+ offset -= LayoutSize(object->logicalLeft(), object->logicalTop());
+ object = object->parentBox();
+ } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
+
+ if (!sibling)
+ return 0;
+
+ RenderBlock* beforeBlock = toRenderBlock(sibling);
+
+ offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
+
+ RenderObject* child = beforeBlock->lastChild();
+ while (child && child->isRenderBlock()) {
+ beforeBlock = toRenderBlock(child);
+ offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
+ child = beforeBlock->lastChild();
+ }
+ return beforeBlock;
+}
+
void RenderBlock::insertPositionedObject(RenderBox* o)
{
ASSERT(!isAnonymousBlock());
@@ -3487,12 +3400,18 @@ void RenderBlock::insertPositionedObject(RenderBox* o)
m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
m_positionedObjects->add(o);
+
+ if (o->style()->position() == FixedPosition && view())
+ view()->insertFixedPositionedObject(o);
}
void RenderBlock::removePositionedObject(RenderBox* o)
{
if (m_positionedObjects)
m_positionedObjects->remove(o);
+
+ if (view())
+ view()->removeFixedPositionedObject(o);
}
void RenderBlock::removePositionedObjects(RenderBlock* o)
@@ -3510,7 +3429,7 @@ void RenderBlock::removePositionedObjects(RenderBlock* o)
r = *it;
if (!o || r->isDescendantOf(o)) {
if (o)
- r->setChildNeedsLayout(true, false);
+ r->setChildNeedsLayout(true, MarkOnlyThis);
// It is parent blocks job to add positioned child to positioned objects list of its containing block
// Parent layout needs to be invalidated to ensure this happens.
@@ -3549,23 +3468,21 @@ RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
// Our location is irrelevant if we're unsplittable or no pagination is in effect.
// Just go ahead and lay out the float.
- if (!o->isPositioned()) {
- bool isChildRenderBlock = o->isRenderBlock();
- if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
- o->setChildNeedsLayout(true, false);
+ bool isChildRenderBlock = o->isRenderBlock();
+ if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
+ o->setChildNeedsLayout(true, MarkOnlyThis);
- bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
- if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
- o->layoutIfNeeded();
- else {
- o->computeLogicalWidth();
- o->computeBlockDirectionMargins(this);
- }
+ bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
+ if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
+ o->layoutIfNeeded();
+ else {
+ o->computeLogicalWidth();
+ o->computeBlockDirectionMargins(this);
}
setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
- newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself. Otherwise someone else will.
- newObj->m_isDescendant = true;
+ newObj->setShouldPaint(!o->hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will.
+ newObj->setIsDescendant(true);
newObj->m_renderer = o;
m_floatingObjects->add(newObj);
@@ -3585,8 +3502,8 @@ void RenderBlock::removeFloatingObject(RenderBox* o)
LayoutUnit logicalBottom = logicalBottomForFloat(r);
// Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
- if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<LayoutUnit>::max())
- logicalBottom = numeric_limits<LayoutUnit>::max();
+ if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == MAX_LAYOUT_UNIT)
+ logicalBottom = MAX_LAYOUT_UNIT;
else {
// Special-case zero- and less-than-zero-height floats: those don't touch
// the line that they're on, but it still needs to be dirtied. This is
@@ -3714,9 +3631,8 @@ bool RenderBlock::positionNewFloats()
for (; it != end; ++it) {
FloatingObject* floatingObject = *it;
// The containing block is responsible for positioning floats, so if we have floats in our
- // list that come from somewhere else, do not attempt to position them. Also don't attempt to handle
- // positioned floats, since the positioning layout code handles those.
- if (floatingObject->renderer()->containingBlock() != this || floatingObject->renderer()->isPositioned())
+ // list that come from somewhere else, do not attempt to position them.
+ if (floatingObject->renderer()->containingBlock() != this)
continue;
RenderBox* childBox = floatingObject->renderer();
@@ -3765,7 +3681,7 @@ bool RenderBlock::positionNewFloats()
setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
if (childBlock)
- childBlock->setChildNeedsLayout(true, false);
+ childBlock->setChildNeedsLayout(true, MarkOnlyThis);
childBox->layoutIfNeeded();
}
}
@@ -3786,7 +3702,7 @@ void RenderBlock::newLine(EClear clear)
{
positionNewFloats();
// set y position
- int newY = 0;
+ LayoutUnit newY = 0;
switch (clear)
{
case CLEFT:
@@ -3816,7 +3732,7 @@ void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
descendantSet = new HashSet<RenderBox*>;
gPercentHeightDescendantsMap->set(this, descendantSet);
}
- bool added = descendantSet->add(descendant).second;
+ bool added = descendantSet->add(descendant).isNewEntry;
if (!added) {
ASSERT(gPercentHeightContainerMap->get(descendant));
ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
@@ -3902,9 +3818,12 @@ inline void RenderBlock::FloatIntervalSearchAdapter<FloatTypeValue>::collectIfNe
LayoutUnit RenderBlock::textIndentOffset() const
{
LayoutUnit cw = 0;
+ RenderView* renderView = 0;
if (style()->textIndent().isPercent())
cw = containingBlock()->availableLogicalWidth();
- return style()->textIndent().calcMinValue(cw);
+ else if (style()->textIndent().isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(style()->textIndent(), cw, renderView);
}
LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
@@ -4027,7 +3946,7 @@ LayoutUnit RenderBlock::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) co
if (!m_floatingObjects)
return logicalHeight;
- LayoutUnit bottom = numeric_limits<LayoutUnit>::max();
+ LayoutUnit bottom = MAX_LAYOUT_UNIT;
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
@@ -4037,7 +3956,7 @@ LayoutUnit RenderBlock::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) co
bottom = min(floatBottom, bottom);
}
- return bottom == numeric_limits<LayoutUnit>::max() ? zeroLayoutUnit : bottom;
+ return bottom == MAX_LAYOUT_UNIT ? ZERO_LAYOUT_UNIT : bottom;
}
LayoutUnit RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
@@ -4062,7 +3981,7 @@ void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l
RootInlineBox* lowestDirtyLine = lastRootBox();
RootInlineBox* afterLowest = lowestDirtyLine;
- while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < numeric_limits<LayoutUnit>::max()) {
+ while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < MAX_LAYOUT_UNIT) {
afterLowest = lowestDirtyLine;
lowestDirtyLine = lowestDirtyLine->prevRootBox();
}
@@ -4073,40 +3992,21 @@ void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit l
}
}
-void RenderBlock::addPositionedFloats()
-{
- if (!m_positionedObjects)
- return;
-
- Iterator end = m_positionedObjects->end();
- for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
- RenderBox* positionedObject = *it;
- if (!positionedObject->isFloating())
- continue;
-
- ASSERT(!positionedObject->needsLayout());
-
- // If we're a positioned float, then we need to insert ourselves as a floating object also. We only do
- // this after the positioned object has received a layout, since otherwise the dimensions and placement
- // won't be correct.
- FloatingObject* floatingObject = insertFloatingObject(positionedObject);
- setLogicalLeftForFloat(floatingObject, logicalLeftForChild(positionedObject) - marginLogicalLeftForChild(positionedObject));
- setLogicalTopForFloat(floatingObject, logicalTopForChild(positionedObject) - marginBeforeForChild(positionedObject));
- setLogicalHeightForFloat(floatingObject, logicalHeightForChild(positionedObject) + marginBeforeForChild(positionedObject) + marginAfterForChild(positionedObject));
-
- m_floatingObjects->addPlacedObject(floatingObject);
-
- m_hasPositionedFloats = true;
- }
-}
-
-void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
+void RenderBlock::clearFloats()
{
if (m_floatingObjects)
m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode());
- // Clear our positioned floats boolean.
- m_hasPositionedFloats = false;
+ HashSet<RenderBox*> oldIntrudingFloatSet;
+ if (!childrenInline() && m_floatingObjects) {
+ const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObject* floatingObject = *it;
+ if (!floatingObject->isDescendant())
+ oldIntrudingFloatSet.add(floatingObject->m_renderer);
+ }
+ }
// Inline blocks are covered by the isReplaced() check in the avoidFloats method.
if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
@@ -4114,8 +4014,8 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
deleteAllValues(m_floatingObjects->set());
m_floatingObjects->clear();
}
- if (layoutPass == PositionedFloatLayoutPass)
- addPositionedFloats();
+ if (!oldIntrudingFloatSet.isEmpty())
+ markAllDescendantsWithFloatsForLayout();
return;
}
@@ -4135,9 +4035,6 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
m_floatingObjects->clear();
}
- if (layoutPass == PositionedFloatLayoutPass)
- addPositionedFloats();
-
// We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
// floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
// See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
@@ -4148,7 +4045,7 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
// out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
// to avoid floats.
RenderBlock* parentBlock = toRenderBlock(parent());
- bool parentHasFloats = parentBlock->hasPositionedFloats();
+ bool parentHasFloats = false;
RenderObject* prev = previousSibling();
while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
if (prev->isFloating())
@@ -4164,19 +4061,19 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
LayoutUnit logicalLeftOffset = 0;
if (prev)
logicalTopOffset -= toRenderBox(prev)->logicalTop();
- else if (!parentHasFloats) {
+ else {
prev = parentBlock;
logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
}
// Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
RenderBlock* block = toRenderBlock(prev);
- if (block && block->m_floatingObjects && block->lowestFloatLogicalBottomIncludingPositionedFloats() > logicalTopOffset)
+ if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
if (childrenInline()) {
- LayoutUnit changeLogicalTop = numeric_limits<LayoutUnit>::max();
- LayoutUnit changeLogicalBottom = numeric_limits<LayoutUnit>::min();
+ LayoutUnit changeLogicalTop = MAX_LAYOUT_UNIT;
+ LayoutUnit changeLogicalBottom = MIN_LAYOUT_UNIT;
if (m_floatingObjects) {
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
@@ -4218,7 +4115,7 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
RendererToFloatInfoMap::iterator end = floatMap.end();
for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
FloatingObject* floatingObject = (*it).second;
- if (!floatingObject->m_isDescendant) {
+ if (!floatingObject->isDescendant()) {
changeLogicalTop = 0;
changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
}
@@ -4226,6 +4123,19 @@ void RenderBlock::clearFloats(BlockLayoutPass layoutPass)
deleteAllValues(floatMap);
markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
+ } else if (!oldIntrudingFloatSet.isEmpty()) {
+ // If there are previously intruding floats that no longer intrude, then children with floats
+ // should also get layout because they might need their floating object lists cleared.
+ if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size())
+ markAllDescendantsWithFloatsForLayout();
+ else {
+ const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+ FloatingObjectSetIterator end = floatingObjectSet.end();
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it)
+ oldIntrudingFloatSet.remove((*it)->m_renderer);
+ if (!oldIntrudingFloatSet.isEmpty())
+ markAllDescendantsWithFloatsForLayout();
+ }
}
}
@@ -4244,7 +4154,7 @@ LayoutUnit RenderBlock::addOverhangingFloats(RenderBlock* child, bool makeChildP
FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
FloatingObject* r = *childIt;
- LayoutUnit logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<LayoutUnit>::max() - childLogicalTop);
+ LayoutUnit logicalBottomForFloat = min(this->logicalBottomForFloat(r), MAX_LAYOUT_UNIT - childLogicalTop);
LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat;
lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
@@ -4261,11 +4171,11 @@ LayoutUnit RenderBlock::addOverhangingFloats(RenderBlock* child, bool makeChildP
// far out as we can, to the outermost block that overlaps the float, stopping only
// if we hit a self-painting layer boundary.
if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
- r->m_shouldPaint = false;
+ r->setShouldPaint(false);
else
- floatingObj->m_shouldPaint = false;
-
- floatingObj->m_isDescendant = true;
+ floatingObj->setShouldPaint(false);
+
+ floatingObj->setIsDescendant(true);
// We create the floating object list lazily.
if (!m_floatingObjects)
@@ -4274,19 +4184,19 @@ LayoutUnit RenderBlock::addOverhangingFloats(RenderBlock* child, bool makeChildP
m_floatingObjects->add(floatingObj);
}
} else {
- if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
- r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
+ if (makeChildPaintOtherFloats && !r->shouldPaint() && !r->m_renderer->hasSelfPaintingLayer()
+ && r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
// The float is not overhanging from this block, so if it is a descendant of the child, the child should
// paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
// layer.
// If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
// it should paint.
- r->m_shouldPaint = true;
+ r->setShouldPaint(true);
}
// Since the float doesn't overhang, it didn't get put into our list. We need to go ahead and add its overflow in to the
// child now.
- if (r->m_isDescendant)
+ if (r->isDescendant())
child->addOverflowFromChild(r->m_renderer, LayoutSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
}
}
@@ -4337,7 +4247,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, LayoutUnit logicalLeftOf
floatingObj->setY(floatingObj->y() + prev->marginTop());
}
- floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it.
+ floatingObj->setShouldPaint(false); // We are not in the direct inheritance chain for this float. We will never paint it.
floatingObj->m_renderer = r->m_renderer;
// We create the floating object list lazily.
@@ -4365,7 +4275,8 @@ void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove
if (!everHadLayout())
return;
- setChildNeedsLayout(true, !inLayout);
+ MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainingBlockChain;
+ setChildNeedsLayout(true, markParents);
if (floatToRemove)
removeFloatingObject(floatToRemove);
@@ -4386,26 +4297,21 @@ void RenderBlock::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove)
{
if (!m_floatingObjects)
return;
+
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
- for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- if (logicalBottomForFloat(*it) > logicalHeight()) {
+
+ for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) {
+ if (!next->isRenderBlock() || next->isFloatingOrPositioned() || toRenderBlock(next)->avoidsFloats())
+ continue;
+
+ RenderBlock* nextBlock = toRenderBlock(next);
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
RenderBox* floatingBox = (*it)->renderer();
if (floatToRemove && floatingBox != floatToRemove)
continue;
-
- RenderObject* next = nextSibling();
- while (next) {
- if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
- RenderBlock* nextBlock = toRenderBlock(next);
- if (nextBlock->containsFloat(floatingBox))
- nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
- else
- break;
- }
-
- next = next->nextSibling();
- }
+ if (nextBlock->containsFloat(floatingBox))
+ nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
}
}
}
@@ -4434,7 +4340,7 @@ LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop)
}
// We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
- LayoutUnit result = clearSet ? max<LayoutUnit>(0, logicalBottom - logicalTop) : zeroLayoutUnit;
+ LayoutUnit result = clearSet ? max<LayoutUnit>(0, logicalBottom - logicalTop) : ZERO_LAYOUT_UNIT;
if (!result && child->avoidsFloats()) {
LayoutUnit newLogicalTop = logicalTop;
while (true) {
@@ -4474,10 +4380,10 @@ LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop)
bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
{
- if (!scrollsOverflow() || !hasLayer())
+ if (!scrollsOverflow())
return false;
- return layer()->hitTestOverflowControls(result, pointInContainer - toLayoutSize(accumulatedOffset));
+ return layer()->hitTestOverflowControls(result, roundedIntPoint(pointInContainer - toLayoutSize(accumulatedOffset)));
}
bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
@@ -4554,7 +4460,7 @@ bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& re
for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
--it;
FloatingObject* floatingObject = *it;
- if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
+ if (floatingObject->shouldPaint() && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObject, adjustedLocation + LayoutSize(xOffset, yOffset));
@@ -4884,7 +4790,10 @@ int RenderBlock::columnGap() const
}
void RenderBlock::calcColumnWidth()
-{
+{
+ if (document()->regionBasedColumnsEnabled())
+ return;
+
// Calculate our column width and column count.
// FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
unsigned desiredColumnCount = 1;
@@ -5018,7 +4927,7 @@ bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, LayoutUnit p
view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
}
- } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
+ } else if (contentLogicalHeight() > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
// Now that we know the intrinsic height of the columns, we have to rebalance them.
columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((float)contentLogicalHeight() / desiredColumnCount));
}
@@ -5211,11 +5120,11 @@ void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point)
ColumnInfo* colInfo = columnInfo();
LayoutUnit logicalLeft = logicalLeftOffsetForContent();
- size_t colCount = columnCount(colInfo);
+ unsigned colCount = columnCount(colInfo);
LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
LayoutUnit colLogicalHeight = colInfo->columnHeight();
- for (size_t i = 0; i < colCount; ++i) {
+ for (unsigned i = 0; i < colCount; ++i) {
// Compute the edges for a given column in the block progression direction.
LayoutRect sliceRect = LayoutRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
if (!isHorizontalWritingMode())
@@ -5409,7 +5318,7 @@ static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
{
- LayoutUnit snappedResult = ceiledLayoutUnit(result);
+ LayoutUnit snappedResult = ceilf(result);
preferredWidth = max(snappedResult, preferredWidth);
}
@@ -5420,7 +5329,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
RenderStyle* styleToUse = style();
RenderBlock* containingBlock = this->containingBlock();
- LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : zeroLayoutUnit;
+ LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : ZERO_LAYOUT_UNIT;
// If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space.
@@ -5541,7 +5450,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
LayoutUnit ti = 0;
if (!addedTextIndent) {
addedTextIndent = true;
- ti = styleToUse->textIndent().calcMinValue(cw);
+ ti = minimumValueForLength(styleToUse->textIndent(), cw, view());
childMin += ti;
childMax += ti;
}
@@ -5612,7 +5521,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
LayoutUnit ti = 0;
if (!addedTextIndent) {
addedTextIndent = true;
- ti = styleToUse->textIndent().calcMinValue(cw);
+ ti = minimumValueForLength(styleToUse->textIndent(), cw, view());
childMin+=ti; beginMin += ti;
childMax+=ti; beginMax += ti;
}
@@ -5806,11 +5715,11 @@ LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction,
if (firstLine && document()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
- return s->computedLineHeight();
+ return s->computedLineHeight(view());
}
if (m_lineHeight == -1)
- m_lineHeight = style()->computedLineHeight();
+ m_lineHeight = style()->computedLineHeight(view());
return m_lineHeight;
}
@@ -5838,9 +5747,9 @@ LayoutUnit RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLi
bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
: (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
- int baselinePos = ignoreBaseline ? LayoutUnit(-1) : lastLineBoxBaseline();
+ LayoutUnit baselinePos = ignoreBaseline ? static_cast<LayoutUnit>(-1) : lastLineBoxBaseline();
- int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
+ LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
if (baselinePos != -1 && baselinePos <= bottomOfContent)
return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
@@ -5993,120 +5902,67 @@ static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
return 0;
}
-void RenderBlock::updateFirstLetter()
+void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* currentChild)
{
- if (!document()->usesFirstLetterRules())
- return;
- // Don't recur
- if (style()->styleType() == FIRST_LETTER)
- return;
-
- // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
- // an efficient way to check for that situation though before implementing anything.
- RenderObject* firstLetterBlock = findFirstLetterBlock(this);
- if (!firstLetterBlock)
- return;
+ RenderObject* firstLetter = currentChild->parent();
+ RenderObject* firstLetterContainer = firstLetter->parent();
+ RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
+ ASSERT(firstLetter->isFloating() || firstLetter->isInline());
- // Drill into inlines looking for our first text child.
- RenderObject* currChild = firstLetterBlock->firstChild();
- while (currChild) {
- if (currChild->isText())
- break;
- if (currChild->isListMarker())
- currChild = currChild->nextSibling();
- else if (currChild->isFloatingOrPositioned()) {
- if (currChild->style()->styleType() == FIRST_LETTER) {
- currChild = currChild->firstChild();
- break;
- }
- currChild = currChild->nextSibling();
- } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
- break;
- else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && canHaveGeneratedChildren(currChild)) {
- // We found a lower-level node with first-letter, which supersedes the higher-level style
- firstLetterBlock = currChild;
- currChild = currChild->firstChild();
- }
+ if (Node::diff(firstLetter->style(), pseudoStyle, document()) == Node::Detach) {
+ // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
+ RenderObject* newFirstLetter;
+ if (pseudoStyle->display() == INLINE)
+ newFirstLetter = new (renderArena()) RenderInline(document());
else
- currChild = currChild->firstChild();
- }
-
- if (!currChild)
- return;
-
- // If the child already has style, then it has already been created, so we just want
- // to update it.
- if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
- RenderObject* firstLetter = currChild->parent();
- RenderObject* firstLetterContainer = firstLetter->parent();
- RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
- ASSERT(firstLetter->isFloating() || firstLetter->isInline());
-
- if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
- // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
- RenderObject* newFirstLetter;
- if (pseudoStyle->display() == INLINE)
- newFirstLetter = new (renderArena()) RenderInline(document());
- else
- newFirstLetter = new (renderArena()) RenderBlock(document());
- newFirstLetter->setStyle(pseudoStyle);
-
- // Move the first letter into the new renderer.
- LayoutStateDisabler layoutStateDisabler(view());
- while (RenderObject* child = firstLetter->firstChild()) {
- if (child->isText())
- toRenderText(child)->removeAndDestroyTextBoxes();
- firstLetter->removeChild(child);
- newFirstLetter->addChild(child, 0);
- }
-
- RenderTextFragment* remainingText = 0;
- RenderObject* nextSibling = firstLetter->nextSibling();
- RenderObject* remainingTextObject = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText();
- if (remainingTextObject && remainingTextObject->isText() && toRenderText(remainingTextObject)->isTextFragment())
- remainingText = toRenderTextFragment(remainingTextObject);
- if (remainingText) {
- ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
- // Replace the old renderer with the new one.
- remainingText->setFirstLetter(newFirstLetter);
- toRenderBoxModelObject(newFirstLetter)->setFirstLetterRemainingText(remainingText);
- }
- firstLetter->destroy();
- firstLetter = newFirstLetter;
- firstLetterContainer->addChild(firstLetter, nextSibling);
- } else
- firstLetter->setStyle(pseudoStyle);
-
- for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
- if (genChild->isText())
- genChild->setStyle(pseudoStyle);
- }
+ newFirstLetter = new (renderArena()) RenderBlock(document());
+ newFirstLetter->setStyle(pseudoStyle);
+
+ // Move the first letter into the new renderer.
+ LayoutStateDisabler layoutStateDisabler(view());
+ while (RenderObject* child = firstLetter->firstChild()) {
+ if (child->isText())
+ toRenderText(child)->removeAndDestroyTextBoxes();
+ firstLetter->removeChild(child);
+ newFirstLetter->addChild(child, 0);
+ }
+
+ RenderTextFragment* remainingText = 0;
+ RenderObject* nextSibling = firstLetter->nextSibling();
+ RenderObject* remainingTextObject = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText();
+ if (remainingTextObject && remainingTextObject->isText() && toRenderText(remainingTextObject)->isTextFragment())
+ remainingText = toRenderTextFragment(remainingTextObject);
+ if (remainingText) {
+ ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
+ // Replace the old renderer with the new one.
+ remainingText->setFirstLetter(newFirstLetter);
+ toRenderBoxModelObject(newFirstLetter)->setFirstLetterRemainingText(remainingText);
+ }
+ firstLetter->destroy();
+ firstLetter = newFirstLetter;
+ firstLetterContainer->addChild(firstLetter, nextSibling);
+ } else
+ firstLetter->setStyle(pseudoStyle);
- return;
+ for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
+ if (genChild->isText())
+ genChild->setStyle(pseudoStyle);
}
+}
- if (!currChild->isText() || currChild->isBR())
- return;
-
- // If the child does not already have style, we create it here.
- RenderObject* firstLetterContainer = currChild->parent();
-
- // Our layout state is not valid for the repaints we are going to trigger by
- // adding and removing children of firstLetterContainer.
- LayoutStateDisabler layoutStateDisabler(view());
-
- RenderText* textObj = toRenderText(currChild);
-
- // Create our pseudo style now that we have our firstLetterContainer determined.
+void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild)
+{
+ RenderObject* firstLetterContainer = currentChild->parent();
RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
-
RenderObject* firstLetter = 0;
if (pseudoStyle->display() == INLINE)
firstLetter = new (renderArena()) RenderInline(document());
else
firstLetter = new (renderArena()) RenderBlock(document());
firstLetter->setStyle(pseudoStyle);
- firstLetterContainer->addChild(firstLetter, currChild);
+ firstLetterContainer->addChild(firstLetter, currentChild);
+
+ RenderText* textObj = toRenderText(currentChild);
// The original string is going to be either a generated content string or a DOM node's
// string. We want the original string before it got transformed in case first-letter has
@@ -6159,6 +6015,63 @@ void RenderBlock::updateFirstLetter()
}
}
+void RenderBlock::updateFirstLetter()
+{
+ if (!document()->usesFirstLetterRules())
+ return;
+ // Don't recur
+ if (style()->styleType() == FIRST_LETTER)
+ return;
+
+ // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
+ // an efficient way to check for that situation though before implementing anything.
+ RenderObject* firstLetterBlock = findFirstLetterBlock(this);
+ if (!firstLetterBlock)
+ return;
+
+ // Drill into inlines looking for our first text child.
+ RenderObject* currChild = firstLetterBlock->firstChild();
+ while (currChild) {
+ if (currChild->isText())
+ break;
+ if (currChild->isListMarker())
+ currChild = currChild->nextSibling();
+ else if (currChild->isFloatingOrPositioned()) {
+ if (currChild->style()->styleType() == FIRST_LETTER) {
+ currChild = currChild->firstChild();
+ break;
+ }
+ currChild = currChild->nextSibling();
+ } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
+ break;
+ else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && canHaveGeneratedChildren(currChild)) {
+ // We found a lower-level node with first-letter, which supersedes the higher-level style
+ firstLetterBlock = currChild;
+ currChild = currChild->firstChild();
+ } else
+ currChild = currChild->firstChild();
+ }
+
+ if (!currChild)
+ return;
+
+ // If the child already has style, then it has already been created, so we just want
+ // to update it.
+ if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
+ updateFirstLetterStyle(firstLetterBlock, currChild);
+ return;
+ }
+
+ if (!currChild->isText() || currChild->isBR())
+ return;
+
+ // Our layout state is not valid for the repaints we are going to trigger by
+ // adding and removing children of firstLetterContainer.
+ LayoutStateDisabler layoutStateDisabler(view());
+
+ createFirstLetterRenderer(firstLetterBlock, currChild);
+}
+
// Helper methods for obtaining the last line, computing line counts and heights for line counts
// (crawling into blocks).
static bool shouldCheckLines(RenderObject* obj)
@@ -6196,7 +6109,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
if (block->childrenInline()) {
for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
if (++count == l)
- return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : zeroLayoutUnit);
+ return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : ZERO_LAYOUT_UNIT);
}
}
else {
@@ -6205,7 +6118,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
if (shouldCheckLines(obj)) {
int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
if (result != -1)
- return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : zeroLayoutUnit);
+ return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : ZERO_LAYOUT_UNIT);
}
else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
normalFlowChildWithoutLines = obj;
@@ -6278,7 +6191,7 @@ void RenderBlock::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit&
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
FloatingObject* r = *it;
// Only examine the object if our m_shouldPaint flag is set.
- if (r->m_shouldPaint) {
+ if (r->shouldPaint()) {
LayoutUnit floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
LayoutUnit floatRight = floatLeft + r->m_renderer->width();
left = min(left, floatLeft);
@@ -6295,11 +6208,11 @@ void RenderBlock::borderFitAdjust(LayoutRect& rect) const
return;
// Walk any normal flow lines to snugly fit.
- LayoutUnit left = numeric_limits<LayoutUnit>::max();
- LayoutUnit right = numeric_limits<LayoutUnit>::min();
+ LayoutUnit left = MAX_LAYOUT_UNIT;
+ LayoutUnit right = MIN_LAYOUT_UNIT;
LayoutUnit oldWidth = rect.width();
adjustForBorderFit(0, left, right);
- if (left != numeric_limits<LayoutUnit>::max()) {
+ if (left != MAX_LAYOUT_UNIT) {
left = min(left, oldWidth - (borderRight() + paddingRight()));
left -= (borderLeft() + paddingLeft());
@@ -6308,7 +6221,7 @@ void RenderBlock::borderFitAdjust(LayoutRect& rect) const
rect.expand(-left, 0);
}
}
- if (right != numeric_limits<LayoutUnit>::min()) {
+ if (right != MIN_LAYOUT_UNIT) {
right = max(right, borderLeft() + paddingLeft());
right += (borderRight() + paddingRight());
@@ -6365,7 +6278,7 @@ void RenderBlock::setPaginationStrut(LayoutUnit strut)
m_rareData->m_paginationStrut = strut;
}
-void RenderBlock::setPageLogicalOffset(int logicalOffset)
+void RenderBlock::setPageLogicalOffset(LayoutUnit logicalOffset)
{
if (!m_rareData) {
if (!logicalOffset)
@@ -6513,14 +6426,23 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
switch (alignment) {
case alignLeft:
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset();
break;
case alignCenter:
x = (x + w - (borderRight() + paddingRight())) / 2;
+ if (currentStyle->isLeftToRightDirection())
+ x += textIndentOffset() / 2;
+ else
+ x -= textIndentOffset() / 2;
break;
case alignRight:
x = w - (borderRight() + paddingRight()) - caretWidth;
+ if (!currentStyle->isLeftToRightDirection())
+ x -= textIndentOffset();
break;
}
+ x = min(x, w - borderRight() - paddingRight() - caretWidth);
if (extraWidthToEndOfLine) {
if (isRenderBlock()) {
@@ -6593,52 +6515,13 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()));
}
-RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
-{
- RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
-
- RenderBlock* newBox = 0;
- if (isFlexibleBox) {
- newStyle->setDisplay(BOX);
- newBox = new (renderArena()) RenderDeprecatedFlexibleBox(document() /* anonymous box */);
- } else {
- newStyle->setDisplay(BLOCK);
- newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
- }
-
- newBox->setStyle(newStyle.release());
- return newBox;
-}
-
-RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
-{
- if (otherAnonymousBlock->isAnonymousColumnsBlock())
- return createAnonymousColumnsBlock();
- if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
- return createAnonymousColumnSpanBlock();
- return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
-}
-
-RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
-{
- RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
- newStyle->inheritColumnPropertiesFrom(style());
- newStyle->setDisplay(BLOCK);
-
- RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
- newBox->setStyle(newStyle.release());
- return newBox;
-}
-
-RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
+RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
{
- RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
- newStyle->setColumnSpan(ColumnSpanAll);
- newStyle->setDisplay(BLOCK);
-
- RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
- newBox->setStyle(newStyle.release());
- return newBox;
+ if (isAnonymousColumnsBlock())
+ return createAnonymousColumnsWithParentRenderer(parent);
+ if (isAnonymousColumnSpanBlock())
+ return createAnonymousColumnSpanWithParentRenderer(parent);
+ return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
}
bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
@@ -6777,7 +6660,7 @@ LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit
|| (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID);
if (!isUnsplittable)
return logicalOffset;
- LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : zeroLayoutUnit);
+ LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : ZERO_LAYOUT_UNIT);
LayoutState* layoutState = view()->layoutState();
if (layoutState->m_columnInfo)
layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
@@ -6876,7 +6759,7 @@ LayoutUnit RenderBlock::adjustBlockChildForPagination(LayoutUnit logicalTopAfter
// When the child shifts to clear an item, its width can
// change (because it has more available line width).
// So go ahead and mark the item as dirty.
- child->setChildNeedsLayout(true, false);
+ child->setChildNeedsLayout(true, MarkOnlyThis);
}
if (childRenderBlock) {
@@ -7072,20 +6955,6 @@ LayoutUnit RenderBlock::marginAfterForChild(const RenderBoxModelObject* child) c
return child->marginBottom();
}
-LayoutUnit RenderBlock::marginLogicalLeftForChild(const RenderBoxModelObject* child) const
-{
- if (isHorizontalWritingMode())
- return child->marginLeft();
- return child->marginTop();
-}
-
-LayoutUnit RenderBlock::marginLogicalRightForChild(const RenderBoxModelObject* child) const
-{
- if (isHorizontalWritingMode())
- return child->marginRight();
- return child->marginBottom();
-}
-
LayoutUnit RenderBlock::marginStartForChild(const RenderBoxModelObject* child) const
{
if (isHorizontalWritingMode())
@@ -7168,13 +7037,13 @@ void RenderBlock::setMarginAfterForChild(RenderBox* child, LayoutUnit margin)
RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
{
- int childBeforePositive = 0;
- int childBeforeNegative = 0;
- int childAfterPositive = 0;
- int childAfterNegative = 0;
+ LayoutUnit childBeforePositive = 0;
+ LayoutUnit childBeforeNegative = 0;
+ LayoutUnit childAfterPositive = 0;
+ LayoutUnit childAfterNegative = 0;
- int beforeMargin = 0;
- int afterMargin = 0;
+ LayoutUnit beforeMargin = 0;
+ LayoutUnit afterMargin = 0;
RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
@@ -7256,34 +7125,29 @@ inline void RenderBlock::FloatingObjects::clear()
m_placedFloatsTree.clear();
m_leftObjectsCount = 0;
m_rightObjectsCount = 0;
- m_positionedObjectsCount = 0;
}
inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
{
if (type == FloatingObject::FloatLeft)
m_leftObjectsCount++;
- else if (type == FloatingObject::FloatRight)
+ else
m_rightObjectsCount++;
- else
- m_positionedObjectsCount++;
}
inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
{
if (type == FloatingObject::FloatLeft)
m_leftObjectsCount--;
- else if (type == FloatingObject::FloatRight)
- m_rightObjectsCount--;
else
- m_positionedObjectsCount--;
+ m_rightObjectsCount--;
}
inline RenderBlock::FloatingObjectInterval RenderBlock::FloatingObjects::intervalForFloatingObject(FloatingObject* floatingObject)
{
if (m_horizontalWritingMode)
- return RenderBlock::FloatingObjectInterval(floatingObject->y(), floatingObject->maxY(), floatingObject);
- return RenderBlock::FloatingObjectInterval(floatingObject->x(), floatingObject->maxX(), floatingObject);
+ return RenderBlock::FloatingObjectInterval(floatingObject->pixelSnappedY(), floatingObject->pixelSnappedMaxY(), floatingObject);
+ return RenderBlock::FloatingObjectInterval(floatingObject->pixelSnappedX(), floatingObject->pixelSnappedMaxX(), floatingObject);
}
void RenderBlock::FloatingObjects::addPlacedObject(FloatingObject* floatingObject)
@@ -7371,6 +7235,45 @@ TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, c
return constructTextRun(context, font, string.characters(), string.length(), style, expansion, flags);
}
+RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderObject* parent, EDisplay display)
+{
+ // FIXME: Do we need to cover the new flex box here ?
+ // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
+ EDisplay newDisplay;
+ RenderBlock* newBox = 0;
+ if (display == BOX || display == INLINE_BOX) {
+ newBox = new (parent->renderArena()) RenderDeprecatedFlexibleBox(parent->document() /* anonymous box */);
+ newDisplay = BOX;
+ } else {
+ newBox = new (parent->renderArena()) RenderBlock(parent->document() /* anonymous box */);
+ newDisplay = BLOCK;
+ }
+
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), newDisplay);
+ newBox->setStyle(newStyle.release());
+ return newBox;
+}
+
+RenderBlock* RenderBlock::createAnonymousColumnsWithParentRenderer(const RenderObject* parent)
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
+ newStyle->inheritColumnPropertiesFrom(parent->style());
+
+ RenderBlock* newBox = new (parent->renderArena()) RenderBlock(parent->document() /* anonymous box */);
+ newBox->setStyle(newStyle.release());
+ return newBox;
+}
+
+RenderBlock* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const RenderObject* parent)
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
+ newStyle->setColumnSpan(ColumnSpanAll);
+
+ RenderBlock* newBox = new (parent->renderArena()) RenderBlock(parent->document() /* anonymous box */);
+ newBox->setStyle(newStyle.release());
+ return newBox;
+}
+
#ifndef NDEBUG
void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj) const
@@ -7388,7 +7291,7 @@ String ValueToString<int>::string(const int value)
String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::FloatingObject* floatingObject)
{
- return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->x(), floatingObject->y(), floatingObject->maxX(), floatingObject->maxY());
+ return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->pixelSnappedX(), floatingObject->pixelSnappedY(), floatingObject->pixelSnappedMaxX(), floatingObject->pixelSnappedMaxY());
}
#endif