summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderBlock.cpp')
-rw-r--r--WebCore/rendering/RenderBlock.cpp169
1 files changed, 86 insertions, 83 deletions
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 7b6c817..9ea5209 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -124,7 +124,7 @@ RenderBlock::RenderBlock(Node* node)
: RenderBox(node)
, m_floatingObjects(0)
, m_positionedObjects(0)
- , m_inlineContinuation(0)
+ , m_continuation(0)
, m_maxMargin(0)
, m_lineHeight(-1)
{
@@ -169,9 +169,9 @@ void RenderBlock::destroy()
// Destroy our continuation before anything other than anonymous children.
// The reason we don't destroy it before anonymous children is that they may
// have continuations of their own that are anonymous children of our continuation.
- if (m_inlineContinuation) {
- m_inlineContinuation->destroy();
- m_inlineContinuation = 0;
+ if (m_continuation) {
+ m_continuation->destroy();
+ m_continuation = 0;
}
if (!documentBeingDestroyed()) {
@@ -500,7 +500,7 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
ASSERT(child->isAnonymousBlock());
ASSERT(!child->childrenInline());
- if (child->inlineContinuation())
+ if (child->continuation())
return;
RenderObject* firstAnChild = child->m_children.firstChild();
@@ -544,10 +544,10 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// fold the inline content back together.
RenderObject* prev = oldChild->previousSibling();
RenderObject* next = oldChild->nextSibling();
- bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() &&
- (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) &&
- (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
- (!next || (next->isAnonymousBlock() && next->childrenInline()));
+ bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline()
+ && (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->continuation())
+ && (!prev || (prev->isAnonymousBlock() && prev->childrenInline()))
+ && (!next || (next->isAnonymousBlock() && next->childrenInline()));
if (canDeleteAnonymousBlocks && prev && next) {
// Take all the children out of the |next| block and put them in
// the |prev| block.
@@ -756,7 +756,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
int repaintTop = 0;
int repaintBottom = 0;
int maxFloatBottom = 0;
- if (!firstChild())
+ if (!firstChild() && !isAnonymousBlock())
setChildrenInline(true);
if (childrenInline())
layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom);
@@ -1628,24 +1628,27 @@ 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 = colRects->at(i);
colRect.move(tx, ty);
- context->save();
-
- // Each strip pushes a clip, since column boxes are specified as being
- // like overflow:hidden.
- context->clip(colRect);
-
- // Adjust tx and ty to change where we paint.
PaintInfo info(paintInfo);
info.rect.intersect(colRect);
- // Adjust our x and y when painting.
- int finalX = tx + currXOffset;
- int finalY = ty + currYOffset;
- if (paintingFloats)
- paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
- else
- paintContents(info, finalX, finalY);
+ if (!info.rect.isEmpty()) {
+ context->save();
+
+ // Each strip pushes a clip, since column boxes are specified as being
+ // like overflow:hidden.
+ context->clip(colRect);
+
+ // Adjust our x and y when painting.
+ int finalX = tx + currXOffset;
+ int finalY = ty + currYOffset;
+ if (paintingFloats)
+ paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
+ else
+ paintContents(info, finalX, finalY);
+ context->restore();
+ }
+
// Move to the next position.
if (style()->direction() == LTR)
currXOffset += colRect.width() + colGap;
@@ -1653,8 +1656,6 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
currXOffset -= (colRect.width() + colGap);
currYOffset -= colRect.height();
-
- context->restore();
}
}
@@ -1791,8 +1792,9 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
// 6. paint continuation outlines.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
- if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
- RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
+ RenderInline* inlineCont = inlineElementContinuation();
+ if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
+ RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
if (!inlineRenderer->hasSelfPaintingLayer())
containingBlock()->addContinuationWithOutline(inlineRenderer);
else if (!inlineRenderer->firstLineBox())
@@ -1865,6 +1867,21 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
}
}
+RenderInline* RenderBlock::inlineElementContinuation() const
+{
+ return m_continuation && m_continuation->isInline() ? toRenderInline(m_continuation) : 0;
+}
+
+RenderBlock* RenderBlock::blockElementContinuation() const
+{
+ if (!m_continuation || m_continuation->isInline())
+ return 0;
+ RenderBlock* nextContinuation = toRenderBlock(m_continuation);
+ if (nextContinuation->isAnonymousBlock())
+ return nextContinuation->blockElementContinuation();
+ return 0;
+}
+
static ContinuationOutlineTableMap* continuationOutlineTable()
{
DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
@@ -1875,7 +1892,7 @@ void RenderBlock::addContinuationWithOutline(RenderInline* flow)
{
// We can't make this work if the inline is in a layer. We'll just rely on the broken
// way of painting.
- ASSERT(!flow->layer() && !flow->isInlineContinuation());
+ ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
ContinuationOutlineTableMap* table = continuationOutlineTable();
ListHashSet<RenderInline*>* continuations = table->get(this);
@@ -2009,13 +2026,13 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
}
#ifndef BUILDING_ON_TIGER
-static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, ListHashSet<RenderBox*>* positionedObjects)
+static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
{
if (!positionedObjects)
return;
- ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
- for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
+ RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
+ for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
RenderBox* r = *it;
paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height()));
}
@@ -2301,7 +2318,7 @@ void RenderBlock::insertPositionedObject(RenderBox* o)
{
// Create the list of special objects if we don't aleady have one
if (!m_positionedObjects)
- m_positionedObjects = new ListHashSet<RenderBox*>;
+ m_positionedObjects = new PositionedObjectsListHashSet;
m_positionedObjects->add(o);
}
@@ -3420,17 +3437,19 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
// We need to do multiple passes, breaking up our hit testing into strips.
- // We can always go left to right, since column contents are clipped (meaning that there
- // can't be any overlap).
Vector<IntRect>* colRects = columnRects();
- unsigned colCount = colRects->size();
+ int colCount = colRects->size();
if (!colCount)
return false;
- int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - colRects->at(0).width();
+ int left = borderLeft() + paddingLeft();
int currYOffset = 0;
- int colGap = columnGap();
- for (unsigned i = 0; i < colCount; i++) {
+ int i;
+ for (i = 0; i < colCount; i++)
+ currYOffset -= colRects->at(i).height();
+ for (i = colCount - 1; i >= 0; i--) {
IntRect colRect = colRects->at(i);
+ int currXOffset = colRect.x() - left;
+ currYOffset += colRect.height();
colRect.move(tx, ty);
#ifdef ANDROID_HITTEST_WITHSIZE
@@ -3450,14 +3469,6 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
#endif
return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
}
-
- // Move to the next position.
- if (style()->direction() == LTR)
- currXOffset += colRect.width() + colGap;
- else
- currXOffset -= (colRect.width() + colGap);
-
- currYOffset -= colRect.height();
}
return false;
@@ -3962,11 +3973,13 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
unsigned colCount = colRects->size();
if (!colCount)
return;
- int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - colRects->at(0).width();
+
+ int left = borderLeft() + paddingLeft();
+
int currYOffset = 0;
- int colGap = columnGap();
for (unsigned i = 0; i < colCount; i++) {
IntRect colRect = colRects->at(i);
+ int currXOffset = colRect.x() - left;
IntRect repaintRect = r;
repaintRect.move(currXOffset, currYOffset);
@@ -3976,11 +3989,6 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
result.unite(repaintRect);
// Move to the next position.
- if (style()->direction() == LTR)
- currXOffset += colRect.width() + colGap;
- else
- currXOffset -= (colRect.width() + colGap);
-
currYOffset -= colRect.height();
}
@@ -3993,23 +4001,18 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
return;
Vector<IntRect>& columnRects = *this->columnRects();
-
- int gapWidth = columnGap();
-
- int xOffset = style()->direction() == LTR ? 0 : contentWidth() - columnRects[0].width();
+
+ int left = borderLeft() + paddingLeft();
int yOffset = 0;
size_t columnCount = columnRects.size();
for (size_t i = 0; i < columnCount; ++i) {
IntRect columnRect = columnRects[i];
+ int xOffset = columnRect.x() - left;
if (point.y() < columnRect.bottom() + yOffset) {
offset.expand(xOffset, -yOffset);
return;
}
- if (style()->direction() == LTR)
- xOffset += columnRect.width() + gapWidth;
- else
- xOffset -= columnRect.width() + gapWidth;
yOffset += columnRect.height();
}
}
@@ -5009,12 +5012,12 @@ void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
// For blocks inside inlines, we go ahead and include margins so that we run right up to the
// inline boxes above and below us (thus getting merged with them to form a single irregular
// shape).
- if (inlineContinuation()) {
+ if (isAnonymousBlockContinuation()) {
rects.append(IntRect(tx, ty - collapsedMarginTop(),
width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
- inlineContinuation()->absoluteRects(rects,
- tx - x() + inlineContinuation()->containingBlock()->x(),
- ty - y() + inlineContinuation()->containingBlock()->y());
+ continuation()->absoluteRects(rects,
+ tx - x() + inlineElementContinuation()->containingBlock()->x(),
+ ty - y() + inlineElementContinuation()->containingBlock()->y());
} else
rects.append(IntRect(tx, ty, width(), height()));
}
@@ -5024,11 +5027,11 @@ void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
// For blocks inside inlines, we go ahead and include margins so that we run right up to the
// inline boxes above and below us (thus getting merged with them to form a single irregular
// shape).
- if (inlineContinuation()) {
+ if (isAnonymousBlockContinuation()) {
FloatRect localRect(0, -collapsedMarginTop(),
width(), height() + collapsedMarginTop() + collapsedMarginBottom());
quads.append(localToAbsoluteQuad(localRect));
- inlineContinuation()->absoluteQuads(quads);
+ continuation()->absoluteQuads(quads);
} else
quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
}
@@ -5036,26 +5039,26 @@ void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
{
IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
- if (inlineContinuation())
+ if (isAnonymousBlockContinuation())
r.inflateY(collapsedMarginTop());
return r;
}
RenderObject* RenderBlock::hoverAncestor() const
{
- return inlineContinuation() ? inlineContinuation() : RenderBox::hoverAncestor();
+ return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
}
void RenderBlock::updateDragState(bool dragOn)
{
RenderBox::updateDragState(dragOn);
- if (inlineContinuation())
- inlineContinuation()->updateDragState(dragOn);
+ if (continuation())
+ continuation()->updateDragState(dragOn);
}
RenderStyle* RenderBlock::outlineStyleForRepaint() const
{
- return inlineContinuation() ? inlineContinuation()->style() : style();
+ return isAnonymousBlockContinuation() ? continuation()->style() : style();
}
void RenderBlock::childBecameNonInline(RenderObject*)
@@ -5072,11 +5075,11 @@ void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& poi
return;
Node* n = node();
- if (inlineContinuation())
+ if (isAnonymousBlockContinuation())
// We are in the margins of block elements that are part of a continuation. In
- // this case we're actually still inside the enclosing inline element that was
+ // this case we're actually still inside the enclosing element that was
// split. Go ahead and set our inner node accordingly.
- n = inlineContinuation()->node();
+ n = continuation()->node();
if (n) {
result.setInnerNode(n);
@@ -5169,11 +5172,11 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
// For blocks inside inlines, we go ahead and include margins so that we run right up to the
// inline boxes above and below us (thus getting merged with them to form a single irregular
// shape).
- if (inlineContinuation()) {
+ if (inlineElementContinuation()) {
// FIXME: This check really isn't accurate.
- bool nextInlineHasLineBox = inlineContinuation()->firstLineBox();
+ bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
// FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
- bool prevInlineHasLineBox = toRenderInline(inlineContinuation()->node()->renderer())->firstLineBox();
+ bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
@@ -5205,10 +5208,10 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
}
}
- if (inlineContinuation())
- inlineContinuation()->addFocusRingRects(rects,
- tx - x() + inlineContinuation()->containingBlock()->x(),
- ty - y() + inlineContinuation()->containingBlock()->y());
+ if (inlineElementContinuation())
+ inlineElementContinuation()->addFocusRingRects(rects,
+ tx - x() + inlineElementContinuation()->containingBlock()->x(),
+ ty - y() + inlineElementContinuation()->containingBlock()->y());
}
RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const