summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderInline.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-24 16:36:50 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-24 16:36:50 +0100
commitad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch)
treeb34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/WebCore/rendering/RenderInline.cpp
parent03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff)
downloadqtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/WebCore/rendering/RenderInline.cpp')
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp135
1 files changed, 89 insertions, 46 deletions
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index a4d95c003..3be57ae0a 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -126,6 +126,33 @@ void RenderInline::updateBoxModelInfoFromStyle()
setHasReflection(false);
}
+static bool hasRelPositionedInlineAncestor(RenderObject* p)
+{
+ while (p && p->isRenderInline()) {
+ if (p->isRelPositioned())
+ return true;
+ p = p->parent();
+ }
+ return false;
+}
+
+static void updateStyleOfAnonymousBlockContinuations(RenderObject* block, const RenderStyle* newStyle, const RenderStyle* oldStyle)
+{
+ for (;block && block->isAnonymousBlock(); block = block->nextSibling()) {
+ if (!toRenderBlock(block)->isAnonymousBlockContinuation() || block->style()->position() == newStyle->position())
+ continue;
+ // If we are no longer relatively positioned but our descendant block(s) still have a relatively positioned ancestor then
+ // their containing anonymous block should keep its relative positioning.
+ RenderInline* cont = toRenderBlock(block)->inlineElementContinuation();
+ if (oldStyle->position() == RelativePosition && hasRelPositionedInlineAncestor(cont))
+ continue;
+ RefPtr<RenderStyle> blockStyle = RenderStyle::createAnonymousStyle(block->style());
+ blockStyle->setPosition(newStyle->position());
+ blockStyle->setDisplay(BLOCK);
+ block->setStyle(blockStyle);
+ }
+}
+
void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBoxModelObject::styleDidChange(diff, oldStyle);
@@ -137,13 +164,24 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
// and after the block share the same style, but the block doesn't
// need to pass its style on to anyone else.
RenderStyle* newStyle = style();
- for (RenderInline* currCont = inlineElementContinuation(); currCont; currCont = currCont->inlineElementContinuation()) {
+ RenderInline* continuation = inlineElementContinuation();
+ for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) {
RenderBoxModelObject* nextCont = currCont->continuation();
currCont->setContinuation(0);
currCont->setStyle(newStyle);
currCont->setContinuation(nextCont);
}
+ // If an inline's relative positioning has changed then any descendant blocks will need to change their relative positioning accordingly.
+ // Do this by updating the position of the descendant blocks' containing anonymous blocks - there may be more than one.
+ if (continuation && oldStyle && newStyle->position() != oldStyle->position()
+ && (newStyle->position() == RelativePosition || (oldStyle->position() == RelativePosition))) {
+ // If any descendant blocks exist then they will be in the next anonymous block and its siblings.
+ RenderObject* block = containingBlock()->nextSibling();
+ ASSERT(block && block->isAnonymousBlock());
+ updateStyleOfAnonymousBlockContinuations(block, newStyle, oldStyle);
+ }
+
if (!m_alwaysCreateLineBoxes) {
bool alwaysCreateLineBoxes = hasSelfPaintingLayer() || hasBoxDecorations() || newStyle->hasPadding() || newStyle->hasMargin() || hasOutline();
if (oldStyle && alwaysCreateLineBoxes) {
@@ -245,6 +283,11 @@ void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderOb
// the children after |beforeChild| and put them in a clone of this object.
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
newStyle->setDisplay(BLOCK);
+
+ // If inside an inline affected by relative positioning the block needs to be affected by it too.
+ // Giving the block a layer like this allows it to collect the x/y offsets from inline parents later.
+ if (hasRelPositionedInlineAncestor(this))
+ newStyle->setPosition(RelativePosition);
RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
newBox->setStyle(newStyle.release());
@@ -988,7 +1031,7 @@ LayoutRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* rep
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
// anyway if its size does change.
LayoutRect repaintRect(r);
- repaintRect.move(-cb->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
+ repaintRect.move(-cb->scrolledContentOffset()); // For overflow:auto/scroll/hidden.
LayoutRect boxRect(LayoutPoint(), cb->layer()->size());
r = intersection(repaintRect, boxRect);
@@ -1089,7 +1132,7 @@ void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer,
// o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
// anyway if its size does change.
- topLeft -= containerBox->layer()->scrolledContentOffset(); // For overflow:auto/scroll/hidden.
+ topLeft -= containerBox->scrolledContentOffset(); // For overflow:auto/scroll/hidden.
LayoutRect repaintRect(topLeft, rect.size());
LayoutRect boxRect(LayoutPoint(), containerBox->layer()->size());
@@ -1120,7 +1163,7 @@ LayoutSize RenderInline::offsetFromContainer(RenderObject* container, const Layo
container->adjustForColumns(offset, point);
if (container->hasOverflowClip())
- offset -= toRenderBox(container)->layer()->scrolledContentOffset();
+ offset -= toRenderBox(container)->scrolledContentOffset();
return offset;
}
@@ -1403,24 +1446,24 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L
const Color outlineColor)
{
RenderStyle* styleToUse = style();
- LayoutUnit outlineWidth = styleToUse->outlineWidth();
+ int outlineWidth = styleToUse->outlineWidth();
EBorderStyle outlineStyle = styleToUse->outlineStyle();
bool antialias = shouldAntialiasLines(graphicsContext);
- LayoutUnit offset = style()->outlineOffset();
+ int offset = style()->outlineOffset();
+
+ LayoutRect box(LayoutPoint(paintOffset.x() + thisline.x() - offset, paintOffset.y() + thisline.y() - offset),
+ LayoutSize(thisline.width() + offset, thisline.height() + offset));
- LayoutUnit top = paintOffset.y() + thisline.y() - offset;
- LayoutUnit left = paintOffset.x() + thisline.x() - offset;
- LayoutUnit bottom = paintOffset.y() + thisline.maxY() + offset;
- LayoutUnit right = paintOffset.x() + thisline.maxX() + offset;
+ IntRect pixelSnappedBox = pixelSnappedIntRect(box);
// left edge
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
- left,
- bottom + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
+ pixelSnappedBox.x(),
+ pixelSnappedBox.maxY() + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX() - 1) <= thisline.x() ? outlineWidth : 0),
BSLeft,
outlineColor, outlineStyle,
(lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : -outlineWidth),
@@ -1429,10 +1472,10 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L
// right edge
drawLineForBoxSide(graphicsContext,
- right,
- top - (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : 0),
- right + outlineWidth,
- bottom + (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? outlineWidth : 0),
+ pixelSnappedBox.maxX(),
+ pixelSnappedBox.y() - (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : 0),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.maxX() - 1) <= nextline.x() ? outlineWidth : 0),
BSRight,
outlineColor, outlineStyle,
(lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : -outlineWidth),
@@ -1441,31 +1484,31 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L
// upper edge
if (thisline.x() < lastline.x())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - outlineWidth,
- min(right + outlineWidth, (lastline.isEmpty() ? 1000000 : paintOffset.x() + lastline.x())),
- top,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - outlineWidth,
+ min(pixelSnappedBox.maxX() + outlineWidth, (lastline.isEmpty() ? 1000000 : paintOffset.x() + lastline.x())),
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
outlineWidth,
- (!lastline.isEmpty() && paintOffset.x() + lastline.x() + 1 < right + outlineWidth) ? -outlineWidth : outlineWidth,
+ (!lastline.isEmpty() && paintOffset.x() + lastline.x() + 1 < pixelSnappedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth,
antialias);
if (lastline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(lastline.isEmpty() ? -1000000 : paintOffset.x() + lastline.maxX(), left - outlineWidth),
- top - outlineWidth,
- right + outlineWidth,
- top,
+ max(lastline.isEmpty() ? -1000000 : paintOffset.x() + lastline.maxX(), pixelSnappedBox.x() - outlineWidth),
+ pixelSnappedBox.y() - outlineWidth,
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
- (!lastline.isEmpty() && left - outlineWidth < paintOffset.x() + lastline.maxX()) ? -outlineWidth : outlineWidth,
+ (!lastline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOffset.x() + lastline.maxX()) ? -outlineWidth : outlineWidth,
outlineWidth, antialias);
if (thisline.x() == thisline.maxX())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- top - outlineWidth,
- right + outlineWidth,
- top,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.y() - outlineWidth,
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.y(),
BSTop, outlineColor, outlineStyle,
outlineWidth,
outlineWidth,
@@ -1474,31 +1517,31 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L
// lower edge
if (thisline.x() < nextline.x())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- bottom,
- min(right + outlineWidth, !nextline.isEmpty() ? paintOffset.x() + nextline.x() + 1 : 1000000),
- bottom + outlineWidth,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.maxY(),
+ min(pixelSnappedBox.maxX() + outlineWidth, !nextline.isEmpty() ? paintOffset.x() + nextline.x() + 1 : 1000000),
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
outlineWidth,
- (!nextline.isEmpty() && paintOffset.x() + nextline.x() + 1 < right + outlineWidth) ? -outlineWidth : outlineWidth,
+ (!nextline.isEmpty() && paintOffset.x() + nextline.x() + 1 < pixelSnappedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth,
antialias);
if (nextline.maxX() < thisline.maxX())
drawLineForBoxSide(graphicsContext,
- max(!nextline.isEmpty() ? paintOffset.x() + nextline.maxX() : -1000000, left - outlineWidth),
- bottom,
- right + outlineWidth,
- bottom + outlineWidth,
+ max(!nextline.isEmpty() ? paintOffset.x() + nextline.maxX() : -1000000, pixelSnappedBox.x() - outlineWidth),
+ pixelSnappedBox.maxY(),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
- (!nextline.isEmpty() && left - outlineWidth < paintOffset.x() + nextline.maxX()) ? -outlineWidth : outlineWidth,
+ (!nextline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOffset.x() + nextline.maxX()) ? -outlineWidth : outlineWidth,
outlineWidth, antialias);
if (thisline.x() == thisline.maxX())
drawLineForBoxSide(graphicsContext,
- left - outlineWidth,
- bottom,
- right + outlineWidth,
- bottom + outlineWidth,
+ pixelSnappedBox.x() - outlineWidth,
+ pixelSnappedBox.maxY(),
+ pixelSnappedBox.maxX() + outlineWidth,
+ pixelSnappedBox.maxY() + outlineWidth,
BSBottom, outlineColor, outlineStyle,
outlineWidth,
outlineWidth,