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/RenderObject.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/RenderObject.cpp')
| -rwxr-xr-x | Source/WebCore/rendering/RenderObject.cpp | 118 |
1 files changed, 90 insertions, 28 deletions
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index 73d874416..a91b7f89c 100755 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -158,7 +158,7 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style) case RUN_IN: case COMPACT: // Only non-replaced block elements can become a region. - if (!style->regionThread().isEmpty() && doc->renderView()) + if (doc->cssRegionsEnabled() && !style->regionThread().isEmpty() && doc->renderView()) return new (arena) RenderRegion(node, doc->renderView()->ensureRenderFlowThreadWithName(style->regionThread())); return new (arena) RenderBlock(node); case LIST_ITEM: @@ -266,6 +266,16 @@ static bool isBeforeAfterContentGeneratedByAncestor(RenderObject* renderer, Rend return false; } +RenderTable* RenderObject::createAnonymousTable() const +{ + RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); + newStyle->setDisplay(TABLE); + + RenderTable* table = new (renderArena()) RenderTable(document() /* is anonymous */); + table->setStyle(newStyle.release()); + return table; +} + void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) { RenderObjectChildList* children = virtualChildren(); @@ -310,11 +320,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) if (afterChild && afterChild->isAnonymous() && afterChild->isTable() && !afterChild->isBeforeContent()) table = toRenderTable(afterChild); else { - table = new (renderArena()) RenderTable(document() /* is anonymous */); - RefPtr<RenderStyle> newStyle = RenderStyle::create(); - newStyle->inheritFrom(style()); - newStyle->setDisplay(TABLE); - table->setStyle(newStyle.release()); + table = createAnonymousTable(); addChild(table, beforeChild); } table->addChild(newChild); @@ -329,6 +335,17 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) toRenderText(newChild)->setText(textToTransform.release(), true); } + // SVG creates renderers for <g display="none">, as SVG requires children of hidden + // <g>s to have renderers - at least that's how our implementation works. Consider: + // <g display="none"><foreignObject><body style="position: relative">FOO... + // - requiresLayer() would return true for the <body>, creating a new RenderLayer + // - when the document is painted, both layers are painted. The <body> layer doesn't + // know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't. + // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree + // and stop creating layers at all for these cases - they're not used anyways. + if (newChild->hasLayer() && !layerCreationAllowedForSubtree()) + toRenderBoxModelObject(newChild)->layer()->removeOnlyThisLayer(); + if (beforeChildHasBeforeAndAfterContent) children->updateBeforeAfterContent(this, BEFORE); } @@ -790,7 +807,7 @@ bool RenderObject::mustRepaintBackgroundOrBorder() const return false; } -void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, LayoutUnit x1, LayoutUnit y1, LayoutUnit x2, LayoutUnit y2, +void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, BoxSide side, Color color, EBorderStyle style, int adjacentWidth1, int adjacentWidth2, bool antialias) { @@ -1110,7 +1127,7 @@ void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rec const AtomicString& href = static_cast<Element*>(n)->getAttribute(hrefAttr); if (href.isNull()) return; - context->setURLForRect(n->document()->completeURL(href), rect); + context->setURLForRect(n->document()->completeURL(href), pixelSnappedIntRect(rect)); } void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRect& paintRect) @@ -1124,7 +1141,7 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRe Color outlineColor = styleToUse->visitedDependentColor(CSSPropertyOutlineColor); - LayoutUnit outlineOffset = styleToUse->outlineOffset(); + int outlineOffset = styleToUse->outlineOffset(); if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) { if (!theme()->supportsFocusRing(styleToUse)) { @@ -1136,10 +1153,10 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRe if (styleToUse->outlineStyleIsAuto() || styleToUse->outlineStyle() == BNONE) return; - LayoutRect inner = paintRect; + IntRect inner = pixelSnappedIntRect(paintRect); inner.inflate(outlineOffset); - LayoutRect outer = inner; + IntRect outer = pixelSnappedIntRect(inner); outer.inflate(outlineWidth); // FIXME: This prevents outlines from painting inside the object. See bug 12042 @@ -1161,14 +1178,14 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRe outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue()); } - LayoutUnit leftOuter = outer.x(); - LayoutUnit leftInner = inner.x(); - LayoutUnit rightOuter = outer.maxX(); - LayoutUnit rightInner = inner.maxX(); - LayoutUnit topOuter = outer.y(); - LayoutUnit topInner = inner.y(); - LayoutUnit bottomOuter = outer.maxY(); - LayoutUnit bottomInner = inner.maxY(); + int leftOuter = outer.x(); + int leftInner = inner.x(); + int rightOuter = outer.maxX(); + int rightInner = inner.maxX(); + int topOuter = outer.y(); + int topInner = inner.y(); + int bottomOuter = outer.maxY(); + int bottomInner = inner.maxY(); drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth); drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth); @@ -1417,8 +1434,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta LayoutUnit shadowRight; style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight); - LayoutUnit borderRight = isBox() ? toRenderBox(this)->borderRight() : LayoutUnit(0); - LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : LayoutUnit(0); + LayoutUnit borderRight = isBox() ? toRenderBox(this)->borderRight() : zeroLayoutUnit; + LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : zeroLayoutUnit; LayoutUnit borderWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), max(borderRight, max<LayoutUnit>(style()->borderTopRightRadius().width().calcValue(boxWidth), style()->borderBottomRightRadius().width().calcValue(boxWidth)))) + max(ow, shadowRight); LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth, newOutlineBox.y(), @@ -1436,8 +1453,8 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta LayoutUnit shadowBottom; style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom); - LayoutUnit borderBottom = isBox() ? toRenderBox(this)->borderBottom() : LayoutUnit(0); - LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : LayoutUnit(0); + LayoutUnit borderBottom = isBox() ? toRenderBox(this)->borderBottom() : zeroLayoutUnit; + LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : zeroLayoutUnit; LayoutUnit borderHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), max(borderBottom, max<LayoutUnit>(style()->borderBottomLeftRadius().height().calcValue(boxHeight), style()->borderBottomRightRadius().height().calcValue(boxHeight)))) + max(ow, shadowBottom); LayoutRect bottomRect(newOutlineBox.x(), min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - borderHeight, @@ -1500,7 +1517,7 @@ void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, RenderBox* boxParent = toRenderBox(o); LayoutRect repaintRect(rect); - repaintRect.move(-boxParent->layer()->scrolledContentOffset()); // For overflow:auto/scroll/hidden. + repaintRect.move(-boxParent->scrolledContentOffset()); // For overflow:auto/scroll/hidden. LayoutRect boxRect(LayoutPoint(), boxParent->layer()->size()); rect = intersection(repaintRect, boxRect); @@ -1931,6 +1948,12 @@ void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly) if (child->style()->columnSpan()) newStyle->setColumnSpan(ColumnSpanAll); } + + // Preserve the position style of anonymous block continuations as they can have relative position when + // they contain block descendants of relative positioned inlines. + if (child->isRelPositioned() && toRenderBlock(child)->isAnonymousBlockContinuation()) + newStyle->setPosition(child->style()->position()); + newStyle->setDisplay(child->style()->display()); child->setStyle(newStyle.release()); } @@ -2006,7 +2029,7 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, b transformState.move(columnOffset); if (o->hasOverflowClip()) - transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset()); + transformState.move(-toRenderBox(o)->scrolledContentOffset()); o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState, wasFixed); } @@ -2017,7 +2040,7 @@ void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, Trans if (o) { o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); if (o->hasOverflowClip()) - transformState.move(toRenderBox(o)->layer()->scrolledContentOffset()); + transformState.move(toRenderBox(o)->scrolledContentOffset()); } } @@ -2079,7 +2102,7 @@ LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint& o->adjustForColumns(offset, point); if (o->hasOverflowClip()) - offset -= toRenderBox(o)->layer()->scrolledContentOffset(); + offset -= toRenderBox(o)->scrolledContentOffset(); return offset; } @@ -2231,6 +2254,18 @@ void RenderObject::willBeDestroyed() remove(); +#ifndef NDEBUG + if (!documentBeingDestroyed() && view() && view()->hasRenderFlowThreads()) { + // After remove, the object and the associated information should not be in any flow thread. + const RenderFlowThreadList* flowThreadList = view()->renderFlowThreadList(); + for (RenderFlowThreadList::const_iterator iter = flowThreadList->begin(); iter != flowThreadList->end(); ++iter) { + const RenderFlowThread* renderFlowThread = *iter; + ASSERT(!renderFlowThread->hasChild(this)); + ASSERT(!renderFlowThread->hasChildInfo(this)); + } + } +#endif + // If this renderer had a parent, remove should have destroyed any counters // attached to this renderer and marked the affected other counters for // reevaluation. This apparently redundant check is here for the case when @@ -2247,6 +2282,33 @@ void RenderObject::willBeDestroyed() } } +void RenderObject::destroyAndCleanupAnonymousWrappers() +{ + RenderObject* parent = this->parent(); + + // If the tree is destroyed or our parent is not anonymous, there is no need for a clean-up phase. + if (documentBeingDestroyed() || !parent || !parent->isAnonymous()) { + destroy(); + return; + } + + bool parentIsLeftOverAnonymousWrapper = false; + + // Currently we only remove anonymous cells' wrapper but we should remove all unneeded + // wrappers. See http://webkit.org/b/52123 as an example where this is needed. + if (parent->isTableCell()) + parentIsLeftOverAnonymousWrapper = parent->firstChild() == this && parent->lastChild() == this; + + destroy(); + + // WARNING: |this| is deleted here. + + if (parentIsLeftOverAnonymousWrapper) { + ASSERT(!parent->firstChild()); + parent->destroyAndCleanupAnonymousWrappers(); + } +} + void RenderObject::destroy() { willBeDestroyed(); @@ -2487,7 +2549,7 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co linethrough = decorationColor(curr); } } - if (curr->isFloating() || curr->isPositioned()) + if (curr->isFloating() || curr->isPositioned() || curr->isRubyText()) return; curr = curr->parent(); if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation()) |
