summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/RenderBlock.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-25 19:08:45 +0100
committerSteve Block <steveblock@google.com>2011-06-08 13:51:31 +0100
commit2bde8e466a4451c7319e3a072d118917957d6554 (patch)
tree28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/WebCore/rendering/RenderBlock.cpp
parent6939c99b71d9372d14a0c74a772108052e8c48c8 (diff)
downloadexternal_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz
external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/WebCore/rendering/RenderBlock.cpp')
-rw-r--r--Source/WebCore/rendering/RenderBlock.cpp292
1 files changed, 185 insertions, 107 deletions
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 7488ff5..919e23b 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -34,6 +34,7 @@
#include "HTMLFormElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
+#include "InlineIterator.h"
#include "InlineTextBox.h"
#include "PaintInfo.h"
#include "RenderCombineText.h"
@@ -51,6 +52,7 @@
#include "Settings.h"
#include "TextRun.h"
#include "TransformState.h"
+#include "visible_units.h"
#include <wtf/StdLibExtras.h>
#ifdef ANDROID_LAYOUT
@@ -243,8 +245,7 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
// FIXME: We could save this call when the change only affected non-inherited properties
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isAnonymousBlock()) {
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
if (style()->specifiesColumns()) {
if (child->style()->specifiesColumns())
newStyle->inheritColumnPropertiesFrom(style());
@@ -937,6 +938,9 @@ static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje
if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
return false;
+ if (oldChild->parent() && oldChild->parent()->isDetails())
+ return false;
+
if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
|| (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
return false;
@@ -979,8 +983,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::create();
- newStyle->inheritFrom(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
inlineChildrenBlock->setStyle(newStyle);
@@ -1136,7 +1139,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
return; // cause us to come in here. Just bail.
- if (!relayoutChildren && layoutOnlyPositionedObjects())
+ if (!relayoutChildren && simplifiedLayout())
return;
LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
@@ -1292,7 +1295,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
}
IntRect repaintRect;
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
else
repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
@@ -1331,17 +1334,21 @@ void RenderBlock::addOverflowFromChildren()
ColumnInfo* colInfo = columnInfo();
if (columnCount(colInfo)) {
IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
+ if (!hasOverflowClip())
+ addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
} else {
IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
+ if (!hasOverflowClip())
+ addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
}
}
}
@@ -1364,7 +1371,7 @@ void RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
// be considered reachable.
IntRect clientRect(clientBoxRect());
IntRect rectToApply;
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
else
rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
@@ -1422,34 +1429,31 @@ bool RenderBlock::expandsToEncloseOverhangingFloats() const
void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
{
- bool isHorizontal = style()->isHorizontalWritingMode();
- bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontal);
+ bool isHorizontal = isHorizontalWritingMode();
bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
RenderLayer* childLayer = child->layer();
- if (hasStaticInlinePosition)
- childLayer->setStaticInlinePosition(borderAndPaddingStart());
-
- if (hasStaticBlockPosition) {
- int logicalTop = logicalHeight();
- if (!marginInfo.canCollapseWithMarginBefore()) {
- child->computeBlockDirectionMargins(this);
- int marginBefore = marginBeforeForChild(child);
- int collapsedBeforePos = marginInfo.positiveMargin();
- int collapsedBeforeNeg = marginInfo.negativeMargin();
- if (marginBefore > 0) {
- if (marginBefore > collapsedBeforePos)
- collapsedBeforePos = marginBefore;
- } else {
- if (-marginBefore > collapsedBeforeNeg)
- collapsedBeforeNeg = -marginBefore;
- }
- logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
+ childLayer->setStaticInlinePosition(borderAndPaddingStart());
+
+ int logicalTop = logicalHeight();
+ if (!marginInfo.canCollapseWithMarginBefore()) {
+ child->computeBlockDirectionMargins(this);
+ int marginBefore = marginBeforeForChild(child);
+ int collapsedBeforePos = marginInfo.positiveMargin();
+ int collapsedBeforeNeg = marginInfo.negativeMargin();
+ if (marginBefore > 0) {
+ if (marginBefore > collapsedBeforePos)
+ collapsedBeforePos = marginBefore;
+ } else {
+ if (-marginBefore > collapsedBeforeNeg)
+ collapsedBeforeNeg = -marginBefore;
}
- if (childLayer->staticBlockPosition() != logicalTop) {
- childLayer->setStaticBlockPosition(logicalTop);
+ logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
+ }
+ if (childLayer->staticBlockPosition() != logicalTop) {
+ childLayer->setStaticBlockPosition(logicalTop);
+ if (hasStaticBlockPosition)
child->setChildNeedsLayout(true, false);
- }
}
}
@@ -1818,7 +1822,7 @@ void RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginIn
void RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
{
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
if (applyDelta == ApplyLayoutDelta)
view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
child->setX(logicalLeft);
@@ -1831,7 +1835,7 @@ void RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, Appl
void RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
{
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
if (applyDelta == ApplyLayoutDelta)
view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
child->setY(logicalTop);
@@ -2080,21 +2084,58 @@ void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int
ASSERT(oldLayoutDelta == view()->layoutDelta());
}
-bool RenderBlock::layoutOnlyPositionedObjects()
+void RenderBlock::simplifiedNormalFlowLayout()
{
- if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
+ if (childrenInline()) {
+ ListHashSet<RootInlineBox*> lineBoxes;
+ bool endOfInline = false;
+ RenderObject* o = bidiFirst(this, 0, false);
+ while (o) {
+ if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
+ o->layoutIfNeeded();
+ if (toRenderBox(o)->inlineBoxWrapper()) {
+ RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
+ lineBoxes.add(box);
+ }
+ } else if (o->isText() || (o->isRenderInline() && !endOfInline))
+ o->setNeedsLayout(false);
+ o = bidiNext(this, o, 0, false, &endOfInline);
+ }
+
+ // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
+ GlyphOverflowAndFallbackFontsMap textBoxDataMap;
+ for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
+ RootInlineBox* box = *it;
+ box->computeOverflow(box->lineTop(), box->lineBottom(), document()->inNoQuirksMode(), textBoxDataMap);
+ }
+ } else {
+ for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
+ if (!box->isPositioned())
+ box->layoutIfNeeded();
+ }
+ }
+}
+
+bool RenderBlock::simplifiedLayout()
+{
+ if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
return false;
LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
-
+
if (needsPositionedMovementLayout()) {
tryLayoutDoingPositionedMovementOnly();
if (needsLayout())
return false;
}
- // All we have to is lay out our positioned objects.
- layoutPositionedObjects(false);
+ // Lay out positioned descendants or objects that just need to recompute overflow.
+ if (needsSimplifiedNormalFlowLayout())
+ simplifiedNormalFlowLayout();
+
+ // Lay out our positioned objects if our positioned child bit is set.
+ if (posChildNeedsLayout())
+ layoutPositionedObjects(false);
// Recompute our overflow information.
// FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
@@ -2137,7 +2178,7 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
// non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned
// 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(style()->isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
+ if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
r->setChildNeedsLayout(true, false);
// If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
@@ -2221,6 +2262,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
// paints the root's background.
if (!isRoot()) {
IntRect overflowBox = visualOverflowRect();
+ flipForWritingMode(overflowBox);
overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
overflowBox.move(tx, ty);
if (!overflowBox.intersects(paintInfo.rect))
@@ -2259,7 +2301,7 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
- int inlineDirectionSize = style()->isHorizontalWritingMode() ? colRect.width() : colRect.height();
+ int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
// Move to the next position.
if (style()->isLeftToRightDirection()) {
@@ -2272,10 +2314,10 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
// Now paint the column rule.
if (i < colCount - 1) {
- int ruleLeft = style()->isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
- int ruleRight = style()->isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
- int ruleTop = style()->isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
- int ruleBottom = style()->isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
+ int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
+ int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
+ int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
+ int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
}
@@ -2297,8 +2339,8 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnRectAt(colInfo, i);
flipForWritingMode(colRect);
- int logicalLeftOffset = (style()->isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
- IntSize offset = style()->isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
+ int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
+ IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
colRect.move(tx, ty);
PaintInfo info(paintInfo);
info.rect.intersect(colRect);
@@ -2321,7 +2363,7 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
context->restore();
}
- int blockDelta = (style()->isHorizontalWritingMode() ? colRect.height() : colRect.width());
+ int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
if (style()->isFlippedBlocksWritingMode())
currLogicalTopOffset += blockDelta;
else
@@ -2510,7 +2552,7 @@ IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const
// This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode. We have to subtract out our left/top offsets twice, since
// it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
// case.
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
}
@@ -2738,18 +2780,18 @@ static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint&
static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
{
- return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
+ return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
}
static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
{
- return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
+ return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
}
IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
{
IntRect result;
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
result = logicalRect;
else
result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
@@ -2846,10 +2888,10 @@ GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint
selTop, paintInfo));
IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
- logicalRect.move(style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
+ logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
- if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
- || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
+ if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
+ || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
lastSelectedLine = curr;
@@ -3294,12 +3336,23 @@ bool RenderBlock::positionNewFloats()
return true;
}
-bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine)
+bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, bool firstLine, int& lineLeftOffset, int& lineRightOffset)
{
bool didPosition = positionNewFloats();
- if (!didPosition || !newFloat->m_paginationStrut)
+ if (!didPosition)
return didPosition;
+
+ int blockOffset = logicalHeight();
+ if (blockOffset >= logicalTopForFloat(newFloat) && blockOffset < logicalBottomForFloat(newFloat)) {
+ if (newFloat->type() == FloatingObject::FloatLeft)
+ lineLeftOffset = logicalRightForFloat(newFloat);
+ else
+ lineRightOffset = logicalLeftForFloat(newFloat);
+ }
+ if (!newFloat->m_paginationStrut)
+ return didPosition;
+
FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
ASSERT(floatingObjectSet.last() == newFloat);
@@ -3329,8 +3382,10 @@ bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObjec
}
}
- setLogicalHeight(logicalHeight() + paginationStrut);
-
+ setLogicalHeight(blockOffset + paginationStrut);
+ lineLeftOffset = logicalLeftOffsetForLine(logicalHeight(), firstLine);
+ lineRightOffset = logicalRightOffsetForLine(logicalHeight(), firstLine);
+
return didPosition;
}
@@ -3416,6 +3471,11 @@ HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
}
+// FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
+// present. We need to add a structure to floating objects to represent "lines" of floats. Then instead of checking
+// each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
+// the vertical offset that we'd like to check. Computing the "lines" would be rather complicated, but could replace the left
+// objects and right objects count hack that is currently used here.
int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
{
int left = fixedOffset;
@@ -3423,18 +3483,23 @@ int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool
if (heightRemaining)
*heightRemaining = 1;
+ // We know the list is non-empty, since we have "left" objects to search for.
+ // Therefore we can assume that begin != end, and that we can do at least one
+ // decrement.
FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
- FloatingObjectSetIterator end = floatingObjectSet.end();
- for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObjectSetIterator begin = floatingObjectSet.begin();
+ FloatingObjectSetIterator it = floatingObjectSet.end();
+ do {
+ --it;
FloatingObject* r = *it;
if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
&& r->type() == FloatingObject::FloatLeft
&& logicalRightForFloat(r) > left) {
- left = logicalRightForFloat(r);
+ left = max(left, logicalRightForFloat(r));
if (heightRemaining)
*heightRemaining = logicalBottomForFloat(r) - logicalTop;
}
- }
+ } while (it != begin);
}
if (applyTextIndent && style()->isLeftToRightDirection()) {
@@ -3454,18 +3519,24 @@ int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool
if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
if (heightRemaining)
*heightRemaining = 1;
+
+ // We know the list is non-empty, since we have "right" objects to search for.
+ // Therefore we can assume that begin != end, and that we can do at least one
+ // decrement.
FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
- FloatingObjectSetIterator end = floatingObjectSet.end();
- for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+ FloatingObjectSetIterator begin = floatingObjectSet.begin();
+ FloatingObjectSetIterator it = floatingObjectSet.end();
+ do {
+ --it;
FloatingObject* r = *it;
if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
&& r->type() == FloatingObject::FloatRight
&& logicalLeftForFloat(r) < right) {
- right = logicalLeftForFloat(r);
+ right = min(right, logicalLeftForFloat(r));
if (heightRemaining)
*heightRemaining = logicalBottomForFloat(r) - logicalTop;
}
- }
+ } while (it != begin);
}
if (applyTextIndent && !style()->isLeftToRightDirection()) {
@@ -3663,8 +3734,8 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
if (logicalBottom > logicalHeight()) {
// If the object is not in the list, we add it now.
if (!containsFloat(r->m_renderer)) {
- int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
- int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
+ int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
+ int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
floatingObj->m_renderer = r->m_renderer;
@@ -3712,7 +3783,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
if (!prev->m_floatingObjects)
return;
- logicalLeftOffset += (style()->isHorizontalWritingMode() ? marginLeft() : marginTop());
+ logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
FloatingObjectSetIterator prevEnd = prevSet.end();
@@ -3720,8 +3791,8 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
FloatingObject* r = *prevIt;
if (logicalBottomForFloat(r) > logicalTopOffset) {
if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
- int leftOffset = style()->isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
- int topOffset = style()->isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
+ int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
+ int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
@@ -3731,7 +3802,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, i
// into account. Only apply this code if prev is the parent, since otherwise the left margin
// will get applied twice.
if (prev != parent()) {
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
floatingObj->setX(floatingObj->x() + prev->marginLeft());
else
floatingObj->setY(floatingObj->y() + prev->marginTop());
@@ -3868,7 +3939,7 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
bool useClip = (hasControlClip() || useOverflowClip);
IntRect hitTestArea(result.rectForPoint(_x, _y));
- bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty).intersects(hitTestArea));
+ bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
if (checkChildren) {
// Hit test descendants first.
int scrolledX = tx;
@@ -3945,7 +4016,7 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
int logicalLeft = logicalLeftOffsetForContent();
int currLogicalTopOffset = 0;
int i;
- bool isHorizontal = style()->isHorizontalWritingMode();
+ bool isHorizontal = isHorizontalWritingMode();
for (i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
@@ -4038,12 +4109,12 @@ static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock*
ancestor = ancestor->parent();
// If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
- if (!ancestor || ancestor->node()->isContentEditable() == childNode->isContentEditable())
+ if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
return child->positionForPoint(pointInChildCoordinates);
// Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
int childMiddle = parent->logicalWidthForChild(child) / 2;
- int logicalLeft = parent->style()->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
+ int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
if (logicalLeft < childMiddle)
return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
@@ -4090,7 +4161,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
// pass the box a top position that is inside it
IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
- if (!style()->isHorizontalWritingMode())
+ if (!isHorizontalWritingMode())
point = point.transposedPoint();
if (closestBox->renderer()->isReplaced())
return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
@@ -4100,7 +4171,9 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
if (lastRootBoxWithChildren) {
// We hit this case for Mac behavior when the Y coordinate is below the last box.
ASSERT(moveCaretToBoundary);
- return VisiblePosition(positionForBox(lastRootBoxWithChildren->lastLeafChild(), false), DOWNSTREAM);
+ InlineBox* logicallyLastBox;
+ if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
+ return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
}
// Can't reach this. We have a root line box, but it has no kids.
@@ -4121,8 +4194,8 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
if (isReplaced()) {
// FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
- int pointLogicalLeft = style()->isHorizontalWritingMode() ? point.x() : point.y();
- int pointLogicalTop = style()->isHorizontalWritingMode() ? point.y() : point.x();
+ int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
+ int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
@@ -4135,7 +4208,7 @@ VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
offsetForContents(contentsX, contentsY);
IntPoint pointInContents(contentsX, contentsY);
IntPoint pointInLogicalContents(pointInContents);
- if (!style()->isHorizontalWritingMode())
+ if (!isHorizontalWritingMode())
pointInLogicalContents = pointInLogicalContents.transposedPoint();
if (childrenInline())
@@ -4303,7 +4376,7 @@ IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
: logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
}
@@ -4370,7 +4443,7 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
for (unsigned i = 0; i < colInfo->columnCount(); i++) {
// Add in half the column gap to the left and right of the rect.
IntRect colRect = columnRectAt(colInfo, i);
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
// FIXME: The clamping that follows is not completely right for right-to-left
@@ -4440,7 +4513,7 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = columnRectAt(colInfo, i);
IntRect repaintRect = r;
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
int currXOffset = colRect.x() - logicalLeft;
repaintRect.move(currXOffset, currLogicalOffset);
currLogicalOffset -= colRect.height();
@@ -4464,7 +4537,7 @@ IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point)
ColumnInfo* colInfo = columnInfo();
int columnLogicalHeight = colInfo->columnHeight();
int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
return IntPoint(point.x(), expandedLogicalHeight - point.y());
return IntPoint(expandedLogicalHeight - point.x(), point.y());
}
@@ -4478,7 +4551,7 @@ void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
ColumnInfo* colInfo = columnInfo();
int columnLogicalHeight = colInfo->columnHeight();
int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
rect.setY(expandedLogicalHeight - rect.maxY());
else
rect.setX(expandedLogicalHeight - rect.maxX());
@@ -4499,7 +4572,7 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
for (size_t i = 0; i < colCount; ++i) {
// Compute the edges for a given column in the block progression direction.
IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
- if (!style()->isHorizontalWritingMode())
+ if (!isHorizontalWritingMode())
sliceRect = sliceRect.transposedRect();
// If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
@@ -4508,7 +4581,7 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
// Now we're in the same coordinate space as the point. See if it is inside the rectangle.
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
return;
@@ -4851,7 +4924,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
continue;
}
- if (t->style()->hasTextCombine())
+ if (t->style()->hasTextCombine() && t->isCombineText())
toRenderCombineText(t)->combineText();
// Determine if we have a breakable character. Pass in
@@ -5064,7 +5137,7 @@ bool RenderBlock::hasLineIfEmpty() const
if (!node())
return false;
- if (node()->isContentEditable() && node()->rootEditableElement() == node())
+ if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
return true;
if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
@@ -5159,7 +5232,7 @@ int RenderBlock::lastLineBoxBaseline() const
if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
return -1;
- LineDirectionMode lineDirection = style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
+ LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
if (childrenInline()) {
if (!firstLineBox() && hasLineIfEmpty()) {
@@ -5766,6 +5839,14 @@ IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int*
case WEBKIT_RIGHT:
alignment = alignRight;
break;
+ case TASTART:
+ if (!currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
+ case TAEND:
+ if (currentStyle->isLeftToRightDirection())
+ alignment = alignRight;
+ break;
}
int x = borderLeft() + paddingLeft();
@@ -5857,8 +5938,7 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
{
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
RenderBlock* newBox = 0;
if (isFlexibleBox) {
@@ -5884,8 +5964,7 @@ RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherA
RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
{
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
newStyle->inheritColumnPropertiesFrom(style());
newStyle->setDisplay(BLOCK);
@@ -5896,8 +5975,7 @@ RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
{
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
+ RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
newStyle->setColumnSpan(true);
newStyle->setDisplay(BLOCK);
@@ -5915,7 +5993,7 @@ int RenderBlock::nextPageLogicalTop(int logicalOffset) const
// The logicalOffset is in our coordinate space. We can add in our pushed offset.
int pageLogicalHeight = layoutState->m_pageLogicalHeight;
IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
- int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
return logicalOffset + remainingLogicalHeight;
}
@@ -5976,7 +6054,7 @@ int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset,
if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
return logicalOffset;
IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
- int offset = style()->isHorizontalWritingMode() ? delta.height() : delta.width();
+ int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
if (remainingLogicalHeight < childLogicalHeight)
return logicalOffset + remainingLogicalHeight;
@@ -6012,7 +6090,7 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& d
if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
return;
IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
- int offset = style()->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
+ int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
if (remainingLogicalHeight < lineHeight) {
int totalLogicalHeight = lineHeight + max(0, logicalOffset);
@@ -6034,7 +6112,7 @@ int RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
// The child has a different directionality. If the child is parallel, then it's just
// flipped relative to us. We can use the collapsed margin for the opposite edge.
- if (child->style()->isHorizontalWritingMode() == style()->isHorizontalWritingMode())
+ if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
return child->collapsedMarginAfter();
// The child is perpendicular to us, which means its margins don't collapse but are on the
@@ -6051,7 +6129,7 @@ int RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
// The child has a different directionality. If the child is parallel, then it's just
// flipped relative to us. We can use the collapsed margin for the opposite edge.
- if (child->style()->isHorizontalWritingMode() == style()->isHorizontalWritingMode())
+ if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
return child->collapsedMarginBefore();
// The child is perpendicular to us, which means its margins don't collapse but are on the
@@ -6093,21 +6171,21 @@ int RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
int RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
{
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
}
int RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
{
- if (style()->isHorizontalWritingMode())
+ if (isHorizontalWritingMode())
return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
}
void RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
{
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
if (style()->isLeftToRightDirection())
child->setMarginLeft(margin);
else
@@ -6122,7 +6200,7 @@ void RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
void RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
{
- if (style()->isHorizontalWritingMode()) {
+ if (isHorizontalWritingMode()) {
if (style()->isLeftToRightDirection())
child->setMarginRight(margin);
else
@@ -6195,7 +6273,7 @@ RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
beforeMargin = child->marginBefore();
afterMargin = child->marginAfter();
}
- } else if (child->style()->isHorizontalWritingMode() == style()->isHorizontalWritingMode()) {
+ } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
// The child has a different directionality. If the child is parallel, then it's just
// flipped relative to us. We can use the margins for the opposite edges.
if (childRenderBlock) {