diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
commit | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch) | |
tree | b34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/WebCore/rendering/RenderInline.cpp | |
parent | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff) | |
download | qtwebkit-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.cpp | 135 |
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, |